Webhook Event Payloads
This page documents the wire-level shape of an Orbit webhook delivery — the request envelope, the headers Orbit sends, and the metadata Orbit captures about every delivery attempt (including the request headers sent and the response headers received from your endpoint). For the full catalog of event types (message.delivered, call.completed, …) see Webhook Events. For HMAC signature verification see Webhook Security.
Request envelope
Every delivery is a single HTTPPOST with a JSON body that follows the canonical envelope:
The
data shape above is a successful delivery. Terminal-failure payloads
(message.failed, which also covers the expired / submitted_no_receipt
transitions) additionally carry optional error_code and error_message
strings when the message has a provider-supplied failure reason — the raw
code and text the carrier / channel returned. They are absent (not null)
when no provider error was captured, and successful transitions clear them.
See the webhook events reference for the full
failure payload shape.Request headers
Orbit sends every delivery with the following headers:Inspecting delivery attempts
Orbit persists metadata about every delivery attempt (request headers sent, response status, response body, response headers received). Operators can inspect these via the dashboard or the API:GET /api/v1/webhooks/{endpoint_id}/deliveries/{delivery_id}webhooks:read scope.
200 OK
request_headers (captured since 2026-04, migration 217)
The exact header set Orbit sent on this delivery attempt. Useful for self-serve HMAC debugging — operators can inspect the X-Devotel-Signature value Orbit signed against and compare it to what their receiver computed.
Redaction. Orbit redacts the value of any request header matching its secret denylist before persisting (the header name is preserved; only the value becomes <redacted>). Matching is case-insensitive. The full denylist is:
AuthorizationProxy-AuthorizationCookieX-Api-KeyX-Auth-TokenX-CSRF-TokenX-Amz-Security-Token- Any header whose name matches
X-*-Secret(starts withX-, ends with-Secret) - Any header whose name matches
X-*-Token(starts withX-, ends with-Token) - Any header whose name matches
X-*-Key(starts withX-, ends with-Key)
X-Devotel-Signature is deliberately not redacted — you need its plaintext HMAC digest to debug signature reconstruction.
The redaction is one-way — once persisted, the original values are unrecoverable from the delivery row. This is intentional: the deliveries API is read-only and operator-facing; raw secrets must not surface in dashboard render paths even via inspect.
response_headers (captured since 2026-07-01)
The header set returned by your endpoint on this delivery attempt. Useful for:
- Debugging your receiver’s CDN / WAF chain (e.g. confirming Cloudflare didn’t strip your body).
- Correlating with your own logging — many receivers echo a request id (
X-Request-Id/Traceparent) that the deliveries view can surface. - Validating that your receiver returned the expected
Cache-Control: no-storefor webhook responses.
Set-Cookie is never persisted — a session cookie your server issues is a credential, so it is dropped before the delivery row is stored.
Backwards compatibility. Deliveries recorded before 2026-07-01 (when Orbit began capturing response headers) carry response_headers: null. The dashboard renders a “headers not captured for this delivery” empty-state in that case — it does NOT block render of the delivery row itself.
last_response_body
Truncated to the first 500 bytes of the response body. Use for debugging your receiver’s error messages. No truncation marker is appended, so treat the value as potentially clipped whenever it reaches 500 bytes.
Listing recent deliveries
GET /api/v1/webhooks/{endpoint_id}/deliveriesrequest_headers / response_headers fields are returned per row so the dashboard can render the headers panels inline without an extra round-trip per row.
Query parameters
Replay + retry
If your endpoint was down or returned a non-2xx, Orbit retries on the delivery schedule. To force a replay of an already-completed delivery (e.g. after a downstream bug fix):POST /api/v1/webhooks/{endpoint_id}/deliveries/{delivery_id}/replayevent_id and payload and queues it for immediate dispatch. The original row is preserved as audit trail.
To re-queue a failed delivery (without changing the payload):
POST /api/v1/webhooks/{endpoint_id}/deliveries/{delivery_id}/retrypending and sets next_retry_at = now() so the worker picks it up on the next tick.
See also
- Webhooks Overview — registration, retry schedule, delivery guarantees
- Webhook Security — HMAC signature verification
- Webhook Events catalog — full list of
typevalues Orbit emits - Webhook Events reference — per-event-type payload schemas