How Shopify delivers webhooks

Five seconds to respond, 8 retries over 4 hours, then Shopify deletes the subscription. The verified numbers, signature format, and a Node verifier.

Delivery behaviour

Read from the vendor's own documentation, last checked 2026-08-06. Where the vendor states no number, this table carries none.

Response budget5s

1 second to connect, 5 seconds for the whole request

Check whether your handler answers in time

Retry8 retries over 4 hours
Gives upSubscriptions created through the Admin API are deleted after 8 consecutive failures, with a warning email to the app's emergency developer contact
Sourcehttps://shopify.dev/docs/apps/build/webhooks/subscribe/https

Signature

Verified against a working verifier proven by a test suite, not read from documentation. Last verified 2026-08-20.

AlgorithmHMAC-SHA256
Signed payloadraw body
Encodingbase64
Headerx-shopify-hmac-sha256
Tolerancenone enforced

Verify it

The raw request body, byte for byte, before any JSON parsing. Every scheme on this page breaks the moment a framework re-serializes the payload.

const crypto = require("node:crypto");

// base64(HMAC-SHA256(secret, raw body))
const expected = crypto
  .createHmac("sha256", hmacSecret) // admin webhooks: Settings → Notifications
  .update(rawBody)
  .digest("base64");
const received = Buffer.from(req.headers["x-shopify-hmac-sha256"] ?? "");
const wanted = Buffer.from(expected);
// timingSafeEqual throws on a length mismatch, so check that first.
const valid =
  received.length === wanted.length && crypto.timingSafeEqual(received, wanted);

Two different secrets exist: admin-created webhooks sign with the shared secret under Settings → Notifications, app-created ones with the app's client secret. Match how the webhook was created.

What bites

Shopify does not disable the subscription, it deletes it. A subscription made through the Admin API is deleted after 8 consecutive failures, with only a warning email to the app's emergency developer contact; nothing throws, and orders simply stop arriving. Recovery is a reconciliation job against the Admin API, because the missed events were never sent.

Read more

AnyHook sits in front of endpoints that receive from Shopify: it answers in about a second, retries on its own schedule when your server is down, and keeps every event replayable. Change one URL, keep your code.

How it works →