---
title: Configure order attribution for sales channel apps
description: >-
  Learn how to configure, manage, apply, and read order attribution definitions
  for a sales channel app.
source_url:
  html: 'https://shopify.dev/docs/apps/build/sales-channels/order-attribution'
  md: 'https://shopify.dev/docs/apps/build/sales-channels/order-attribution.md'
---

# Configure order attribution for sales channel apps

Sales channels receive order attribution when they send buyers to checkout with a [cart permalink](https://shopify.dev/docs/apps/build/checkout/create-cart-permalinks), [create carts](https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/cart/manage) with the Storefront API, or [create orders](https://shopify.dev/docs/api/admin-graphql/latest/mutations/orderCreate) 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](https://shopify.dev/docs/apps/build/marketing-analytics/pixels) for campaigns, ads, emails, and referrals uses other mechanisms, such as UTM parameters and Marketing Events.

***

## How it works

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`](https://shopify.dev/docs/api/admin-graphql/2026-07/mutations/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.

***

## Requirements

* Create a [sales channel app](https://shopify.dev/docs/apps/build/sales-channels).
* Add and deploy a [`channel_config` extension](https://shopify.dev/docs/apps/build/sales-channels/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.

***

## Step 1: Choose how to create attribution definitions

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

| Use case | Recommended path | Example 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.

***

## Step 2: Use channel-created definitions

For convenience, Shopify creates an attribution definition as a side effect of creating a channel connection with [`channelCreate`](https://shopify.dev/docs/api/admin-graphql/2026-07/mutations/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

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

## Variables

```json
{
  "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.

***

## Step 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

   ```bash
   shopify app generate extension --template order_attribution_config --name attribution-sources
   ```

2. Add definitions to `shopify.extension.toml`:

   ## extensions/attribution-sources/shopify.extension.toml

   ```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

   ```bash
   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.

***

## Step 4: Create or update definitions with the Graph​QL 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

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

## Variables

```json
{
  "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

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

To delete a definition, use `orderAttributionDefinitionDelete`:

## Delete an attribution definition

## Mutation

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

## Variables

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

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

***

## Step 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.

### GraphQL Admin API `orderCreate`

Use `sourceName` when you create an order with [`orderCreate`](https://shopify.dev/docs/api/admin-graphql/2026-07/mutations/orderCreate):

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

## Mutation

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

## Variables

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

### Cart permalinks

For [cart permalinks](https://shopify.dev/docs/apps/build/checkout/create-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

```text
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

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

### Storefront API carts

Use `sourceName` when you create a cart with the [Storefront API](https://shopify.dev/docs/api/storefront/unstable/mutations/cartCreate).

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

## cartCreate mutation

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

## Variables

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

***

## Step 6: Read attribution on orders

Use the `Order.attribution` field to read resolved attribution details for an order. This field replaces [`channelInformation`](https://shopify.dev/docs/api/admin-graphql/2026-07/objects/Order#field-order-channelinformation) for attribution reads.

## Read order attribution

```graphql
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.

***

## Next steps

* Learn how to [configure your channel app](https://shopify.dev/docs/apps/build/sales-channels/channel-config-extension).
* Learn how to [manage channel connections](https://shopify.dev/docs/apps/build/sales-channels/channel-connections).
* Learn how to [create cart permalinks](https://shopify.dev/docs/apps/build/checkout/create-cart-permalinks).

***
