Skip to main content

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’s source determines where its value comes from and how sourceKey is interpreted.
Reads from the attributes/context payload sent on the /recommend or /respond request. sourceKey is the attribute name.Example: track which marketing campaign drove a recommendation.
Given a request like { "attributes": { "campaign": "summer24" } }, this dimension captures campaign: "summer24" on the resulting interaction.

Capture

Active dimensions are resolved and stamped onto interaction_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, and outcome dimensions can be backfilled, because their source values are already stored verbatim on the interaction_history row (context, the decision columns, outcomeTypeKey).
  • customer_attribute dimensions 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 pipeline outcomes node, but not on plain /api/v1/respond.
  • journey dimensions 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 stamps dimensions 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.
  • --apply performs the update.
  • Only request_attribute, decision, and outcome dimensions are backfilled. customer_attribute and journey dimensions are skipped (nothing to backfill from — see History honesty). A decision dimension whose sourceKey isn’t one of offerId/channelId/creativeId/categoryId is 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.
After registering a dimension whose history you want reflected in a metric, run the backfill (if backfillable) and then recompute the metric — see Behavioral Metrics → Automatic re-aggregation.

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

Supports cursor-based pagination. Requires admin, editor, or viewer role.

Create a Dimension

Requires admin or editor role. Returns 409 Conflict if a dimension with the same key already exists for the tenant.

Update a Dimension

Pass the dimension id in the JSON body alongside the updated fields. Requires admin or editor role.

Delete a Dimension

Requires admin or editor role.
Archiving or deleting a dimension stops it from being captured on new interactions and from being offered in the Behavioral Metrics dimension picker. Metrics that already reference the dimension’s key keep computing against whatever history was already captured — review dependent metrics before removing a dimension.

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.