Metafields reference
Origin writes to JSON metafields for every processed order under the reserved app--90823720961 namespace. Each metafield holds one attribution model's data of the touches that drove the order, for one attribution window: a 30-day set is written for every store, and a 365-day set for stores on a plan that includes 365-day attribution windows.
Namespace and access#
All metafields are owned by the Order resource in the app--90823720961 namespace. Every definition uses type: json, access.admin = "merchant_read", and access.storefront = "none".
Available metafields#
There are two sets of metafields, one per attribution window. Both sets contain the same six models and share the same value shape; they differ only in which touches fall inside the window.
30-day window
Written for every processed order on every plan. Only touches within 30 days before the order are included.
| Field | Type | Description |
|---|---|---|
attribution_first_touch* required | SingleTouch | First-touch attribution — the earliest touch in the window. |
attribution_last_touch* required | SingleTouch | Last-touch attribution — the converting touch. |
attribution_linear* required | MultiTouch | Linear attribution — credit shared evenly across all touches. |
attribution_any_click* required | MultiTouch | Any-click attribution — every touch credited in full. |
attribution_last_non_direct* required | SingleTouch | Last non-direct attribution — the most recent touch carrying a UTM. |
attribution_origin* required | MultiTouch | Origin's model — the most recent touch in each channel. |
365-day window
The same six models with a _365d suffix. Only touches within 365 days before the order are included.
_365d metafields are only populated for stores subscribed to a plan that includes 365-day attribution windows. On other plans they are never written, so they will be absent from the order (the query below returns null), not empty.| Field | Type | Description |
|---|---|---|
attribution_first_touch_365d | SingleTouch | First-touch attribution over the 365-day window. |
attribution_last_touch_365d | SingleTouch | Last-touch attribution over the 365-day window. |
attribution_linear_365d | MultiTouch | Linear attribution over the 365-day window. |
attribution_any_click_365d | MultiTouch | Any-click attribution over the 365-day window. |
attribution_last_non_direct_365d | SingleTouch | Last non-direct attribution over the 365-day window. |
attribution_origin_365d | MultiTouch | Origin's model over the 365-day window. |
How each model assigns credit and attributed_revenue is described in Attribution models.
How to read them#
Read Metafield values through the Shopify Admin GraphQL API, Shopify Flow, or an order export (anywhere the merchant’s Admin scope reaches). They are not exposed to the storefront or Storefront API.
query OrderAttribution($id: ID!) {
order(id: $id) {
thirtyDay: metafield(namespace: "app--90823720961", key: "attribution_origin") {
type
value
}
# null unless the store's plan includes 365-day attribution windows
yearLong: metafield(namespace: "app--90823720961", key: "attribution_origin_365d") {
type
value
}
}
}metafield.value before reading fields from it.Value shape#
Every value is an object carrying the attribution window and touches.
- single-touch models hold one
touchornull - multi-touch models hold an ordered
touchesarray (touch_tsascending, except forattribution_originwhich is unordered)
Attribution window#
Each metafield covers a single attribution window: only touches whose touch_ts falls within that many days before the order are included. The unsuffixed metafields use a 30-day window and are written for every store; the _365d metafields use a 365-day window and are only written for stores on a plan that includes 365-day attribution windows. The window is recorded on each value as attribution_window_days (30 or 365), so every metafield is self-describing.
SingleTouch
type SingleTouch = {
attribution_window_days: number;
touch: AttributionTouch | null; // null when no touch falls in the window
}MultiTouch
type MultiTouch = {
attribution_window_days: number;
touches: AttributionTouch[]; // [] when no touch falls in the window
}The touch object#
Each AttributionTouch describes one touchpoint and the credit it received under that model. String fields default to "" when Origin has no value for them.
| Field | Type | Description |
|---|---|---|
utm_source | string | utm_source captured on the touch. |
utm_medium | string | utm_medium captured on the touch. |
utm_campaign | string | utm_campaign captured on the touch. |
utm_content | string | utm_content captured on the touch. |
utm_term | string | utm_term captured on the touch. |
landing_page | string | URL the visitor landed on for this touch. |
touch_ts* required | string | ISO 8601 timestamp of the touch, in UTC. |
credit* required | number | Credit assigned by the touch between 0 - 1. |
attributed_revenue* required | number | Order revenue attributed to this touch: credit * order total, in the order’s currency. |
ad_platform_key | string | Ad platform when the touch is linked to an ad or campaign, e.g. meta or google. Empty otherwise. |
ad_external_id | string | Platform ad ID, when the touch is linked to a specific ad. |
ad_campaign_external_id | string | Platform campaign ID, when the touch is linked to a campaign but not a specific ad. |
ad_external_id; a touch linked only to a campaign fills ad_campaign_external_id.Example#
attribution_linear for an order of 129.00 with two touches in the window — credit and revenue split evenly:
{
"attribution_window_days": 30,
"touches": [
{
"utm_source": "google",
"utm_medium": "cpc",
"utm_campaign": "brand-search",
"utm_content": "",
"utm_term": "",
"landing_page": "https://shop.example.com/?utm_source=google&utm_medium=cpc&utm_campaign=brand-search",
"touch_ts": "2026-05-10T14:02:11.000Z",
"credit": 0.5,
"attributed_revenue": 64.5,
"ad_platform_key": "google",
"ad_external_id": "",
"ad_campaign_external_id": "97431001"
},
{
"utm_source": "facebook",
"utm_medium": "paid_social",
"utm_campaign": "spring-retargeting",
"utm_content": "carousel-a",
"utm_term": "",
"landing_page": "https://shop.example.com/products/hydrating-serum?utm_source=facebook&utm_medium=paid_social&utm_campaign=spring-retargeting&utm_content=carousel-a",
"touch_ts": "2026-05-18T09:47:55.000Z",
"credit": 0.5,
"attributed_revenue": 64.5,
"ad_platform_key": "meta",
"ad_external_id": "120210000000123456",
"ad_campaign_external_id": ""
}
]
}A model with no qualifying touch in the window still records the window:
// attribution_last_non_direct — every in-window touch was direct
{ "attribution_window_days": 30, "touch": null }
// attribution_linear — no touches in the window
{ "attribution_window_days": 30, "touches": [] }