> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# The single message-status map: four owners, one answer

> One index over the three overlapping lifecycle pages — which page owns state meanings vs. transitions vs. vocabulary, a row-per-status owner map, the transition table as a reader actually uses it, the per-channel differences, and a worked reconciliation.

# The single message-status map

Three concept pages describe the same outbound-message state machine from
different angles, and until now nothing said which one to open for a given
question. This page is that index. Read it as a hub: resolve a status here,
then jump straight to the page that owns the answer you actually need —
without reading three pages to find the one rule you came for.

The four owners:

| Owner page                                                                     | What it owns                                                                                                                     | Open it when                                                                                  |
| ------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| [Delivery lifecycle](/concepts/delivery-lifecycle)                             | What each status *means* and who advances it — the actor story behind every transition.                                          | You want to know what a status tells you about the recipient or the send.                     |
| [Message status transition rules](/concepts/message-status-dag)                | The DAG itself — which transitions are legal, the precedence weight, the merge contract, the floors.                             | You are reconciling webhook events into your own datastore and need the merge rules verbatim. |
| [Send-side DLR model](/concepts/send-side-dlr-model)                           | The canonical six-state vocabulary and the SMPP receipt encoders that project statuses onto a bind or webhook.                   | You integrate over SMPP or need to know how a carrier `stat` token maps back.                 |
| [Message status lifecycle reference](/api-reference/messages-status-lifecycle) | The per-status API semantics and the webhook event map — which `message.*` event fires on which transition, with payload shapes. | You are wiring a webhook subscription to `status` values.                                     |

Two sibling lifecycle pages are deliberately separate: [email delivery
lifecycle](/concepts/email-delivery-lifecycle) runs the same machine on a
different provider and adds two outcomes; [delivery lifecycles other than
outbound](/concepts/dlr-model-two-planes) is the ingress/egress split.
Neither replaces the outbound story above.

## The glossary of state rows, with one owner each

Resolve a status you saw in a webhook payload or a `GET /messages/:id`
response here. Each row points at its one owning page; the first owner is
the primary, the second is the edge note.

| Status                 | One-line meaning                                                | Owning page                                                                                                                             |
| ---------------------- | --------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `pending`              | Row exists, not yet on the send queue (transient).              | [Delivery lifecycle](/concepts/delivery-lifecycle)                                                                                      |
| `scheduled`            | Parked until a fire time; cancellable until then.               | [Delivery lifecycle](/concepts/delivery-lifecycle)                                                                                      |
| `queued`               | Platform-side hold, visible and freshable.                      | [Delivery lifecycle](/concepts/delivery-lifecycle)                                                                                      |
| `accepted`             | Provider acknowledged into its queue.                           | [Delivery lifecycle](/concepts/delivery-lifecycle)                                                                                      |
| `sending`              | Worker is dispatching to the provider.                          | [Delivery lifecycle](/concepts/delivery-lifecycle)                                                                                      |
| `sent`                 | Provider wire-accepted; in flight, not carrier-confirmed.       | [Delivery lifecycle](/concepts/delivery-lifecycle)                                                                                      |
| `submitted_no_receipt` | Accepted but no DLR yet — a provisional sentinel.               | [Delivery lifecycle](/concepts/delivery-lifecycle) — edge: [Message status transition rules](/concepts/message-status-dag)              |
| `test_sent`            | Sandbox result; resolved before any provider dispatch.          | [Delivery lifecycle](/concepts/delivery-lifecycle)                                                                                      |
| `delivered`            | Carrier-confirmed delivery.                                     | [Delivery lifecycle](/concepts/delivery-lifecycle) — corrections edge: [Message status transition rules](/concepts/message-status-dag)  |
| `read`                 | Recipient opened it (read-receipt channel).                     | [Delivery lifecycle](/concepts/delivery-lifecycle)                                                                                      |
| `undelivered`          | Carrier tried; handset not reached.                             | [Delivery lifecycle](/concepts/delivery-lifecycle)                                                                                      |
| `failed`               | Dispatch-time or classified carrier failure; retries exhausted. | [Delivery lifecycle](/concepts/delivery-lifecycle)                                                                                      |
| `rejected`             | Pre-send refusal by the platform.                               | [Delivery lifecycle](/concepts/delivery-lifecycle) — vocabulary edge: [Send-side DLR model](/concepts/send-side-dlr-model)              |
| `bounced`              | Email-specific: receiving mail server rejected.                 | [Email delivery lifecycle](/concepts/email-delivery-lifecycle) — shared page: [Delivery lifecycle](/concepts/delivery-lifecycle)        |
| `expired`              | TTL or validity window lapsed before delivery.                  | [Delivery lifecycle](/concepts/delivery-lifecycle) — late-arrival edge: [Message status transition rules](/concepts/message-status-dag) |
| `cancelled`            | Operator cancelled an unsent scheduled message.                 | [Delivery lifecycle](/concepts/delivery-lifecycle)                                                                                      |
| `unknown`              | Unmapped provider status — a defensive sentinel.                | [Message status transition rules](/concepts/message-status-dag)                                                                         |
| `deleted`              | Operator-deleted; absolute floor.                               | [Message status transition rules](/concepts/message-status-dag)                                                                         |

`bounced` and `complained` are the two email-only outcomes; both live on the
email page. Everything else is the shared outbound machine.

## The DAG in one table

