---
title: "Test a webhook with a sample event"
method: POST
path: "/v1/webhooks/{webhook_id}/test"
tags: ["webhooks"]
---

# Test a webhook with a sample event

`POST /v1/webhooks/{webhook_id}/test`

## Request

- Base URL: `https://us1.platform.bird.com`
- URL: `https://us1.platform.bird.com/v1/webhooks/{webhook_id}/test`
- Auth: one of:
  - HTTP bearer
  - API key in cookie `bird_session`

Sends a signed synthetic event and returns whether your endpoint accepted it, its HTTP status, and the round-trip latency. An unreachable endpoint returns `status: failed` in the response body. The endpoint has 10 seconds to respond.

The body is a minimal JSON object with the event `type`, signed like a real delivery. It does not mirror that event's payload. Tests work on paused endpoints and do not appear in [List delivery attempts](/docs/api/reference/list-webhook-attempts).

The operation returns `412` if the endpoint lacks a valid signing secret or, when `event_type` is omitted, has no subscribed event type to use.

## Headers

- `Idempotency-Key` string
- `X-Workspace-Id` string
- `X-Organization-Id` string

## Request body

- WebhookTestRequest
  - `event_type` string: Event type to simulate. Any type from the event catalog is accepted, whether or not the endpoint subscribes to it; an unknown type returns a `422`. When omitted, the endpoint's first subscribed event type is used.

## Response `200`

The test result, including whether your endpoint accepted the event.

