Skip to main content

Webhooks

Orbit webhooks deliver real-time HTTP POST notifications to your server whenever events occur — message delivered, call completed, agent conversation ended, and more. Use webhooks to keep your systems in sync without polling. This page is the hub for everything webhook-related. It covers setup (dashboard and API), the delivery envelope, signature headers, retries, and the dead-letter queue. Two sibling pages carry the deep detail:

How It Works

  1. You register a webhook endpoint URL in the Orbit dashboard or via the API
  2. When an event occurs, Orbit sends an HTTP POST with the event payload to your URL
  3. Your server responds with a 2xx status code to acknowledge receipt
  4. If delivery fails, Orbit retries on a fixed schedule (see Retry Schedule)

Set Up a Webhook in the Dashboard

The fastest way to register an endpoint — no API call required:
  1. Open Settings → Webhooks → Add endpoint
  2. Enter your HTTPS URL (plain HTTP is rejected for production endpoints)
  3. Pick the event types you want to receive, or subscribe to * for everything
  4. Copy the signing secret (whsec_...) shown after creation — this is the only time the cleartext secret is displayed, and you need it to verify signatures
You can view, rotate, or delete the endpoint later from the same page. The cleartext secret is returned only once at creation (or rotation); afterwards the dashboard and API show only a masked preview for identification.

Register a Webhook via the API

Omit secret to have Orbit auto-generate one. Either way, the response includes the full whsec_... cleartext — copy it immediately. If you supply your own, it must be at least 16 characters.

Event Payload Format

Every webhook delivery follows a consistent envelope:
Terminal-failure deliveries (message.failed) additionally include optional error_code and error_message fields carrying the provider’s failure reason. They appear only when the message has a captured provider error and are absent otherwise. See the webhook events reference for the full per-event payload shapes.

Signature Headers

Every delivery is signed with HMAC-SHA256 so you can confirm it genuinely came from Orbit. Each request carries the signature in up to three headers: All three share the same Stripe-style encoding — t=<unix>,v1=<hex> — where t is a Unix timestamp for replay protection and v1 is the HMAC-SHA256 hex digest of <t>.<raw_body> keyed by your signing secret. Verify at least one of them before processing any delivery. Full verification logic and ready-to-use code for Node.js, Python, and Go: Webhook security.

Event Families

The catalog spans every Orbit pillar — a few common families to start with: Subscribe to only the events you need, or pass ["*"] to receive everything. The full catalog of 256 event types (contacts, campaigns, agents, numbers, billing, and more): Webhook events.

Delivery Guarantees

  • At-least-once delivery — events may be delivered more than once; use the id field for deduplication
  • Ordered by event time — events are sent in chronological order, but network conditions can cause out-of-order delivery
  • 30-second timeout — your endpoint must respond within 30 seconds

Idempotency

Because delivery is at-least-once, a retry or a dead-letter replay can deliver the same event again. Deduplicate on the envelope id field (evt_...): persist every event id you have processed and drop deliveries whose id you have already seen. Persist seen ids for at least 7 days — long enough to cover the full retry window plus the dead-letter replay window described below.

Retry Schedule and Dead-Letter Queue

If your endpoint returns a non-2xx response or times out, Orbit retries on an exponential backoff schedule. Each event gets one initial delivery plus 9 retries (10 attempts total). The backoff starts at 30 seconds and doubles with each retry, with +0–20% jitter applied (delays run up to 20% longer than nominal, never shorter):
  • Attempt 1: initial delivery (0s delay)
  • Attempts 2–10: exponential backoff (30s → 60s → 120s → 240s → 480s → 960s → 1920s → 3840s → 7680s)
A delivery counts as successful on any 2xx within 30 seconds. Timeouts and 5xx responses always retry. Retryable 4xx responses (400/422 and similar) also retry until the backoff schedule is exhausted. A proven-dead response — 401, 403, 404, or 410 Gone — skips retries entirely, moves to the dead-letter queue, and immediately disables the endpoint (Orbit notifies the org admin). 410 Gone is also the way to permanently skip retries for a single event — for example when you have deprecated handling for that event type.
Auto-disable on failure streaks: Orbit tracks consecutive failures per endpoint and auto-disables one that exceeds 50 — the same mechanism that fires instantly on the proven-dead statuses above. Re-enable a disabled endpoint from the dashboard once it is healthy again. While an endpoint is disabled, deliveries do not keep retrying in the background.
After the 10th attempt fails, the event moves to the dead-letter queue — roughly 4.3 hours after the first attempt. Dead-lettered events remain replayable for 7 days. List them and put individual deliveries back into the retry pipeline:
The same dead-letter inbox with a one-click requeue is in the dashboard under Developer → Webhooks → Dead-letter queue. For recurring delivery failures — especially signature mismatches — see Troubleshooting: Signature Verification Failures.
If an endpoint accumulates 50 consecutive failures, Orbit auto-disables it and emails the org admin. Re-enable it from the dashboard once your endpoint is healthy again. Deliveries to a disabled endpoint go straight to the dead-letter queue rather than retrying.

Managing Webhooks

List your registered webhooks:
Delete a webhook:

Next Steps