Appearance
Webhooks
Webhooks are how Shopify pushes events to you, so you never have to poll.
Subscribing
Preferred: app-specific subscriptions in shopify.app.toml. They apply to every shop automatically after shopify app deploy.
toml
[webhooks]
api_version = "2026-10"
[[webhooks.subscriptions]]
topics = ["orders/create", "orders/updated"]
uri = "/webhooks/orders"
# optional: only send some fields, or only some events
include_fields = ["id", "name", "customer", "total_price"]
filter = "financial_status:paid"Shop-specific subscriptions (the webhookSubscriptionCreate mutation) are for when different shops need different topics.
Delivery methods
| Method | When |
|---|---|
| HTTPS endpoint | Default. Simplest |
| Amazon EventBridge | High volume, already on AWS |
| Google Cloud Pub/Sub | High volume, already on GCP |
Handling a webhook
ts
// app/routes/webhooks.orders.tsx
export const action = async ({ request }) => {
const { topic, shop, payload, webhookId } = await authenticate.webhook(request); // verifies HMAC
await queue.add({ topic, shop, payload, webhookId }); // do the real work async
return new Response(); // 200 fast
};Rules that save you
- Verify the HMAC. The
X-Shopify-Hmac-Sha256header is an HMAC-SHA256 of the raw body, signed with your app secret.authenticate.webhookdoes this for you. - Respond fast (within a few seconds) with 2xx, then process in a queue. Slow or failing endpoints get retried, and persistent failures can get the subscription removed.
- Deduplicate using
X-Shopify-Webhook-Id. The same event can arrive more than once. - Don't trust ordering.
orders/updatedcan arrive beforeorders/create. Useupdated_atto decide what's newer.
Mandatory compliance (GDPR) webhooks
Every public app must handle these, or it fails review:
| Topic | You must |
|---|---|
customers/data_request | Provide the customer's stored data to the merchant |
customers/redact | Delete that customer's data |
shop/redact | Delete the shop's data. Sent ~48 h after uninstall |
Also handle app/uninstalled: delete sessions and stop jobs for that shop.
Verify the compliance topic details
These requirements weren't re-checked against shopify.dev while writing this handbook. Confirm the current list on the privacy law compliance page before submitting.
Project step: subscribe to
orders/createand log the order name. Add the three compliance topics.
Check yourself
- Why must HMAC be computed on the raw body, not parsed JSON?
- Your handler takes 20 s. What goes wrong, and how do you fix it?