Skip to main content

Configure order attribution for sales channel apps

Sales channels receive order attribution when they send buyers to checkout with a cart permalink, create carts with the Storefront API, or create orders with the GraphQL Admin API. By default, Shopify attributes these orders to your app in the channel filter in the Shopify admin, analytics, and GraphQL Admin API.

Default app-level attribution is enough when you need to show that your sales channel app drove an order, without distinguishing among sources within the app. Create order attribution definitions when your app needs to report a more specific source within the app, such as a specific account, region, marketplace, or surface like Amazon US.

In this guide, you'll learn how to do the following tasks:

  • Create attribution definitions with an app extension.
  • Create, update, query, and delete attribution definitions with the GraphQL Admin API.
  • Use channel-created attribution definitions when sources map to channel connections.
  • Pass attribution handles when creating carts or orders.
  • Read attribution details from orders.
Note

Order attribution identifies the source that created an order. Marketing attribution for campaigns, ads, emails, and referrals uses other mechanisms, such as UTM parameters and Marketing Events.


An order attribution definition contains the label that merchants use to identify an order source:

  • handle: A stable identifier for the attribution source, scoped to your app on a single store.
  • displayName: The user-facing name for the attribution source.
  • icon: Optional sanitized SVG content displayed with the attribution source where order attribution details appear, and returned by Order.attribution.icon.

When your app creates a cart or order, it passes the attribution definition handle in the sourceName field, or the source_name parameter for cart permalinks. Shopify stores that handle on the order and uses it to resolve attribution details for the order index page, analytics, and the GraphQL Admin API.

You can create attribution definitions in three ways:

  • Channel-created definitions: Call channelCreate to create a channel connection. Shopify creates an attribution definition for the channel connection that uses the channel:<channel.handle> format, such as channel:amazon-us-a1b2c3.
  • Declarative definitions: Define static sources in the order_attribution_config extension. Use this when your app has a known set of sources, such as google-shopping and youtube.
  • GraphQL-managed definitions: Use the GraphQL Admin API to create and manage definitions for each store. Use this when sources are dynamic, such as merchant accounts, regions, or marketplace connections.

  • Create a sales channel app.
  • Add and deploy a channel_config extension. Your app must be a channel app to use order attribution definitions.
  • Use Shopify CLI 4.0.0 or higher.
  • Use GraphQL Admin API version 2026-07 or higher for order attribution definition APIs and Order.attribution.
Tip

You don't need the order_attribution_config extension if your app manages definitions only with the GraphQL Admin API or uses only channel-created definitions.


Anchor to Step 1: Choose how to create attribution definitionsStep 1: Choose how to create attribution definitions

Choose the creation path that matches how your app models order sources:

Use caseRecommended pathExample handle
Sources that map directly to channel connections.channelCreate mutation.channel:amazon-us.
Static sources that ship with your app.order_attribution_config extension.youtube.
Sources that vary by store or merchant account.orderAttributionDefinitionUpsert mutation.amazon-us-a1b2c3.

Use stable handles. After an order uses a handle, changing that handle can make historical attribution harder to resolve. To change the merchant-facing label, update displayName instead.


Anchor to Step 2: Use channel-created definitionsStep 2: Use channel-created definitions

For convenience, Shopify creates an attribution definition as a side effect of creating a channel connection with channelCreate. This supports the common case where your app attributes orders per channel connection, so you don't need to create a custom attribution definition unless you need finer- or coarser-grained attribution.

If an attribution source maps to a channel connection, create the connection with channelCreate:

POST https://{shop}.myshopify.com/admin/api/2026-07/graphql.json

Mutation

mutation ChannelCreate($input: ChannelCreateInput!) {
channelCreate(input: $input) {
channel {
id
handle
}
userErrors {
field
message
code
}
}
}

Variables

{
"input": {
"handle": "amazon-us-a1b2c3",
"specificationHandle": "amazon-us",
"accountId": "A1B2C3",
"accountName": "Amazon US"
}
}

To attribute orders to a channel-created definition, pass the channel handle returned by channelCreate with the channel: prefix. This is the handle that you provided in the channelCreate input, or the handle that Shopify generated if you didn't provide one. For example, if channelCreate returns handle: "amazon-us-a1b2c3", then pass channel:amazon-us-a1b2c3 as the source.

If channel-created definitions model all of your attribution sources, then you can skip the order_attribution_config extension and GraphQL Admin API definition steps. You can also ignore channel-created definitions and create custom definitions with the extension or GraphQL Admin API if you need finer- or coarser-grained attribution than channel connections provide.


Anchor to Step 3: Create definitions with an extensionStep 3: Create definitions with an extension

