Overview
Webhooks push order-lifecycle events to your systems as they happen, so you can react to a provider accepting, scheduling, or completing an order without pollingGET /reseller/orders.
Register an HTTPS endpoint, subscribe it to the event types you care about, and
Offergrid POSTs a signed JSON envelope to it every time one of those events
occurs on an order your team placed.
Every delivery attempt — success or failure — is recorded and queryable via
GET /reseller/webhooks/{id}/deliveries.
That log is the first place to look when something appears to be missing.Registering a webhook
The response contains the signing secret, and it is shown only once — store it before you discard the response.url must be https:// — plain HTTP is rejected at validation.
Event types
You only receive events for orders where your team is the reseller. Providers
subscribe to the same four event types and receive them scoped to their
offers instead — same event, different audience.If your team is hybrid, one webhook covers both roles and you receive each
event exactly once. Compare
providerTeamId and resellerTeamId in the
payload against your own team id to tell which side of an order you are on.Payload structure
Every delivery is a POST withContent-Type: application/json and this
envelope:
order.item.status_changed
from and to are the item’s statuses; orderStatus is the parent order’s
status recomputed from all of its items — so you can update an order-level view
without a follow-up read. See Order Lifecycle for
the full status set.
Other event payloads
order.created, order.item.created, and order.cancelled carry the same
payloads documented on the provider side:
order.created ·
order.item.created ·
order.cancelled.
Verifying signatures
Signed deliveries carry a single header:t= component
and is also part of the signed payload, so a verifier can reject stale or
replayed deliveries. The signature is HMAC-SHA256 over the string
`${t}.${rawBody}`, keyed with your webhook secret, hex-encoded.
The scheme is identical for both roles — the worked Node and Python verifiers
in Verifying signatures apply
unchanged.
Delivery behaviour
Return 2xx as soon as you have durably accepted the event, then do the work in a
background job:
id, which is stable across retries:
Testing your endpoint
Point a webhook at a tunnel while you develop:Still want to poll?
Webhooks do not replace reconciliation. Because delivery is at-least-once and unordered, a periodic sweep ofGET /reseller/orders
is a good safety net — daily is plenty once webhooks are live. See
Tracking Orders.
Troubleshooting
No deliveries arriving
No deliveries arriving
- Confirm the webhook is
isActive: true. - Confirm it subscribes to the event type you expect — a webhook only
receives types listed in its
eventsarray. - Check the delivery log. Attempts with a non-2xx status mean the problem is on your side; no attempts at all means no matching event was emitted for your team.
- Confirm your team is the reseller on the order. You do not receive events for orders another reseller placed, even for the same offer.
Signature verification always fails
Signature verification always fails
- Sign the raw body, not a re-serialized copy.
- Read the timestamp from the
t=component ofX-Offergrid-Signature. There is nox-offergrid-timestampheader. - The signed string is the timestamp, a literal dot, then the raw body.
- Compare hex-decoded buffers, checking lengths first: Node’s
timingSafeEqualthrows on a length mismatch. - Confirm you stored the secret from the creation response — it is shown only once and cannot be retrieved later.
Receiving the same event more than once
Receiving the same event more than once
Expected. Delivery is at-least-once, and a retry re-sends to every
subscribed target. Deduplicate on the envelope
id.Next steps
Tracking Orders
Monitoring order status in the dashboard
Order Lifecycle
Every status an order and its items can be in
Reseller API Reference
Every reseller endpoint, including webhook management
API Integration
Broader integration patterns