Events

View as Markdown

Dial publishes a single stream of JSON events per account. Anything that affects your numbers — an inbound SMS, a finished call — arrives on that stream and is the same payload whether you consume it via POST /api/v1/events/wait, dial wait-for, or a local target fanning out from the listen daemon.

Envelope

Every event shares one envelope; the type selects the shape of the data payload.

FieldTypeDescription
idstringA stable per-event identifier. On webhook deliveries it is mirrored in the X-Dial-Event-ID header; deduplicate on it.
objectstringAlways "event".
typestringThe event type — one of the names below.
versionintegerPayload schema version. Currently 1 everywhere.
createdAtstringISO-8601 timestamp of when the event happened on Dial’s side.
relatedObjectobject | nullPointer to the REST resource the event concerns — { id, type, url }. url is the get-by-id path when one exists (calls) or null (messages). null for events with no underlying resource (webhook.ping).
dataobjectThe event-specific payload, documented per type below.

All field names are camelCase, matching the REST surface. Read event-specific values from data.

Provider-specific fields. Dial may include additional internal identifiers in event payloads (carrier message IDs, voice-provider call IDs, etc.). They aren’t part of the public contract — only the fields documented per event type are guaranteed to stay. Ignore anything you don’t recognize.

Event types

Delivery semantics

The upstream stream Dial publishes is presence-based — clients only see events that arrive while they’re connected. A dial wait-for or REST long-poll catches the next event live; the listen daemon replays events missed during a brief disconnect (up to ~2 minutes). For guaranteed, off-machine delivery, register a webhook — Dial POSTs each event to your HTTPS endpoint, signed and retried at-least-once.