Use the order_attribution_config extension when your app has a known set of attribution sources that can be deployed with your app. This step isn't required if you only use channel-created definitions.

  1. Generate the extension:

    Terminal

    shopify app generate extension --template order_attribution_config --name attribution-sources
  2. Add definitions to shopify.extension.toml:

    extensions/attribution-sources/shopify.extension.toml

    [[extensions]]
    type = "order_attribution_config"
    name = "Attribution sources"

    [[extensions.definitions]]
    handle = "google-shopping"
    display_name = "Google Shopping"
    icon = "icons/google-shopping.svg"

    [[extensions.definitions]]
    handle = "youtube"
    display_name = "YouTube Shopping"

    The icon value must point to an SVG file. Use SVG icons where viewBox is 0 0 20 20.

  3. Deploy the extension:

    Terminal

    shopify app deploy

When a merchant installs or updates your app, Shopify syncs the extension definitions to that store. Shopify retains definitions after a merchant uninstalls your app so historical orders can still resolve attribution display details.


Anchor to Step 4: Create or update definitions with the GraphQL Admin APIStep 4: Create or update definitions with the GraphQL Admin API

Use the GraphQL Admin API when your app needs to create or update attribution definitions at runtime.

The orderAttributionDefinitionUpsert mutation creates a definition if the handle doesn't exist for your app on the store. If a definition with the same handle exists, then the mutation updates the provided fields. If you include icon, then provide sanitized SVG content where viewBox is 0 0 20 20.

POST https://{shop}.myshopify.com/admin/api/2026-07/graphql.json

Mutation

mutation UpsertOrderAttributionDefinition($input: OrderAttributionDefinitionUpsertInput!) {
orderAttributionDefinitionUpsert(input: $input) {
orderAttributionDefinition {
id
handle
displayName
icon
}
userErrors {
field
message
code
}
}
}

Variables

{
"input": {
"handle": "amazon-us-a1b2c3",
"displayName": "Amazon US",
"icon": "<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 2 2 18h16L10 2Z\" /></svg>"
}
}

To list the approved definitions for your app on a store, query orderAttributionDefinitions:

List attribution definitions

query OrderAttributionDefinitions {
orderAttributionDefinitions(first: 10) {
nodes {
id
handle
displayName
icon
}
}
}

To delete a definition, use orderAttributionDefinitionDelete:

Delete an attribution definition

Mutation

mutation DeleteOrderAttributionDefinition($id: ID!) {
orderAttributionDefinitionDelete(id: $id) {
deletedId
userErrors {
field
message
code
}
}
}

Variables

{
"id": "gid://shopify/OrderAttributionDefinition/1234567890"
}

Deleting an attribution definition doesn't change historical orders that already reference its handle.


Anchor to Step 5: Pass the attribution handle when creating carts or ordersStep 5: Pass the attribution handle when creating carts or orders

After you've created an attribution definition, pass its handle when your app creates a cart or order.

Use sourceName when you create an order with orderCreate:

POST https://{shop}.myshopify.com/admin/api/2026-07/graphql.json

Mutation

mutation OrderCreate($order: OrderCreateOrderInput!) {
orderCreate(order: $order) {
order {
id
name
sourceName
attribution {
handle
displayName
}
}
userErrors {
field
message
}
}
}

Variables

{
"order": {
"sourceName": "amazon-us-a1b2c3",
"lineItems": [
{
"variantId": "gid://shopify/ProductVariant/123",
"quantity": 1,
"priceSet": {
"shopMoney": {
"amount": "10.00",
"currencyCode": "USD"
}
}
}
]
}
}

For cart permalinks, pass source_name with the attribution handle. Include a storefront access token so Shopify can identify the app that owns the attribution definition:

Cart permalink with order attribution

https://{shop}.myshopify.com/cart/{variant_id}:{quantity}?access_token={storefront_access_token}&source_name=amazon-us-a1b2c3

To use a channel-created attribution definition, pass the attribution definition handle that Shopify creates for your app:

Cart permalink with channel-based order attribution

https://{shop}.myshopify.com/cart/{variant_id}:{quantity}?access_token={storefront_access_token}&source_name={app_attribution_definition_handle}

Anchor to Storefront API cartsStorefront API carts

Use sourceName when you create a cart with the Storefront API.

POST https://{shop}.myshopify.com/api/unstable/graphql.json

cartCreate mutation

mutation CartCreate($input: CartInput!) {
cartCreate(input: $input) {
cart {
id
checkoutUrl
}
userErrors {
field
message
}
}
}

Variables

{
"input": {
"sourceName": "channel:amazon-us-a1b2c3",
"lines": [
{
"merchandiseId": "gid://shopify/ProductVariant/123",
"quantity": 1
}
]
}
}

Anchor to Step 6: Read attribution on ordersStep 6: Read attribution on orders

Use the Order.attribution field to read resolved attribution details for an order. This field replaces channelInformation for attribution reads.

Read order attribution

query OrderAttribution($id: ID!) {
order(id: $id) {
id
name
attribution {
handle
displayName
icon
}
}
}

The attribution field returns the resolved attribution definition when one exists. If an order doesn't match a definition, then Shopify returns the app's default attribution details.

Users can use order attribution in the order index page and analytics to understand which source drove an order.



Was this page helpful?