Webhooks

Get pushed a signed event the moment an order or placement changes status, instead of polling.

Webhooks let Respona push order and placement status changes to an HTTPS endpoint you host, so you don’t have to poll. They complement polling - the webhook tells you something changed; you then read authoritative state (and live pricing) back from the API.

Webhooks are configured per workspace from Settings → Webhooks (the same place you manage API keys). Webhook delivery is server-to-server; the endpoint you register must be a public HTTPS URL.

Events

EventFires when
order.status_changedA client order changes status (e.g. DRAFTLAUNCHEDIN_PROGRESSCOMPLETED).
placement.status_changedA placement changes status (e.g. ORDEREDIN_PROGRESSPENDING_APPROVALAPPROVEDLIVE).

The status / previous_status strings match exactly what GET /rest/api/v1/orders/{order_id} returns. DRAFT transitions are not delivered (you created the draft yourself), and transitions that don’t change the public status are suppressed.

Payload

Content-Type: application/json, snake_case, and no tenant identifiers. order_id / placement_id are the same identifiers the REST API uses, so you can read current state straight back.

1{
2 "event": "placement.status_changed",
3 "delivery_id": "b3f1c2a4-...",
4 "webhook_id": "9d8c7b6a-...",
5 "occurred_at": "2026-07-27T10:15:30Z",
6 "api_version": "v1",
7 "data": {
8 "order_id": "48213",
9 "placement_id": "99120",
10 "number": "PL-1042",
11 "status": "LIVE",
12 "previous_status": "IN_PROGRESS"
13 }
14}

Headers on every delivery:

HeaderMeaning
X-Respona-Signaturet=<unix_seconds>,v1=<hex-hmac> - see Verifying signatures.
X-Respona-EventThe event type, e.g. placement.status_changed.
X-Respona-Delivery-IdUnique per delivery. Use it to dedupe.
X-Respona-Webhook-IdThe endpoint that received this event.
X-Respona-Api-VersionPayload version (v1).

Verifying signatures

Each delivery is signed with the endpoint’s signing secret (shown once when you create or rotate the endpoint - store it somewhere safe). Verify before trusting a payload:

  1. Read the X-Respona-Signature header - it looks like t=1769509200,v1=5257a869....
  2. Compute HMAC-SHA256(secret, "{t}.{raw_request_body}") as lowercase hex.
  3. Compare it (constant-time) against the v1 value. Reject if it doesn’t match.
  4. Reject deliveries whose t is too old (e.g. more than 5 minutes) to blunt replay.
1import hashlib, hmac, time
2
3def verify(secret: str, signature_header: str, raw_body: bytes, tolerance_seconds: int = 300) -> bool:
4 parts = dict(p.split("=", 1) for p in signature_header.split(","))
5 timestamp = int(parts["t"])
6 if abs(time.time() - timestamp) > tolerance_seconds:
7 return False
8 expected = hmac.new(secret.encode(), f"{timestamp}.".encode() + raw_body, hashlib.sha256).hexdigest()
9 # The header may carry more than one v1= value during a secret rotation; accept if any matches.
10 provided = [v for k, v in (p.split("=", 1) for p in signature_header.split(",")) if k == "v1"]
11 return any(hmac.compare_digest(expected, p) for p in provided)

During a secret rotation the signature header carries two v1= values (old and new) for the grace window, so a consumer mid-rollout verifies against either. Once you’ve moved to the new secret, the old one stops signing when the window closes.

Delivery, retries, and ordering

  • At-least-once. A delivery may arrive more than once. Make your handler idempotent by deduping on X-Respona-Delivery-Id.
  • Respond fast with a 2xx. Any 2xx within the timeout is success. Do slow work asynchronously - acknowledge first, process after.
  • Retries with backoff. A non-2xx response or a timeout is retried on an increasing schedule (roughly 1m, 5m, 30m, 2h, 6h) before the delivery is marked exhausted.
  • Order is best-effort, not guaranteed. Two rapid transitions can arrive out of order. Every payload carries occurred_at and previous_status so you can order events and detect gaps; treat the REST API as the source of truth.
  • Auto-pause. An endpoint that fails many deliveries in a row is automatically paused; resume it from Settings once you’ve fixed it.

Managing endpoints

From Settings → Webhooks you can create, edit, pause, and delete endpoints, rotate the signing secret (with an overlap window so you never miss a beat), pick which events an endpoint receives, and review a delivery history with per-attempt response codes plus a Redeliver button to replay a past delivery.

Security notes

  • Endpoints must be HTTPS and resolve to a public address - URLs pointing at private, loopback, or link-local ranges are rejected at registration and re-checked at delivery time.
  • The signing secret is shown once and never again. If you lose it, rotate to get a new one.
  • Treat the secret like a password: never log it, never expose it client-side.