> ## 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.

# Delivery log

> Search every message delivery across SMS, WhatsApp, email, and voice from one page — by message ID, provider reference, recipient, or sender — and share a pre-filtered view as a link.

# 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 the Delivery Log 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.

## Search behaviour

The search box accepts:

* A **message ID** returned by the send API (for example `msg_a1b2c3d4e5f6a7b8`). A lookup that matches the `msg_…` shape is flagged as a *correlated lookup* — the scope is a single identifier rather than a free-text scan, and a correlation strip above the results lists which channels the matching rows span. Matching identifiers follow the 8–32 hexadecimal-character suffix shape after the `msg_` prefix.
* A **provider reference** (the external message ID a carrier or Meta dashboard shows for the delivery).
* **Free text** matched against the recipient, the sender, and the searchable body content.

Three filters narrow the result set: **Channel** (SMS, WhatsApp, Email, voice), **Status** (queued, scheduled, sending, sent, delivered, read, rejected, failed, undelivered, expired, submitted without a receipt), and **Direction** (outbound or inbound). Leave a filter on *all* to keep it out of the request — defaults never travel to the backend as literal filters.

Each result carries its channel chip, and selecting a row opens the standard message detail page — the same drill-down every channel workspace uses.

## Shareable filtered links

The page reads its initial filters from the URL, so you can bookmark or share a pre-filtered view:

```text theme={null}
# Look up a specific message ID
/${locale}/messages/delivery-log?q=msg_a1b2c3d4e5f6a7b8

# All failed outbound WhatsApp deliveries
/${locale}/messages/delivery-log?channel=whatsapp&status=failed&direction=outbound

# Free-text recipient lookup across every channel
/${locale}/messages/delivery-log?q=%2B14155552671
```

Supported parameters: `q` (search text), `channel`, `status`, `direction`. The dashboard URL parameters map one-to-one onto the list-messages API filter vocabulary — the same lookup the page performs is available over the API, so a URL built against the API's filter vocabulary works in this page.

## Query the log programmatically

Every lookup the dashboard page performs runs against `GET /api/v1/messages`, so any workflow that outgrows a browser tab — a ledger reconciliation, a support script, an on-call runbook — can run the same lookup over the API. Each request carries an `X-API-Key` header (live keys are prefixed `dv_live_sk_`).

```bash theme={null}
export ORBIT_API_KEY="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:

```bash theme={null}
curl "https://api.orbit.devotel.io/api/v1/messages?q=msg_a1b2c3d4e5f6a7b8" \
  -H "X-API-Key: $ORBIT_API_KEY"
```

**Response — 200 OK**

```json theme={null}
{
  "data": [
    {
      "id": "msg_a1b2c3d4e5f6a7b8",
      "channel": "whatsapp",
      "direction": "outbound",
      "status": "delivered",
      "to": "+14155552671",
      "created_at": "2026-08-23T09:41:12.000Z"
    }
  ],
  "meta": {
    "request_id": "req_…",
    "timestamp": "2026-08-23T09:41:13.000Z",
    "pagination": { "cursor": null, "has_more": false, "total": 1 }
  }
}
```

### Filtered scan

Pass the same `channel` / `status` / `direction` values the shareable-link URL accepts:

```bash theme={null}
curl "https://api.orbit.devotel.io/api/v1/messages?channel=whatsapp&status=failed&direction=outbound" \
  -H "X-API-Key: $ORBIT_API_KEY"
```

**Response — 200 OK**

```json theme={null}
{
  "data": [
    {
      "id": "msg_f1e2d3c4b5a69788",
      "channel": "whatsapp",
      "direction": "outbound",
      "status": "failed",
      "to": "+14155552671",
      "created_at": "2026-08-23T08:12:03.000Z"
    },
    {
      "id": "msg_9c8b7a6d5e4f3210",
      "channel": "whatsapp",
      "direction": "outbound",
      "status": "failed",
      "to": "+14155559977",
      "created_at": "2026-08-22T18:45:51.000Z"
    }
  ],
  "meta": {
    "request_id": "req_…",
    "timestamp": "2026-08-23T09:41:13.000Z",
    "pagination": { "cursor": null, "has_more": false, "total": 2 }
  }
}
```

### Node SDK

The Node SDK (`@devotel-orbit/node`) wraps the same endpoint as `orbit.messages.list()`:

```ts theme={null}
import { Orbit } from "@devotel-orbit/node";

const orbit = new Orbit({ apiKey: process.env.ORBIT_API_KEY! });

// Filtered scan — same params as the shareable link.
const page = await orbit.messages.list({
  channel: "whatsapp",
  status: "failed",
  direction: "outbound",
});

for (const row of page.data) {
  console.log(row.id, row.channel, row.status, row.to);
}
```

## What still goes through a channel workspace

The Delivery Log is a lookup surface, not a workspace. Compose, template management, and channel-specific settings stay in the per-channel pages. If the row you need requires channel-specific actions, open it from the result list — the message detail page is shared, so anything reachable from a channel workspace is reachable from a Delivery Log row too.
