List messages across inboxes or for one inbox
Lists messages newest first across every inbox on your account, or a single inbox via inboxId.
Lists messages newest first across every inbox on your account, or a single inbox via inboxId. The default view is the unified projection over inbound, outbound, and agent-to-agent messages; narrow it with threadId, direction (inbound or outbound), and channel. Results are keyset-paginated — limit defaults to 25 (max 100), and each page returns an opaque nextCursor you pass back as cursor to page forward. One special case: direction=outbound with no channel returns the send ledger instead — the same rows carrying delivery status, providerMessageId, and bounce/complaint timestamps — and that ledger view is unpaginated (honoring only inboxId and limit), so passing cursor or threadId alongside it returns 400; add an explicit channel (e.g. ?channel=email&direction=outbound) for the paginated unified list. An unrecognized channel, direction, limit, or cursor is a 400. Requires the messages:read scope; see keyset pagination.
Scope: messages:read. Send the API key as a bearer token; Scopes lists what each one reaches.
Request
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
limit | integer | no | Maximum number of items in the page. (minimum 1, maximum 100, default 25) |
cursor | string | no | The nextCursor of the previous page; omit it for the first page (Pagination). |
inboxId | string | no | |
threadId | string (uuid) | no | |
direction | "inbound", "outbound" | no | |
channel | "email", "a2a", "sms", "whatsapp", "telegram", "slack", "webchat", "voice", "push", "api" | no | Filter to a single channel. "email" and "a2a" are live today; the remaining values are reserved for future channels (they filter to an empty list until wired). Unknown values are a 400. |
Response
200 Success. Body: application/json, MessageListResponse.
| Field | Type | Required | Description |
|---|---|---|---|
object | "list" | yes | |
data | array of Message | yes | |
pagination | Pagination | yes |
Errors
Every error has the same body, {"error": {"type", "code", "message", "param"}}; branch on code. Errors lists every code.
| Status | Meaning |
|---|---|
400 | The request is malformed or a value is invalid (invalid_request, invalid_domain, idempotency_key_mismatch). |
401 | The API key is missing or invalid. |
403 | The key lacks the scope this endpoint needs (scope_missing) or may not do this (not_permitted). |
404 | No such resource in this account (resource_not_found). |
422 | The request is well-formed but a field failed validation (validation_failed). |
429 | Rate limit, plan limit, budget or spend cap reached (rate_limited, plan_limit_reached, budget_exceeded, spend_cap_reached). |
500 | An unexpected error; retry with backoff, then contact support (internal_error). |
Get attachment metadata
Returns metadata for one email attachment by attachmentId — its filename, contentType, sizeBytes, contentId, disposition, and createdAt, plus the messageId it belongs to.
Send a message from a Dairo inbox
Sends one message from the inbox named by inboxId to the addresses in to (plus optional cc/bcc, up to 50 recipients total); the inbox's own channel decides the transport — email, Telegram, or Slack.