---
title: "List a mailbox's messages"
canonical: "https://bird.com/docs/api/reference/list-mailbox-messages"
---

# List a mailbox's messages

`GET /v1/email/mailboxes/{mailbox_id}/messages`

Returns the messages in a mailbox across all of its conversations,
newest first. By default only received messages in the inbox and all
sent messages are returned. Pass `label` to see another view instead:

- `archive`: Filed-away mail.
- `spam` or `blocked`: Mail placed in either folder.
- `trash`: Trashed messages.
- `unread`: Messages you have not read yet, across all conversations.
- Any custom label you have applied.

Filter by direction or combined delivery status. Pass
`include=extracted_text` to inline each message's extracted plain text.
`before` and `after` filter by time. To page through results, pass the
response cursors back as `starting_after` or `ending_before`.

## Code samples

**cURL**

```sh
curl -X GET "https://us1.platform.bird.com/v1/email/mailboxes/{mailbox_id}/messages" \
  -H "Authorization: Bearer $TOKEN" \
  --url-query "label=unread" \
  --url-query "limit=25"
```

Examples: [cURL](/docs/api/reference/list-mailbox-messages.curl.md)

## Example response `200`

```json
{
  "data": [
    {
      "id": "rem_01krdgeqcxet5s7t44vh8rt9mg",
      "direction": "inbound",
      "channel": "email",
      "thread_id": "thr_01krdgeqcxet5s7t44vh8rt9mg",
      "subject": "Re: Your order",
      "labels": [
        "inbox",
        "unread"
      ],
      "recipients": [
        {
          "status": "delivered"
        }
      ],
      "authentication": "pass",
      "attachment_manifest": [
        {
          "id": "rea_01krdgeqcxet5s7t44vh8rt9mg",
          "filename": "invoice.pdf",
          "content_type": "application/pdf"
        }
      ],
      "contact_id": "con_01krdgeqcxet5s7t44vh8rt9mg",
      "source": {
        "resource": "/v1/email/inbound-messages/rem_01krdgeqcxet5s7t44vh8rt9mg"
      }
    }
  ],
  "next_cursor": "eyJ2IjoxLCJzIjoiXCIyMDI2LTA1LTI1VDE0OjAzOjEwWlwiIiwiaSI6IjAxOTJmM2IxLTRjN2UtN2EyYi05ZDYxLThmM2E1YzJlN2I0MCJ9",
  "prev_cursor": null,
  "refresh_cursor": "eyJ2IjoxLCJzIjoiXCIyMDI2LTA1LTI1VDE2OjQyOjAxWlwiIiwiaSI6IjAxOTJmM2IxLTllMDQtN2NkMy1iODE3LTJhNmY0ZDFjOGUwOSJ9"
}
```

## Path parameters

- `mailbox_id` (string): Mailbox identifier. Starts with `mbx_`.

## Query parameters

- `label` (string): Filter to messages that have this label. `trash` lists trashed messages. Any other label, whether that is `archive`, `spam`, `blocked`, `unread` or one of your own, lists the messages that have it and are not in the trash. When omitted, received messages in the inbox and all sent messages are returned.
- `direction` (string)

  Filter to received (`inbound`) or sent (`outbound`) messages.

  Possible values: `outbound`, `inbound`
- `status` (string)

  Filter sent messages by combined delivery status: `accepted`, `sent`, `delivered`, or `failed`.

  Possible values: `accepted`, `sent`, `delivered`, `failed`
- `after` (string): Filter to messages that occurred at or after this time. Page through results with `starting_after` or `ending_before` instead of this value.
- `before` (string): Filter to messages that occurred at or before this time. Page through results with `starting_after` or `ending_before` instead of this value.
- `include` (string)

  Set to `extracted_text` to inline each message's extracted plain text.

  Possible values: `extracted_text`
- `limit` (integer): Maximum number of items to return per page.
- `starting_after` (string): Cursor from the `next_cursor` field of a previous list response. Returns items immediately after the cursor position in the current sort order.
- `ending_before` (string): Cursor from the `prev_cursor` or `refresh_cursor` field of a previous list response. Returns items immediately before the cursor position in the current sort order. `prev_cursor` returns the preceding page. `refresh_cursor` anchors at the first row of that response, which on a newest-first sort is how to fetch the items that have appeared since.

## Response body

- `data` (array of object, required)
- `data.id` (string, required): Message ID. Received messages have a `rem_` ID, sent messages an `em_` ID: the same IDs used by the received-message and sent-message logs.
- `data.direction` (string, required)

  Which way the message went. `inbound` means you received it, `outbound` means you sent it.

  Possible values: `inbound`, `outbound`
