Manage webhook subscriptions
A webhook subscription tells Shopify which events your app is interested in and where to deliver them.
This page covers the subscription configuration options, including how to choose between subscription types and delivery methods. To shape the content of each delivery, see Delivery structure and Delivery filtering.
Anchor to RequirementsRequirements
Each topic you subscribe to requires a corresponding access scope. See the Webhooks reference for the full list of topics and their required scopes.
If your app is distributed through the Shopify App Store, it must be subscribed to Shopify's mandatory compliance topics. You can create mandatory compliance webhook subscriptions in Dev Dashboard or by updating your app configuration file.
Anchor to VersioningVersioning
Like most Shopify APIs, webhooks are versioned. Shopify recommends updating to the latest stable API version each quarter.
The api_version field in [webhooks] controls the GraphQL Admin API version used to serialize payloads for all app-specific subscriptions:
shopify.app.toml
For shop-specific subscriptions created using the GraphQL Admin API, the version is determined by the request URL.
Each delivery includes the API version that serialized its payload. For HTTPS deliveries, check the X-Shopify-API-Version header. For Google Cloud Pub/Sub or Amazon EventBridge, the version appears in the message payload instead.
Before updating api_version, test the new version against your handler code using the CLI:
Pass with the flags shown above, or run the command with no parameters and follow the prompts. Your existing subscriptions will continue using the earlier version until you update and deploy.
Anchor to Update the API versionUpdate the API version
App configuration file
- Set
webhooks.api_versionto the new version inshopify.app.toml. - Save the file. If
app devis running, the version updates automatically for your dev store. - Run
shopify app deployto release the change to production.
Dev Dashboard
- From your Dev Dashboard, go to Apps.
- Click on your app.
- Click Versions → Create a version.
- In the Webhooks API Version field, select the newer API version.
- Click Release.
- Set
webhooks.api_versionto the new version inshopify.app.toml. - Save the file. If
app devis running, the version updates automatically for your dev store. - Run
shopify app deployto release the change to production.
Anchor to Subscription typesSubscription types
Shopify supports two ways to configure webhook subscriptions:
- App-specific subscriptions: (Recommended) Defined in
shopify.app.tomland applied uniformly across every shop that installs your app. - Shop-specific subscriptions: Created using GraphQL Admin API; configuration can differ per shop.
Choose app-specific subscriptions unless your topics, delivery URIs, or filters need to vary between shops. Use the table below to compare the capabilities and behavior of these two options:
| App-specific | Shop-specific | |
|---|---|---|
| Compliance topics | Supported. See Privacy law compliance. | Can be configured in your app configuration file. Cannot be subscribed to using the Admin API. |
| Differentiating between methods | Available in the Subscription Method field in Logs | Available in the Subscription Method field in Logs |
| Identifying your subscriptions | No ID, denoted config-managed | Available as the Subscription ID field in Logs. Query by subscription ID. |
| Interface for management | Your app configuration file | GraphQL Admin API |
| Metafield namespaces | Does not support metafieldNamespaces | metafieldNamespaces can be used as an input field (example). |
| Scopes | Requires scopes in your app configuration file | Scopes can be configured in your app configuration file or in your Dev Dashboard. They cannot be set using the Admin API. |
| Topics | Supports every topic except product_feeds/full_sync, product_feeds/full_sync_finish, and product_feeds/incremental_sync. | Supports every topic. |
| Troubleshooting | Failing subscriptions will not be deleted by Shopify. | Failing subscriptions will be deleted by Shopify. |
| Viewing subscriptions | Available under Subscriptions in your app's Dev Dashboard > Versions > Configuration | Query the GraphQL Admin API (example). |
Shopify recommends using Google Pub/Sub as a cloud-based solution for delivering webhooks. You can also use Amazon EventBridge. If you prefer to build your own webhooks infrastructure, you can deliver through HTTPS, but there are extra considerations to take into account.
If you have shop-specific subscriptions and are migrating to app-specific subscriptions, remove existing subscriptions to the same topics first to avoid conflicts and duplicate notifications. See Migrate to app-specific subscriptions.
Anchor to App-specific subscriptionsApp-specific subscriptions
You can subscribe your app to webhook topics using your app configuration file, rather than using the Admin API. Use this to configure and manage your subscriptions across all shops where your app is installed. Shopify recommends subscribing to webhooks using this approach.
App-specific subscription
shopify.app.toml
[webhooks]
api_version = "2026-04"
[[webhooks.subscriptions]]
topics = ["products/create"]
uri = "https://your-app.example.com/webhooks/products"{} Response
{
"id": 9554194432293,
"title": "T-Shirt",
"status": "active",
"vendor": "My Store",
"product_type": "Shirts",
"variants": [
{
"id": 123456789,
"title": "Default Title",
"price": "29.99",
"sku": "TSHIRT-001"
}
],
"tags": "cotton, comfortable"
}Anchor to Subscription fieldsSubscription fields
Each webhook subscription is defined by a [[webhooks.subscriptions]] entry in your shopify.app.toml file.
Every subscription requires the following fields:
| Field | Purpose |
|---|---|
topics | One or more topic names to subscribe to (for example products/create). |
uri | Delivery destination. HTTPS URL, AWS EventBridge ARN, or Google Pub/Sub URI. |
Additional optional fields are available for filtering deliveries, defining their response structure, and identifying subscriptions:
| Field | Purpose |
|---|---|
include_fields | Fields to include in the payload. If omitted, the full payload is sent. See Delivery filtering. |
filter | Filter expression to gate deliveries. See Delivery filtering. |
name | Subscription name. Shopify echoes this in the X-Shopify-Name header. Use to label and differentiate subscriptions to the same topic. Alphanumeric, -, _, up to 50 characters. |
Anchor to Migrate to app-specific subscriptionsMigrate to app-specific subscriptions
If you have shop-specific subscriptions already, and are migrating your app to app-specific subscriptions, then make sure you first remove any existing webhook subscriptions to the same topics. This avoids potential conflicts and duplicate notifications.
- Check the list of existing shop-specific webhook topics your app is subscribed to by using the GraphQL Admin API
webhookSubscriptionsquery. - Delete the relevant queries, subscription, and handler code from your app.
- Deploy a new version of your app by running
shopify app deploy. You can check that your subscriptions have been deleted by checking the Versions page for your app in the Dev Dashboard. - Configure your app to subscribe to app-specific subscriptions. Refer to the create a subscription tutorial to get started.
Anchor to Shop-specific subscriptionsShop-specific subscriptions
To subscribe to webhook topics where the configuration depends on the shop your app is installed on, use the GraphQL Admin API.
For the available input fields, see WebhookSubscriptionInput.
React Router template
Shopify recommends that you use the Shopify CLI and React Router template when subscribing to webhooks using the GraphQL Admin API. The template abstracts away the actual GraphQL mutation you would otherwise have to write.
In app/shopify.server.ts, add your subscription to the webhooks config and register it in the afterAuth hook:
app/shopify.server.ts
Google Pub/Sub
const shopify = shopifyApp({
webhooks: {
ORDERS_CREATED: {
deliveryMethod: DeliveryMethod.PubSub,
pubSubProject: "<GCP-PROJECT>",
pubSubTopic: "<PUB_SUB_TOPIC>",
},
},
hooks: {
afterAuth: async ({ session }) => {
shopify.registerWebhooks({ session });
},
},
});Amazon EventBridge
const shopify = shopifyApp({
webhooks: {
ORDERS_CREATED: {
deliveryMethod: DeliveryMethod.EventBridge,
arn: "<ARN>",
},
},
hooks: {
afterAuth: async ({ session }) => {
shopify.registerWebhooks({ session });
},
},
});If you're using Amazon EventBridge, set arn to the ARN that you retrieved when you associated your event bus during setup.
GraphQL Admin API
Use the webhookSubscriptionCreate mutation. Specify the topic using GraphQL enum screaming case syntax (for example, ORDERS_CREATE).
Request: POST /admin/api/2026-04/graphql.json
Create a webhook subscription
For Google Pub/Sub, set uri to pubsub://{project-id}:{topic-id}. For Amazon EventBridge, set uri to the ARN from your EventBridge console under Partner Event Sources.
Add this code wherever you process your after-authentication hooks. This is the equivalent of app/shopify.server.ts in the React Router template.
You can also test with example GraphQL queries using the GraphiQL interface by pressing g in the console where your app is running. You must include values for the variables to execute the mutation.
Shopify recommends that you use the Shopify CLI and React Router template when subscribing to webhooks using the GraphQL Admin API. The template abstracts away the actual GraphQL mutation you would otherwise have to write.
In app/shopify.server.ts, add your subscription to the webhooks config and register it in the afterAuth hook:
app/shopify.server.ts
Google Pub/Sub
const shopify = shopifyApp({
webhooks: {
ORDERS_CREATED: {
deliveryMethod: DeliveryMethod.PubSub,
pubSubProject: "<GCP-PROJECT>",
pubSubTopic: "<PUB_SUB_TOPIC>",
},
},
hooks: {
afterAuth: async ({ session }) => {
shopify.registerWebhooks({ session });
},
},
});Amazon EventBridge
const shopify = shopifyApp({
webhooks: {
ORDERS_CREATED: {
deliveryMethod: DeliveryMethod.EventBridge,
arn: "<ARN>",
},
},
hooks: {
afterAuth: async ({ session }) => {
shopify.registerWebhooks({ session });
},
},
});If you're using Amazon EventBridge, set arn to the ARN that you retrieved when you associated your event bus during setup.
When using Google Cloud Pub/Sub or Amazon EventBridge, deliveries include additional fields beyond the sample payloads in the Webhooks reference. HMAC verification is not required for cloud event bus deliveries.
Anchor to Custom appsCustom apps
Webhooks are available for all custom apps to use. However, custom apps created in the Shopify admin cannot take advantage of the tooling available through the Shopify CLI, including subscribing to webhook topics using the app configuration file.
This means that webhook subscriptions must be set up and configured using the GraphQL Admin API.
- Create an app in the Shopify Admin and install it on your test shop to get your Admin API Access token.
- Configure your Admin API scopes by selecting the scopes that you'll need for each webhook topic that you intend to subscribe to. Learn more about which topics require which Shopify scopes in the Webhooks reference.
- Subscribe to webhook topics using the Admin API and your Admin API access token.
Anchor to TopicsTopics
A topic identifies both the resource and the action that qualifies a delivery.
For example, products/update fires when an existing product changes; products/create fires when a new one is created.
You can list multiple topics in a single subscription to route qualifying events from each to the same uri.
See the Webhooks reference for the full list of supported topics and their required scopes.
Events is in developer preview for a subset of topics. If your topic is supported, you can run an Events subscription alongside this webhook in the same shopify.app.toml. Check the Events reference for supported topics.
Events is in developer preview for a subset of topics. If your topic is supported, you can run an Events subscription alongside this webhook in the same shopify.app.toml. Check the Events reference for supported topics.
Anchor to Test your subscriptionsTest your subscriptions
Use the Shopify CLI webhook trigger command to test delivery. Pass flags directly or run with no parameters and follow the prompts:
For the --address flag, use the appropriate format for your delivery method:
| Delivery method | --address value |
|---|---|
| Amazon EventBridge | Your ARN from the EventBridge console under Partner Event Sources > Select your event source > Partner event source ARN |
| HTTPS | Your endpoint URL |
| Google Pub/Sub | pubsub://{project-id}:{topic-id} — your GCP project ID and Pub/Sub topic ID |
Anchor to ExampleExample
The following subscription listens for new product creations and delivers to a single endpoint.
It uses no filter or include_fields, so every qualifying creation fires a delivery with the full product payload.
Products subscription
shopify.app.toml
[webhooks]
api_version = "2026-04"
[[webhooks.subscriptions]]
topics = ["products/create"]
uri = "https://your-app.example.com/webhooks/products"{} Response
{
"id": 9554194432293,
"title": "T-Shirt",
"status": "active",
"vendor": "My Store",
"product_type": "Shirts",
"variants": [
{
"id": 123456789,
"title": "Default Title",
"price": "29.99",
"sku": "TSHIRT-001"
}
],
"tags": "cotton, comfortable"
}Anchor to Next stepsNext steps
- Delivery filtering: Gate deliveries with
filterexpressions. - Delivery structure: Shape the payload with
include_fields.