Webhooks · security
Webhook subscriptions and delivery
Current subscription, signing, retry, SSRF, secret-return, and emitted-event truth.
Webhook subscriptions and delivery
The event implementation is under private release acceptance; Marketplace remains disabled until that acceptance is complete. The reviewed webhooks.events.v2 contract covers subscription management and the resource notifications below. An old management-only app version does not inherit event authority: a new reviewed version and fresh merchant approval are required.
Subscription operations
Use GET /api/v1/webhooks, POST /api/v1/webhooks, and DELETE /api/v1/webhooks/{id} with webhooks:manage. Creation accepts one event type declared by the exact installed version and an HTTPS endpoint. Subscriptions are bound to the exact installed reviewed version and authorization generation. Recreating the same installation/event/endpoint rotates the secret and reactivates the subscription.
One-time signing secret
The create response returns data.signing_secret once, together with its last four characters. Store the full secret securely at that moment. Later list responses return only secret_last_four. Rotating a subscription replaces the previous secret, so update the receiver atomically.
Delivery format and signing
The JSON body contains id, type, occurred_at, and data. Delivery sends X-Saas-Event-Id, X-Saas-Timestamp, and X-Saas-Signature. The signature is HMAC-SHA256 formatted as v1=<hex> over:
<timestamp>.<event_id>.<exact_request_body>
Verify the exact raw body before parsing, compare signatures in constant time, enforce a timestamp tolerance, and deduplicate the stable event ID.
Network and retry behavior
Endpoints must use HTTPS and a public address. Delivery rejects private, loopback, link-local, reserved, and unsafe targets, resolves DNS, and pins the verified public address for the request. It does not follow redirects. The request timeout is 15 seconds. Delivery uses at most six attempts with bounded exponential backoff, then reaches dead; failures do not retry forever.
Resource event contract
The merchant approval screen lists the exact events declared by the reviewed version. A subscription can receive only an event in that allowlist. Business changes and their delivery records commit or roll back together. The same resource/event is coalesced within a transaction; no-op changes do not create events. New subscriptions do not receive historical events.
| Event | Trigger | Resource |
|---|---|---|
products.created | Product added | product |
products.updated | Product business fields change | product |
customers.created | Customer added | customer |
orders.created | Order created | order |
orders.updated | Order business fields change | order |
orders.cancelled | Order enters cancelled status | order |
orders.fulfilled | Order enters shipped or delivered; shipped → delivered does not emit a second fulfilment | order |
inventory.updated | Nonzero inventory is added, quantity/reservation changes, or an inventory record is removed | inventory |
app.uninstalled | The merchant disconnects this exact app | installation |
The data object contains schema_version: 1, store_id and resource. A resource contains type and id; inventory also includes product_id, nullable variant_id and location_id. The uninstall receipt adds app_id. Notifications never contain names, contact details, addresses, payment credentials, quantities or full database rows. Reading details requires a separately approved operational read permission; an event does not invent a public API for a planned scope. A referenced resource may already be deleted when the receiver reads it.
Final uninstall receipt
A reviewed app.uninstalled subscription may receive one final receipt for its own disconnected installation. All ordinary tokens, subscriptions and queued deliveries are revoked first. The receipt uses the exact previous subscription, expires after five minutes and has at most three attempts with a 30-second retry delay. It grants no new read access. Reinstallation, endpoint/secret changes, suspension, scope removal or release disablement cancels pending receipts permanently. Restoring access does not revive them. Delivery is best effort: expiry or network failure can prevent the receipt from arriving.
Revocation edge case
Developer, app, version or installation revocation disables stale authority. Queued deliveries preserve their subscription epoch and installation generation. A one-use admission checks current authority after safe DNS resolution, and completion requires the exact unexpired claim. A request already admitted to the network cannot be recalled. Receivers must remain idempotent and should stop acting on events after merchant authorization is revoked.