Take event payloads and reconciles them against the platform rules. This is
the transition table as a reader uses it — grouped by what dictates the next
move, not alphabetically sorted. Cross-check it against the full table on
the [Message status transition rules](/concepts/message-status-dag) page
before you hard-code a merge.

| From                   | Forward (by weight)                                     | Recoverable corrections                       | Floors it can hit                                           |
| ---------------------- | ------------------------------------------------------- | --------------------------------------------- | ----------------------------------------------------------- |
| `pending`              | any in-flight or outcome state                          | —                                             | `cancelled`, `deleted`                                      |
| `scheduled`            | `queued`                                                | —                                             | `cancelled`, `expired`, `deleted`                           |
| `queued`               | `accepted`, `sending`, `sent`, `test_sent`, `delivered` | `submitted_no_receipt`                        | `failed`, `rejected`, `undelivered`, `expired`, `cancelled` |
| `accepted`             | `sending`, `sent`, `test_sent`, `delivered`             | `submitted_no_receipt`                        | `failed`, `rejected`, `undelivered`, `expired`, `cancelled` |
| `sending`              | `sent`, `test_sent`, `delivered`                        | `submitted_no_receipt`                        | `failed`, `rejected`, `undelivered`, `expired`, `cancelled` |
| `sent`                 | `delivered`, `read`                                     | `submitted_no_receipt`                        | `failed`, `rejected`, `undelivered`, `expired`, `cancelled` |
| `submitted_no_receipt` | `delivered`, `read`                                     | — (itself the recoverable one)                | `failed`, `rejected`, `undelivered`, `expired`              |
| `delivered`            | `read`                                                  | `undelivered`, `failed` (carrier corrections) | —                                                           |
| `unknown`              | any concrete state (it weights below everything)        | —                                             | —                                                           |

Everything from any row to `deleted` is also legal on operator request. Any
transition not listed, or a backward move not named under Recoverable
corrections, is ignored as a duplicate. The full per-from table with
verbatim allowed sets is on the [Message status transition rules](/concepts/message-status-dag)
page — treat that page as the merge contract and this table as the reader
digest.

## When the same status means different things per channel

Three channel-specific flips change what a status tells you; none of them
change the status itself.

* **Meta DM (Instagram, Messenger) has no DLR.** Meta never emits a delivery receipt.
  `sent` flips to `submitted_no_receipt` after 5 minutes, and on an opted-in
  recipient that sentinel is a *functional delivery signal*, not genuine
  ambiguity. Branch on `metadata.no_dlr_channel` to tell the Meta case from
  the SMPP case. Owner: [Delivery lifecycle](/concepts/delivery-lifecycle).
* **SMPP grace window.** On SMS, MMS, voice, fax, and RCS, the receipt window
  is 30 minutes. A row stuck `sent` past that window is promoted
  `submitted_no_receipt` (intermediate, not terminal). Owner: [Delivery
  lifecycle](/concepts/delivery-lifecycle); the late-arrival expiry rule and
  the carrier-correction allowance live on [Message status transition rules](/concepts/message-status-dag).
* **Email adds a bounce outcome.** A receiving mail server can reject after
  acceptance, producing `bounced` — an email-only arm the shared lifecycle
  treats as one bullet and the email page treats as the structural story.
  Owner: [Email delivery lifecycle](/concepts/email-delivery-lifecycle).

SMPP encoding of this vocabulary — which `stat`/`err` token a bind receives
for each canonical state — is its own surface on the [Send-side DLR
model](/concepts/send-side-dlr-model) page.

## Worked reconciliation: apply the merge to a report table

Suppose a day's export of your own status mirror shows these rows, sorted by
message id then by arrival time. Apply the merge contract in order.

```text theme={null}
row 1:  msg_a1  delivered (weight 4)
        event:  undelivered  →  ACCEPT — named carrier correction,
                row closes at undelivered
row 2:  msg_a2  submitted_no_receipt (weight 2.5)
        event:  delivered    →  ACCEPT — higher weight wins
row 3:  msg_a3  delivered (weight 4)
        event:  sent (weight 2) → IGNORE — regression, duplicate
row 4:  msg_a4  cancelled (floor)
        event:  delivered   →  IGNORE — floors accept nothing
row 5:  msg_a5  deleted (floor)
        event:  submitted_no_receipt → IGNORE
```

The three rules this walkthrough applied, restated: (1) only the recoverable
correction transitions move a row backward; (2) no provider callback moves a
row off `deleted` or `cancelled`; (3) dedupe first — a redelivered event
must not re-apply a transition you already recorded. The full correctness
proof and a minimal JavaScript merge implementation live on the [Message
status transition rules](/concepts/message-status-dag) page.

## See also

* [Delivery lifecycle](/concepts/delivery-lifecycle) — what each status
  means and who advances it
* [Message status transition rules](/concepts/message-status-dag) — the
  allowed transitions, precedence, and merge contract
* [Send-side DLR model](/concepts/send-side-dlr-model) — canonical
  vocabulary and SMPP encoders
* [Email delivery lifecycle](/concepts/email-delivery-lifecycle) — the
  email-specific outcomes beside the shared machine
* [Message status lifecycle reference](/api-reference/messages-status-lifecycle) —
  per-status semantics and the webhook-event map
* [Operational sentinels](/concepts/operational-sentinels) — the settled-but-
  non-outcome statuses beside the DAG
