# List messages in a conversation

`GET /v1/amb/conversations/{conversation_id}/messages`

Returns the messages in a conversation, newest first, both received and
sent. To page through older messages, use `starting_after`. The sort
order is fixed, so to render the messages in conversation order, reverse
the page yourself. Messages do not expire based on age.

## Code samples

**TypeScript**

```ts
const result = await bird.amb.conversations.listMessages(
  "acv_01krdgeqcxet5s7t44vh8rt9mg",
  { limit: 2 },
);
console.log(result);
```

Examples: [TypeScript](/docs/api/reference/list-amb-conversation-messages.ts.md) · [Python](/docs/api/reference/list-amb-conversation-messages.py.md) · [Go](/docs/api/reference/list-amb-conversation-messages.go.md) · [PHP](/docs/api/reference/list-amb-conversation-messages.php.md) · [CLI](/docs/api/reference/list-amb-conversation-messages.cli.md) · [MCP](/docs/api/reference/list-amb-conversation-messages.mcp.md) · [cURL](/docs/api/reference/list-amb-conversation-messages.curl.md)

## Example response `200`

```json
{
  "data": [
    {
      "id": "amb_01krdgeqcxet5s7t44vh8rt9mg",
      "conversation_id": "acv_01krdgeqcxet5s7t44vh8rt9mg",
      "business_id": "abz_01krdgeqcxet5s7t44vh8rt9mg",
      "direction": "outbound",
      "status": "accepted",
      "kind": "text",
      "source": "operator",
      "in_reply_to_message_id": "amb_01krdgeqcxet5s7t44vh8rt9mg",
      "locale": "en_US",
      "category": "order_update",
      "tags": [
        {
          "name": "category",
          "value": "welcome"
        }
      ],
      "cost": {
        "amount": "0.00990",
        "currency_code": "USD",
        "transaction_amount": "0.00790",
        "passthrough_amount": "0.00200"
      },
      "last_error": {
        "code": "bird:business_not_registered",
        "description": "Apple refused the message with HTTP status 404."
      }
    }
  ],
  "next_cursor": "eyJ2IjoxLCJzIjoiXCIyMDI2LTA1LTI1VDE0OjAzOjEwWlwiIiwiaSI6IjAxOTJmM2IxLTRjN2UtN2EyYi05ZDYxLThmM2E1YzJlN2I0MCJ9",
  "prev_cursor": null,
  "refresh_cursor": "eyJ2IjoxLCJzIjoiXCIyMDI2LTA1LTI1VDE2OjQyOjAxWlwiIiwiaSI6IjAxOTJmM2IxLTllMDQtN2NkMy1iODE3LTJhNmY0ZDFjOGUwOSJ9"
}
```

## Path parameters

- `conversation_id` (string): Conversation identifier. Starts with `acv_`.

## Query parameters

- `direction` (string)

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

  Possible values: `outbound`, `inbound`
