Webhooks: get notified when things change in your store
Webhooks are the easiest way to wire LaunchMyStore into the rest of your business. When something happens in your store — an order is paid, a product is updated, a customer signs up — LMS calls a URL you control with the event payload. No polling, no missed updates.
How LMS webhooks work
- You register a callback URL and a topic in your admin (or via the API).
- When that topic fires in your store, LMS dispatches the event to your URL with a JSON body.
- If your endpoint returns a 2xx response within 10 seconds, the delivery is logged as
SUCCESS. - If it fails or times out, LMS retries up to 3 times with exponential backoff (1 min, 5 min, 15 min) plus jitter.
- Permanent 4xx responses (except 429) skip retries.
Supported topics
The platform currently dispatches the following webhook topics:
| Topic | When it fires |
|---|---|
orders/create | A new order is created |
orders/updated | An existing order is updated |
orders/paid | An order is marked paid |
orders/cancelled | An order is cancelled |
orders/fulfilled | All items on an order are fulfilled |
fulfillments/create | A fulfillment is created |
fulfillments/update | A fulfillment is updated |
refunds/create | A refund is recorded |
products/create | A product is created |
products/update | A product is updated |
products/delete | A product is deleted |
collections/create | A collection is created |
collections/update | A collection is updated |
collections/delete | A collection is deleted |
customers/create | A customer signs up |
customers/update | A customer profile is updated |
customers/delete | A customer is deleted |
carts/create | A cart is started |
carts/update | A cart is modified |
checkouts/create | A checkout begins |
checkouts/update | A checkout is updated |
discounts/create | A discount is created |
discounts/update | A discount is updated |
discounts/delete | A discount is deleted |
blogs/create | A blog is created |
blogs/update | A blog is updated |
blogs/delete | A blog is deleted |
inventory/update | Inventory levels change |
themes/publish | A theme is published |
themes/update | A theme is updated |
shop/update | Store settings change |
app/installed | An app is installed |
app/uninstalled | An app is uninstalled |
newsletter/create | A shopper subscribes |
contact_form/create | A shopper submits the contact form |
customers/data_request | GDPR data request (mandatory) |
customers/redact | GDPR customer redact (mandatory) |
shop/redact | GDPR shop redact (mandatory) |
Registering a webhook
You can register a webhook in admin under Tools → Webhooks, or via the REST API:
curl -X POST https://api.launchmystore.io/Webhooks/add-webhook \
-H "Authorization: Bearer <merchant-jwt>" \
-H "Content-Type: application/json" \
-d '{
"event": "orders/paid",
"callbackUrl": "https://example.com/lms/webhooks",
"isEnabled": true
}'
Apps register through the OAuth-scoped /api/v1/webhooks.json endpoint with a secret for HMAC signing.
Payload structure
Every delivery is a JSON POST with these headers:
X-LMS-Topic– the topic that fired, e.g.orders/paid.X-LMS-Webhook-Id– unique delivery ID (use this for idempotency).X-LMS-Delivery-Attempt– attempt number, starts at1.X-LMS-Hmac-SHA256– base64 HMAC of the raw body (app webhooks only).X-LMS-Api-Version– the contract version the payload is shaped to (e.g.2026-06).X-LMS-Shop-Domain– which store fired the event.
The body itself depends on the topic — for an order it contains the full Shopify-shaped order object (snake_case, with line_items, financial_status, etc.); for an inventory event it contains the SKU, location, and new level.
Retry policy
LMS retries deliveries up to 3 times:
- Attempt 2 — 1 minute after attempt 1
- Attempt 3 — 5 minutes after attempt 2
- Attempt 4 — 15 minutes after attempt 3
Each delay has ±10% jitter to avoid thundering-herd retries. Retries are fully automatic — you don’t need to do anything to trigger them. After 3 failed attempts, the delivery is marked FAILED and no further automatic retries occur.
If you build an app, the developer portal also shows a per-app delivery log where you can inspect each attempt and manually re-trigger a failed delivery. Merchant webhooks set up under Tools → Webhooks rely on the automatic retry schedule above.
Idempotency
Because deliveries may be retried, design your handler to be idempotent. The recommended pattern: store X-LMS-Webhook-Id in your database the first time you process it. If you see the same ID again, skip processing and return 200.
FAQ
What’s the difference between merchant webhooks and app webhooks?
Merchant webhooks are configured in your admin under Tools → Webhooks and don’t have a secret — they’re unsigned. App webhooks are registered by an installed app, carry the app’s secret, and include the X-LMS-Hmac-SHA256 header so the recipient can verify authenticity.
Will my server be hammered with retries if it’s down?
No. Retries are capped at 3 attempts spread across roughly 21 minutes. Permanent 4xx responses (except 429) skip retries entirely, so a bad URL won’t keep firing.
How do I see what was sent?
Under Tools → Webhooks you can view, edit and delete the webhooks you’ve set up. A detailed delivery log — with the attempt count, response code, response body and any error for each delivery — is available to app developers in the developer portal, where you can also re-trigger a failed delivery. If you only need to confirm an integration is wired up, send a test event and check that your endpoint received it.
Can I subscribe to all topics at once?
No — each subscription targets exactly one topic. Create one webhook per topic you care about. This keeps payloads focused and makes integrations easier to reason about.
What’s the timeout for my endpoint?
10 seconds. If you can’t complete processing in that window, return 200 immediately and queue the work for background processing.
Are webhooks delivered in order?
Not strictly. Retries can interleave with new events for the same resource. Use timestamps in the payload (or your own ordering logic) when order matters.