Skip to main content

Webhooks

Webhooks allow your app to receive real-time notifications when events occur in a merchant’s store. Instead of polling for changes, LaunchMyStore pushes events to your server as they happen.

How Webhooks Work

Registering Webhooks

Register webhooks during app installation. GET, POST, and DELETE on /api/v1/webhooks.json are all gated by the read_shop scope (there is no dedicated webhook write scope):

Webhook Topics

Exactly 23 topics are registerable via POST /api/v1/webhooks.json. Any topic outside this list is rejected with 422.

Orders

Refunds

Products

Customers

Inventory

Fulfillments

Subscriptions

App

GDPR compliance topics (customers/data_request, customers/redact, shop/redact) are delivered by the platform but are not registerable through webhooks.json — see GDPR Webhooks.
See Webhook Topics for each topic’s payload shape.

Webhook Payload

The request body is the event resource itself — there is no envelope. Order, product, customer, collection and refund events are delivered as snake_case objects (line_items, financial_status, money fields are decimal strings). The topic, contract version and sending store are in the request headers, not the body: See Webhook Topics for each topic’s payload shape.

Verifying Webhooks

Every signed webhook carries an X-LMS-Hmac-SHA256 header — a base64 HMAC-SHA256 of the raw request body, keyed by this webhook’s signing secret. The secret depends on how the webhook was created: the per-subscription secret for API-registered webhooks (POST /api/v1/webhooks.json), your app’s clientSecret for manifest-declared and GDPR webhooks, or the per-webhook secret shown in the merchant admin for store-level webhooks. Compute the HMAC over the raw bytes, never a re-serialized JSON object, then compare with a timing-safe comparison. See Webhook Verification for the exact algorithm and copy-paste examples in Node.js, Python, Ruby, PHP and Go.

Delivery & Retries

  • Timeout: Your endpoint must respond within 10 seconds
  • Response: Return 2xx status code to acknowledge receipt
  • Retries: Failed deliveries are retried 3 times with exponential backoff:
    • 1st retry: 1 minute
    • 2nd retry: 5 minutes
    • 3rd retry: 15 minutes
  • Dead letter: After 3 failures, the webhook is logged and no more retries

Best Practices

Return 200 immediately, then process asynchronously. Long-running handlers cause timeouts.
Webhooks may be delivered more than once. Deduplicate on the X-LMS-Webhook-Id request header.
Always verify HMAC signatures to ensure webhooks are authentic.
Webhook (and fulfillment-service) callback URLs must use http/https and be publicly reachable. Link-local / cloud-metadata addresses (169.254.0.0/16, e.g. 169.254.169.254) and the unspecified address (0.0.0.0) are rejected in every environment; private, loopback and *.local/*.internal hosts (localhost, 127.0.0.1, 10.x, 192.168.x, 172.16–31.x) are rejected in production (allowed in local dev so you can test against localhost). Use HTTPS in production.

Managing Webhooks

List Webhooks

Delete Webhook