- WebhookTestResponse
  - `status` 'delivered' | 'failed', required: Whether your endpoint accepted the test event. `delivered` means it returned a `2xx` status; `failed` means it returned a non-`2xx` status or could not be reached (see `error` for the latter).
  - `response_status_code` integer, nullable, required: HTTP status returned by your endpoint. Null when no response was received (timeout, connection error, DNS failure).
  - `response_body` string: Response body returned by your endpoint, truncated to the first 1024 bytes. Omitted when your endpoint returned no body or could not be reached.
  - `response_duration_ms` integer, required: Round-trip delivery latency in milliseconds.
  - `event_payload` union: Webhook delivery body. `type` identifies the event variant, `timestamp` is when the event occurred, and `data` contains the event-specific payload. See the [webhooks guide](/docs/guides/webhooks) for signature verification.
    - EventAMBAccepted: An outbound message was accepted for processing after confirming billing coverage. This does not confirm receipt by Apple.
      - `type` 'amb.accepted', required: Always `amb.accepted` for this event.
      - `timestamp` string, date-time, required: When this lifecycle event occurred, independent of webhook delivery time.
      - `data` EventAMBMessageData, required (unresolved $ref)
    - EventAMBConversationClosed: A customer conversation closed. Closing a conversation is not a message.
      - `type` 'amb.conversation_closed', required: Always `amb.conversation_closed` for this event.
      - `timestamp` string, date-time, required: When this lifecycle event occurred, independent of webhook delivery time.
      - `data` EventAMBConversationData, required: Conversation identity and routing context when a lifecycle event occurred.
        - `workspace_id` string, required
        - `business_account_id` string, required
        - `conversation_id` string, required
        - `open_count` integer, required: Number of times the conversation has opened, starting at 1 and increasing on each reopen. Together with the conversation ID and event type, this identifies the lifecycle occurrence across retries.
        - `origin` string: Source of the lifecycle change, when recorded.
        - `group_id` string: Apple entry-point group recorded for this occurrence, when present.
        - `intent_id` string: Apple entry-point intent recorded for this occurrence, when present.
        - `queue` string: Routing queue recorded for this occurrence, when present.
    - EventAMBConversationReopened: An existing customer conversation reopened after it had closed.
      - `type` 'amb.conversation_reopened', required: Always `amb.conversation_reopened` for this event.
      - `timestamp` string, date-time, required: When this lifecycle event occurred, independent of webhook delivery time.
      - `data` EventAMBConversationData, required: Conversation identity and routing context when a lifecycle event occurred.
        - `workspace_id` string, required
        - `business_account_id` string, required
        - `conversation_id` string, required
        - `open_count` integer, required: Number of times the conversation has opened, starting at 1 and increasing on each reopen. Together with the conversation ID and event type, this identifies the lifecycle occurrence across retries.
        - `origin` string: Source of the lifecycle change, when recorded.
        - `group_id` string: Apple entry-point group recorded for this occurrence, when present.
        - `intent_id` string: Apple entry-point intent recorded for this occurrence, when present.
        - `queue` string: Routing queue recorded for this occurrence, when present.
    - EventAMBConversationStarted: A customer conversation opened for the first time.
      - `type` 'amb.conversation_started', required: Always `amb.conversation_started` for this event.
      - `timestamp` string, date-time, required: When this lifecycle event occurred, independent of webhook delivery time.
      - `data` EventAMBConversationData, required: Conversation identity and routing context when a lifecycle event occurred.
        - `workspace_id` string, required
        - `business_account_id` string, required
        - `conversation_id` string, required
        - `open_count` integer, required: Number of times the conversation has opened, starting at 1 and increasing on each reopen. Together with the conversation ID and event type, this identifies the lifecycle occurrence across retries.
        - `origin` string: Source of the lifecycle change, when recorded.
        - `group_id` string: Apple entry-point group recorded for this occurrence, when present.
        - `intent_id` string: Apple entry-point intent recorded for this occurrence, when present.
        - `queue` string: Routing queue recorded for this occurrence, when present.
    - EventAMBReceived: Bird received an ordinary customer message from Apple. Invitation responses are excluded.
      - `type` 'amb.received', required: Always `amb.received` for this event.
      - `timestamp` string, date-time, required: When this lifecycle event occurred, independent of webhook delivery time.
      - `data` EventAMBMessageData, required (unresolved $ref)
    - EventAMBRejected: Bird refused an outbound message before acceptance. This message has no accepted event.
      - `type` 'amb.rejected', required: Always `amb.rejected` for this event.
      - `timestamp` string, date-time, required: When this lifecycle event occurred, independent of webhook delivery time.
      - `data` EventAMBMessageData, required (unresolved $ref)
    - EventAMBSendFailed: An accepted outbound message could not be handed to Apple. The message snapshot carries the failure detail.
      - `type` 'amb.send_failed', required: Always `amb.send_failed` for this event.
      - `timestamp` string, date-time, required: When this lifecycle event occurred, independent of webhook delivery time.
      - `data` EventAMBMessageData, required (unresolved $ref)
    - EventAMBSent: Apple accepted an outbound message from Bird. This does not establish delivery to the customer or a read receipt.
      - `type` 'amb.sent', required: Always `amb.sent` for this event.
      - `timestamp` string, date-time, required: When this lifecycle event occurred, independent of webhook delivery time.
      - `data` EventAMBMessageData, required (unresolved $ref)
    - EventAMBSuppressionCreated: An address was added to the workspace's Apple Messages for Business suppression ledger.
      - `type` 'amb_suppression.created', required: Always `amb_suppression.created` for this event.
      - `timestamp` string, date-time, required: When the suppression episode took effect.
      - `data` EventAMBSuppressionCreatedData, required: Payload of the amb_suppression.created event.
        - `suppression_id` string, required
        - `business_account_id` string, required
        - `address` string, required: The canonical phone number or exact opaque Apple identifier that was suppressed.
        - `address_type` 'phone_number' | 'opaque_user_id', required: What kind of value `address` holds. - `phone_number` means `address` is the customer's phone number. Apple's CloseSession event carries a phone number rather than an opaque identifier, so a suppression opened by a close on a conversation identified by phone number takes this kind. - `opaque_user_id` means `address` is the opaque identifier Apple assigns to the customer's conversation with the business, stable across a close and a later re-initiation.
        - `reason` string, required: Why the handle is suppressed. `manual` means it was added directly through this API or the dashboard. `opted_out` covers every case where Apple or the customer signaled they should not be contacted: a close, a permanent delivery failure, a declined invitation, or a stop keyword. This list grows over time, so treat an unknown value as informational rather than rejecting the record.
        - `origin` string, required: Who created the episode. user and api_key identify manual blocks. close_session and gone are protected automatic conversation facts. Phone invitation opt-outs are recorded as preferences.
        - `workspace_id` string, required
    - EventDomainFailed: A sending domain failed DNS verification.
      - `type` 'domain.failed', required: Event type.
      - `timestamp` string, date-time, required: When the event occurred.
      - `data` EventDomainFailedData, required: Payload of the domain.failed event.
        - `domain_id` string, required
        - `domain` string, required: The sending domain hostname.
        - `workspace_id` string, required
        - `failure_reason` string, nullable: Why verification failed, when a specific reason is available (for example, the DKIM record was not found at the expected selector).
    - EventDomainVerified: A sending domain completed DNS verification successfully.
      - `type` 'domain.verified', required: Event type.
      - `timestamp` string, date-time, required: When the event occurred.
      - `data` EventDomainVerifiedData, required: Payload of the domain.verified event.
        - `domain_id` string, required
        - `domain` string, required: The sending domain hostname.
        - `workspace_id` string, required
    - EventEmailAccepted: The API accepted the email send and is preparing it for delivery. Fires once per requested recipient.
      - `type` 'email.accepted', required: Event type.
      - `timestamp` string, date-time, required: Time the API accepted the send.
      - `data` EventEmailAcceptedData, required: Identity fields shared by every email lifecycle event payload.
        - `email_id` string, required
        - `recipient_id` string, required
        - `workspace_id` string, required
        - `recipient` string, email, required: Recipient address as it appeared on the envelope.
        - `recipient_role` 'to' | 'cc' | 'bcc', required: Envelope position of a recipient on an outbound email event.
        - `tags` Tag[], nullable, required: Tags provided on the send request, echoed on every event for the send so you can route and correlate without an extra lookup. Null when the send carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object provided on the send request, echoed on every event for the send so you can correlate events with your own records. Null when the send carried no metadata.
        - `broadcast_id` string, required
    - EventEmailBounced: An outbound email permanently failed at the recipient's mail server. Fires once per recipient.
      - `type` 'email.bounced', required: Event type.
      - `timestamp` string, date-time, required: Time the bounce was recorded.
      - `data` EventEmailBouncedData, required: Identity fields shared by every email lifecycle event payload.
        - `email_id` string, required
        - `recipient_id` string, required
        - `workspace_id` string, required
        - `recipient` string, email, required: Recipient address as it appeared on the envelope.
        - `recipient_role` 'to' | 'cc' | 'bcc', required: Envelope position of a recipient on an outbound email event.
        - `tags` Tag[], nullable, required: Tags provided on the send request, echoed on every event for the send so you can route and correlate without an extra lookup. Null when the send carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object provided on the send request, echoed on every event for the send so you can correlate events with your own records. Null when the send carried no metadata.
        - `broadcast_id` string, required
        - `bounce_type` 'hard' | 'soft' | 'undetermined' | 'admin' | 'block', required: Bounce classification. - `hard`: A permanent failure, such as an invalid address or a domain that does not exist. - `soft`: A transient failure, such as a full mailbox or a server that is temporarily unavailable. - `block`: The receiving mail server refused the sending IP on reputation grounds. - `admin`: An administrative refusal, such as relaying denied or a blocklisted domain. - `undetermined`: The receiving server's response was ambiguous.
        - `bounce_class` integer, nullable, required: Numeric bounce classification for fine-grained deliverability triage, or null when the receiving server's response could not be classified. Lets you distinguish, for example, a DNS failure from a spam block when both would be `bounce_type: soft` or `bounce_type: block`.
        - `bounce_code` string, nullable, required: SMTP reply code returned by the receiving mail server, or null when none was provided.
        - `bounce_description` string, nullable, required: Human-readable reason the receiving mail server gave for the bounce, or null when none was provided.
        - `sending_ip` string, nullable, required: The IP address used to send this message, or null when it is not known.
    - EventEmailCanceled: A scheduled send was canceled before it fired. Fires once for each message regardless of its recipient count.
      - `type` 'email.canceled', required: Event type.
      - `timestamp` string, date-time, required: Time the scheduled send was canceled.
      - `data` EventEmailCanceledData, required: Identity fields shared by the message-level email lifecycle events (scheduled, canceled), which are not tied to a single recipient.
        - `email_id` string, required
        - `workspace_id` string, required
        - `tags` Tag[], nullable, required: Tags provided on the send request, echoed on the event so you can route and correlate without an extra lookup. Null when the send carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object provided on the send request, echoed on the event so you can correlate events with your own records. Null when the send carried no metadata.
    - EventEmailClicked: The recipient clicked a tracked link in the email. May fire more than once per recipient.
      - `type` 'email.clicked', required: Event type.
      - `timestamp` string, date-time, required: Time the click was recorded.
      - `data` EventEmailClickedData, required: Identity fields shared by every email lifecycle event payload.
        - `email_id` string, required
        - `recipient_id` string, required
        - `workspace_id` string, required
        - `recipient` string, email, required: Recipient address as it appeared on the envelope.
        - `recipient_role` 'to' | 'cc' | 'bcc', required: Envelope position of a recipient on an outbound email event.
        - `tags` Tag[], nullable, required: Tags provided on the send request, echoed on every event for the send so you can route and correlate without an extra lookup. Null when the send carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object provided on the send request, echoed on every event for the send so you can correlate events with your own records. Null when the send carried no metadata.
        - `broadcast_id` string, required
        - `url` string, required: The URL the recipient clicked.
        - `ip_address` string, nullable, required: IP address of the client that clicked the link, or null when it is not known.
        - `user_agent` string, nullable, required: User-agent string of the client that clicked the link, or null when it is not known.
    - EventEmailComplained: The recipient marked the email as spam through their mailbox provider's feedback loop. Fires once per recipient.
      - `type` 'email.complained', required: Event type.
      - `timestamp` string, date-time, required: Time the complaint was recorded.
      - `data` EventEmailComplainedData, required: Identity fields shared by every email lifecycle event payload.
        - `email_id` string, required
        - `recipient_id` string, required
        - `workspace_id` string, required
        - `recipient` string, email, required: Recipient address as it appeared on the envelope.
        - `recipient_role` 'to' | 'cc' | 'bcc', required: Envelope position of a recipient on an outbound email event.
        - `tags` Tag[], nullable, required: Tags provided on the send request, echoed on every event for the send so you can route and correlate without an extra lookup. Null when the send carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object provided on the send request, echoed on every event for the send so you can correlate events with your own records. Null when the send carried no metadata.
        - `broadcast_id` string, required
        - `feedback_type` string, nullable, required: The kind of feedback the mailbox provider reported (such as `abuse` or `fraud`), or null when the provider did not specify one.
    - EventEmailDeferred: The recipient's mail server temporarily refused the email. Delivery remains pending and is retried. May fire more than once per recipient.
      - `type` 'email.deferred', required: Event type.
      - `timestamp` string, date-time, required: Time the deferral was recorded.
      - `data` EventEmailDeferredData, required: Identity fields shared by every email lifecycle event payload.
        - `email_id` string, required
        - `recipient_id` string, required
        - `workspace_id` string, required
        - `recipient` string, email, required: Recipient address as it appeared on the envelope.
        - `recipient_role` 'to' | 'cc' | 'bcc', required: Envelope position of a recipient on an outbound email event.
        - `tags` Tag[], nullable, required: Tags provided on the send request, echoed on every event for the send so you can route and correlate without an extra lookup. Null when the send carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object provided on the send request, echoed on every event for the send so you can correlate events with your own records. Null when the send carried no metadata.
        - `broadcast_id` string, required
        - `bounce_type` 'hard' | 'soft' | 'undetermined' | 'admin' | 'block', required: Bounce classification. - `hard`: A permanent failure, such as an invalid address or a domain that does not exist. - `soft`: A transient failure, such as a full mailbox or a server that is temporarily unavailable. - `block`: The receiving mail server refused the sending IP on reputation grounds. - `admin`: An administrative refusal, such as relaying denied or a blocklisted domain. - `undetermined`: The receiving server's response was ambiguous.
        - `bounce_class` integer, nullable, required: Numeric bounce classification for fine-grained deliverability triage, or null when the receiving server's response could not be classified. Distinguishes, for example, a greylisting deferral from a full mailbox.
        - `defer_reason` string, nullable, required: Human-readable reason the receiving mail server gave for the deferral, or null when none was provided.
        - `sending_ip` string, nullable, required: The IP address used to send this message, or null when it is not known.
    - EventEmailDelivered: An outbound email reached the recipient's mail server and was accepted.
      - `type` 'email.delivered', required: Event type.
      - `timestamp` string, date-time, required: Time the recipient's mail server accepted the message.
      - `data` EventEmailDeliveredData, required: Identity fields shared by every email lifecycle event payload.
        - `email_id` string, required
        - `recipient_id` string, required
        - `workspace_id` string, required
        - `recipient` string, email, required: Recipient address as it appeared on the envelope.
        - `recipient_role` 'to' | 'cc' | 'bcc', required: Envelope position of a recipient on an outbound email event.
        - `tags` Tag[], nullable, required: Tags provided on the send request, echoed on every event for the send so you can route and correlate without an extra lookup. Null when the send carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object provided on the send request, echoed on every event for the send so you can correlate events with your own records. Null when the send carried no metadata.
        - `broadcast_id` string, required
    - EventEmailListUnsubscribed: Recipient unsubscribed via the RFC 8058 one-click List-Unsubscribe mechanism. Fires once per recipient.
      - `type` 'email.list_unsubscribed', required: Event type.
      - `timestamp` string, date-time, required: Time the unsubscribe was recorded.
      - `data` EventEmailListUnsubscribedData, required: Identity fields shared by every email lifecycle event payload.
        - `email_id` string, required
        - `recipient_id` string, required
        - `workspace_id` string, required
        - `recipient` string, email, required: Recipient address as it appeared on the envelope.
        - `recipient_role` 'to' | 'cc' | 'bcc', required: Envelope position of a recipient on an outbound email event.
        - `tags` Tag[], nullable, required: Tags provided on the send request, echoed on every event for the send so you can route and correlate without an extra lookup. Null when the send carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object provided on the send request, echoed on every event for the send so you can correlate events with your own records. Null when the send carried no metadata.
        - `broadcast_id` string, required
    - EventEmailOpened: The recipient opened the email (the tracking pixel was loaded). May fire more than once per recipient.
      - `type` 'email.opened', required: Event type.
      - `timestamp` string, date-time, required: Time the open was recorded.
      - `data` EventEmailOpenedData, required: Identity fields shared by every email lifecycle event payload.
        - `email_id` string, required
        - `recipient_id` string, required
        - `workspace_id` string, required
        - `recipient` string, email, required: Recipient address as it appeared on the envelope.
        - `recipient_role` 'to' | 'cc' | 'bcc', required: Envelope position of a recipient on an outbound email event.
        - `tags` Tag[], nullable, required: Tags provided on the send request, echoed on every event for the send so you can route and correlate without an extra lookup. Null when the send carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object provided on the send request, echoed on every event for the send so you can correlate events with your own records. Null when the send carried no metadata.
        - `broadcast_id` string, required
        - `ip_address` string, nullable, required: IP address of the client that opened the email, or null when it is not known.
        - `user_agent` string, nullable, required: User-agent string of the client that opened the email, or null when it is not known.
    - EventEmailOutOfBandBounce: A bounce notification arrived after the message had already been accepted for delivery. Fires once per recipient.
      - `type` 'email.out_of_band_bounce', required: Event type.
      - `timestamp` string, date-time, required: Time the bounce notification was recorded.
      - `data` EventEmailOutOfBandBounceData, required: Identity fields shared by every email lifecycle event payload.
        - `email_id` string, required
        - `recipient_id` string, required
        - `workspace_id` string, required
        - `recipient` string, email, required: Recipient address as it appeared on the envelope.
        - `recipient_role` 'to' | 'cc' | 'bcc', required: Envelope position of a recipient on an outbound email event.
        - `tags` Tag[], nullable, required: Tags provided on the send request, echoed on every event for the send so you can route and correlate without an extra lookup. Null when the send carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object provided on the send request, echoed on every event for the send so you can correlate events with your own records. Null when the send carried no metadata.
        - `broadcast_id` string, required
        - `bounce_type` 'hard' | 'soft' | 'undetermined' | 'admin' | 'block', required: Bounce classification. - `hard`: A permanent failure, such as an invalid address or a domain that does not exist. - `soft`: A transient failure, such as a full mailbox or a server that is temporarily unavailable. - `block`: The receiving mail server refused the sending IP on reputation grounds. - `admin`: An administrative refusal, such as relaying denied or a blocklisted domain. - `undetermined`: The receiving server's response was ambiguous.
        - `bounce_class` integer, nullable, required: Numeric bounce classification for fine-grained deliverability triage, or null when the receiving server's response could not be classified.
        - `bounce_code` string, nullable, required: SMTP reply code returned by the receiving mail server, or null when none was provided.
        - `bounce_description` string, nullable, required: Human-readable reason the receiving mail server gave for the bounce, or null when none was provided.
        - `sending_ip` string, nullable, required: The IP address used to send this message, or null when it is not known.
    - EventEmailProcessed: The API prepared the message for delivery to the recipient's mail server. Fires once per recipient.
      - `type` 'email.processed', required: Event type.
      - `timestamp` string, date-time, required: Time the message was prepared for delivery.
      - `data` EventEmailProcessedData, required: Identity fields shared by every email lifecycle event payload.
        - `email_id` string, required
        - `recipient_id` string, required
        - `workspace_id` string, required
        - `recipient` string, email, required: Recipient address as it appeared on the envelope.
        - `recipient_role` 'to' | 'cc' | 'bcc', required: Envelope position of a recipient on an outbound email event.
        - `tags` Tag[], nullable, required: Tags provided on the send request, echoed on every event for the send so you can route and correlate without an extra lookup. Null when the send carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object provided on the send request, echoed on every event for the send so you can correlate events with your own records. Null when the send carried no metadata.
        - `broadcast_id` string, required
    - EventEmailReceived: The API received and parsed an inbound email. The payload carries the message's identifiers, sender and recipients, subject, threading reference, and authentication results, which is enough to route and triage without a fetch. Fetch content separately. Get the parsed body with `GET /v1/email/inbound-messages/{id}/body`. Get the original MIME with `GET /v1/email/inbound-messages/{id}/raw`. Get attachment bytes with `GET /v1/email/inbound-messages/{id}/attachments/{attachment_id}`.
      - `type` 'email.received', required: Event type.
      - `timestamp` string, date-time, required: When the API received the message.
      - `data` EventEmailReceivedData, required: Payload of the email.received event.
        - `inbound_message_id` string, required
        - `workspace_id` string, required
        - `message_id` string, nullable, required: RFC 5322 Message-ID header from the sender, or null when the sender did not include one.
        - `from` string, email, required: Address from the message's From header, with the relay's parsed sender and then the SMTP envelope sender as fallbacks when that header cannot be read. This field alone does not authenticate the sender.
        - `to` string[], required: Parsed recipient addresses from the message headers, not the envelope recipient used to route this delivery.
        - `subject` string, nullable, required: Subject line as received, or null when the message had no subject.
        - `in_reply_to` string, nullable: `In-Reply-To` header containing the `Message-ID` this message replies to, or null when it is not a reply.
        - `authentication` 'pass' | 'fail' | 'unknown' | 'null', nullable: 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`.
        - `spf_pass` boolean, nullable: 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`.
        - `dkim_pass` boolean, nullable: 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`.
        - `dmarc_pass` boolean, nullable: 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`.
        - `spam_score` number, nullable: Content spam score when available. The receiving provider currently supplies no score, so this is `null`.
    - EventEmailRejected: The API rejected the email before delivery because of suppression, transmission failure, content, or policy. Fires once per recipient.
      - `type` 'email.rejected', required: Event type.
      - `timestamp` string, date-time, required: Time the rejection was recorded.
      - `data` EventEmailRejectedData, required: Identity fields shared by every email lifecycle event payload.
        - `email_id` string, required
        - `recipient_id` string, required
        - `workspace_id` string, required
        - `recipient` string, email, required: Recipient address as it appeared on the envelope.
        - `recipient_role` 'to' | 'cc' | 'bcc', required: Envelope position of a recipient on an outbound email event.
        - `tags` Tag[], nullable, required: Tags provided on the send request, echoed on every event for the send so you can route and correlate without an extra lookup. Null when the send carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object provided on the send request, echoed on every event for the send so you can correlate events with your own records. Null when the send carried no metadata.
        - `broadcast_id` string, required
        - `rejection_reason` 'recipient_suppressed' | 'transmission_failed' | 'generation_failure' | 'policy_rejection' | 'domain_unverified' | 'quota_exceeded' | 'recipient_not_allowed', required: Why an email was rejected before delivery. - `recipient_suppressed`: The recipient is on the workspace suppression list, so delivery was never attempted. - `transmission_failed`: The message could not be transmitted for delivery. - `generation_failure`: The message could not be built for delivery (template or content issue). - `policy_rejection`: The message was refused by sending policy. - `domain_unverified`: The sending domain was not verified. - `quota_exceeded`: The organization's send quota was reached. - `recipient_not_allowed`: A recipient was not permitted for this send (for shared onboarding-domain sends, recipients must be verified workspace members).
    - EventEmailScheduled: The API accepted an email scheduled for a future time. Fires once per message when the schedule is created.
      - `type` 'email.scheduled', required: Event type.
      - `timestamp` string, date-time, required: Time the send was scheduled.
      - `data` EventEmailScheduledData, required: Identity fields shared by the message-level email lifecycle events (scheduled, canceled), which are not tied to a single recipient.
        - `email_id` string, required
        - `workspace_id` string, required
        - `tags` Tag[], nullable, required: Tags provided on the send request, echoed on the event so you can route and correlate without an extra lookup. Null when the send carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object provided on the send request, echoed on the event so you can correlate events with your own records. Null when the send carried no metadata.
        - `scheduled_at` string, date-time, required: When the message is scheduled to send.
    - EventEmailUnsubscribed: Recipient unsubscribed by clicking a tracked unsubscribe link in the email. Fires once per recipient.
      - `type` 'email.unsubscribed', required: Event type.
      - `timestamp` string, date-time, required: Time the unsubscribe was recorded.
      - `data` EventEmailUnsubscribedData, required: Identity fields shared by every email lifecycle event payload.
        - `email_id` string, required
        - `recipient_id` string, required
        - `workspace_id` string, required
        - `recipient` string, email, required: Recipient address as it appeared on the envelope.
        - `recipient_role` 'to' | 'cc' | 'bcc', required: Envelope position of a recipient on an outbound email event.
        - `tags` Tag[], nullable, required: Tags provided on the send request, echoed on every event for the send so you can route and correlate without an extra lookup. Null when the send carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object provided on the send request, echoed on every event for the send so you can correlate events with your own records. Null when the send carried no metadata.
        - `broadcast_id` string, required
    - EventEmailMailboxMessageDelivered: Every recipient of a mailbox message reached a delivered state. This event fires once per message. The same send also emits one `email.delivered` event for each recipient. Choose one event family for each automation and deduplicate mailbox events by `message_id`.
      - `type` 'email_mailbox.message_delivered', required: Event type.
      - `timestamp` string, date-time, required: When the event occurred.
      - `data` EventEmailMailboxMessageDeliveredData, required: Payload of the email_mailbox.message_delivered event.
        - `message_id` string, required
        - `mailbox_id` string, required
        - `thread_id` string, required
    - EventEmailMailboxMessageFailed: A mailbox message reached a terminal delivery failure. This event fires once per message. The same send also emits per-recipient `email.*` events. Choose one event family for each automation and deduplicate mailbox events by `message_id`.
      - `type` 'email_mailbox.message_failed', required: Event type.
      - `timestamp` string, date-time, required: When the event occurred.
      - `data` EventEmailMailboxMessageFailedData, required: Payload of the email_mailbox.message_failed event.
        - `message_id` string, required
        - `mailbox_id` string, required
        - `thread_id` string, required
        - `reason` string, required: Why the message reached a terminal delivery failure.
    - EventEmailMailboxMessageReceived: An email arrived in a mailbox. The same message also emits an `email.received` event. The two events can arrive in either order. Choose one event family for each automation and deduplicate mailbox events by `message_id`.
      - `type` 'email_mailbox.message_received', required: Event type.
      - `timestamp` string, date-time, required: When the event occurred.
      - `data` EventEmailMailboxMessageReceivedData, required: Identifiers, threading details, authentication results, and extracted text for a received mailbox message. The thread-message endpoints provide the original source during its 30-day retention window.
        - `message_id` string, required
        - `mailbox_id` string, required
        - `thread_id` string, required
        - `route_id` string, nullable: ID (ein_…) of the explicit inbound route that matched, or null when the message was delivered by the virtual exact-address route.
        - `from` string, email, required: Envelope-from address.
        - `to` string[], required: Recipient addresses the message was sent to.
        - `subject` string, nullable, required: Subject line as received, or null when the message had no subject.
        - `extracted_text` string, nullable: Plain-text body with quoted history removed, capped at 64 KB. See `truncated_text` to check whether the value was truncated. Null when extraction produces no text.
        - `truncated_text` boolean: True when `extracted_text` was truncated to the 64 KB cap. Fetch the full text through the thread-member endpoint.
        - `attachment_count` integer, required: Number of attachments on the message. Attachment content remains available for the mailbox's retention tier.
        - `authentication` 'pass' | 'fail' | 'unknown' | 'null', nullable: 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`.
        - `spf_pass` boolean, nullable: 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`.
        - `dkim_pass` boolean, nullable: 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`.
        - `dmarc_pass` boolean, nullable: 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`.
    - EventEmailMailboxMessageSent: A mailbox message was handed off for delivery. This event fires once per message. The same send also emits per-recipient `email.*` events. Choose one event family for each automation and deduplicate mailbox events by `message_id`.
      - `type` 'email_mailbox.message_sent', required: Event type.
      - `timestamp` string, date-time, required: When the event occurred.
      - `data` EventEmailMailboxMessageSentData, required: Payload of the email_mailbox.message_sent event.
        - `message_id` string, required
        - `mailbox_id` string, required
        - `thread_id` string, required
    - EventEmailMailboxSuspended: This mailbox-suspension event is reserved and is not currently emitted.
      - `type` 'email_mailbox.suspended', required: Event type.
      - `timestamp` string, date-time, required: When the event occurred.
      - `data` EventEmailMailboxSuspendedData, required: Payload of the email_mailbox.suspended event.
        - `mailbox_id` string, required
        - `reason` string, required: Why the mailbox was suspended.
    - EventEmailMailboxThreadCreated: A new thread was created in a mailbox, from either direction.
      - `type` 'email_mailbox.thread_created', required: Event type.
      - `timestamp` string, date-time, required: When the event occurred.
      - `data` EventEmailMailboxThreadCreatedData, required: Payload of the email_mailbox.thread_created event.
        - `thread_id` string, required
        - `mailbox_id` string, required
        - `subject` string, nullable, required: Subject of the first message in the thread, or null when it had none.
        - `initiated_by` 'inbound' | 'outbound', required: Which direction created the thread.
    - EventEmailSuppressionCreated: An email address was added to the workspace's suppression list (manually, via complaint, or via hard bounce).
      - `type` 'email_suppression.created', required: Event type.
      - `timestamp` string, date-time, required: When the event occurred.
      - `data` EventEmailSuppressionCreatedData, required: Payload of the email_suppression.created event.
        - `suppression_id` string, required
        - `email` string, email, required: The recipient address that was added to the suppression list.
        - `reason` string, required: Why the address was suppressed. New values may be added over time; treat unknown values as informational.
        - `workspace_id` string, required
    - EventPreferenceDeleted: A stated preference was deleted, superseding it in the ledger without erasing its history.
      - `type` 'preference.deleted', required: Always `preference.deleted` for this event.
      - `timestamp` string, date-time, required: When the delete took effect (`effective_at`), not when it was recorded.
      - `data` EventPreferenceDeletedData, required: Identity fields shared by every preference lifecycle event: the key plus the ledger entry the write appended. `effective_at` is not repeated here: it is the envelope `timestamp`.
        - `preference_id` string, required
        - `transition_id` string, required
        - `channel` string, required: The channel a preference statement applies to. A preference addresses one channel: the handle that identifies the person differs per channel, so opting out of one channel says nothing about the others. New channels can be added over time, so a value outside this list can be returned.
        - `handle` string, required: Who the statement is about: an email address on the email channel, a phone number in E.164 format on SMS, WhatsApp, and Apple Messages for Business.
        - `sender_scope` string, nullable, required: The sender the statement is limited to, or null when it covers the whole channel. On Apple Messages for Business, this is the Apple business ID used to send invitations. Present-with-null on every payload of this type: it is part of the key alongside `topic_id`, and pinning its presence keeps a subscriber from ever learning `(handle, channel)` as the unique key.
        - `topic_id` string, nullable, required: The topic the statement is limited to, or null when it covers every topic. Reserved: always null in v1. Present-with-null for the same reason as `sender_scope`.
        - `coverage` 'all' | 'non_transactional', required: How much traffic the statement covers. `non_transactional` covers marketing and other non-essential messages while transactional messages such as receipts and verification codes keep flowing; `all` covers every message including transactional ones. Apple Messages for Business phone invitations have no transactional exemption, so either value covers them.
        - `contact_id` string, required
    - EventPreferenceGranted: A stated preference was granted (a person consented, or a customer wrote a grant) and became the key's live statement.
      - `type` 'preference.granted', required: Always `preference.granted` for this event.
      - `timestamp` string, date-time, required: When the statement took effect (`effective_at`), not when it was recorded.
      - `data` EventPreferenceGrantedData, required: Identity fields shared by every preference lifecycle event: the key plus the ledger entry the write appended. `effective_at` is not repeated here: it is the envelope `timestamp`.
        - `preference_id` string, required
        - `transition_id` string, required
        - `channel` string, required: The channel a preference statement applies to. A preference addresses one channel: the handle that identifies the person differs per channel, so opting out of one channel says nothing about the others. New channels can be added over time, so a value outside this list can be returned.
        - `handle` string, required: Who the statement is about: an email address on the email channel, a phone number in E.164 format on SMS, WhatsApp, and Apple Messages for Business.
        - `sender_scope` string, nullable, required: The sender the statement is limited to, or null when it covers the whole channel. On Apple Messages for Business, this is the Apple business ID used to send invitations. Present-with-null on every payload of this type: it is part of the key alongside `topic_id`, and pinning its presence keeps a subscriber from ever learning `(handle, channel)` as the unique key.
        - `topic_id` string, nullable, required: The topic the statement is limited to, or null when it covers every topic. Reserved: always null in v1. Present-with-null for the same reason as `sender_scope`.
        - `coverage` 'all' | 'non_transactional', required: How much traffic the statement covers. `non_transactional` covers marketing and other non-essential messages while transactional messages such as receipts and verification codes keep flowing; `all` covers every message including transactional ones. Apple Messages for Business phone invitations have no transactional exemption, so either value covers them.
        - `contact_id` string, required
    - EventPreferenceRevoked: A stated preference was revoked (a person opted out, or a customer wrote a revoke) and became the key's live statement.
      - `type` 'preference.revoked', required: Always `preference.revoked` for this event.
      - `timestamp` string, date-time, required: When the statement took effect (`effective_at`), not when it was recorded.
      - `data` EventPreferenceRevokedData, required: Identity fields shared by every preference lifecycle event: the key plus the ledger entry the write appended. `effective_at` is not repeated here: it is the envelope `timestamp`.
        - `preference_id` string, required
        - `transition_id` string, required
        - `channel` string, required: The channel a preference statement applies to. A preference addresses one channel: the handle that identifies the person differs per channel, so opting out of one channel says nothing about the others. New channels can be added over time, so a value outside this list can be returned.
        - `handle` string, required: Who the statement is about: an email address on the email channel, a phone number in E.164 format on SMS, WhatsApp, and Apple Messages for Business.
        - `sender_scope` string, nullable, required: The sender the statement is limited to, or null when it covers the whole channel. On Apple Messages for Business, this is the Apple business ID used to send invitations. Present-with-null on every payload of this type: it is part of the key alongside `topic_id`, and pinning its presence keeps a subscriber from ever learning `(handle, channel)` as the unique key.
        - `topic_id` string, nullable, required: The topic the statement is limited to, or null when it covers every topic. Reserved: always null in v1. Present-with-null for the same reason as `sender_scope`.
        - `coverage` 'all' | 'non_transactional', required: How much traffic the statement covers. `non_transactional` covers marketing and other non-essential messages while transactional messages such as receipts and verification codes keep flowing; `all` covers every message including transactional ones. Apple Messages for Business phone invitations have no transactional exemption, so either value covers them.
        - `contact_id` string, required
    - EventSMSAccepted: The API accepted the SMS send request and queued it for processing.
      - `type` 'sms.accepted', required: Event type.
      - `timestamp` string, date-time, required: Time the API accepted the request.
      - `data` EventSMSAcceptedData, required: Identity fields shared by every SMS lifecycle event payload.
        - `sms_id` string, required
        - `workspace_id` string, required
        - `to` string, required: Where the message went. On an outbound message this is the recipient's phone number in E.164 format; on an inbound one it is your own number that received it.
        - `from` string, required: Where the message came from. On an outbound message this is the sender you sent it from: an E.164 number, an alphanumeric sender ID, or a short code. On an inbound one it is the phone number that sent it to you.
        - `tags` Tag[], nullable, required: Tags provided on the send request, echoed on every event for the message so you can route and correlate without an extra lookup. Null when the message carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object provided on the send request, echoed on every event for the message so you can correlate events with your own records. Null when the message carried no metadata.
        - `requested_language` string, required: A language tag in BCP-47 form, for example `en` or `pt-BR`.
        - `resolved_language` string, required: A language tag in BCP-47 form, for example `en` or `pt-BR`.
        - `template_id` string, required
        - `template_version_id` string, required
        - `template_content_hash` string, required: A fingerprint of SMS template text, prefixed with its algorithm. Compare it within this API version to identify the exact source without transferring it.
        - `cost` MessageCost, nullable: What was charged for a message, split into the components that make it up. `null` until at least one component has been priced.
          - `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.
          - `currency_code` string, required: ISO 4217 three-letter currency code.
          - `transaction_amount` string, nullable, 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.
          - `passthrough_amount` string, nullable, 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.
        - `segments` SMSSegments, required: Segment breakdown for the message body. Segment count drives billing.
          - `count` integer, required: Number of segments the body is split into. Each segment is a billable unit.
          - `encoding` 'GSM_7BIT' | 'UCS2', required: Encoding used for the body. The `GSM_7BIT` encoding fits 160 septets (seven-bit units) in one segment, or 153 per part in a multi-segment message. The `UCS2` encoding applies when the body contains a character outside the GSM 03.38 alphabet, including emoji, CJK, and some accented characters. It fits 70 UTF-16 code units in one segment, or 67 per part. Neither limit counts characters, and both alphabets have characters that cost two units. Under `GSM_7BIT` there are ten such entries, and they are the whole set: `^`, `{`, `}`, `\`, `[`, `]`, `~`, `|`, `€`, and the form feed control. Eighty of those fill a single segment. Under `UCS2` an emoji outside the Basic Multilingual Plane is a surrogate pair costing two code units, so 35 of those fill a single segment.
          - `characters` integer, required: Character count of the body, counted in Unicode code points under either encoding. This is not the segment measure: a `GSM_7BIT` extended-table character counts once here but costs two septets, and a `UCS2` emoji outside the Basic Multilingual Plane counts once here but costs two of the segment's 70 code units.
    - EventSMSDelivered: The carrier confirmed delivery of the message to the recipient handset.
      - `type` 'sms.delivered', required: Event type.
      - `timestamp` string, date-time, required: Time the carrier confirmed delivery.
      - `data` EventSMSDeliveredData, required: Identity fields shared by every SMS lifecycle event payload.
        - `sms_id` string, required
        - `workspace_id` string, required
        - `to` string, required: Where the message went. On an outbound message this is the recipient's phone number in E.164 format; on an inbound one it is your own number that received it.
        - `from` string, required: Where the message came from. On an outbound message this is the sender you sent it from: an E.164 number, an alphanumeric sender ID, or a short code. On an inbound one it is the phone number that sent it to you.
        - `tags` Tag[], nullable, required: Tags provided on the send request, echoed on every event for the message so you can route and correlate without an extra lookup. Null when the message carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object provided on the send request, echoed on every event for the message so you can correlate events with your own records. Null when the message carried no metadata.
        - `requested_language` string, required: A language tag in BCP-47 form, for example `en` or `pt-BR`.
        - `resolved_language` string, required: A language tag in BCP-47 form, for example `en` or `pt-BR`.
        - `template_id` string, required
        - `template_version_id` string, required
        - `template_content_hash` string, required: A fingerprint of SMS template text, prefixed with its algorithm. Compare it within this API version to identify the exact source without transferring it.
        - `cost` MessageCost, nullable: What was charged for a message, split into the components that make it up. `null` until at least one component has been priced.
          - `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.
          - `currency_code` string, required: ISO 4217 three-letter currency code.
          - `transaction_amount` string, nullable, 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.
          - `passthrough_amount` string, nullable, 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.
        - `carrier` string: Carrier that delivered the message. Absent when the carrier does not report one.
        - `mcc_mnc` string: Mobile country code and mobile network code of the carrier. Absent when the carrier does not report one.
    - EventSMSExpired: The message's validity period elapsed before it could be delivered.
      - `type` 'sms.expired', required: Event type.
      - `timestamp` string, date-time, required: Time the message expired.
      - `data` EventSMSExpiredData, required: Identity fields shared by every SMS lifecycle event payload.
        - `sms_id` string, required
        - `workspace_id` string, required
        - `to` string, required: Where the message went. On an outbound message this is the recipient's phone number in E.164 format; on an inbound one it is your own number that received it.
        - `from` string, required: Where the message came from. On an outbound message this is the sender you sent it from: an E.164 number, an alphanumeric sender ID, or a short code. On an inbound one it is the phone number that sent it to you.
        - `tags` Tag[], nullable, required: Tags provided on the send request, echoed on every event for the message so you can route and correlate without an extra lookup. Null when the message carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object provided on the send request, echoed on every event for the message so you can correlate events with your own records. Null when the message carried no metadata.
        - `requested_language` string, required: A language tag in BCP-47 form, for example `en` or `pt-BR`.
        - `resolved_language` string, required: A language tag in BCP-47 form, for example `en` or `pt-BR`.
        - `template_id` string, required
        - `template_version_id` string, required
        - `template_content_hash` string, required: A fingerprint of SMS template text, prefixed with its algorithm. Compare it within this API version to identify the exact source without transferring it.
        - `cost` MessageCost, nullable: What was charged for a message, split into the components that make it up. `null` until at least one component has been priced.
          - `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.
          - `currency_code` string, required: ISO 4217 three-letter currency code.
          - `transaction_amount` string, nullable, 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.
          - `passthrough_amount` string, nullable, 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.
        - `error` SMSError, nullable, required: Failure detail for a message that could not be delivered or was rejected.
          - `code` string, required: Standardized failure reason: - `invalid_destination`: The number is unassigned, ported out, or malformed. - `unreachable`: The handset is off or outside coverage. - `blocked_by_carrier`: The carrier filtered the message. - `blocked_by_fraud_protection`: Bird fraud protection blocked suspected SMS pumping. - `blocked_by_recipient`: The recipient device blocked the sender. - `landline_unreachable`: The destination is a landline that does not accept SMS. - `content_rejected`: The carrier rejected the content. - `sender_unregistered`: The sender is not registered for the destination. - `recipient_opted_out`: The recipient is on a suppression list. - `provider_unavailable`: The provider remained unavailable after retries. - `insufficient_balance`: The workspace wallet could not fund the send. - `unknown`: The failure could not be classified. This is an open enum. Accept unrecognized values.
          - `description` string, required: The failure in words: the provider's reason text, or Bird's explanation for a fraud protection block or a message refused before submission. Free-form, so branch on `code` and show this to a human.
          - `carrier_error_code` string, nullable: Raw provider-supplied error code, finer-grained than the `code` that normalizes it. Not a Bird-defined value, so quote it to support when asking why a message failed. Null when the provider sent none, including any failure decided before one was reached.
          - `occurred_at` string, date-time, required: When the failure occurred.
    - EventSMSFailed: Message delivery failed permanently.
      - `type` 'sms.failed', required: Event type.
      - `timestamp` string, date-time, required: Time the failure was recorded.
      - `data` EventSMSFailedData, required: Identity fields shared by every SMS lifecycle event payload.
        - `sms_id` string, required
        - `workspace_id` string, required
        - `to` string, required: Where the message went. On an outbound message this is the recipient's phone number in E.164 format; on an inbound one it is your own number that received it.
        - `from` string, required: Where the message came from. On an outbound message this is the sender you sent it from: an E.164 number, an alphanumeric sender ID, or a short code. On an inbound one it is the phone number that sent it to you.
        - `tags` Tag[], nullable, required: Tags provided on the send request, echoed on every event for the message so you can route and correlate without an extra lookup. Null when the message carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object provided on the send request, echoed on every event for the message so you can correlate events with your own records. Null when the message carried no metadata.
        - `requested_language` string, required: A language tag in BCP-47 form, for example `en` or `pt-BR`.
        - `resolved_language` string, required: A language tag in BCP-47 form, for example `en` or `pt-BR`.
        - `template_id` string, required
        - `template_version_id` string, required
        - `template_content_hash` string, required: A fingerprint of SMS template text, prefixed with its algorithm. Compare it within this API version to identify the exact source without transferring it.
        - `cost` MessageCost, nullable: What was charged for a message, split into the components that make it up. `null` until at least one component has been priced.
          - `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.
          - `currency_code` string, required: ISO 4217 three-letter currency code.
          - `transaction_amount` string, nullable, 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.
          - `passthrough_amount` string, nullable, 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.
        - `error` SMSError, nullable, required: Failure detail for a message that could not be delivered or was rejected.
          - `code` string, required: Standardized failure reason: - `invalid_destination`: The number is unassigned, ported out, or malformed. - `unreachable`: The handset is off or outside coverage. - `blocked_by_carrier`: The carrier filtered the message. - `blocked_by_fraud_protection`: Bird fraud protection blocked suspected SMS pumping. - `blocked_by_recipient`: The recipient device blocked the sender. - `landline_unreachable`: The destination is a landline that does not accept SMS. - `content_rejected`: The carrier rejected the content. - `sender_unregistered`: The sender is not registered for the destination. - `recipient_opted_out`: The recipient is on a suppression list. - `provider_unavailable`: The provider remained unavailable after retries. - `insufficient_balance`: The workspace wallet could not fund the send. - `unknown`: The failure could not be classified. This is an open enum. Accept unrecognized values.
          - `description` string, required: The failure in words: the provider's reason text, or Bird's explanation for a fraud protection block or a message refused before submission. Free-form, so branch on `code` and show this to a human.
          - `carrier_error_code` string, nullable: Raw provider-supplied error code, finer-grained than the `code` that normalizes it. Not a Bird-defined value, so quote it to support when asking why a message failed. Null when the provider sent none, including any failure decided before one was reached.
          - `occurred_at` string, date-time, required: When the failure occurred.
    - EventSMSReceived: A message was received on one of your numbers.
      - `type` 'sms.received', required: Always `sms.received` for this event.
      - `timestamp` string, date-time, required: Time the sender sent the message.
      - `data` union, required
        - object: Identity fields shared by every SMS lifecycle event payload.
          - `sms_id` string, required
          - `workspace_id` string, required
          - `to` string, required: Where the message went. On an outbound message this is the recipient's phone number in E.164 format; on an inbound one it is your own number that received it.
          - `from` string, required: Where the message came from. On an outbound message this is the sender you sent it from: an E.164 number, an alphanumeric sender ID, or a short code. On an inbound one it is the phone number that sent it to you.
          - `tags` Tag[], nullable, required: Tags provided on the send request, echoed on every event for the message so you can route and correlate without an extra lookup. Null when the message carried no tags.
            - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
            - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
          - `metadata` object, nullable, required: The metadata object provided on the send request, echoed on every event for the message so you can correlate events with your own records. Null when the message carried no metadata.
          - `requested_language` string, required: A language tag in BCP-47 form, for example `en` or `pt-BR`.
          - `resolved_language` string, required: A language tag in BCP-47 form, for example `en` or `pt-BR`.
          - `template_id` string, required
          - `template_version_id` string, required
          - `template_content_hash` string, required: A fingerprint of SMS template text, prefixed with its algorithm. Compare it within this API version to identify the exact source without transferring it.
          - `cost` MessageCost, nullable: What was charged for a message, split into the components that make it up. `null` until at least one component has been priced.
            - `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.
            - `currency_code` string, required: ISO 4217 three-letter currency code.
            - `transaction_amount` string, nullable, 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.
            - `passthrough_amount` string, nullable, 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.
        - object: Identity fields shared by every SMS lifecycle event payload.
          - `sms_id` string, required
          - `workspace_id` string, required
          - `to` string, required: Where the message went. On an outbound message this is the recipient's phone number in E.164 format; on an inbound one it is your own number that received it.
          - `from` string, required: Where the message came from. On an outbound message this is the sender you sent it from: an E.164 number, an alphanumeric sender ID, or a short code. On an inbound one it is the phone number that sent it to you.
          - `tags` Tag[], nullable, required: Tags provided on the send request, echoed on every event for the message so you can route and correlate without an extra lookup. Null when the message carried no tags.
            - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
            - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
          - `metadata` object, nullable, required: The metadata object provided on the send request, echoed on every event for the message so you can correlate events with your own records. Null when the message carried no metadata.
          - `requested_language` string, required: A language tag in BCP-47 form, for example `en` or `pt-BR`.
          - `resolved_language` string, required: A language tag in BCP-47 form, for example `en` or `pt-BR`.
          - `template_id` string, required
          - `template_version_id` string, required
          - `template_content_hash` string, required: A fingerprint of SMS template text, prefixed with its algorithm. Compare it within this API version to identify the exact source without transferring it.
          - `cost` MessageCost, nullable: What was charged for a message, split into the components that make it up. `null` until at least one component has been priced.
            - `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.
            - `currency_code` string, required: ISO 4217 three-letter currency code.
            - `transaction_amount` string, nullable, 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.
            - `passthrough_amount` string, nullable, 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.
    - EventSMSRejected: The API rejected the message before sending it to the carrier because of an invalid destination, suppression, or content or policy restriction.
      - `type` 'sms.rejected', required: Event type.
      - `timestamp` string, date-time, required: Time the rejection was recorded.
      - `data` EventSMSRejectedData, required: Identity fields shared by every SMS lifecycle event payload.
        - `sms_id` string, required
        - `workspace_id` string, required
        - `to` string, required: Where the message went. On an outbound message this is the recipient's phone number in E.164 format; on an inbound one it is your own number that received it.
        - `from` string, required: Where the message came from. On an outbound message this is the sender you sent it from: an E.164 number, an alphanumeric sender ID, or a short code. On an inbound one it is the phone number that sent it to you.
        - `tags` Tag[], nullable, required: Tags provided on the send request, echoed on every event for the message so you can route and correlate without an extra lookup. Null when the message carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object provided on the send request, echoed on every event for the message so you can correlate events with your own records. Null when the message carried no metadata.
        - `requested_language` string, required: A language tag in BCP-47 form, for example `en` or `pt-BR`.
        - `resolved_language` string, required: A language tag in BCP-47 form, for example `en` or `pt-BR`.
        - `template_id` string, required
        - `template_version_id` string, required
        - `template_content_hash` string, required: A fingerprint of SMS template text, prefixed with its algorithm. Compare it within this API version to identify the exact source without transferring it.
        - `cost` MessageCost, nullable: What was charged for a message, split into the components that make it up. `null` until at least one component has been priced.
          - `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.
          - `currency_code` string, required: ISO 4217 three-letter currency code.
          - `transaction_amount` string, nullable, 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.
          - `passthrough_amount` string, nullable, 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.
        - `error` SMSError, nullable, required: Failure detail for a message that could not be delivered or was rejected.
          - `code` string, required: Standardized failure reason: - `invalid_destination`: The number is unassigned, ported out, or malformed. - `unreachable`: The handset is off or outside coverage. - `blocked_by_carrier`: The carrier filtered the message. - `blocked_by_fraud_protection`: Bird fraud protection blocked suspected SMS pumping. - `blocked_by_recipient`: The recipient device blocked the sender. - `landline_unreachable`: The destination is a landline that does not accept SMS. - `content_rejected`: The carrier rejected the content. - `sender_unregistered`: The sender is not registered for the destination. - `recipient_opted_out`: The recipient is on a suppression list. - `provider_unavailable`: The provider remained unavailable after retries. - `insufficient_balance`: The workspace wallet could not fund the send. - `unknown`: The failure could not be classified. This is an open enum. Accept unrecognized values.
          - `description` string, required: The failure in words: the provider's reason text, or Bird's explanation for a fraud protection block or a message refused before submission. Free-form, so branch on `code` and show this to a human.
          - `carrier_error_code` string, nullable: Raw provider-supplied error code, finer-grained than the `code` that normalizes it. Not a Bird-defined value, so quote it to support when asking why a message failed. Null when the provider sent none, including any failure decided before one was reached.
          - `occurred_at` string, date-time, required: When the failure occurred.
    - EventSMSSent: The API handed the message to the carrier for delivery.
      - `type` 'sms.sent', required: Event type.
      - `timestamp` string, date-time, required: Time the message was handed to the carrier.
      - `data` EventSMSSentData, required: Identity fields shared by every SMS lifecycle event payload.
        - `sms_id` string, required
        - `workspace_id` string, required
        - `to` string, required: Where the message went. On an outbound message this is the recipient's phone number in E.164 format; on an inbound one it is your own number that received it.
        - `from` string, required: Where the message came from. On an outbound message this is the sender you sent it from: an E.164 number, an alphanumeric sender ID, or a short code. On an inbound one it is the phone number that sent it to you.
        - `tags` Tag[], nullable, required: Tags provided on the send request, echoed on every event for the message so you can route and correlate without an extra lookup. Null when the message carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object provided on the send request, echoed on every event for the message so you can correlate events with your own records. Null when the message carried no metadata.
        - `requested_language` string, required: A language tag in BCP-47 form, for example `en` or `pt-BR`.
        - `resolved_language` string, required: A language tag in BCP-47 form, for example `en` or `pt-BR`.
        - `template_id` string, required
        - `template_version_id` string, required
        - `template_content_hash` string, required: A fingerprint of SMS template text, prefixed with its algorithm. Compare it within this API version to identify the exact source without transferring it.
        - `cost` MessageCost, nullable: What was charged for a message, split into the components that make it up. `null` until at least one component has been priced.
          - `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.
          - `currency_code` string, required: ISO 4217 three-letter currency code.
          - `transaction_amount` string, nullable, 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.
          - `passthrough_amount` string, nullable, 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.
        - `carrier` string: Carrier that handled the message. Absent when the carrier does not report one.
        - `mcc_mnc` string: Mobile country code and mobile network code of the carrier. Absent when the carrier does not report one.
    - EventSMSUndelivered: The carrier reported a non-permanent failure to deliver the message.
      - `type` 'sms.undelivered', required: Event type.
      - `timestamp` string, date-time, required: Time the non-delivery was recorded.
      - `data` EventSMSUndeliveredData, required: Identity fields shared by every SMS lifecycle event payload.
        - `sms_id` string, required
        - `workspace_id` string, required
        - `to` string, required: Where the message went. On an outbound message this is the recipient's phone number in E.164 format; on an inbound one it is your own number that received it.
        - `from` string, required: Where the message came from. On an outbound message this is the sender you sent it from: an E.164 number, an alphanumeric sender ID, or a short code. On an inbound one it is the phone number that sent it to you.
        - `tags` Tag[], nullable, required: Tags provided on the send request, echoed on every event for the message so you can route and correlate without an extra lookup. Null when the message carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object provided on the send request, echoed on every event for the message so you can correlate events with your own records. Null when the message carried no metadata.
        - `requested_language` string, required: A language tag in BCP-47 form, for example `en` or `pt-BR`.
        - `resolved_language` string, required: A language tag in BCP-47 form, for example `en` or `pt-BR`.
        - `template_id` string, required
        - `template_version_id` string, required
        - `template_content_hash` string, required: A fingerprint of SMS template text, prefixed with its algorithm. Compare it within this API version to identify the exact source without transferring it.
        - `cost` MessageCost, nullable: What was charged for a message, split into the components that make it up. `null` until at least one component has been priced.
          - `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.
          - `currency_code` string, required: ISO 4217 three-letter currency code.
          - `transaction_amount` string, nullable, 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.
          - `passthrough_amount` string, nullable, 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.
        - `error` SMSError, nullable, required: Failure detail for a message that could not be delivered or was rejected.
          - `code` string, required: Standardized failure reason: - `invalid_destination`: The number is unassigned, ported out, or malformed. - `unreachable`: The handset is off or outside coverage. - `blocked_by_carrier`: The carrier filtered the message. - `blocked_by_fraud_protection`: Bird fraud protection blocked suspected SMS pumping. - `blocked_by_recipient`: The recipient device blocked the sender. - `landline_unreachable`: The destination is a landline that does not accept SMS. - `content_rejected`: The carrier rejected the content. - `sender_unregistered`: The sender is not registered for the destination. - `recipient_opted_out`: The recipient is on a suppression list. - `provider_unavailable`: The provider remained unavailable after retries. - `insufficient_balance`: The workspace wallet could not fund the send. - `unknown`: The failure could not be classified. This is an open enum. Accept unrecognized values.
          - `description` string, required: The failure in words: the provider's reason text, or Bird's explanation for a fraud protection block or a message refused before submission. Free-form, so branch on `code` and show this to a human.
          - `carrier_error_code` string, nullable: Raw provider-supplied error code, finer-grained than the `code` that normalizes it. Not a Bird-defined value, so quote it to support when asking why a message failed. Null when the provider sent none, including any failure decided before one was reached.
          - `occurred_at` string, date-time, required: When the failure occurred.
    - EventSMSSuppressionCreated: A destination was added to the workspace's SMS suppression ledger: a subscriber's STOP, a carrier opt-out, or a manual add.
      - `type` 'sms_suppression.created', required: Always `sms_suppression.created` for this event.
      - `timestamp` string, date-time, required: When the episode's opening statement took effect (`effective_at`).
      - `data` EventSMSSuppressionCreatedData, required: Payload of the sms_suppression.created event.
        - `suppression_id` string, required
        - `destination` string, required: The subscriber, in E.164 format.
        - `originator` string, required: The sender this stops. An SMS suppression is the exact (sender, recipient) pair, so your other senders still reach this subscriber.
        - `reason` string, required: Reason this sender cannot message the subscriber: - `keyword_stop`: The subscriber sent a stop keyword. A start keyword clears it. - `carrier_opted_out`: The carrier reported the opt-out. - `manual`: Your workspace added the suppression through the API or dashboard. This is an open enum. Accept unrecognized values.
        - `workspace_id` string, required
    - EventVerifyAttemptDelivered: The channel confirmed delivery of a one-time passcode to the recipient.
      - `type` 'verify.attempt.delivered', required: Event type.
      - `timestamp` string, date-time, required: Time delivery was confirmed.
      - `data` EventVerifyAttemptDeliveredData, required: Identity fields shared by every Verify lifecycle event payload.
        - `verification_id` string, required
        - `workspace_id` string, required
        - `to` VerificationTo, required: The recipient to verify. Provide an `email`, a `phone_number`, or both; at least one is required. The addresses also identify the verification: a check must supply exactly the set used on the create call, so a verification created with both addresses is not found by either one alone.
          - `email` string, email: The recipient's email address. Case does not matter; the address is lowercased before use.
          - `phone_number` string: The recipient's phone number in E.164 format, with the leading `+` and country code (for example `+15551234567`). A number in any other format is rejected as an invalid recipient (`422`).
        - `metadata` object, nullable, required: The metadata object provided when the verification was created, echoed on every event for the session so you can correlate events with your own records. Null when the verification carried no metadata.
        - `channel` string, required: The channel a passcode is delivered over. Open enum: new channels may be added over time, so treat any unrecognized value as a future channel rather than an error.
        - `address` string, required: The single address this attempt was dispatched to, an E.164 phone number or an email address.
        - `carrier` string, nullable, required: Carrier that delivered the message, when the carrier network reports it. Always null for email, WhatsApp, Telegram, and voice.
        - `mcc_mnc` string, nullable, required: Mobile country code and mobile network code of the delivering carrier, when reported. Always null for email, WhatsApp, Telegram, and voice.
        - `delivered_at` string, date-time, required: Time delivery was confirmed.
    - EventVerifyAttemptSent: A one-time passcode was dispatched to the recipient on a channel.
      - `type` 'verify.attempt.sent', required: Event type.
      - `timestamp` string, date-time, required: Time the passcode was dispatched.
      - `data` EventVerifyAttemptSentData, required: Identity fields shared by every Verify lifecycle event payload.
        - `verification_id` string, required
        - `workspace_id` string, required
        - `to` VerificationTo, required: The recipient to verify. Provide an `email`, a `phone_number`, or both; at least one is required. The addresses also identify the verification: a check must supply exactly the set used on the create call, so a verification created with both addresses is not found by either one alone.
          - `email` string, email: The recipient's email address. Case does not matter; the address is lowercased before use.
          - `phone_number` string: The recipient's phone number in E.164 format, with the leading `+` and country code (for example `+15551234567`). A number in any other format is rejected as an invalid recipient (`422`).
        - `metadata` object, nullable, required: The metadata object provided when the verification was created, echoed on every event for the session so you can correlate events with your own records. Null when the verification carried no metadata.
        - `channel` string, required: The channel a passcode is delivered over. Open enum: new channels may be added over time, so treat any unrecognized value as a future channel rather than an error.
        - `address` string, required: The single address this attempt was dispatched to, an E.164 phone number or an email address.
        - `from` string, nullable, required: The sender the passcode was sent from: a phone number, alphanumeric sender ID, short code, or email address. Null when the channel exposes no sender.
        - `sent_at` string, date-time, required: Time the passcode was dispatched.
    - EventVerifyAttemptUndelivered: A one-time passcode failed to deliver to the recipient.
      - `type` 'verify.attempt.undelivered', required: Event type.
      - `timestamp` string, date-time, required: Time the failure was recorded.
      - `data` EventVerifyAttemptUndeliveredData, required: Identity fields shared by every Verify lifecycle event payload.
        - `verification_id` string, required
        - `workspace_id` string, required
        - `to` VerificationTo, required: The recipient to verify. Provide an `email`, a `phone_number`, or both; at least one is required. The addresses also identify the verification: a check must supply exactly the set used on the create call, so a verification created with both addresses is not found by either one alone.
          - `email` string, email: The recipient's email address. Case does not matter; the address is lowercased before use.
          - `phone_number` string: The recipient's phone number in E.164 format, with the leading `+` and country code (for example `+15551234567`). A number in any other format is rejected as an invalid recipient (`422`).
        - `metadata` object, nullable, required: The metadata object provided when the verification was created, echoed on every event for the session so you can correlate events with your own records. Null when the verification carried no metadata.
        - `channel` string, required: The channel a passcode is delivered over. Open enum: new channels may be added over time, so treat any unrecognized value as a future channel rather than an error.
        - `address` string, required: The single address this attempt was dispatched to, an E.164 phone number or an email address.
        - `reason` string, required: Why a passcode send did not deliver: - `carrier_rejected`: The SMS carrier rejected the send. - `hard_bounce`: The email permanently bounced. - `soft_bounce`: The email temporarily bounced, such as when a mailbox is full. - `undelivered`: The channel reported a generic delivery failure. - `channel_unavailable`: The channel could not be used, so the verification moved to the next channel. - `channel_disabled`: Sending on the channel is temporarily disabled, so the verification moved to the next channel. - `channel_restricted`: The channel does not carry passcodes to this destination country. The verification moves to the next channel enabled there, or fails when the country has no other. - `delivery_timeout`: No delivery confirmation arrived before the channel's timeout, so the verification moved to the next channel. - `not_billable`: The send could not be charged, so it was never handed to the channel. Usually the workspace balance is too low to cover it. Topping up the balance is what clears this. New reasons may be added over time. Treat unrecognized values as reasons added later rather than errors.
        - `error` string, nullable, required: Diagnostic text describing the failure, for display only. Null when none was reported.
        - `failed_at` string, date-time, required: Time the failure was recorded.
    - EventVerifyVerificationCreated: A verification session was created and its first one-time passcode is being sent.
      - `type` 'verify.verification.created', required: Event type.
      - `timestamp` string, date-time, required: Time the verification session was created.
      - `data` EventVerifyVerificationCreatedData, required: Identity fields shared by every Verify lifecycle event payload.
        - `verification_id` string, required
        - `workspace_id` string, required
        - `to` VerificationTo, required: The recipient to verify. Provide an `email`, a `phone_number`, or both; at least one is required. The addresses also identify the verification: a check must supply exactly the set used on the create call, so a verification created with both addresses is not found by either one alone.
          - `email` string, email: The recipient's email address. Case does not matter; the address is lowercased before use.
          - `phone_number` string: The recipient's phone number in E.164 format, with the leading `+` and country code (for example `+15551234567`). A number in any other format is rejected as an invalid recipient (`422`).
        - `metadata` object, nullable, required: The metadata object provided when the verification was created, echoed on every event for the session so you can correlate events with your own records. Null when the verification carried no metadata.
        - `channel` string, required: The channel a passcode is delivered over. Open enum: new channels may be added over time, so treat any unrecognized value as a future channel rather than an error.
        - `status` string, required: The verification's state at creation, always `pending`. Open enum for forward compatibility.
        - `created_at` string, date-time, required: Time the verification session was created.
    - EventVerifyVerificationFailed: The verification ended without the recipient receiving a passcode: every planned channel reported that its send would not arrive.
      - `type` 'verify.verification.failed', required: Always `verify.verification.failed` for this event.
      - `timestamp` string, date-time, required: Time the verification was resolved.
      - `data` EventVerifyVerificationFailedData, required: Identity fields shared by every Verify lifecycle event payload.
        - `verification_id` string, required
        - `workspace_id` string, required
        - `to` VerificationTo, required: The recipient to verify. Provide an `email`, a `phone_number`, or both; at least one is required. The addresses also identify the verification: a check must supply exactly the set used on the create call, so a verification created with both addresses is not found by either one alone.
          - `email` string, email: The recipient's email address. Case does not matter; the address is lowercased before use.
          - `phone_number` string: The recipient's phone number in E.164 format, with the leading `+` and country code (for example `+15551234567`). A number in any other format is rejected as an invalid recipient (`422`).
        - `metadata` object, nullable, required: The metadata object provided when the verification was created, echoed on every event for the session so you can correlate events with your own records. Null when the verification carried no metadata.
        - `status` string, required: The verification's state, always `failed`. Open enum for forward compatibility.
        - `reason` string, required: Why a verification session reached its final state without succeeding: `attempts_exhausted` (too many incorrect passcodes), `ttl_elapsed` (the time window elapsed before a correct passcode), or `undeliverable` (no planned channel could deliver a passcode, so the recipient never had one to submit). Open enum: new reasons may be added over time, so treat any unrecognized value as a future reason rather than an error.
        - `channel` string, required: The channel a passcode is delivered over. Open enum: new channels may be added over time, so treat any unrecognized value as a future channel rather than an error.
        - `last_attempt_reason` string, required: Why a passcode send did not deliver: - `carrier_rejected`: The SMS carrier rejected the send. - `hard_bounce`: The email permanently bounced. - `soft_bounce`: The email temporarily bounced, such as when a mailbox is full. - `undelivered`: The channel reported a generic delivery failure. - `channel_unavailable`: The channel could not be used, so the verification moved to the next channel. - `channel_disabled`: Sending on the channel is temporarily disabled, so the verification moved to the next channel. - `channel_restricted`: The channel does not carry passcodes to this destination country. The verification moves to the next channel enabled there, or fails when the country has no other. - `delivery_timeout`: No delivery confirmation arrived before the channel's timeout, so the verification moved to the next channel. - `not_billable`: The send could not be charged, so it was never handed to the channel. Usually the workspace balance is too low to cover it. Topping up the balance is what clears this. New reasons may be added over time. Treat unrecognized values as reasons added later rather than errors.
        - `failed_at` string, date-time, required: Time the verification was resolved.
    - EventVerifyVerificationVerified: The verification was successfully resolved: the recipient confirmed the correct code.
      - `type` 'verify.verification.verified', required: Event type.
      - `timestamp` string, date-time, required: Time the verification was verified.
      - `data` EventVerifyVerificationVerifiedData, required: Identity fields shared by every Verify lifecycle event payload.
        - `verification_id` string, required
        - `workspace_id` string, required
        - `to` VerificationTo, required: The recipient to verify. Provide an `email`, a `phone_number`, or both; at least one is required. The addresses also identify the verification: a check must supply exactly the set used on the create call, so a verification created with both addresses is not found by either one alone.
          - `email` string, email: The recipient's email address. Case does not matter; the address is lowercased before use.
          - `phone_number` string: The recipient's phone number in E.164 format, with the leading `+` and country code (for example `+15551234567`). A number in any other format is rejected as an invalid recipient (`422`).
        - `metadata` object, nullable, required: The metadata object provided when the verification was created, echoed on every event for the session so you can correlate events with your own records. Null when the verification carried no metadata.
        - `status` string, required: The verification's state, always `verified`. Open enum for forward compatibility.
        - `channel` string, required: The channel a passcode is delivered over. Open enum: new channels may be added over time, so treat any unrecognized value as a future channel rather than an error.
        - `verified_at` string, date-time, required: Time the verification was verified.
    - EventVoiceCallAnswered: The called party answered and media began flowing.
      - `type` 'voice_call.answered', required: Event type.
      - `timestamp` string, date-time, required: Time the call was answered.
      - `data` EventVoiceCallAnsweredData, required: Identity fields shared by every voice call lifecycle event payload.
        - `call_id` string, required
        - `session_id` string
        - `workspace_id` string, required
        - `direction` 'inbound' | 'outbound', required: Whether the call was placed from your side, by your PBX, the API, the browser or Bird dialing onward for you (outbound), or arrived from a remote party (inbound).
        - `from` string, required: Calling party number in E.164 format.
        - `to` string, required: Called party number in E.164 format.
    - EventVoiceCallEnded: The call ended after either party hung up or call setup failed.
      - `type` 'voice_call.ended', required: Event type.
      - `timestamp` string, date-time, required: Time either party hung up or call setup failed.
      - `data` EventVoiceCallEndedData, required: Identity fields shared by every voice call lifecycle event payload.
        - `call_id` string, required
        - `session_id` string
        - `workspace_id` string, required
        - `direction` 'inbound' | 'outbound', required: Whether the call was placed from your side, by your PBX, the API, the browser or Bird dialing onward for you (outbound), or arrived from a remote party (inbound).
        - `from` string, required: Calling party number in E.164 format.
        - `to` string, required: Called party number in E.164 format.
        - `status` 'answered' | 'no_answer' | 'busy' | 'canceled' | 'failed' | 'rejected' | 'unknown' | 'ringing' | 'in_progress', required: Call status. A call that has ended carries one of: - `answered` means it connected and the far end picked up. - `no_answer` means nobody picked up before the call timed out. - `rejected` means it was refused rather than attempted. Either we turned it away before dialing a carrier, in which case `rejection_reason` names the check it failed where there was one, or the far end declined it. - `failed` means it was attempted and did not work, and `sip_response_code` is what came back. - `unknown` means the outcome could not be determined. Contact support with the call `id` if you see one. An active call carries `ringing` before it is picked up and `in_progress` afterward. The call list's `status` filter takes any mix of the two sets. `busy` and `canceled` are reserved for incoming calls delivered to your own numbers: `busy` for a called party that rejected the call as busy, `canceled` for a caller who hung up before it was picked up. Neither is emitted yet and both outcomes are reported as `failed` today.
        - `sip_response_code` integer, nullable, required: Final SIP response code received from the carrier. Null when no SIP response was received, for example on timeout or DNS failure.
        - `duration_ms` integer, required: Total call duration in milliseconds, measured from the first SIP `INVITE` to the `BYE` or final response.
        - `billable_ms` integer, required: Billable duration in milliseconds, measured from answer to call end. Zero for unanswered calls.
    - EventVoiceCallInitiated: Call routing began.
      - `type` 'voice_call.initiated', required: Event type.
      - `timestamp` string, date-time, required: Time the call was initiated.
      - `data` EventVoiceCallInitiatedData, required: Identity fields shared by every voice call lifecycle event payload.
        - `call_id` string, required
        - `session_id` string
        - `workspace_id` string, required
        - `direction` 'inbound' | 'outbound', required: Whether the call was placed from your side, by your PBX, the API, the browser or Bird dialing onward for you (outbound), or arrived from a remote party (inbound).
        - `from` string, required: Calling party number in E.164 format.
        - `to` string, required: Called party number in E.164 format.
    - EventWhatsAppAccepted: The API accepted and charged the send request.
      - `type` 'whatsapp.accepted', required: Event type.
      - `timestamp` string, date-time, required: Time the API accepted and charged the send request.
      - `data` EventWhatsAppAcceptedData, required: Identity fields shared by every WhatsApp lifecycle event payload.
        - `whatsapp_id` string, required
        - `workspace_id` string, required
        - `direction` 'outbound' | 'inbound', required: Whether the message was sent by the business (`outbound`) or received from the contact (`inbound`).
        - `from` WhatsAppAddress, required: Sender or recipient of a WhatsApp message: a phone number, a business-scoped user ID, or both. A message received from a WhatsApp user carries whatever profile they publish, which may be neither.
          - `phone_number` string: Phone number in E.164 format, when known.
          - `bsuid` string: Business-scoped user ID, Meta's identifier for the WhatsApp user. Present only on the WhatsApp-user side of the message.
          - `group_id` string
          - `username` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the contact has not adopted one, and on a message received before this workspace started recording them. Same form as a number's own username (`WhatsAppNumberProfile.username`), without a leading `@`; a message cannot be addressed by it.
          - `display_name` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the message carries no profile, and on a message received before this workspace started recording them.
        - `to` WhatsAppAddress, required: Sender or recipient of a WhatsApp message: a phone number, a business-scoped user ID, or both. A message received from a WhatsApp user carries whatever profile they publish, which may be neither.
          - `phone_number` string: Phone number in E.164 format, when known.
          - `bsuid` string: Business-scoped user ID, Meta's identifier for the WhatsApp user. Present only on the WhatsApp-user side of the message.
          - `group_id` string
          - `username` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the contact has not adopted one, and on a message received before this workspace started recording them. Same form as a number's own username (`WhatsAppNumberProfile.username`), without a leading `@`; a message cannot be addressed by it.
          - `display_name` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the message carries no profile, and on a message received before this workspace started recording them.
        - `tags` Tag[], nullable, required: Tags from the send request, echoed on every event for the message. Null when the message was not sent through Bird, or its request carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object from the send request, echoed on every event for the message. Null when the message was not sent through Bird, or its request carried no metadata.
        - `in_reply_to_message_id` string
        - `origin` string: Where a message came from when it did not come through Bird live: its provenance. It does not say who answers the contact. On a number shared with the WhatsApp Business app, a message can come from the app while Bird keeps answering. - `business_agent_echo`: the Meta Business Agent on this number composed it. - `business_app_echo`: someone sent it from the WhatsApp Business app on a number shared with it. - `history_sync`: WhatsApp copied it, in either direction, from the WhatsApp Business app's chat history when the number was shared. Neither `/v1/whatsapp/messages` nor a webhook event reports an imported message, so neither carries this value.
    - EventWhatsAppDelivered: The message was delivered to the recipient's device.
      - `type` 'whatsapp.delivered', required: Event type.
      - `timestamp` string, date-time, required: Time the message was delivered to the recipient's device.
      - `data` EventWhatsAppDeliveredData, required: Identity fields shared by every WhatsApp lifecycle event payload.
        - `whatsapp_id` string, required
        - `workspace_id` string, required
        - `direction` 'outbound' | 'inbound', required: Whether the message was sent by the business (`outbound`) or received from the contact (`inbound`).
        - `from` WhatsAppAddress, required: Sender or recipient of a WhatsApp message: a phone number, a business-scoped user ID, or both. A message received from a WhatsApp user carries whatever profile they publish, which may be neither.
          - `phone_number` string: Phone number in E.164 format, when known.
          - `bsuid` string: Business-scoped user ID, Meta's identifier for the WhatsApp user. Present only on the WhatsApp-user side of the message.
          - `group_id` string
          - `username` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the contact has not adopted one, and on a message received before this workspace started recording them. Same form as a number's own username (`WhatsAppNumberProfile.username`), without a leading `@`; a message cannot be addressed by it.
          - `display_name` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the message carries no profile, and on a message received before this workspace started recording them.
        - `to` WhatsAppAddress, required: Sender or recipient of a WhatsApp message: a phone number, a business-scoped user ID, or both. A message received from a WhatsApp user carries whatever profile they publish, which may be neither.
          - `phone_number` string: Phone number in E.164 format, when known.
          - `bsuid` string: Business-scoped user ID, Meta's identifier for the WhatsApp user. Present only on the WhatsApp-user side of the message.
          - `group_id` string
          - `username` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the contact has not adopted one, and on a message received before this workspace started recording them. Same form as a number's own username (`WhatsAppNumberProfile.username`), without a leading `@`; a message cannot be addressed by it.
          - `display_name` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the message carries no profile, and on a message received before this workspace started recording them.
        - `tags` Tag[], nullable, required: Tags from the send request, echoed on every event for the message. Null when the message was not sent through Bird, or its request carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object from the send request, echoed on every event for the message. Null when the message was not sent through Bird, or its request carried no metadata.
        - `in_reply_to_message_id` string
        - `origin` string: Where a message came from when it did not come through Bird live: its provenance. It does not say who answers the contact. On a number shared with the WhatsApp Business app, a message can come from the app while Bird keeps answering. - `business_agent_echo`: the Meta Business Agent on this number composed it. - `business_app_echo`: someone sent it from the WhatsApp Business app on a number shared with it. - `history_sync`: WhatsApp copied it, in either direction, from the WhatsApp Business app's chat history when the number was shared. Neither `/v1/whatsapp/messages` nor a webhook event reports an imported message, so neither carries this value.
        - `recipient` WhatsAppAddress: Sender or recipient of a WhatsApp message: a phone number, a business-scoped user ID, or both. A message received from a WhatsApp user carries whatever profile they publish, which may be neither.
          - `phone_number` string: Phone number in E.164 format, when known.
          - `bsuid` string: Business-scoped user ID, Meta's identifier for the WhatsApp user. Present only on the WhatsApp-user side of the message.
          - `group_id` string
          - `username` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the contact has not adopted one, and on a message received before this workspace started recording them. Same form as a number's own username (`WhatsAppNumberProfile.username`), without a leading `@`; a message cannot be addressed by it.
          - `display_name` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the message carries no profile, and on a message received before this workspace started recording them.
    - EventWhatsAppFailed: Message delivery failed permanently.
      - `type` 'whatsapp.failed', required: Event type.
      - `timestamp` string, date-time, required: Time the failure was recorded.
      - `data` EventWhatsAppFailedData, required: Identity fields shared by every WhatsApp lifecycle event payload.
        - `whatsapp_id` string, required
        - `workspace_id` string, required
        - `direction` 'outbound' | 'inbound', required: Whether the message was sent by the business (`outbound`) or received from the contact (`inbound`).
        - `from` WhatsAppAddress, required: Sender or recipient of a WhatsApp message: a phone number, a business-scoped user ID, or both. A message received from a WhatsApp user carries whatever profile they publish, which may be neither.
          - `phone_number` string: Phone number in E.164 format, when known.
          - `bsuid` string: Business-scoped user ID, Meta's identifier for the WhatsApp user. Present only on the WhatsApp-user side of the message.
          - `group_id` string
          - `username` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the contact has not adopted one, and on a message received before this workspace started recording them. Same form as a number's own username (`WhatsAppNumberProfile.username`), without a leading `@`; a message cannot be addressed by it.
          - `display_name` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the message carries no profile, and on a message received before this workspace started recording them.
        - `to` WhatsAppAddress, required: Sender or recipient of a WhatsApp message: a phone number, a business-scoped user ID, or both. A message received from a WhatsApp user carries whatever profile they publish, which may be neither.
          - `phone_number` string: Phone number in E.164 format, when known.
          - `bsuid` string: Business-scoped user ID, Meta's identifier for the WhatsApp user. Present only on the WhatsApp-user side of the message.
          - `group_id` string
          - `username` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the contact has not adopted one, and on a message received before this workspace started recording them. Same form as a number's own username (`WhatsAppNumberProfile.username`), without a leading `@`; a message cannot be addressed by it.
          - `display_name` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the message carries no profile, and on a message received before this workspace started recording them.
        - `tags` Tag[], nullable, required: Tags from the send request, echoed on every event for the message. Null when the message was not sent through Bird, or its request carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object from the send request, echoed on every event for the message. Null when the message was not sent through Bird, or its request carried no metadata.
        - `in_reply_to_message_id` string
        - `origin` string: Where a message came from when it did not come through Bird live: its provenance. It does not say who answers the contact. On a number shared with the WhatsApp Business app, a message can come from the app while Bird keeps answering. - `business_agent_echo`: the Meta Business Agent on this number composed it. - `business_app_echo`: someone sent it from the WhatsApp Business app on a number shared with it. - `history_sync`: WhatsApp copied it, in either direction, from the WhatsApp Business app's chat history when the number was shared. Neither `/v1/whatsapp/messages` nor a webhook event reports an imported message, so neither carries this value.
        - `error` WhatsAppError, nullable, required: Failure detail for a message that could not be delivered or was rejected.
          - `code` string, required: Standardized failure reason: - `insufficient_balance`: The workspace wallet could not fund the send. - `price_not_found`: No price was configured for the destination and template. - `internal_error`: An unexpected service failure occurred. - `undeliverable`: The recipient could not be reached. - `service_window_expired`: The 24-hour service window closed; send a template. - `rate_limited`: The send was throttled. - `recipient_suppressed`: The recipient is on the workspace suppression list. - `media_rejected`: WhatsApp could not fetch the media URL, or refused the file it found there; `description` carries its reason. This is an open enum. Accept unrecognized values.
          - `description` string, required: Human-readable explanation of the failure.
          - `meta_error_code` string, nullable: Raw error code from the WhatsApp Cloud API, when available, for low-level debugging.
          - `occurred_at` string, date-time, required: When the failure occurred.
    - EventWhatsAppGroupJoinRequestCreated: Someone asked to join a group that requires approval.
      - `type` 'whatsapp.group.join_request_created', required: Always `whatsapp.group.join_request_created` for this event.
      - `timestamp` string, date-time, required: When the person asked to join.
      - `data` EventWhatsAppGroupJoinRequestData, required: Payload shared by the whatsapp.group.join_request_created and whatsapp.group.join_request_revoked events. Everything about the person who asked is nested under `join_request`; the sibling identifiers name the business side.
        - `group_id` string, required
        - `whatsapp_number_id` string, required
        - `workspace_id` string, required
        - `join_request` WhatsAppGroupJoinRequestSummary, required: Someone who asked to be let into a group, as named by a join-request webhook event.
          - `id` string, required
          - `bsuid` string, required: Business-scoped user ID, Meta's identifier for this person against your business. The one identifier every request has, and the one that carries over to `participants` if you approve it.
          - `phone_number` string, nullable, required: Phone number in E.164 format. Null when WhatsApp withholds it, which it does for anyone who has not shared their number with your business.
          - `username` string, nullable, required: The WhatsApp username this person chose. Null when they have none, and theirs to change, so it names them in a list rather than keying anything.
    - EventWhatsAppGroupJoinRequestRevoked: Someone withdrew their request to join a group before it was decided.
      - `type` 'whatsapp.group.join_request_revoked', required: Always `whatsapp.group.join_request_revoked` for this event.
      - `timestamp` string, date-time, required: When the person withdrew their request.
      - `data` EventWhatsAppGroupJoinRequestData, required: Payload shared by the whatsapp.group.join_request_created and whatsapp.group.join_request_revoked events. Everything about the person who asked is nested under `join_request`; the sibling identifiers name the business side.
        - `group_id` string, required
        - `whatsapp_number_id` string, required
        - `workspace_id` string, required
        - `join_request` WhatsAppGroupJoinRequestSummary, required: Someone who asked to be let into a group, as named by a join-request webhook event.
          - `id` string, required
          - `bsuid` string, required: Business-scoped user ID, Meta's identifier for this person against your business. The one identifier every request has, and the one that carries over to `participants` if you approve it.
          - `phone_number` string, nullable, required: Phone number in E.164 format. Null when WhatsApp withholds it, which it does for anyone who has not shared their number with your business.
          - `username` string, nullable, required: The WhatsApp username this person chose. Null when they have none, and theirs to change, so it names them in a list rather than keying anything.
    - EventWhatsAppReacted: A contact placed, changed or took back a reaction on a message.
      - `type` 'whatsapp.reacted', required: Always `whatsapp.reacted` for this event.
      - `timestamp` string, date-time, required: When the contact reacted, as reported by WhatsApp. Meta reports this to the second, so a contact who changes or withdraws a reaction quickly can produce two events sharing one timestamp. Sorting reactions on one message by this field cannot order those, and neither can delivery order, which retries make unreliable. Act on the reaction each event carries, as the change it describes; do not reconstruct the sequence from the events or treat the last one to arrive as the message's standing reaction. Read the message back for the reactions that stand: `getWhatsAppMessage` (`GET /v1/whatsapp/messages/{message_id}`) returns one entry per sender in `reactions`, and `listWhatsAppMessageReactionEvents` has every change.
      - `data` EventWhatsAppReactedData, required: Payload of the whatsapp.reacted event. Names the message the contact reacted to, not the reaction, because a reaction is an annotation on a message rather than a message of its own.
        - `whatsapp_id` string, required
        - `emoji` string, nullable, required: The emoji the contact placed, as WhatsApp sent it and not normalized. Null when they took their reaction back rather than placing one. Always present, so null is the removal itself rather than a value we are missing.
        - `from` WhatsAppAddress, required: Sender or recipient of a WhatsApp message: a phone number, a business-scoped user ID, or both. A message received from a WhatsApp user carries whatever profile they publish, which may be neither.
          - `phone_number` string: Phone number in E.164 format, when known.
          - `bsuid` string: Business-scoped user ID, Meta's identifier for the WhatsApp user. Present only on the WhatsApp-user side of the message.
          - `group_id` string
          - `username` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the contact has not adopted one, and on a message received before this workspace started recording them. Same form as a number's own username (`WhatsAppNumberProfile.username`), without a leading `@`; a message cannot be addressed by it.
          - `display_name` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the message carries no profile, and on a message received before this workspace started recording them.
        - `to` WhatsAppAddress, required: Sender or recipient of a WhatsApp message: a phone number, a business-scoped user ID, or both. A message received from a WhatsApp user carries whatever profile they publish, which may be neither.
          - `phone_number` string: Phone number in E.164 format, when known.
          - `bsuid` string: Business-scoped user ID, Meta's identifier for the WhatsApp user. Present only on the WhatsApp-user side of the message.
          - `group_id` string
          - `username` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the contact has not adopted one, and on a message received before this workspace started recording them. Same form as a number's own username (`WhatsAppNumberProfile.username`), without a leading `@`; a message cannot be addressed by it.
          - `display_name` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the message carries no profile, and on a message received before this workspace started recording them.
        - `workspace_id` string, required
    - EventWhatsAppRead: The recipient read the message.
      - `type` 'whatsapp.read', required: Event type.
      - `timestamp` string, date-time, required: Time the recipient read the message.
      - `data` EventWhatsAppReadData, required: Identity fields shared by every WhatsApp lifecycle event payload.
        - `whatsapp_id` string, required
        - `workspace_id` string, required
        - `direction` 'outbound' | 'inbound', required: Whether the message was sent by the business (`outbound`) or received from the contact (`inbound`).
        - `from` WhatsAppAddress, required: Sender or recipient of a WhatsApp message: a phone number, a business-scoped user ID, or both. A message received from a WhatsApp user carries whatever profile they publish, which may be neither.
          - `phone_number` string: Phone number in E.164 format, when known.
          - `bsuid` string: Business-scoped user ID, Meta's identifier for the WhatsApp user. Present only on the WhatsApp-user side of the message.
          - `group_id` string
          - `username` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the contact has not adopted one, and on a message received before this workspace started recording them. Same form as a number's own username (`WhatsAppNumberProfile.username`), without a leading `@`; a message cannot be addressed by it.
          - `display_name` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the message carries no profile, and on a message received before this workspace started recording them.
        - `to` WhatsAppAddress, required: Sender or recipient of a WhatsApp message: a phone number, a business-scoped user ID, or both. A message received from a WhatsApp user carries whatever profile they publish, which may be neither.
          - `phone_number` string: Phone number in E.164 format, when known.
          - `bsuid` string: Business-scoped user ID, Meta's identifier for the WhatsApp user. Present only on the WhatsApp-user side of the message.
          - `group_id` string
          - `username` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the contact has not adopted one, and on a message received before this workspace started recording them. Same form as a number's own username (`WhatsAppNumberProfile.username`), without a leading `@`; a message cannot be addressed by it.
          - `display_name` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the message carries no profile, and on a message received before this workspace started recording them.
        - `tags` Tag[], nullable, required: Tags from the send request, echoed on every event for the message. Null when the message was not sent through Bird, or its request carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object from the send request, echoed on every event for the message. Null when the message was not sent through Bird, or its request carried no metadata.
        - `in_reply_to_message_id` string
        - `origin` string: Where a message came from when it did not come through Bird live: its provenance. It does not say who answers the contact. On a number shared with the WhatsApp Business app, a message can come from the app while Bird keeps answering. - `business_agent_echo`: the Meta Business Agent on this number composed it. - `business_app_echo`: someone sent it from the WhatsApp Business app on a number shared with it. - `history_sync`: WhatsApp copied it, in either direction, from the WhatsApp Business app's chat history when the number was shared. Neither `/v1/whatsapp/messages` nor a webhook event reports an imported message, so neither carries this value.
        - `recipient` WhatsAppAddress: Sender or recipient of a WhatsApp message: a phone number, a business-scoped user ID, or both. A message received from a WhatsApp user carries whatever profile they publish, which may be neither.
          - `phone_number` string: Phone number in E.164 format, when known.
          - `bsuid` string: Business-scoped user ID, Meta's identifier for the WhatsApp user. Present only on the WhatsApp-user side of the message.
          - `group_id` string
          - `username` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the contact has not adopted one, and on a message received before this workspace started recording them. Same form as a number's own username (`WhatsAppNumberProfile.username`), without a leading `@`; a message cannot be addressed by it.
          - `display_name` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the message carries no profile, and on a message received before this workspace started recording them.
    - EventWhatsAppReceived: A contact sent the business a WhatsApp message. Not raised while the Meta Business Agent holds the conversation; the message is still stored and returned by the message reads.
      - `type` 'whatsapp.received', required: Event type.
      - `timestamp` string, date-time, required: Time the contact sent the message, as reported by WhatsApp.
      - `data` EventWhatsAppReceivedData, required: Identity fields shared by every WhatsApp lifecycle event payload.
        - `whatsapp_id` string, required
        - `workspace_id` string, required
        - `direction` 'outbound' | 'inbound', required: Whether the message was sent by the business (`outbound`) or received from the contact (`inbound`).
        - `from` WhatsAppAddress, required: Sender or recipient of a WhatsApp message: a phone number, a business-scoped user ID, or both. A message received from a WhatsApp user carries whatever profile they publish, which may be neither.
          - `phone_number` string: Phone number in E.164 format, when known.
          - `bsuid` string: Business-scoped user ID, Meta's identifier for the WhatsApp user. Present only on the WhatsApp-user side of the message.
          - `group_id` string
          - `username` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the contact has not adopted one, and on a message received before this workspace started recording them. Same form as a number's own username (`WhatsAppNumberProfile.username`), without a leading `@`; a message cannot be addressed by it.
          - `display_name` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the message carries no profile, and on a message received before this workspace started recording them.
        - `to` WhatsAppAddress, required: Sender or recipient of a WhatsApp message: a phone number, a business-scoped user ID, or both. A message received from a WhatsApp user carries whatever profile they publish, which may be neither.
          - `phone_number` string: Phone number in E.164 format, when known.
          - `bsuid` string: Business-scoped user ID, Meta's identifier for the WhatsApp user. Present only on the WhatsApp-user side of the message.
          - `group_id` string
          - `username` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the contact has not adopted one, and on a message received before this workspace started recording them. Same form as a number's own username (`WhatsAppNumberProfile.username`), without a leading `@`; a message cannot be addressed by it.
          - `display_name` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the message carries no profile, and on a message received before this workspace started recording them.
        - `tags` Tag[], nullable, required: Tags from the send request, echoed on every event for the message. Null when the message was not sent through Bird, or its request carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object from the send request, echoed on every event for the message. Null when the message was not sent through Bird, or its request carried no metadata.
        - `in_reply_to_message_id` string
        - `origin` string: Where a message came from when it did not come through Bird live: its provenance. It does not say who answers the contact. On a number shared with the WhatsApp Business app, a message can come from the app while Bird keeps answering. - `business_agent_echo`: the Meta Business Agent on this number composed it. - `business_app_echo`: someone sent it from the WhatsApp Business app on a number shared with it. - `history_sync`: WhatsApp copied it, in either direction, from the WhatsApp Business app's chat history when the number was shared. Neither `/v1/whatsapp/messages` nor a webhook event reports an imported message, so neither carries this value.
        - `text` WhatsAppText: Text content of a WhatsApp message.
          - `body` string, required: The message text.
        - `image` WhatsAppImage: Fields shared by every media content object on a WhatsApp message.
          - `id` string
          - `url` string, uri: Where to fetch the media. On an inbound message, or one from the WhatsApp Business app, this is a Bird URL you fetch with your API key; it is absent when the file could not be retrieved from WhatsApp. It stays populated after the stored bytes expire, and the link returns `410` from then on. On a message sent through Bird it is the URL the sender supplied, whose availability is the sender's to guarantee.
          - `mime_type` string: Media type WhatsApp reported for the file, for example `image/jpeg`. Absent on messages sent through Bird.
          - `caption` string: Text shown beneath the image. Absent when the sender wrote none.
        - `video` WhatsAppVideo: Fields shared by every media content object on a WhatsApp message.
          - `id` string
          - `url` string, uri: Where to fetch the media. On an inbound message, or one from the WhatsApp Business app, this is a Bird URL you fetch with your API key; it is absent when the file could not be retrieved from WhatsApp. It stays populated after the stored bytes expire, and the link returns `410` from then on. On a message sent through Bird it is the URL the sender supplied, whose availability is the sender's to guarantee.
          - `mime_type` string: Media type WhatsApp reported for the file, for example `image/jpeg`. Absent on messages sent through Bird.
          - `caption` string: Text shown beneath the video. Absent when the sender wrote none.
        - `audio` WhatsAppAudio: Fields shared by every media content object on a WhatsApp message.
          - `id` string
          - `url` string, uri: Where to fetch the media. On an inbound message, or one from the WhatsApp Business app, this is a Bird URL you fetch with your API key; it is absent when the file could not be retrieved from WhatsApp. It stays populated after the stored bytes expire, and the link returns `410` from then on. On a message sent through Bird it is the URL the sender supplied, whose availability is the sender's to guarantee.
          - `mime_type` string: Media type WhatsApp reported for the file, for example `image/jpeg`. Absent on messages sent through Bird.
          - `voice` boolean: Whether this is a voice note rather than an attached audio file. A voice note auto-downloads in the WhatsApp client and can be transcribed for the recipient.
        - `sticker` WhatsAppSticker: Fields shared by every media content object on a WhatsApp message.
          - `id` string
          - `url` string, uri: Where to fetch the media. On an inbound message, or one from the WhatsApp Business app, this is a Bird URL you fetch with your API key; it is absent when the file could not be retrieved from WhatsApp. It stays populated after the stored bytes expire, and the link returns `410` from then on. On a message sent through Bird it is the URL the sender supplied, whose availability is the sender's to guarantee.
          - `mime_type` string: Media type WhatsApp reported for the file, for example `image/jpeg`. Absent on messages sent through Bird.
          - `animated` boolean: Whether the sticker is animated. Absent on an outbound message.
        - `document` WhatsAppDocument: Fields shared by every media content object on a WhatsApp message.
          - `id` string
          - `url` string, uri: Where to fetch the media. On an inbound message, or one from the WhatsApp Business app, this is a Bird URL you fetch with your API key; it is absent when the file could not be retrieved from WhatsApp. It stays populated after the stored bytes expire, and the link returns `410` from then on. On a message sent through Bird it is the URL the sender supplied, whose availability is the sender's to guarantee.
          - `mime_type` string: Media type WhatsApp reported for the file, for example `image/jpeg`. Absent on messages sent through Bird.
          - `caption` string: Text shown beneath the document. Absent when the sender wrote none.
          - `filename` string: The sender's own name for the file.
        - `location` WhatsAppLocation: Location content of a WhatsApp message: a point on the map the recipient can open in their maps app.
          - `latitude` number, double: Latitude in decimal degrees.
          - `longitude` number, double: Longitude in decimal degrees.
          - `name` string: Name of the place. Absent when the sender shared a plain pin.
          - `address` string: Street address of the place. Shown only when `name` is also set.
          - `url` string, uri: Link to the place, which WhatsApp includes mainly for business locations. Present on an inbound message when the sender's client supplied one, and absent on a message you sent, since sending a location does not support this field.
        - `contact_cards` WhatsAppContactCard[]: Contact cards the contact shared, either by tapping a button that asked for their number or by sending a card from their address book.
          - `origin` string: Why the card arrived. `contact_request` means the contact tapped a button this workspace sent asking for their number, which is the only signal that the message answers that ask; `other` means they shared a card in the chat. Open enum: treat an unrecognized value as a way of sharing added since. Set on a card the contact shared; absent on one this workspace sent.
          - `vcard` string: The contact's card in vCard format. WhatsApp sends it on a card shared in the chat and omits it on a button tap, which carries the number alone. Set on a card the contact shared; absent on one this workspace sent.
          - `name` WhatsAppContactName: The contact's name, in the parts their device supplied. Every part is optional: WhatsApp sends what the card holds and omits the rest.
            - `formatted_name` string: The whole name as the contact's device renders it.
            - `first_name` string
            - `middle_name` string
            - `last_name` string
            - `prefix` string
            - `suffix` string
          - `org` WhatsAppContactOrg: Where the contact works, as their card records it.
            - `company` string
            - `department` string
            - `title` string
          - `birthday` string: The contact's birthday, which WhatsApp sends as `YYYY-MM-DD`. Passed through as text rather than typed as a date: the value comes off the contact's own device unvalidated, and a card we could not parse would otherwise have to lose the field or fail the whole read.
          - `phone_numbers` WhatsAppContactPhone[]: The numbers on the card. A button tap carries the contact's own number here, which is the point of asking.
            - `phone_number` string: The number as the card holds it, normalized to E.164 where we can parse it. A card is whatever the contact's device stored, so a number that no country's numbering plan accepts, an extension among them, is passed through exactly as it arrived rather than dropped. Parse defensively: most values are E.164 and none is guaranteed to be.
            - `type` string: The label attached to this value, for example `CELL`, `Home` or `iPhone`. Free text: WhatsApp defines no vocabulary. A label on a received card is lowercased; one this workspace sent reads back exactly as sent.
          - `emails` WhatsAppContactEmail[]
            - `email` string
            - `type` string: The label attached to this value, for example `CELL`, `Home` or `iPhone`. Free text: WhatsApp defines no vocabulary. A label on a received card is lowercased; one this workspace sent reads back exactly as sent.
          - `urls` WhatsAppContactUrl[]
            - `url` string: The address as the card holds it, which is often bare rather than a full URL, so it is passed through as text rather than validated.
            - `type` string: The label attached to this value, for example `CELL`, `Home` or `iPhone`. Free text: WhatsApp defines no vocabulary. A label on a received card is lowercased; one this workspace sent reads back exactly as sent.
          - `addresses` WhatsAppContactAddress[]
            - `street` string
            - `city` string
            - `state` string
            - `zip` string
            - `country` string
            - `country_code` string: The country as the card holds it, left exactly as WhatsApp sent it: it describes a postal address rather than a routing destination.
            - `type` string: The label attached to this value, for example `CELL`, `Home` or `iPhone`. Free text: WhatsApp defines no vocabulary. A label on a received card is lowercased; one this workspace sent reads back exactly as sent.
        - `interactive_reply` WhatsAppInteractiveReply: What the contact tapped, on an inbound message answering an interactive message or a template's quick-reply button. `type` names the kind and the field it names carries it, as everywhere else in this arm. Inbound only: a message that offers something to tap reads as `interactive` instead, and the two never appear together.
          - `type` string, required: Which kind of tap the reply came from. - `button`: a reply button on an interactive message, or a quick-reply button on a template. Both carry an identifier and a label, so they read the same way. - `list`: a row chosen from a list's menu. Only this kind carries a `description`. Open enum: WhatsApp adds interactive kinds over time, so treat an unrecognized value as a future kind rather than an error.
          - `button` WhatsAppInteractiveQuickReplyButton: A reply button's label and the handle it carries back. On the echo of a message Bird sent, the pair the send declared; on an inbound `interactive_reply`, the pair the contact tapped. No length is declared here, because a tap can echo a template's quick-reply button, whose label runs longer than an interactive message's own allows.
            - `slug` string, required: The handle the button carries back, never shown to the recipient. On a tap on a template's quick-reply button, it is the payload that template declared.
            - `text` string, required: The label the recipient saw.
          - `list` WhatsAppInteractiveListRow: One option in a list's menu. On the echo of a message Bird sent, the row as declared; on an inbound `interactive_reply`, the row the contact chose. No length is declared here: this is what WhatsApp reported, not what a send is held to.
            - `slug` string, required: The handle the row carries back, never shown to the recipient.
            - `text` string, required: The row's label, shown as its title in the menu.
            - `description` string: The second line under the label. Absent when the row carried none.
        - `unsupported` WhatsAppUnsupported: A message whose content we do not model, named so it is visible in the message log rather than arriving empty. Never on a message sent through Bird.
          - `type` string, required: The WhatsApp content type we did not model. `unsupported` is not a placeholder here: WhatsApp reports its own `unsupported` type for a message its own clients cannot render, and that arrives as this value. Open enum: WhatsApp adds content types over time, so treat an unrecognized value as a future type rather than an error.
    - EventWhatsAppRejected: The API rejected the message before sending it to WhatsApp because the recipient is on the workspace suppression list, the wallet has insufficient balance, or the destination is unpriced. The message is not sent or charged.
      - `type` 'whatsapp.rejected', required: Event type.
      - `timestamp` string, date-time, required: Time the rejection was recorded.
      - `data` EventWhatsAppRejectedData, required: Identity fields shared by every WhatsApp lifecycle event payload.
        - `whatsapp_id` string, required
        - `workspace_id` string, required
        - `direction` 'outbound' | 'inbound', required: Whether the message was sent by the business (`outbound`) or received from the contact (`inbound`).
        - `from` WhatsAppAddress, required: Sender or recipient of a WhatsApp message: a phone number, a business-scoped user ID, or both. A message received from a WhatsApp user carries whatever profile they publish, which may be neither.
          - `phone_number` string: Phone number in E.164 format, when known.
          - `bsuid` string: Business-scoped user ID, Meta's identifier for the WhatsApp user. Present only on the WhatsApp-user side of the message.
          - `group_id` string
          - `username` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the contact has not adopted one, and on a message received before this workspace started recording them. Same form as a number's own username (`WhatsAppNumberProfile.username`), without a leading `@`; a message cannot be addressed by it.
          - `display_name` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the message carries no profile, and on a message received before this workspace started recording them.
        - `to` WhatsAppAddress, required: Sender or recipient of a WhatsApp message: a phone number, a business-scoped user ID, or both. A message received from a WhatsApp user carries whatever profile they publish, which may be neither.
          - `phone_number` string: Phone number in E.164 format, when known.
          - `bsuid` string: Business-scoped user ID, Meta's identifier for the WhatsApp user. Present only on the WhatsApp-user side of the message.
          - `group_id` string
          - `username` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the contact has not adopted one, and on a message received before this workspace started recording them. Same form as a number's own username (`WhatsAppNumberProfile.username`), without a leading `@`; a message cannot be addressed by it.
          - `display_name` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the message carries no profile, and on a message received before this workspace started recording them.
        - `tags` Tag[], nullable, required: Tags from the send request, echoed on every event for the message. Null when the message was not sent through Bird, or its request carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object from the send request, echoed on every event for the message. Null when the message was not sent through Bird, or its request carried no metadata.
        - `in_reply_to_message_id` string
        - `origin` string: Where a message came from when it did not come through Bird live: its provenance. It does not say who answers the contact. On a number shared with the WhatsApp Business app, a message can come from the app while Bird keeps answering. - `business_agent_echo`: the Meta Business Agent on this number composed it. - `business_app_echo`: someone sent it from the WhatsApp Business app on a number shared with it. - `history_sync`: WhatsApp copied it, in either direction, from the WhatsApp Business app's chat history when the number was shared. Neither `/v1/whatsapp/messages` nor a webhook event reports an imported message, so neither carries this value.
        - `error` WhatsAppError, nullable, required: Failure detail for a message that could not be delivered or was rejected.
          - `code` string, required: Standardized failure reason: - `insufficient_balance`: The workspace wallet could not fund the send. - `price_not_found`: No price was configured for the destination and template. - `internal_error`: An unexpected service failure occurred. - `undeliverable`: The recipient could not be reached. - `service_window_expired`: The 24-hour service window closed; send a template. - `rate_limited`: The send was throttled. - `recipient_suppressed`: The recipient is on the workspace suppression list. - `media_rejected`: WhatsApp could not fetch the media URL, or refused the file it found there; `description` carries its reason. This is an open enum. Accept unrecognized values.
          - `description` string, required: Human-readable explanation of the failure.
          - `meta_error_code` string, nullable: Raw error code from the WhatsApp Cloud API, when available, for low-level debugging.
          - `occurred_at` string, date-time, required: When the failure occurred.
    - EventWhatsAppSent: The message was handed to Meta for delivery. Raised for a message your workspace sent through Bird, for one sent from the WhatsApp Business app on a number shared with it (`origin: business_app_echo`), and for one the Meta Business Agent sent on your number (`origin: business_agent_echo`).
      - `type` 'whatsapp.sent', required: Event type.
      - `timestamp` string, date-time, required: Time the message was handed to Meta for delivery.
      - `data` EventWhatsAppSentData, required: Identity fields shared by every WhatsApp lifecycle event payload.
        - `whatsapp_id` string, required
        - `workspace_id` string, required
        - `direction` 'outbound' | 'inbound', required: Whether the message was sent by the business (`outbound`) or received from the contact (`inbound`).
        - `from` WhatsAppAddress, required: Sender or recipient of a WhatsApp message: a phone number, a business-scoped user ID, or both. A message received from a WhatsApp user carries whatever profile they publish, which may be neither.
          - `phone_number` string: Phone number in E.164 format, when known.
          - `bsuid` string: Business-scoped user ID, Meta's identifier for the WhatsApp user. Present only on the WhatsApp-user side of the message.
          - `group_id` string
          - `username` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the contact has not adopted one, and on a message received before this workspace started recording them. Same form as a number's own username (`WhatsAppNumberProfile.username`), without a leading `@`; a message cannot be addressed by it.
          - `display_name` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the message carries no profile, and on a message received before this workspace started recording them.
        - `to` WhatsAppAddress, required: Sender or recipient of a WhatsApp message: a phone number, a business-scoped user ID, or both. A message received from a WhatsApp user carries whatever profile they publish, which may be neither.
          - `phone_number` string: Phone number in E.164 format, when known.
          - `bsuid` string: Business-scoped user ID, Meta's identifier for the WhatsApp user. Present only on the WhatsApp-user side of the message.
          - `group_id` string
          - `username` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the contact has not adopted one, and on a message received before this workspace started recording them. Same form as a number's own username (`WhatsAppNumberProfile.username`), without a leading `@`; a message cannot be addressed by it.
          - `display_name` string: Present only on a message received from a WhatsApp user, on `from`; never on an outbound send's `to`, where the profile is not known. Absent when the message carries no profile, and on a message received before this workspace started recording them.
        - `tags` Tag[], nullable, required: Tags from the send request, echoed on every event for the message. Null when the message was not sent through Bird, or its request carried no tags.
          - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
          - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
        - `metadata` object, nullable, required: The metadata object from the send request, echoed on every event for the message. Null when the message was not sent through Bird, or its request carried no metadata.
        - `in_reply_to_message_id` string
        - `origin` string: Where a message came from when it did not come through Bird live: its provenance. It does not say who answers the contact. On a number shared with the WhatsApp Business app, a message can come from the app while Bird keeps answering. - `business_agent_echo`: the Meta Business Agent on this number composed it. - `business_app_echo`: someone sent it from the WhatsApp Business app on a number shared with it. - `history_sync`: WhatsApp copied it, in either direction, from the WhatsApp Business app's chat history when the number was shared. Neither `/v1/whatsapp/messages` nor a webhook event reports an imported message, so neither carries this value.
    - EventWhatsAppSuppressionCreated: An address was added to the workspace's WhatsApp suppression ledger.
      - `type` 'whatsapp_suppression.created', required: Always `whatsapp_suppression.created` for this event.
      - `timestamp` string, date-time, required: When the episode's opening statement took effect (`effective_at`).
      - `data` EventWhatsAppSuppressionCreatedData, required: Payload of the whatsapp_suppression.created event.
        - `suppression_id` string, required
        - `address` string, required: The suppressed WhatsApp address. For a phone number this is canonical E.164 with a leading plus sign, such as `+5511977670804`.
        - `waba` string, nullable, required: The WhatsApp Business Account the suppression is limited to, identified by its WhatsApp-issued account ID, or null when it covers the whole workspace.
        - `reason` string, required: Why the address is suppressed. `manual` means it was added directly rather than created automatically from a delivery outcome. This list grows over time, so treat an unknown value as informational rather than rejecting the record.
        - `workspace_id` string, required
  - `error` string: A short explanation of why the event could not be delivered. Present only when your endpoint could not be reached.

## Other responses

- `400`: Bad request
- `401`: Authentication required
- `403`: Insufficient permissions
- `404`: Resource not found
- `412`: Precondition failed
- `422`: The request has invalid field values, violates a business rule, or carries a query parameter the endpoint does not declare. Field validation errors use `type: validation_error` and include the affected fields in `details`. Business-rule errors identify the failed rule in `type`.
- `429`: Rate limit exceeded
- `500`: Internal server error
- `503`: The service is temporarily unavailable. If `Retry-After` is present, wait for that delay before retrying; otherwise, retry with exponential backoff. Reuse the same idempotency key and request when retrying a mutation.

---

[API](https://skmtc.dev/messagebird/apis/bird-api.md) · [All operations](https://skmtc.dev/messagebird/apis/bird-api/llms.txt) · [OpenAPI document](https://skmtc.dev/messagebird/apis/bird-api/revisions/6dfce1179799?raw)
