Normalized inbound event envelope
Inbound messaging events (received messages, delivery receipts, failures, reads, opt-outs) come from several upstream carriers, and each carrier reports a different status vocabulary: Telnyx firesmessage.sending_failed, SMPP receipts carry codes like UNDLV and DELIVRD, DIDWW reports its own status strings. Orbit folds all of them onto the same canonical webhook events — this page documents the three pieces that make that folding predictable:
- The
data.normalizedblock stamped on inbound message and opt-out envelopes - The
normalized.inboundshare event — one subscription covering the whole inbound family - The inbound-events catalog endpoint — the machine-readable mapping table of every upstream carrier status to the canonical event it resolves to
The data.normalized block
Deliveries whose event belongs to the inbound family carry an extra normalized object inside data:
The
kind discriminator:
The block is additive — every field your handler already reads keeps its existing name and position. Events outside the inbound family do not carry
normalized.
Subscribe once with normalized.inbound
normalized.inbound is a share-able subscription name that covers the whole inbound family at once. Set it as an endpoint’s entire event list and the endpoint receives message.received, message.delivered, message.failed, message.read, and contact.opted_out — without enumerating them:
*) behave exactly as before — the share name is a convenience, not a replacement.
The inbound-events catalog
The mapping table itself is served by one authed endpoint:GET /api/v1/webhooks/inbound-eventskind, and the full list of upstream carrier statuses (grouped by carrier — the Devotel softswitch, Telnyx, DIDWW, and Meta) that normalize to it.
kind values here (delivery, failure, opt_out, received) describe the carrier-status mapping; the kind values on the data.normalized envelope block above (inbound, message, opt_out) describe the delivery’s place in the inbound family. Both are closed enums you can branch on.
Use the catalog to check that your handler’s switch statement covers the same mapping the platform normalizes with — for example when adding support for a new carrier, or when a raw status appears in your logs that your switch does not yet handle. The same table ships in the SDK as normalizeInboundEvent in the shared webhook normalization module: pass it a raw carrier status (with or without the carrier name) and it returns the canonical event and status pair, so receiver-side validation never drifts from the platform’s mapping.
See also
- Webhook Events catalog — every event type you can subscribe to
- Webhook Event Payloads — the full envelope and header anatomy
- Webhook Overview — endpoints, signing, retries, and the dead-letter queue
- Webhook Security — signature verification