Webhooks
A webhook subscription delivers your account’s events to an HTTPS endpoint you control. Register a URL and the event types you care about, and Dial POSTs each matching event to that URL — signed, retried, and idempotency-keyed.
Webhooks are the at-least-once, off-machine counterpart to the presence-based
event stream: instead of holding a connection open with
dial wait-for, your server receives events as they happen.
Create a subscription
Create one from the dashboard Webhooks page, or via the API:
targetUrlmust be HTTPS and must not point at a private, loopback, or link-local address.eventTypesis either["*"](all events) or an explicit list of event types, e.g.["message.received", "call.ended"].
The response includes a signing secret (whsec_…). The dashboard masks it and lets you
copy it on demand; over the API the full secret is returned at creation and via
GET /api/v1/webhooks/{id}/secret.
Delivery format
Each delivery is an HTTP POST to your targetUrl with the event JSON as the body and these headers:
The body is the same event envelope you’d get from the
event stream, plus a top-level id field equal to X-Dial-Event-ID.
Verify the signature
The signature protects against forged and replayed deliveries. Recompute the HMAC over
{timestamp}.{raw_request_body} with your subscription secret and compare:
Retries
Dial considers a delivery successful on any HTTP 2xx. Anything else — a non-2xx
status, a connection error, or a timeout (10s per attempt) — is retried with exponential
backoff, up to 6 attempts total (1 initial + 5 retries). Because deliveries retry,
your endpoint must be idempotent: dedupe on X-Dial-Event-ID.
Test with a ping
The dashboard’s Fire ping button (and POST /api/v1/webhooks/{id}/ping) sends a
webhook.ping event to that subscription, bypassing
its eventTypes filter. When the ping is delivered and your endpoint returns 2xx, the
dashboard records the time as Last ping. Use it to confirm a new endpoint is reachable
and verifying signatures correctly.