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.
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#
| 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. |
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) {
metafield(namespace: "app--90823720961", key: "attribution_origin") {
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#
Currently Origin only supports 30-day attribution windows for metafield data: only touches whose touch_ts falls within 30 days before the order are included. The window is recorded on each value as attribution_window_days, 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": [] }