> For the complete documentation index, see [llms.txt](https://docs.appmixer.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.appmixer.com/connector-configuration/shopify.md).

# Shopify

Configure the Shopify.

{% hint style="info" %}
The setup depends on the connector version:

* **Version 3 and later** — OAuth 2.0. You register one Shopify app and users connect their store through its consent screen. Version 4 calls the GraphQL Admin API only, which Shopify requires of new public apps in the App Store; version 3 calls the REST Admin API. Both use the same app setup; only the scopes differ (see below).
* **Version 2.x** — an Admin API access token that each user creates in their own store admin. Shopify stopped allowing new custom apps to be created there on January 1, 2026, so this only works for stores that already have such an app.
* **Version 1.x** — the legacy OAuth 2.0 setup at the end of this page.
  {% endhint %}

## Version 3 and Later: OAuth 2.0 Application

You register a Shopify app once and store its credentials in the Backoffice. Users then connect a store by entering its address and approving the app on Shopify's consent screen, which shows your app's name and logo.

### Create the App

1. Open the [Shopify Dev Dashboard](https://dev.shopify.com/dashboard), go to **Apps** and click **Create app**. Choose **Start from Dev Dashboard**, enter the app name and click **Create**.
2. On the **Versions** page fill in:
   * **App URL**: the URL of your product or of your Appmixer instance.
   * **Embed app in Shopify admin**: off.
   * **Scopes**: a comma-separated list. All scopes the connector version 4 uses:

     ```
     read_customers,write_customers,read_products,write_products,read_orders,write_orders,read_draft_orders,read_fulfillments,read_inventory,read_locations,read_reports,read_returns,read_discounts,write_discounts,read_publications,write_publications
     ```

     For version 3, replace `read_publications,write_publications` with `read_price_rules,write_price_rules`. See [What the Scopes Are For](#what-the-scopes-are-for) to leave out the ones of components you do not offer.
   * **Redirect URLs**: `https://[YOUR_API_BASE]/auth/shopify/callback`, for example `https://api.appmixer.com/auth/shopify/callback`.
   * **Webhooks API version**: the latest one.
3. Click **Release**.
4. Open the app **Settings** and note the **Client ID** and **Client secret** in the **Credentials** card.

{% hint style="warning" %}
Shopify grants the scopes configured in the app version, not the ones the connector asks for. A component whose scope is missing in the app answers `403 Forbidden`. After you change the scopes, release a new version and reconnect the Shopify account in Appmixer so that the store owner approves them.
{% endhint %}

{% hint style="info" %}
`read_orders` covers the orders of the last 60 days only. For older orders, request the **Read all orders scope** under **API access requests** in the Partner Dashboard (it needs Shopify's approval) and add `read_all_orders` to the scopes of the app.
{% endhint %}

### What the Scopes Are For

The connector asks for all its scopes in one consent: Shopify keeps one valid token per app and store, so a second consent for more scopes would invalidate the first. The scopes that version 4 components need:

* `read_customers` — the customer components and triggers, and every component that returns orders, draft orders or checkouts (they include the customer).
* `write_customers` — **Create**, **Update** and **Delete Customer**.
* `read_orders` — the order components and triggers, **New Refund**, the fulfillment, checkout and draft order triggers, **Abandoned Cart**, **Return Tracking**, and the customer components (they include the customer's last order).
* `write_orders` — **Create**, **Update** and **Delete Order**.
* `read_products`, `write_products` — the product components and triggers; **Create Order** and **Inventory Level Updated** read products too.
* `read_publications`, `write_publications` — **Create Product** and **Update Product**, to publish a product to the Online Store (**Publish to Online Store**).
* `read_draft_orders` — **New Draft Order**, **Updated Draft Order**.
* `read_fulfillments` — **New Fulfillment**, **Updated Fulfillment**.
* `read_inventory`, `read_locations` — **Inventory Level Updated**.
* `read_returns` — **Return Tracking**.
* `read_discounts`, `write_discounts` — **Create**, **Get** and **Delete Discount Code**.
* `read_reports` — **Run Report**, **Sales Report**, **Payments Report**.

**Make API Call** declares all of them, so it can reach any of these resources.

### Choose the Distribution

In the [Partner Dashboard](https://partners.shopify.com), open **Apps**, select the app, go to **Distribution** and choose **Public distribution**. Custom distribution limits the app to a single store (or one Shopify Plus organization), and the choice cannot be changed later. Once chosen, the page shows the **Shopify App Store listing** card; you do not have to submit the app to use it on development stores.

{% hint style="warning" %}
A public app that is not published can only be installed on development stores. To connect production stores, the app has to pass Shopify's app review. This guide does not cover all the requirements of the review.
{% endhint %}

### Request Protected Customer Data Access

Customers, orders, draft orders, checkouts, fulfillments, refunds and returns are protected customer data. Until the app has access to it, these components and triggers answer `403 Forbidden`, even on a development store. The distribution has to be chosen first.

1. In the Partner Dashboard, open **Apps**, select the app and click **API access requests** in the sidebar.
2. In **Protected customer data access**, click **Request access**.
3. Under **Select your data use and reasons**, open **Protected customer data**, tick the reasons that describe how your product uses the data (for example **Store management** and **App functionality**) and click **Save**.
4. In **Protected customer fields (optional)**, select **Name**, **Email**, **Phone** and **Address** the same way and save each. Without them Shopify returns these fields empty.

<figure><img src="https://802996127-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIAGKHlIqVKJe9agnFr14%2Fuploads%2Fgit-blob-088ba9f7374c605ef8e5b4b484238f72ce5c0d42%2Fshopify_img_8.png?alt=media" alt=""><figcaption></figcaption></figure>

On development stores the access works as soon as the steps above are saved — the request stays in the **Draft** state and does not have to be submitted. Before you submit the app for review, also fill in the **Data protection details**:

<figure><img src="https://802996127-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIAGKHlIqVKJe9agnFr14%2Fuploads%2Fgit-blob-f1cb40f5a4035d8313114c9862d51f684436fd2c%2Fshopify-data-protection.png?alt=media" alt=""><figcaption></figcaption></figure>

### Compliance Webhooks

A public app has to provide Shopify's mandatory compliance webhooks. The connector implements them; set these URLs in the app:

* Customer data request endpoint: `https://[YOUR_API_BASE]/plugins/appmixer/shopify/customers/data_request`
* Customer data erasure endpoint: `https://[YOUR_API_BASE]/plugins/appmixer/shopify/customers/redact`
* Shop data erasure endpoint: `https://[YOUR_API_BASE]/plugins/appmixer/shopify/shop/redact`

The connector verifies the signature of each request with the client secret and stores the request. An administrator can list the stored requests with a `GET` request to the same URLs.

### Configuration in the Backoffice

* Configure the Client ID as `clientId` and the Client secret as `clientSecret` in the service settings within the Backoffice, under the configuration ID `appmixer:shopify`.
* To learn more about configuring connectors, please visit the [Connector Configuration](https://docs.appmixer.com/appmixer/getting-started/services) section.

### Connect Your Account in Appmixer

When adding a Shopify account in Appmixer, enter the **Store Address** — the store subdomain without `.myshopify.com` (for example `my-store` for `my-store.myshopify.com`) — and approve the app on the Shopify consent screen.

{% hint style="info" %}
Shopify keeps one valid access token per app and store. Connecting the same store a second time (as another account or by another user) invalidates the earlier account within an hour, so connect each store only once. The access token is refreshed automatically; an account that is not used for 90 days has to be reconnected.
{% endhint %}

## Version 2.x: Admin API Access Token

{% hint style="warning" %}
Shopify no longer allows new custom apps to be created in the store admin (since January 1, 2026). The steps below can only be followed in a store where **Develop apps** already contains such an app. For new setups use connector version 4.
{% endhint %}

There is nothing to register or configure in the Backoffice. Every user generates their own access token directly in their Shopify store admin by creating a custom app:

### Create a Custom App in Your Shopify Admin

1. Log in to your Shopify admin and go to **Settings → Apps and sales channels → Develop apps**. The direct link is `https://admin.shopify.com/store/<your-store>/settings/apps/development`, where `<your-store>` is the store subdomain (for example `my-store` for `my-store.myshopify.com`). This is also where you later change the scopes of an existing app: open the app, then **Configuration → Admin API integration → Edit**. Scopes added to an installed app apply to its existing access token as soon as you save — there is no need to generate a new token or reconnect the account in Appmixer.
2. If app development is not enabled yet, click **Allow custom app development** and confirm.
3. Click **Create an app**, enter a name (for example `Appmixer`) and click **Create app**.

### Configure API Scopes

1. On the app detail page, open the **Configuration** tab and click **Configure** in the **Admin API integration** section.
2. Enable the following scopes (required by the Appmixer Shopify components):
   * `read_customers`, `write_customers`
   * `read_products`, `write_products`
   * `read_orders`, `write_orders`
3. If you use the additional components, also enable the scopes they depend on. Enable only the ones you need:
   * `read_reports` — **Run Report**, **Sales Report**, **Payments Report**
   * `read_price_rules`, `write_price_rules`, `read_discounts`, `write_discounts` — **Create Discount Code**, **Get Discount Code** (connector version 2.1.0 and later). Without them Shopify answers `403 — This action requires merchant approval for write_price_rules scope`.
   * `read_draft_orders` — **New Draft Order**, **Updated Draft Order**
   * `read_fulfillments` — **New Fulfillment**, **Updated Fulfillment**
   * `read_inventory`, `read_locations` — **Inventory Level Updated**
   * `read_returns` — **Return Tracking** (also requires the store's Shopify API version to be **2023-10 or later** — the Returns API does not exist on older versions)
   * `read_orders` (already enabled above) covers **New Paid Order**, **New Refund**, **New / Updated Checkout** and **Abandoned Cart** — Shopify has no separate checkout scope; checkouts and abandoned checkouts are part of the orders scope.
4. Click **Save**.

{% hint style="info" %}
The **report** components run ShopifyQL queries through the GraphQL Admin API. They need only `read_reports` and also work on Basic and development stores.
{% endhint %}

### Generate the Access Token

1. Open the **API credentials** tab and click **Install app**, then confirm with **Install**.
2. In the **Admin API access token** section, click **Reveal token once** and copy the token (it starts with `shpat_`).

{% hint style="warning" %}
The token is displayed **only once**. If you lose it, uninstall and reinstall the app on the **API credentials** tab to generate a new one.
{% endhint %}

### Connect Your Account in Appmixer

When adding a Shopify account in Appmixer, fill in:

* **Store Address**: your store subdomain without `.myshopify.com` (for example `my-store` for `my-store.myshopify.com`)
* **Admin API Access Token**: the `shpat_...` token generated above

## Trigger Components

Alongside the customer, order, product, report and discount code actions, the connector provides trigger components that start a flow when something happens in the store. Most are webhook-based (Shopify calls Appmixer in real time); **Abandoned Cart** polls the store's abandoned checkouts because Shopify has no cart-abandoned webhook.

In version 4, a webhook trigger subscribes to its topic when the flow starts and removes the subscription when the flow stops. When a webhook arrives, the trigger reads the object through the GraphQL Admin API, so it emits the same fields as the matching Get and Find components. Scopes needed in version 4:

| Trigger                                                                        | Fires when                                                                        | Scopes (version 4)                                   |
| ------------------------------------------------------------------------------ | --------------------------------------------------------------------------------- | ---------------------------------------------------- |
| New Order / Updated Order / Cancelled Order / Fulfilled Order / New Paid Order | an order is created / updated / cancelled / fulfilled / paid                      | `read_orders`, `read_customers`                      |
| Deleted Order                                                                  | an order is deleted (emits its id)                                                | `read_orders`                                        |
| New Refund                                                                     | a refund is created on an order                                                   | `read_orders`                                        |
| New Fulfillment / Updated Fulfillment                                          | a fulfillment is created / updated (tracking or shipment status changes)          | `read_orders`, `read_fulfillments`                   |
| New Checkout / Updated Checkout                                                | a checkout is created / updated in the online store                               | `read_orders`, `read_customers`                      |
| Abandoned Cart                                                                 | a checkout is abandoned (polled)                                                  | `read_orders`, `read_customers`                      |
| New Draft Order / Updated Draft Order                                          | a draft order is created / updated                                                | `read_draft_orders`, `read_orders`, `read_customers` |
| Inventory Level Updated                                                        | an inventory level changes (e.g. for low-stock alerts)                            | `read_inventory`, `read_locations`, `read_products`  |
| Return Tracking                                                                | a return is requested, approved, declined, cancelled, closed, reopened or updated | `read_returns`, `read_orders`                        |
| New Customer / Updated Customer                                                | a customer is created / updated                                                   | `read_customers`, `read_orders`                      |
| Deleted Customer                                                               | a customer is deleted (emits its id)                                              | `read_customers`                                     |
| New Product / Updated Product / Deleted Product                                | a product is created / updated / deleted                                          | `read_products`                                      |

{% hint style="info" %}
A checkout has an id only once Shopify lists it as abandoned, that is after the buyer entered contact details. Until then **New Checkout** and **Updated Checkout** emit the checkout token alone; afterwards they emit the whole abandoned checkout. **Abandoned Cart** sees a checkout about 10 minutes after it was abandoned.
{% endhint %}

Make sure the corresponding scopes are enabled on the app, otherwise the trigger fails to register or returns `403 Forbidden`.

## Version 1.x (Legacy): OAuth 2.0 Application

{% hint style="warning" %}
The OAuth setup below is only needed for connector versions 1.x. Note that only a 'developer' shop instance can be authenticated with your OAuth application unless your app is verified by Shopify. 'Production' shop instances cannot authenticate with an unverified app. This guide does not cover all the requirements for the app verification process.
{% endhint %}

#### Setting Up a Shopify Partner Account

**Sign Up or Log In**: If you haven’t already, go to the [Shopify Partners page](https://partners.shopify.com) and sign up for an account. If you have an account, just log in.

#### Create a New App

**Create a New App**: Once logged in, navigate to the "Apps" section using the dashboard menu. Click on "Create app" to get started, select the "Create app manually"

<figure><img src="https://802996127-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIAGKHlIqVKJe9agnFr14%2Fuploads%2Fgit-blob-69cf04673b6a071431be33c77bb1182eef2e851f%2Fshopify_img_5.png?alt=media" alt=""><figcaption></figcaption></figure>

Note the `clientId` and `clientSecret`. Next, click on the "Choose distribution"

<figure><img src="https://802996127-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIAGKHlIqVKJe9agnFr14%2Fuploads%2Fgit-blob-16ae94113fc5bdcce4191c25598054c9a44f6f1e%2Fshopify_img_6.png?alt=media" alt=""><figcaption></figcaption></figure>

Select the "Public distribution" option

<figure><img src="https://802996127-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIAGKHlIqVKJe9agnFr14%2Fuploads%2Fgit-blob-e6cc804aa607cb6d1d370917329eb34f648cee67%2Fshopify_img_7.png?alt=media" alt=""><figcaption></figcaption></figure>

Go to the "Configuration" section from the main menu

* set the Redirect URI to `https://[YOUR_API_BASE]/auth/shopify/callback`, for example `https://api.appmixer.com/auth/shopify/callback`
* event version to the latest (2024-01)
* Embed app in Shopify admin: `false`
* set the compliance webhooks (it's required for the submission)
  * Customer data request endpoint: `https://[YOUR_API_BASE]/plugins/appmixer/shopify/customers/data_request`
  * Customer data erasure endpoint: `https://[YOUR_API_BASE]/plugins/appmixer/shopify/customers/redact`
  * Shop data erasure endpoint: `https://[YOUR_API_BASE]/plugins/appmixer/shopify/shop/redact`
*

![](https://802996127-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIAGKHlIqVKJe9agnFr14%2Fuploads%2Fgit-blob-b1d7dbd10b9b9918d567da085e0bb7f4205e27e4%2Fshopify-2.png?alt=media)

Go to the "API Access" section from the main menu. In the "Access requests" request access for the "Protected customer data access" Fill details in the "Select your data use and reasons" section:

<figure><img src="https://802996127-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIAGKHlIqVKJe9agnFr14%2Fuploads%2Fgit-blob-088ba9f7374c605ef8e5b4b484238f72ce5c0d42%2Fshopify_img_8.png?alt=media" alt=""><figcaption></figcaption></figure>

Fill the form in the "Provide your data protection details" section:

<figure><img src="https://802996127-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIAGKHlIqVKJe9agnFr14%2Fuploads%2Fgit-blob-f1cb40f5a4035d8313114c9862d51f684436fd2c%2Fshopify-data-protection.png?alt=media" alt=""><figcaption></figcaption></figure>

#### Configuration in the Backoffice

* Configure the App Key as `clientId` and the App Secret as `clientSecret` in the service settings within the Backoffice, under the configuration ID `appmixer:shopify`. Also, add the `appStoreInstallRedirectUri` pointing to your instance, for example `https://my.master-hamster-87765.appmixer.cloud/`
* To learn more about configuring connectors, please visit the [Connector Configuration](https://docs.appmixer.com/appmixer/getting-started/services) section.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.appmixer.com/connector-configuration/shopify.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