- `data.channel` (string, required): Channel this message lives on. Always `email`.
- `data.thread_id` (string, required): Conversation this message belongs to.
- `data.from` (string, required): Sender address.
- `data.to` (array of string, required): Recipient addresses on the To line.
- `data.cc` (array of string, required): Recipient addresses on the Cc line. Empty when the message had none.
- `data.delivered_to` (nullable string, required): Address the message was actually delivered to, when it differs from the mailbox address (for example mail routed in from another address). Null for sent messages and for mail addressed directly to the mailbox.
- `data.subject` (nullable string, required): Message subject. Null when the message had no subject.
- `data.preview` (nullable string, required): Short plain-text preview of the message body.
- `data.extracted_text` (nullable string): Plain-text content of the message with quoted history stripped. Readable for the mailbox's full retention tier, in both directions. Always present when fetching a single message. On list endpoints it is included only when the request sets `include=extracted_text`. Null when no text could be extracted.
- `data.labels` (array of string, required)

  Labels on this message. A received message always has exactly one placement label:

  - `inbox`: Accepted mail.
  - `archive`: The message's conversation was filed away.
  - `spam`: The message is filed in Spam.
  - `blocked`: The message was rejected by the mailbox's receive policy or rules.

  A received message also has `unread` until it is read. `trash` marks a message in the trash, in either direction. Custom labels share the same list, and a message has at most 20 labels in total.
- `data.status` (nullable string, required)

  Aggregate delivery status of a sent message:

  - `accepted`: Accepted for sending.
  - `sent`: Handed off to the provider.
  - `delivered`: All attempted recipients delivered.
  - `failed`: Terminal failure.

  Null for received messages.
- `data.recipients` (nullable array, required): Terminal per-recipient delivery outcomes of a sent message, filled in as each one becomes known and kept for the mailbox's full retention tier. Null for received messages and before any recipient reaches a terminal state. Per-recipient event detail lives on the sent-message log (`source`) for 30 days.
- `data.authentication` (nullable string, required)

  DMARC result for the domain in the received message's `From` header.

  - `pass`: SPF or DKIM passed and aligned with that domain.
  - `fail`: DMARC was evaluated and did not pass.
  - `unknown`: no trustworthy verdict is available.

  This follows `dmarc_pass` and does not verify a particular person. The receiving provider currently supplies no DMARC result, so received messages report `unknown`.

  Null for sent messages. This field is readable for the mailbox's full
  retention tier, so the verdict is still available after the 30-day
  received-message log has expired.

  Possible values: `pass`, `fail`, `unknown`, `null`
- `data.spf_pass` (nullable boolean, required): Whether the receiving provider reports that SPF authorized the envelope sender for the sending server. A soft failure is `false`. Missing, neutral and inconclusive results are `null`. Sent messages have `null` results. Kept for the mailbox retention tier.
- `data.dkim_pass` (nullable boolean, required): Whether the receiving provider verified a DKIM signature. A passing signature makes this `true` even when another signature fails. Missing signatures and inconclusive verification results are `null`. Sent messages have `null` results. Kept for the mailbox retention tier.
- `data.dmarc_pass` (nullable boolean, required): Whether SPF or DKIM passed and aligned with the domain in the message's `From` header. The receiving provider currently supplies no DMARC result, so this is `null`. Sent messages have `null` results. Kept for the mailbox retention tier.
- `data.purge_at` (string, required): Scheduled permanent-deletion time. This is the end of the mailbox's retention tier, moved to no more than 30 days in the future while the message is in the trash. Restore a trashed message before then with `PATCH {"labels": {"remove": ["trash"]}}`.
- `data.attachment_count` (integer, required): Number of attachments on the message.
- `data.attachment_manifest` (array of object, required): Attachment metadata (filename, content type, size). Both the metadata and the attachment bytes stay available for the mailbox's retention tier.
- `data.attachment_manifest.id` (string, required): Attachment ID, used to download the attachment bytes.
- `data.attachment_manifest.filename` (nullable string, required): Original filename, or null when the attachment had none.
- `data.attachment_manifest.content_type` (nullable string, required): MIME content type, or null when it could not be determined.
- `data.attachment_manifest.size` (integer, required): Attachment size in bytes.
- `data.reference_ids` (array of string, required): RFC 5322 References header entries used to thread the conversation.
- `data.contact_id` (nullable string, required): Contact linked to this message, or null when none is linked.
- `data.source` (object, required): Link to the message's entry in the received-message or sent-message log, which has delivery analytics such as per-recipient events. Log entries expire 30 days after the message occurred.
- `data.source.resource` (string, required): API path of the log entry for this message.
- `data.source.available_until` (string, required): When the log entry (and the message's body and raw MIME) expires.
- `data.occurred_at` (string, required): When the message was received or accepted for sending.
- `next_cursor` (nullable string, required): Cursor for the next page. Pass back as `starting_after` to advance forward. `null` when no next page exists.
- `prev_cursor` (nullable string, required): Cursor for the previous page. Pass back as `ending_before` to step backward. `null` when no previous page exists.
- `refresh_cursor` (nullable string, required): Refresh anchor, the first row of this response. Pass back as `ending_before` to fetch what precedes it in the current sort order. On a newest-first sort those are the items that have appeared since; on any other sort they are the items that sort earlier, so refreshing such a list means re-fetching it instead. Non-`null` whenever `data` is non-empty; `null` only on an empty page. Distinct from `prev_cursor`.

## Related resources

- [Setting up your coding agent](/learn/basics/setting-up-your-coding-agent) (video)
- [What is an MCP server, and how does an agent use one to send messages?](/explained/platform/what-is-an-mcp-server-and-how-does-an-agent-send-messages) (answer)
- [Coding agents](/ai) (product)
- [Build with AI agents](/learn/paths/agents) (course)

[Get an implementation brief](/learn/workspace?topic=agents)