- `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): Page of Apple Messages for Business messages, newest first.
- `data.id` (string, required): ID of the message, assigned when it is accepted or received. Pass it as `message_id` to the get-message and list-events endpoints.
- `data.conversation_id` (string, required): The conversation this message belongs to.
- `data.business_id` (string, required): The business the message was sent from or received by.
- `data.from` (string): Apple business identifier on outbound messages, or the customer's opaque Apple identifier on inbound messages. Omitted when that address is unavailable on a historical record.
- `data.to` (string): Customer's opaque Apple identifier on outbound messages, or the Apple business identifier on inbound messages. Omitted when that address is unavailable on a historical record.
- `data.direction` (string, required)

  Whether a message was sent by the business or received from the customer:

  - `outbound`: A reply the business sent into the conversation.
  - `inbound`: A message the customer sent.

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

  Send status:

  - `accepted`: Accepted and queued for delivery to Apple.
  - `sent`: Handed to Apple. There is no delivery or read receipt on this
    channel, so `sent` is the furthest an outbound message's status
    advances.
  - `send_failed`: Sending stopped because of a business or conversation
    restriction, a recipient opt-out, an Apple refusal, or exhausted attempts.
    An earlier attempt may have reached Apple if its response or the local
    record of success was lost. See `last_error` for why sending stopped.
  - `rejected`: Refused by Bird before any send attempt and never charged:
    the destination has no price, the wallet could not fund the send, or the
    content cannot be sent yet. See `last_error`.
  - `received`: Received as an inbound message.

  Possible values: `accepted`, `sent`, `send_failed`, `rejected`, `received`
- `data.kind` (string, required)

  Derived content classification for filtering and statistics.

  Possible values: `text`, `attachment`, `rich_link`, `quick_reply`, `list_picker`, `time_picker`, `form`, `apple_pay`, `authenticate`, `imessage_app`, `interactive`
- `data.source` (string)

  Who sent this message. Absent on an inbound message, which has no source to report.

  Possible values: `operator`, `automation`, `api`
- `data.content` (object, required): Native message content. Outgoing interactions contain requests; incoming interactions contain replies.
- `data.content.type` (string, required)

  Always text.

  Value: `text`
- `data.content.body` (string): Text displayed in the message. Use one U+FFFC object replacement character per attachment to control placement.
- `data.content.subject` (string): Subject displayed above the message body.
- `data.content.attachments` (array): Ordered attachments. Each object supplies a source URL or an encrypted Apple reference.
- `data.content.attachments.name` (string): Display filename.
- `data.content.attachments.mime_type` (string): Media type of the attachment.
  - Variant `source_url`
    - `data.content.attachments.source_url` (string, required): HTTPS URL Bird downloads and uploads to Apple.
  - Variant `url + owner + key + signature_base64 + size`
    - `data.content.attachments.url` (string, required): Encrypted attachment URL returned by Apple.
    - `data.content.attachments.owner` (string, required): Opaque owner value returned by Apple.
    - `data.content.attachments.signature_base64` (string, required): Attachment authorization signature returned by Apple.
    - `data.content.attachments.key` (string, required): Attachment decryption key returned by Apple.
    - `data.content.attachments.size` (integer, required): Attachment size in bytes.
- `data.content.rich_link_data` (object)
- `data.content.rich_link_data.url` (string, required): HTTPS URL opened by the preview.
- `data.content.rich_link_data.title` (string, required): Preview title.
- `data.content.rich_link_data.assets` (object, required)
- `data.content.rich_link_data.assets.image` (object, required)
- `data.content.rich_link_data.assets.image.source_url` (string, required): HTTPS URL of a PNG preview image up to 200 kB. Bird fetches and encodes it when sending.
- `data.content.rich_link_data.assets.image.mime_type` (string)

  PNG media type required by Apple. Defaults to image/png.

  Value: `image/png`
- `data.content.rich_link_data.assets.video` (object)
- `data.content.rich_link_data.assets.video.url` (string, required): HTTPS video URL fetched by Apple.
- `data.content.rich_link_data.assets.video.mime_type` (string): Media type of the video. Defaults to video/mp4; supply the actual type for other formats.
- `data.content.rich_link_data_ref`: Reusable Apple content reference. Supply the decryption key, or the signed bid and data_ref_sig returned by Apple.
- `data.content.rich_link_data_ref.title` (string): Title supplied by Apple for the preview.
- `data.content.rich_link_data_ref.url` (string, required): Location of the encrypted preview.
- `data.content.rich_link_data_ref.owner` (string, required): Owner identifier supplied by Apple.
- `data.content.rich_link_data_ref.signature_base64` (string, required): Signature supplied by Apple.
- `data.content.rich_link_data_ref.size` (integer, required): Size of the encrypted preview in bytes.
  - Variant `key`
    - `data.content.rich_link_data_ref.key` (string, required): Decryption key supplied by Apple.
  - Variant `bid + data_ref_sig`
    - `data.content.rich_link_data_ref.bid` (string, required): Messages extension identifier supplied by Apple, when present.
    - `data.content.rich_link_data_ref.data_ref_sig` (string, required): Signature binding the reference to the business, when supplied by Apple.
- `data.content.interactive_data`: A built-in interaction or custom iMessage app. Custom apps require the app metadata and both message bubbles.
- `data.content.interactive_data.session_identifier` (string): Session UUID to preserve across interactions. Apple creates one when omitted.
  - Variant `data`
    - `data.content.interactive_data.data` (required): Exactly one built-in interaction. Protocol versions are managed by Bird.
    - `data.content.interactive_data.data.request_identifier` (string): Correlation identifier for this interaction. Bird generates one when omitted.
    - `data.content.interactive_data.data.images` (array of object): Images referenced by identifier.
    - `data.content.interactive_data.data.images.identifier` (string, required): Identifier referenced by a bubble, item, or event.
    - `data.content.interactive_data.data.images.source_url` (string, required): HTTPS URL of a PNG image up to 200 kB. Total interactive image data must not exceed 5 MB.
    - `data.content.interactive_data.data.images.description` (string): Accessibility description read by VoiceOver.
      - Variant `quick_reply`
        - `data.content.interactive_data.data.quick_reply` (object, required)
        - `data.content.interactive_data.data.quick_reply.summary_text` (string, required): Text used for the device notification and shown in the transcript after the customer chooses an item. Send a separate text message to introduce the choices.
        - `data.content.interactive_data.data.quick_reply.items` (array of object, required): The buttons offered to the customer. Apple requires between two and five; outside that range the request is refused with a `422` `AMBQuickReplyItemsInvalid`. For more choices, send `list_picker` content instead.
        - `data.content.interactive_data.data.quick_reply.items.identifier` (string, required): Opaque choice identifier returned in interactive_data.data.quick_reply.selected_identifier.
        - `data.content.interactive_data.data.quick_reply.items.title` (string, required): Label shown on the button.
      - Variant `list_picker`
        - `data.content.interactive_data.data.list_picker` (object, required)
        - `data.content.interactive_data.data.list_picker.sections` (array of object, required): The menu's sections, each with its own heading and rows.
        - `data.content.interactive_data.data.list_picker.sections.title` (string, required): Heading shown above this section's rows.
        - `data.content.interactive_data.data.list_picker.sections.order` (nullable integer): Where this section sits relative to its siblings, ascending. Sections omitting it are laid out in list order, after any that specify one.
        - `data.content.interactive_data.data.list_picker.sections.items` (array of object, required): The rows in this section.
        - `data.content.interactive_data.data.list_picker.sections.items.identifier` (string, required): Opaque item identifier returned in interactive_data.data.list_picker.sections.
        - `data.content.interactive_data.data.list_picker.sections.items.title` (string, required): Label shown on the row.
        - `data.content.interactive_data.data.list_picker.sections.items.subtitle` (nullable string): Secondary line shown under the title.
        - `data.content.interactive_data.data.list_picker.sections.items.image_identifier` (nullable string): Identifier of an image in interactive_data.data.images, shown next to this row. A key with no matching entry in `images` is refused with a `422` `AMBInteractiveImageInvalid`.
        - `data.content.interactive_data.data.list_picker.sections.items.order` (integer): Position within the section, ascending. Defaults to the row's array position.
        - `data.content.interactive_data.data.list_picker.sections.multiple_selection` (boolean): Whether the customer can select more than one row in this section.
      - Variant `event`
        - `data.content.interactive_data.data.event` (object, required)
        - `data.content.interactive_data.data.event.identifier` (string): Your identifier for the event. Defaults to the message identifier.
        - `data.content.interactive_data.data.event.location` (object): Optional appointment location.
        - `data.content.interactive_data.data.event.location.title` (string): Name shown for the appointment location.
        - `data.content.interactive_data.data.event.location.latitude` (number): Latitude in degrees. Set together with `longitude`.
        - `data.content.interactive_data.data.event.location.longitude` (number): Longitude in degrees. Set together with `latitude`.
        - `data.content.interactive_data.data.event.location.radius` (number): Location radius in meters. Apple ignores it without coordinates.
        - `data.content.interactive_data.data.event.timezone_offset` (integer): Minutes from GMT at the event location. Omit to use the customer's time zone.
        - `data.content.interactive_data.data.event.timeslots` (array of object, required): Appointment times with RFC 3339 timestamps and duration in seconds.
        - `data.content.interactive_data.data.event.timeslots.identifier` (string, required): Opaque slot identifier. Apple may instead return only a localized label in interactive_data.reply_message.title.
        - `data.content.interactive_data.data.event.timeslots.start_at` (string, required): When this slot begins. Seconds and fractional seconds must be zero, for example `2026-09-02T14:30:00Z`; otherwise sending returns `422` with error code `E01001`. The timestamp is converted to UTC for Apple while preserving the instant.
        - `data.content.interactive_data.data.event.timeslots.duration_seconds` (integer, required): Duration in seconds. Zero indicates no duration.
        - `data.content.interactive_data.data.event.image_identifier` (string): Identifier of the event image in interactive_data.data.images.
        - `data.content.interactive_data.data.event.title` (string): Event title.
      - Variant `dynamic`
        - `data.content.interactive_data.data.dynamic` (object, required): Form content. Bird supplies Apple’s messageForms template and protocol version.
        - `data.content.interactive_data.data.dynamic.data` (object, required)
        - `data.content.interactive_data.data.dynamic.data.start_page_identifier` (string, required): Identifier of the first page to show.
        - `data.content.interactive_data.data.dynamic.data.private` (boolean): Whether Apple marks the submitted response as private.
        - `data.content.interactive_data.data.dynamic.data.show_summary` (boolean): Whether Apple shows a summary before the customer submits.
        - `data.content.interactive_data.data.dynamic.data.splash` (object)
        - `data.content.interactive_data.data.dynamic.data.splash.header` (string)
        - `data.content.interactive_data.data.dynamic.data.splash.splash_text` (string)
        - `data.content.interactive_data.data.dynamic.data.splash.button_title` (string, required)
        - `data.content.interactive_data.data.dynamic.data.splash.image_identifier` (string)
        - `data.content.interactive_data.data.dynamic.data.pages` (array of object, required): Form pages referenced by the start page and navigation identifiers.
        - `data.content.interactive_data.data.dynamic.data.pages.page_identifier` (string, required): Unique identifier for this page.
        - `data.content.interactive_data.data.dynamic.data.pages.title` (string)
        - `data.content.interactive_data.data.dynamic.data.pages.subtitle` (string, required): Question shown on this page.
        - `data.content.interactive_data.data.dynamic.data.pages.next_page_identifier` (string): Next page to show. Omit to finish the form. Single-select pages route through their items instead.
        - `data.content.interactive_data.data.dynamic.data.pages.submit_form` (boolean): Marks this page as an end page for the form. A page with no next page also finishes the form.
          - Variant `select`
            - `data.content.interactive_data.data.dynamic.data.pages.type` (string, required): Value: `select`
            - `data.content.interactive_data.data.dynamic.data.pages.multiple_selection` (boolean)
            - `data.content.interactive_data.data.dynamic.data.pages.items` (array of object, required)
            - `data.content.interactive_data.data.dynamic.data.pages.items.identifier` (string, required)
            - `data.content.interactive_data.data.dynamic.data.pages.items.title` (string, required)
            - `data.content.interactive_data.data.dynamic.data.pages.items.value` (string, required)
            - `data.content.interactive_data.data.dynamic.data.pages.items.image_identifier` (string)
            - `data.content.interactive_data.data.dynamic.data.pages.items.next_page_identifier` (string)
          - Variant `picker`
            - `data.content.interactive_data.data.dynamic.data.pages.type` (string, required): Value: `picker`
            - `data.content.interactive_data.data.dynamic.data.pages.picker_title` (string): Text beside the picker field. Omit to center the field without a label.
            - `data.content.interactive_data.data.dynamic.data.pages.selected_item_index` (integer): Zero-based index into `items`. Defaults to `0`. Must be less than the number of items; otherwise sending returns `422` `AMBFormPagesInvalid`.
            - `data.content.interactive_data.data.dynamic.data.pages.items` (array of object, required)
            - `data.content.interactive_data.data.dynamic.data.pages.items.identifier` (string, required)
            - `data.content.interactive_data.data.dynamic.data.pages.items.title` (string, required)
            - `data.content.interactive_data.data.dynamic.data.pages.items.value` (string, required)
          - Variant `date_picker`
            - `data.content.interactive_data.data.dynamic.data.pages.type` (string, required): Value: `date_picker`
            - `data.content.interactive_data.data.dynamic.data.pages.hint_text` (string)
            - `data.content.interactive_data.data.dynamic.data.pages.options` (object): Apple defaults to UTC when interpreting these dates.
            - `data.content.interactive_data.data.dynamic.data.pages.options.date_format` (string): Format used to read the date values in these options. Defaults to `MM/dd/yyyy`.
            - `data.content.interactive_data.data.dynamic.data.pages.options.start_date` (string): Date initially shown by the picker, written in `date_format`. Defaults to the current date.
            - `data.content.interactive_data.data.dynamic.data.pages.options.maximum_date` (string): Latest date the picker shows, written in `date_format`. Defaults to the current date.
            - `data.content.interactive_data.data.dynamic.data.pages.options.minimum_date` (string): Earliest date the picker shows, written in `date_format`.
            - `data.content.interactive_data.data.dynamic.data.pages.options.label_text` (string): Label beside the date field. Defaults to `Date`.
          - Variant `input`
            - `data.content.interactive_data.data.dynamic.data.pages.type` (string, required): Value: `input`
            - `data.content.interactive_data.data.dynamic.data.pages.hint_text` (string)
            - `data.content.interactive_data.data.dynamic.data.pages.options` (object)
            - `data.content.interactive_data.data.dynamic.data.pages.options.regex` (string): Pattern Apple uses to validate the input. Use JSON string escaping for backslashes.
            - `data.content.interactive_data.data.dynamic.data.pages.options.placeholder` (string): Shown when the field is empty. Defaults to `Required` when `required` is true, otherwise `Optional`.
            - `data.content.interactive_data.data.dynamic.data.pages.options.required` (boolean): Disables the next-page button until the customer enters a value.
            - `data.content.interactive_data.data.dynamic.data.pages.options.input_type` (string)

              Defaults to `singleline`.

              Possible values: `singleline`, `multiline`
            - `data.content.interactive_data.data.dynamic.data.pages.options.label_text` (string): Label for `singleline` input only. Omit for no label.
            - `data.content.interactive_data.data.dynamic.data.pages.options.prefix_text` (string): Text beside `singleline` input only, such as a currency symbol. Omit for no prefix.
            - `data.content.interactive_data.data.dynamic.data.pages.options.maximum_character_count` (integer): Defaults to 30 for `singleline` input and 300 for `multiline` input.
            - `data.content.interactive_data.data.dynamic.data.pages.options.keyboard_type` (string)

              Keyboard to display. Defaults to `default`.

              Possible values (may grow over time): `default`, `asciiCapable`, `numbersAndPunctuation`, `URL`, `numberPad`, `phonePad`, `namePhonePad`, `emailAddress`, `decimalPad`, `webSearch`
            - `data.content.interactive_data.data.dynamic.data.pages.options.text_content_type` (string)

              Content hint used for autofill.

              Possible values (may grow over time): `name`, `namePrefix`, `givenName`, `middleName`, `familyName`, `nameSuffix`, `nickname`, `jobTitle`, `organizationName`, `location`, `fullStreetAddress`, `streetAddressLine1`, `streetAddressLine2`, `addressCity`, `addressState`, `addressCityAndState`, `sublocality`, `countryName`, `postalCode`, `telephoneNumber`, `emailAddress`, `URL`, `creditCardNumber`, `username`, `password`, `newPassword`, `oneTimeCode`
      - Variant `authenticate`
        - `data.content.interactive_data.data.authenticate` (object, required): Authentication attempt created through the conversation authentication endpoint. Contains no authorization parameters or credentials.
        - `data.content.interactive_data.data.authenticate.authentication_id` (string, required)
      - Variant `payment`
        - `data.content.interactive_data.data.payment` (object, required): Apple Pay request created through the conversation payment endpoint. Contains no payment token or provider credentials.
        - `data.content.interactive_data.data.payment.payment_id` (string, required)
  - Variant `app_id + app_name + bid + url + app_icon_source_url + use_live_layout + received_message + reply_message`
    - `data.content.interactive_data.app_id` (string, required): App Store identifier of the iMessage app.
    - `data.content.interactive_data.app_name` (string, required): Name of the iMessage app.
    - `data.content.interactive_data.bid` (string, required): Identifier of the iMessage extension, in Apple's `com.apple.messages.MSMessageExtensionBalloonPlugin:team-id:extension-id` format.
    - `data.content.interactive_data.url` (string, required): Opaque URL string that Messages passes to the iMessage app.
    - `data.content.interactive_data.use_live_layout` (boolean, required): Whether Messages renders the received and reply bubbles using Live Layout.
    - `data.content.interactive_data.received_message` (object, required): Content Messages shows in the received message bubble.
    - `data.content.interactive_data.received_message.title` (string, required): Text shown on the message bubble.
    - `data.content.interactive_data.received_message.subtitle` (string): Secondary text shown below the title.
    - `data.content.interactive_data.received_message.style` (string)

      Bubble layout. Apple defaults to `icon` when omitted and ignores it for custom iMessage apps.

      Possible values: `icon`, `small`, `large`
    - `data.content.interactive_data.received_message.image_identifier` (string): Identifier of an image in interactive_data.data.images. Apple ignores it for custom iMessage apps.
    - `data.content.interactive_data.received_message.image_title` (string): Title shown over an attached image in a custom iMessage app bubble.
    - `data.content.interactive_data.received_message.image_subtitle` (string): Subtitle shown over an attached image in a custom iMessage app bubble.
    - `data.content.interactive_data.received_message.secondary_subtitle` (string): Right-aligned title in a custom iMessage app bubble.
    - `data.content.interactive_data.received_message.tertiary_subtitle` (string): Right-aligned subtitle in a custom iMessage app bubble.
    - `data.content.interactive_data.reply_message` (object, required): Content Messages shows in the reply message bubble.
    - `data.content.interactive_data.reply_message.title` (string, required): Text shown on the message bubble.
    - `data.content.interactive_data.reply_message.subtitle` (string): Secondary text shown below the title.
    - `data.content.interactive_data.reply_message.style` (string)

      Bubble layout. Apple defaults to `icon` when omitted and ignores it for custom iMessage apps.

      Possible values: `icon`, `small`, `large`
    - `data.content.interactive_data.reply_message.image_identifier` (string): Identifier of an image in interactive_data.data.images. Apple ignores it for custom iMessage apps.
    - `data.content.interactive_data.reply_message.image_title` (string): Title shown over an attached image in a custom iMessage app bubble.
    - `data.content.interactive_data.reply_message.image_subtitle` (string): Subtitle shown over an attached image in a custom iMessage app bubble.
    - `data.content.interactive_data.reply_message.secondary_subtitle` (string): Right-aligned title in a custom iMessage app bubble.
    - `data.content.interactive_data.reply_message.tertiary_subtitle` (string): Right-aligned subtitle in a custom iMessage app bubble.
    - `data.content.interactive_data.app_icon_source_url` (string, required): Publicly accessible HTTPS URL of the app's PNG icon. The icon must be smaller than 15 kB. We fetch and include it in the request to Apple.
- `data.content.interactive_data_ref`: Reusable Apple content reference. Supply the decryption key, or the signed bid and data_ref_sig returned by Apple.
- `data.content.interactive_data_ref.title` (string): Title supplied by Apple for the preview.
- `data.content.interactive_data_ref.url` (string, required): Location of the encrypted preview.
- `data.content.interactive_data_ref.owner` (string, required): Owner identifier supplied by Apple.
- `data.content.interactive_data_ref.signature_base64` (string, required): Signature supplied by Apple.
- `data.content.interactive_data_ref.size` (integer, required): Size of the encrypted preview in bytes.
  - Variant `key`
    - `data.content.interactive_data_ref.key` (string, required): Decryption key supplied by Apple.
  - Variant `bid + data_ref_sig`
    - `data.content.interactive_data_ref.bid` (string, required): Messages extension identifier supplied by Apple, when present.
    - `data.content.interactive_data_ref.data_ref_sig` (string, required): Signature binding the reference to the business, when supplied by Apple.
- `data.in_reply_to_message_id` (string): Original message matched through Apple’s request identifier within the same workspace, business, and conversation. Omitted when no verified match exists.
- `data.locale` (nullable string): Locale for this message, preserved in Apple’s format, for example en_US. Outbound messages use the request override, then the conversation locale, then the business default. Inbound messages preserve the locale in Apple’s callback. Null when unknown.
- `data.category` (string): The category this message was sent with, for reporting only. It does not affect sending or suppression policy, or select an Apple department or purpose. Defaults to an empty string when a send names no category. Absent on an inbound message, which has no category to report.
- `data.metadata` (object): Arbitrary JSON object for per-message context. Maximum 2 KB serialized. Top-level keys beginning with `__bird` are reserved. Returned in the send response, message reads and customer message webhooks.
- `data.tags` (array of object): Structured `{name, value}` filter labels applied to this message. Absent on an inbound message.
- `data.tags.name` (string, required): Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
- `data.tags.value` (string, required): Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
- `data.cost` (nullable object, required): Recorded message charge. Null in the initial send response and while unpriced. The AMB charge is the transaction amount; no passthrough component is priced.
- `data.cost.amount` (string, required): Total charged, as a decimal string: the sum of the components below. Net of tax, which applies to your wallet balance rather than to an individual charge.
- `data.cost.currency_code` (string, required): ISO 4217 currency code. Every component is denominated in this currency.
- `data.cost.transaction_amount` (nullable string, required): What we charged to carry the message, as a decimal string. `null` when this component was not priced; `"0.00000"` when it priced at zero.
- `data.cost.passthrough_amount` (nullable string, required): Third-party fees we pass on, as a decimal string, such as US 10DLC carrier surcharges. `null` when this component was not priced; `"0.00000"` when it priced at zero.
- `data.last_error` (nullable object): Failure detail on a message whose send failed or that Bird rejected before any send attempt. Omitted when there is no failure detail.
- `data.last_error.code` (string, required): Machine-readable reason a send failed, in one of two namespaces: `bird:` for a reason Bird's own pipeline assigned (for example `bird:business_not_registered`), or `apple:` followed by the HTTP status Apple's API returned for the send attempt (for example `apple:404`). This is an open, growing set in both namespaces; accept unrecognized values.
- `data.last_error.description` (string, required): The failure in words. Free-form, so branch on `code` and show this to a human.
- `data.last_error.occurred_at` (string, required): When the failure occurred.
- `data.created_at` (string, required): The moment this message was accepted (outbound) or received (inbound). This is the timestamp the outbound statistics families bucket and attribute on; there is no separate `accepted_at` field.
- `data.sent_at` (nullable string): When the selected sending outcome occurred. Null unless the current status is `sent` and the message is outbound. For older messages without a retained sending event, the stored record time is used.
- `data.data_ref`: Reusable encrypted content reference returned by Apple after a successful send. Absent until Apple returns one.
- `data.data_ref.title` (string): Title supplied by Apple for the preview.
- `data.data_ref.url` (string, required): Location of the encrypted preview.
- `data.data_ref.owner` (string, required): Owner identifier supplied by Apple.
- `data.data_ref.signature_base64` (string, required): Signature supplied by Apple.
- `data.data_ref.size` (integer, required): Size of the encrypted preview in bytes.
  - Variant `key`
    - `data.data_ref.key` (string, required): Decryption key supplied by Apple.
  - Variant `bid + data_ref_sig`
    - `data.data_ref.bid` (string, required): Messages extension identifier supplied by Apple, when present.
    - `data.data_ref.data_ref_sig` (string, required): Signature binding the reference to the business, when supplied by Apple.
- `data.group` (string): Apple department identifier carried by this message. Omitted when absent from the message or unavailable on a historical record.
- `data.intent` (string): Apple purpose identifier carried by this message. Omitted when absent from the message or unavailable on a historical record.
- `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

- [Should I use a Bird SDK or call the API directly?](/explained/platform/should-i-use-an-sdk-or-call-the-api-directly) (answer)
- [Build your first integration](/learn/paths/integration) (course)
- [Send your first email](/docs/get-started/send-your-first-email) (docs)

[Get an implementation brief](/learn/workspace?topic=api-basics)
