Overview
Dimensions are a per-tenant registry (/data/dimensions) of custom grouping keys — things like a marketing campaign, a customer’s region, or a journey stage — that extend Behavioral Metrics beyond the four built-in fixed dimensions (offerId, channelId, creativeId, outcomeType).
Once a dimension is registered and active, its key becomes a selectable entry in a metric’s groupByDimensions, and its value is stamped onto every new interaction_history row so metrics can group and filter by it.
Field Reference
name + key are unique per tenant.
Sources
Each dimension’ssource determines where its value comes from and how sourceKey is interpreted.
- request_attribute
- customer_attribute
- journey
- decision
- outcome
Reads from the Given a request like
attributes/context payload sent on the /recommend or /respond request. sourceKey is the attribute name.Example: track which marketing campaign drove a recommendation.{ "attributes": { "campaign": "summer24" } }, this dimension captures campaign: "summer24" on the resulting interaction.Capture
Active dimensions are resolved and stamped ontointeraction_history.dimensions (JSONB) at every point an interaction row is written: /api/v1/recommend, /api/v1/respond, /api/v1/respond/bulk, the pipeline’s outcomes node (third-party response-file ingestion), and batch campaign delivery. A dimension whose value is missing, null, or empty for a given interaction is simply omitted from that row’s dimensions object rather than written as an empty string.
Capture is best-effort: the tenant’s active dimension list is cached briefly, and any failure to resolve dimensions never fails or blocks the write it’s attached to — the interaction is recorded with no dimensions instead.
Not every write point has the same context available, so a dimension can resolve at some but not others:
categoryId (a decision-source dimension) is only available at /api/v1/recommend time — it isn’t threaded through the /respond, batch-campaign, or pipeline outcomes capture paths. offerId, channelId, and creativeId resolve everywhere. customer_attribute and journey are covered in History honesty below.History honesty
Whether an existing interaction has a value for a dimension you just registered depends on the dimension’s source:request_attribute,decision, andoutcomedimensions can be backfilled, because their source values are already stored verbatim on theinteraction_historyrow (context, the decision columns,outcomeTypeKey).customer_attributedimensions are forward-only — the profile is read live at capture time and never stored verbatim on the interaction row, so there’s nothing to recover after the fact. It resolves at/api/v1/recommend,/api/v1/respond/bulk, batch campaign delivery, and the pipelineoutcomesnode, but not on plain/api/v1/respond.journeydimensions are forward-only too, and today resolve nowhere at all — see the note on the journey source above.- Older interactions (or any interaction written before a dimension’s capture path existed) show as
(unset)for that dimension, in the UI and at compute time, no matter what you do.
Backfilling history
For the three backfillable sources, a one-time script retroactively stampsdimensions onto historical interaction_history rows so a newly-registered dimension works across existing data, not just interactions recorded after registration:
- Dry run by default — without
--apply, the script only reports how many rows would be updated per dimension; it mutates nothing. --applyperforms the update.- Only
request_attribute,decision, andoutcomedimensions are backfilled.customer_attributeandjourneydimensions are skipped (nothing to backfill from — see History honesty). Adecisiondimension whosesourceKeyisn’t one ofofferId/channelId/creativeId/categoryIdis also skipped, with the reason reported. - Idempotent — an interaction row is only updated when the dimension’s value is present on the row and that key isn’t already stamped in
dimensions, so re-running the script (e.g. after registering more dimensions) never overwrites a value captured live.
Using a dimension
1
Register the dimension
Go to Data > Dimensions, click + New Dimension, and set its name, key, source, and source key.
2
Add it to a metric
In Behavioral Metrics, add the dimension’s
key to a metric’s groupByDimensions (up to 4 total, mixing fixed and custom keys). The metric must use computeMode: "batch" — realtime metrics only support the four fixed dimensions.3
(Optional) backfill history
If the dimension’s source is
request_attribute, decision, or outcome and you want existing history reflected, run the backfill script above.4
Compute
Save the metric (an async recompute fires automatically) or trigger it manually via Compute Now /
POST /api/v1/behavioral-metrics/{id}/compute.5
Reference it in a rule
A Decisioning Gate of type
metric_condition can map the dimension by its registered key in dimensionMapping.API Reference
List Dimensions
admin, editor, or viewer role.
Create a Dimension
admin or editor role. Returns 409 Conflict if a dimension with the same key already exists for the tenant.
Update a Dimension
id in the JSON body alongside the updated fields. Requires admin or editor role.
Delete a Dimension
admin or editor role.
Next Steps
Behavioral Metrics
Group and filter metrics by the dimensions you register here.
Decisioning Gates
Use a dimensioned metric in a
metric_condition rule via dimensionMapping.