Skip to main content

Delivery log

The Delivery Log page gives you one search across every message deliverable — SMS, WhatsApp, email, and voice — instead of opening each channel workspace and searching there. Open it from Messages → Tools → Delivery log. Use it when you need to answer questions the per-channel workspaces cannot:
  • “Did this recipient get the WhatsApp after the SMS failed?” — a mixed-channel history in one result list.
  • “Find this provider-side message ID from a carrier or Meta dashboard paste.” — a match against the provider reference, not a free-text scan.
  • “What is the current status of this message ID?” — a direct lookup by the msg_… identifier returned by the send API.
This guide walks the whole loop: shape the search, narrow it with filters, read each status in the result, and hand the exact view to a teammate as a link.

Searching

The search box accepts three identifier shapes, and the page detects which one you pasted:
  • Message ID — the msg_… identifier the send API returns (for example msg_a1b2c3d4e5f6a7b8). A paste that matches the msg_ prefix plus 8–32 hexadecimal characters is flagged as a correlated lookup: the scope is a single identifier rather than a free-text scan. A correlation strip above the results reads “Correlated by message ID / provider reference:” followed by one channel chip per matching row, so you can see at a glance which channels the identifier spans.
  • Provider reference — the external message ID a carrier or Meta dashboard shows for the delivery (for WhatsApp, the wamid.… value Meta returns). Paste it verbatim and the page matches it against the provider-reference field instead of scanning free text.
  • Free text — anything that does not match an identifier shape is matched against the recipient, the sender, and the searchable body content. Phone numbers work best pasted in E.164 form (+14155552671).
The correlation strip matters when an identifier returns more than one row: a broadcast that retried, or a recipient reachable on two channels, shows one row per channel with its own chip.

Filters

Three dropdowns narrow the result set:
  • Channel — SMS, WhatsApp, voice, email.
  • Status — every lifecycle state, listed under “Working a result” below.
  • Direction — outbound or inbound.
Leaving a filter on all means no filter is sent — the page drops the parameter from the request entirely rather than sending a literal all value. The same applies to the URL: the page reads its initial filters from the query string, but a default such as status=all is ignored, not applied. When you build a share link by hand, only non-default values travel.

Working a result

Each row carries its channel chip, recipient or sender, current status, and timestamp. Selecting a row opens the standard message detail page — the same drill-down every channel workspace uses — where the status timeline shows each lifecycle step with its timestamp and, on a terminal failure, the carrier or provider rejection reason. The status vocabulary means one thing per state; read a row like this: Two statuses look similar but call for different moves: failed means “something went wrong — find the reason and retry,” while undelivered means “the destination cannot take it — stop retrying and fix the list.” submitted_no_receipt sits between: the send happened, only the verdict is missing.

Sharing a view

The page reads its initial filters from the URL, so any view you can build on screen is a link you can paste into a runbook, a ticket, or chat:
Supported parameters: q (search text), channel, status, direction. A teammate opening the link lands on the same filtered result list you saw — no need to dictate filter settings over chat. The parameters map one-to-one onto the list-messages API filter vocabulary, so a URL built against the API works in the page too.

When the log cannot answer

The Delivery Log is a lookup surface: it answers “which messages, in what state.” Some questions need a different tool:
  • A lifecycle stalled at the provider. submitted_no_receipt rows and carrier rejections that need the provider’s own dashboard — open the step-by-step lifecycle in Developer → Delivery Logs, which reads the terminal rejection reason and the receipt trail per step.
  • Channel-specific work. Compose, template management, and channel settings stay in the per-channel workspaces under Messages. The Delivery Log row opens the same shared message detail page those workspaces use, so anything reachable there is reachable from a result row.
  • Voice interactions. Calls live on the interaction timeline, not the message log — use Interaction Search to scan conversations and calls in one list.

API access

The log is not a dashboard-only view: every lookup the page performs runs against GET /api/v1/messages, so a ledger reconciliation, a support script, or an on-call runbook can run the same lookup programmatically. Each request carries an X-API-Key header (live keys are prefixed dv_live_sk_).

Correlated-id lookup

Pass the msg_… id from the send API as q — the single-identifier scope the dashboard flags as a correlated lookup:
Response — 200 OK

Filtered scan

Pass the same channel / status / direction values the shareable link accepts:
Response — 200 OK
Use the API when the dashboard page is one step in a script; use the page when a person needs to see and share the result. Both read the same rows. For a step-by-step console walkthrough of one failing message, Developer → Delivery Logs covers the same endpoint from the console side.