openapi: 3.2.0 info: title: Bird Webhooks API version: '1.0' description: 'Operations tagged webhooks across 2 of this provider''s published API definitions: messagebird-bird-api-openapi.yml, messagebird-webhooks-api-openapi.yml. Each path carries the servers of the definition it was published in.' servers: - url: https://{region}.platform.bird.com description: 'Regional API endpoint. Use the host for the region your organization is hosted in. Official Bird SDKs and the CLI select it automatically from your API key, so you rarely need to set it by hand. ' variables: region: default: us1 enum: - us1 - eu1 description: The region your organization's data is hosted in. - url: https://platform.bird.com description: Region-independent endpoint for authentication and account administration. - url: http://localhost:8080 description: Local development. - url: https://conversations.messagebird.com/v1 description: Production Server - url: https://voice.messagebird.com description: Production Server tags: - name: Webhooks description: Webhook endpoint management. paths: /v1/webhooks: post: operationId: createWebhook summary: Create a webhook endpoint description: 'Registers an `active` webhook endpoint that receives the event types in `events` as signed HTTPS `POST` requests. See the webhooks guide for delivery, signing, and retry behavior. The `201` response is the only response that includes the signing secret (`whsec_` prefix). Store it immediately; if it is lost, rotate the signing secret. A non-HTTPS or non-public `url`, an unknown event type, or exceeding the organization''s endpoint limit returns `422`.' tags: - Webhooks security: - BearerAuth: [] - CookieAuth: [] x-snippet-key: webhooks.create x-audiences: - public - command parameters: - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/WebhookEndpointCreate' responses: '201': description: Created webhook endpoint, including its one-time signing secret. headers: Idempotency-Replay: $ref: '#/components/headers/IdempotencyReplay' content: application/json: schema: $ref: '#/components/schemas/WebhookEndpointCreated' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '422': $ref: '#/components/responses/Unprocessable' '429': $ref: '#/components/responses/RateLimited' '500': $ref: '#/components/responses/InternalError' '503': $ref: '#/components/responses/ServiceUnavailable' x-surfaces: - cli - mcp - n8n - sdk get: operationId: listWebhooks summary: List webhook endpoints description: Returns the workspace's webhook endpoints as a cursor-paginated list, newest first by default. Endpoint objects never include the signing secret; to inspect a single endpoint, use Get a webhook endpoint. tags: - Webhooks security: - BearerAuth: [] - CookieAuth: [] x-snippet-key: webhooks.list x-audiences: - public - command parameters: - name: sort in: query required: false schema: $ref: '#/components/schemas/WebhookSortField' - $ref: '#/components/parameters/OrderDesc' - $ref: '#/components/parameters/PaginationLimit' - $ref: '#/components/parameters/StartingAfter' - $ref: '#/components/parameters/EndingBefore' - $ref: '#/components/parameters/IncludeTotal' responses: '200': description: Paginated list of webhook endpoints. content: application/json: schema: $ref: '#/components/schemas/WebhookEndpointList' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '422': $ref: '#/components/responses/Unprocessable' '429': $ref: '#/components/responses/RateLimited' '500': $ref: '#/components/responses/InternalError' x-surfaces: - cli - mcp - n8n - sdk servers: - url: https://{region}.platform.bird.com description: 'Regional API endpoint. Use the host for the region your organization is hosted in. Official Bird SDKs and the CLI select it automatically from your API key, so you rarely need to set it by hand. ' variables: region: default: us1 enum: - us1 - eu1 description: The region your organization's data is hosted in. - url: https://platform.bird.com description: Region-independent endpoint for authentication and account administration. - url: http://localhost:8080 description: Local development. /v1/webhooks/{webhook_id}: parameters: - name: webhook_id in: path required: true description: ID of the webhook endpoint (`whk_` prefix), as returned when it was created. schema: $ref: '#/components/schemas/WebhookEndpointID' example: whk_01krdgeqcxet5s7t44vh8rt9mg get: operationId: getWebhook summary: Get a webhook endpoint description: Returns one webhook endpoint's configuration and current delivery `status`, including its URL and subscribed event types. The signing secret is never included; if you lost it, mint a new one with Rotate webhook signing secret. tags: - Webhooks security: - BearerAuth: [] - CookieAuth: [] x-snippet-key: webhooks.get x-audiences: - public - command responses: '200': description: Webhook endpoint with its current URL, subscriptions, and status. content: application/json: schema: $ref: '#/components/schemas/WebhookEndpoint' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '422': $ref: '#/components/responses/Unprocessable' '429': $ref: '#/components/responses/RateLimited' '500': $ref: '#/components/responses/InternalError' x-surfaces: - cli - mcp - n8n - sdk patch: operationId: updateWebhook summary: Update a webhook endpoint description: 'Updates the webhook endpoint. Only the fields you send change: `events` replaces the whole subscription set, and `status` pauses or re-enables delivery. The `200` response is the updated endpoint. Invalid input (a non-HTTPS or non-public `url`, an event type outside the catalog) returns a `422`.' tags: - Webhooks security: - BearerAuth: [] - CookieAuth: [] x-snippet-key: webhooks.update x-audiences: - public - command parameters: - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/WebhookEndpointUpdate' responses: '200': description: Webhook endpoint after the update. content: application/json: schema: $ref: '#/components/schemas/WebhookEndpoint' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '422': $ref: '#/components/responses/Unprocessable' '429': $ref: '#/components/responses/RateLimited' '500': $ref: '#/components/responses/InternalError' '503': $ref: '#/components/responses/ServiceUnavailable' x-surfaces: - cli - mcp - n8n - sdk delete: operationId: deleteWebhook summary: Delete a webhook endpoint description: 'Permanently removes the webhook endpoint and stops all deliveries to it, including retries of earlier failed deliveries. This cannot be undone: recreating an endpoint later mints a new `id` and signing secret. To stop deliveries temporarily instead, set `status` to `paused` with Update a webhook endpoint.' tags: - Webhooks security: - BearerAuth: [] - CookieAuth: [] x-snippet-key: webhooks.delete x-audiences: - public - command parameters: - $ref: '#/components/parameters/IdempotencyKey' responses: '204': description: Webhook endpoint deleted. '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '422': $ref: '#/components/responses/Unprocessable' '429': $ref: '#/components/responses/RateLimited' '500': $ref: '#/components/responses/InternalError' '503': $ref: '#/components/responses/ServiceUnavailable' x-surfaces: - cli - mcp - n8n - sdk servers: - url: https://{region}.platform.bird.com description: 'Regional API endpoint. Use the host for the region your organization is hosted in. Official Bird SDKs and the CLI select it automatically from your API key, so you rarely need to set it by hand. ' variables: region: default: us1 enum: - us1 - eu1 description: The region your organization's data is hosted in. - url: https://platform.bird.com description: Region-independent endpoint for authentication and account administration. - url: http://localhost:8080 description: Local development. /v1/webhooks/{webhook_id}/rotate-secret: parameters: - name: webhook_id in: path required: true description: ID of the webhook endpoint (`whk_` prefix), as returned when it was created. schema: $ref: '#/components/schemas/WebhookEndpointID' example: whk_01krdgeqcxet5s7t44vh8rt9mg post: operationId: rotateWebhookSecret summary: Rotate webhook signing secret description: 'Generates a new signing secret for the endpoint and returns it exactly once: store it immediately, it cannot be retrieved after this response. For 24 hours every delivery is signed with both the old and the new secret, so a receiver verifying with either keeps working while you roll the new one out. After the window the old secret stops signing. Verification details are in the webhooks guide. An endpoint holds at most 5 concurrently valid secrets, so rotating repeatedly within the overlap window fails with `WebhookTooManySecrets` until an older secret expires.' tags: - Webhooks security: - BearerAuth: [] - CookieAuth: [] x-snippet-key: webhooks.rotate_secret x-audiences: - public - command parameters: - $ref: '#/components/parameters/IdempotencyKey' responses: '200': description: New signing secret. content: application/json: schema: $ref: '#/components/schemas/WebhookRotateSecretResponse' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '422': $ref: '#/components/responses/Unprocessable' '429': $ref: '#/components/responses/RateLimited' '500': $ref: '#/components/responses/InternalError' '503': $ref: '#/components/responses/ServiceUnavailable' x-surfaces: - cli - mcp - n8n - sdk servers: - url: https://{region}.platform.bird.com description: 'Regional API endpoint. Use the host for the region your organization is hosted in. Official Bird SDKs and the CLI select it automatically from your API key, so you rarely need to set it by hand. ' variables: region: default: us1 enum: - us1 - eu1 description: The region your organization's data is hosted in. - url: https://platform.bird.com description: Region-independent endpoint for authentication and account administration. - url: http://localhost:8080 description: Local development. /v1/webhooks/{webhook_id}/test: parameters: - name: webhook_id in: path required: true description: ID of the webhook endpoint (`whk_` prefix), as returned when it was created. schema: $ref: '#/components/schemas/WebhookEndpointID' example: whk_01krdgeqcxet5s7t44vh8rt9mg post: operationId: testWebhook summary: Test a webhook with a sample event description: '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. 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.' tags: - Webhooks security: - BearerAuth: [] - CookieAuth: [] x-snippet-key: webhooks.test x-audiences: - public - command parameters: - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/WebhookTestRequest' responses: '200': description: The test result, including whether your endpoint accepted the event. content: application/json: schema: $ref: '#/components/schemas/WebhookTestResponse' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '412': $ref: '#/components/responses/PreconditionFailed' '422': $ref: '#/components/responses/Unprocessable' '429': $ref: '#/components/responses/RateLimited' '500': $ref: '#/components/responses/InternalError' '503': $ref: '#/components/responses/ServiceUnavailable' x-surfaces: - cli - mcp - n8n - sdk servers: - url: https://{region}.platform.bird.com description: 'Regional API endpoint. Use the host for the region your organization is hosted in. Official Bird SDKs and the CLI select it automatically from your API key, so you rarely need to set it by hand. ' variables: region: default: us1 enum: - us1 - eu1 description: The region your organization's data is hosted in. - url: https://platform.bird.com description: Region-independent endpoint for authentication and account administration. - url: http://localhost:8080 description: Local development. /v1/webhooks/{webhook_id}/replay: parameters: - name: webhook_id in: path required: true description: ID of the webhook endpoint (`whk_` prefix), as returned when it was created. schema: $ref: '#/components/schemas/WebhookEndpointID' example: whk_01krdgeqcxet5s7t44vh8rt9mg post: operationId: createWebhookReplay summary: Replay failed deliveries description: 'Queues redelivery of deliveries that failed. The window runs from `since` (default: the last 24 hours) to `until`, and events the endpoint already received successfully are skipped, so a replay never double-delivers. Only failed attempts are replayed. An event the endpoint was never sent, such as one that arrived while it was paused, has no failed attempt to replay, so a replay does not recover it. The `202` response means the replay is queued. Events are redelivered asynchronously and retried like any other delivery; no count or task ID is returned, so track results with List delivery attempts. Replays are limited to 20 per organization per UTC day; beyond that the request returns a `429` `WebhookReplayQuotaExceeded`.' tags: - Webhooks security: - BearerAuth: [] - CookieAuth: [] x-audiences: - public parameters: - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/WebhookReplayRequest' responses: '202': description: Replay queued. Events are redelivered asynchronously; no count or task ID is returned. '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '422': $ref: '#/components/responses/Unprocessable' '429': $ref: '#/components/responses/RateLimited' '500': $ref: '#/components/responses/InternalError' '503': $ref: '#/components/responses/ServiceUnavailable' x-surfaces: - n8n servers: - url: https://{region}.platform.bird.com description: 'Regional API endpoint. Use the host for the region your organization is hosted in. Official Bird SDKs and the CLI select it automatically from your API key, so you rarely need to set it by hand. ' variables: region: default: us1 enum: - us1 - eu1 description: The region your organization's data is hosted in. - url: https://platform.bird.com description: Region-independent endpoint for authentication and account administration. - url: http://localhost:8080 description: Local development. /v1/webhooks/{webhook_id}/attempts: parameters: - name: webhook_id in: path required: true description: ID of the webhook endpoint (`whk_` prefix), as returned when it was created. schema: $ref: '#/components/schemas/WebhookEndpointID' example: whk_01krdgeqcxet5s7t44vh8rt9mg get: operationId: listWebhookAttempts summary: List delivery attempts description: 'Returns the endpoint''s recent delivery attempts, newest first. Each entry is one HTTP request, so a retried event appears once per try; use it to see what failed and why before requesting redelivery with Replay failed deliveries. Bound the window with the `before`/`after` timestamps and cap the page with `limit`. To page further back without a cursor, pass the oldest `attempted_at` you received as `before`.' tags: - Webhooks security: - BearerAuth: [] - CookieAuth: [] x-snippet-key: webhooks.attempts x-audiences: - public - command parameters: - name: limit in: query required: false description: Maximum number of attempts to return. Defaults to 50, capped at 100. schema: type: integer minimum: 1 maximum: 100 default: 50 - name: before in: query required: false description: Only return attempts strictly before this timestamp. schema: type: string format: date-time minLength: 1 - name: after in: query required: false description: Only return attempts strictly after this timestamp. schema: type: string format: date-time minLength: 1 responses: '200': description: Recent delivery attempts. content: application/json: schema: $ref: '#/components/schemas/WebhookAttemptList' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '422': $ref: '#/components/responses/Unprocessable' '429': $ref: '#/components/responses/RateLimited' '500': $ref: '#/components/responses/InternalError' x-surfaces: - cli - mcp - n8n - sdk servers: - url: https://{region}.platform.bird.com description: 'Regional API endpoint. Use the host for the region your organization is hosted in. Official Bird SDKs and the CLI select it automatically from your API key, so you rarely need to set it by hand. ' variables: region: default: us1 enum: - us1 - eu1 description: The region your organization's data is hosted in. - url: https://platform.bird.com description: Region-independent endpoint for authentication and account administration. - url: http://localhost:8080 description: Local development. /webhooks: servers: - url: https://conversations.messagebird.com/v1 description: Production Server get: operationId: getWebhooks summary: List webhooks description: Retrieves a list of all configured conversation webhooks. The platform supports up to 10 channel-specific webhooks and 5 generic webhooks. tags: - Webhooks parameters: - $ref: '#/components/parameters/offsetParam' - $ref: '#/components/parameters/limitParam' responses: '200': description: A list of webhooks content: application/json: schema: $ref: '#/components/schemas/WebhookList' '401': description: Unauthorized security: - accessKey: [] x-operation-id-source: normalized x-operation-id-original: listWebhooks post: operationId: postWebhooks summary: Create a webhook description: Creates a new webhook to receive real-time notifications for conversation events. Webhooks can be channel-specific or generic. tags: - Webhooks requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/WebhookCreate' responses: '200': description: Webhook created content: application/json: schema: $ref: '#/components/schemas/Webhook' '400': description: Bad request '401': description: Unauthorized security: - accessKey: [] x-operation-id-source: normalized x-operation-id-original: createWebhook /webhooks/{webhookId}: servers: - url: https://conversations.messagebird.com/v1 description: Production Server get: operationId: viewWebhook summary: View a webhook description: Retrieves the details of a specific webhook by its unique identifier. tags: - Webhooks parameters: - $ref: '#/components/parameters/webhookIdParam' responses: '200': description: Webhook details content: application/json: schema: $ref: '#/components/schemas/Webhook' '401': description: Unauthorized '404': description: Webhook not found security: - accessKey: [] patch: operationId: patchWebhooksByWebhookId summary: Update a webhook description: Updates the configuration of an existing webhook. tags: - Webhooks parameters: - $ref: '#/components/parameters/webhookIdParam' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/WebhookCreate' responses: '200': description: Webhook updated content: application/json: schema: $ref: '#/components/schemas/Webhook' '400': description: Bad request '401': description: Unauthorized '404': description: Webhook not found security: - accessKey: [] x-operation-id-source: normalized x-operation-id-original: updateWebhook delete: operationId: deleteWebhooksByWebhookId summary: Delete a webhook description: Deletes an existing webhook by its unique identifier. tags: - Webhooks parameters: - $ref: '#/components/parameters/webhookIdParam' responses: '204': description: Webhook deleted '401': description: Unauthorized '404': description: Webhook not found security: - accessKey: [] x-operation-id-source: normalized x-operation-id-original: deleteWebhook put: operationId: updateVoiceWebhook summary: Update a voice webhook description: Updates an existing voice webhook configuration. tags: - Webhooks parameters: - $ref: '#/components/parameters/webhookIdParam' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/VoiceWebhookCreate' responses: '200': description: Webhook updated content: application/json: schema: $ref: '#/components/schemas/VoiceWebhookResponse' '400': description: Bad request '401': description: Unauthorized '404': description: Webhook not found security: - accessKey: [] components: schemas: WebhookEventType: type: string minLength: 1 description: 'Webhook event type. This is an open enum, so accept unrecognized values in deliveries. Subscribing to a type outside the event catalog returns a `422`. ' x-extensible-enum: - domain.failed - domain.verified - email.accepted - email.bounced - email.canceled - email.clicked - email.complained - email.deferred - email.delivered - email.list_unsubscribed - email.opened - email.out_of_band_bounce - email.processed - email.received - email.rejected - email.scheduled - email.unsubscribed - email_mailbox.message_delivered - email_mailbox.message_failed - email_mailbox.message_received - email_mailbox.message_sent - email_mailbox.suspended - email_mailbox.thread_created - email_suppression.created - preference.deleted - preference.granted - preference.revoked - sms.accepted - sms.delivered - sms.expired - sms.failed - sms.received - sms.rejected - sms.sent - sms.undelivered - sms_suppression.created - verify.attempt.delivered - verify.attempt.sent - verify.attempt.undelivered - verify.verification.created - verify.verification.failed - verify.verification.verified - voice_call.answered - voice_call.ended - voice_call.initiated - whatsapp.accepted - whatsapp.delivered - whatsapp.failed - whatsapp.reacted - whatsapp.read - whatsapp.received - whatsapp.rejected - whatsapp.sent - whatsapp_suppression.created EventSMSFailedData: type: object description: Payload of the sms.failed event. allOf: - $ref: '#/components/schemas/EventSMSBase' - type: object required: - error properties: error: $ref: '#/components/schemas/SMSError' description: Why the message terminally failed. EventSMSReceived: type: object additionalProperties: false description: A message was received on one of your numbers. required: - type - timestamp - data properties: type: $ref: '#/components/schemas/SMSReceivedEventType' timestamp: type: string minLength: 1 format: date-time description: Time the sender sent the message. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventSMSReceivedData' SMSTemplateID: type: string minLength: 1 pattern: ^smt_[0-9a-hjkmnp-tv-z]{26}$ example: smt_01krdgeqcxet5s7t44vh8rt9mg WhatsAppContactCard: type: object additionalProperties: false description: 'A contact card on this message: one the contact shared, or one this workspace sent. Nothing here is required. WhatsApp sends the parts the card holds and omits the rest, and a card that arrives with only an `origin` is still meaningful, so an empty card reads back empty rather than being dropped. ' properties: origin: type: string minLength: 1 x-extensible-enum: - contact_request - other description: '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. ' example: contact_request vcard: type: string description: '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. ' example: 'BEGIN:VCARD VERSION:3.0 N:Johnson;Barbara;;; TEL;type=CELL:+16505551234 END:VCARD ' name: allOf: - $ref: '#/components/schemas/WhatsAppContactName' description: The contact's name, when the card carries one. org: allOf: - $ref: '#/components/schemas/WhatsAppContactOrg' description: Where the contact works, when the card carries it. birthday: type: string description: '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. ' example: '1999-01-23' phone_numbers: type: array description: 'The numbers on the card. A button tap carries the contact''s own number here, which is the point of asking. ' items: $ref: '#/components/schemas/WhatsAppContactPhone' emails: type: array items: $ref: '#/components/schemas/WhatsAppContactEmail' urls: type: array items: $ref: '#/components/schemas/WhatsAppContactUrl' addresses: type: array items: $ref: '#/components/schemas/WhatsAppContactAddress' example: origin: contact_request phone_numbers: - phone_number: '+16505551234' type: CELL EventEmailListUnsubscribedData: type: object description: Payload of the email.list_unsubscribed event. allOf: - $ref: '#/components/schemas/EventEmailBase' SMSMessageID: type: string minLength: 1 pattern: ^sms_[0-9a-hjkmnp-tv-z]{26}$ example: sms_01krdgeqcxet5s7t44vh8rt9mg WhatsAppErrorCode: type: string minLength: 1 x-extensible-enum: - insufficient_balance - price_not_found - internal_error - undeliverable - service_window_expired - rate_limited - recipient_suppressed - media_rejected description: '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. ' EventEmailProcessedData: type: object description: Payload of the email.processed event. allOf: - $ref: '#/components/schemas/EventEmailBase' CurrencyCode: type: string minLength: 3 maxLength: 3 pattern: ^[A-Z]{3}$ description: ISO 4217 three-letter currency code. example: EUR EventEmailListUnsubscribed: type: object additionalProperties: false description: Recipient unsubscribed via the RFC 8058 one-click List-Unsubscribe mechanism. Fires once per recipient. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - email.list_unsubscribed description: Event type. example: email.list_unsubscribed timestamp: type: string minLength: 1 format: date-time description: Time the unsubscribe was recorded. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventEmailListUnsubscribedData' LanguageTag: type: string minLength: 2 maxLength: 35 description: A language tag in BCP-47 form, for example `en` or `pt-BR`. example: pt-BR WebhookEndpointID: type: string minLength: 1 pattern: ^whk_[0-9a-hjkmnp-tv-z]{26}$ example: whk_01krdgeqcxet5s7t44vh8rt9mg WhatsAppMessageID: type: string minLength: 1 pattern: ^wam_[0-9a-hjkmnp-tv-z]{26}$ example: wam_01krdgeqcxet5s7t44vh8rt9mg EventEmailReceivedData: type: object additionalProperties: false description: Payload of the email.received event. required: - inbound_message_id - workspace_id - message_id - from - to - subject properties: inbound_message_id: $ref: '#/components/schemas/InboundEmailMessageID' description: ID of the received email. Fetch its parsed metadata with `GET /v1/email/inbound-messages/{id}`, and its content from that message's `/body`, `/raw`, and `/attachments` sub-resources. workspace_id: $ref: '#/components/schemas/WorkspaceID' description: ID of the workspace that owns this event. message_id: type: - string - 'null' description: RFC 5322 Message-ID header from the sender, or null when the sender did not include one. example: from: type: string minLength: 1 format: email description: 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. example: alice@example.com to: type: array items: type: string format: email description: Recipient addresses the message was sent to. example: - support@acme.com subject: type: - string - 'null' description: Subject line as received, or null when the message had no subject. example: Welcome to Bird in_reply_to: type: - string - 'null' description: '`In-Reply-To` header containing the `Message-ID` this message replies to, or null when it is not a reply.' example: authentication: type: - string - 'null' enum: - pass - fail - unknown - null description: '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: type: - boolean - 'null' description: 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: type: - boolean - 'null' description: 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: type: - boolean - 'null' description: 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: type: - number - 'null' description: Content spam score when available. The receiving provider currently supplies no score, so this is `null`. EventPreferenceDeleted: type: object additionalProperties: false description: A stated preference was deleted, superseding it in the ledger without erasing its history. required: - type - timestamp - data properties: type: $ref: '#/components/schemas/PreferenceDeletedEventType' timestamp: type: string minLength: 1 format: date-time description: When the delete took effect (`effective_at`), not when it was recorded. example: '2026-08-12T12:00:00Z' data: $ref: '#/components/schemas/EventPreferenceDeletedData' EventEmailBounced: type: object additionalProperties: false description: An outbound email permanently failed at the recipient's mail server. Fires once per recipient. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - email.bounced description: Event type. example: email.bounced timestamp: type: string minLength: 1 format: date-time description: Time the bounce was recorded. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventEmailBouncedData' EventVoiceCallInitiatedData: type: object description: Payload of the voice_call.initiated event. allOf: - $ref: '#/components/schemas/EventVoiceBase' EventSMSRejected: type: object additionalProperties: false description: The API rejected the message before sending it to the carrier because of an invalid destination, suppression, or content or policy restriction. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - sms.rejected description: Event type. example: sms.rejected timestamp: type: string minLength: 1 format: date-time description: Time the rejection was recorded. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventSMSRejectedData' EventEmailScheduled: type: object additionalProperties: false description: The API accepted an email scheduled for a future time. Fires once per message when the schedule is created. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - email.scheduled description: Event type. example: email.scheduled timestamp: type: string minLength: 1 format: date-time description: Time the send was scheduled. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventEmailScheduledData' EventPreferenceGranted: type: object additionalProperties: false description: A stated preference was granted (a person consented, or a customer wrote a grant) and became the key's live statement. required: - type - timestamp - data properties: type: $ref: '#/components/schemas/PreferenceGrantedEventType' timestamp: type: string minLength: 1 format: date-time description: When the statement took effect (`effective_at`), not when it was recorded. example: '2026-08-12T12:00:00Z' data: $ref: '#/components/schemas/EventPreferenceGrantedData' EventWhatsAppDeliveredData: type: object description: Payload of the whatsapp.delivered event. allOf: - $ref: '#/components/schemas/EventWhatsAppBase' - type: object properties: recipient: allOf: - $ref: '#/components/schemas/WhatsAppAddress' description: 'The participant delivery was confirmed to, on a group message. A group send raises this event once per participant, so this is what tells the deliveries apart. Absent on a one-to-one message, whose `to` already names its recipient. ' EventPreferenceRevoked: type: object additionalProperties: false description: A stated preference was revoked (a person opted out, or a customer wrote a revoke) and became the key's live statement. required: - type - timestamp - data properties: type: $ref: '#/components/schemas/PreferenceRevokedEventType' timestamp: type: string minLength: 1 format: date-time description: When the statement took effect (`effective_at`), not when it was recorded. example: '2026-08-12T12:00:00Z' data: $ref: '#/components/schemas/EventPreferenceRevokedData' EventWhatsAppRejected: type: object additionalProperties: false description: 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. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - whatsapp.rejected description: Event type. example: whatsapp.rejected timestamp: type: string minLength: 1 format: date-time description: Time the rejection was recorded. example: '2026-07-23T12:00:00Z' data: $ref: '#/components/schemas/EventWhatsAppRejectedData' EventEmailSuppressionCreated: type: object additionalProperties: false description: An email address was added to the workspace's suppression list (manually, via complaint, or via hard bounce). required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - email_suppression.created description: Event type. example: email_suppression.created timestamp: type: string minLength: 1 format: date-time description: When the event occurred. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventEmailSuppressionCreatedData' EventWhatsAppDelivered: type: object additionalProperties: false description: The message was delivered to the recipient's device. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - whatsapp.delivered description: Event type. example: whatsapp.delivered timestamp: type: string minLength: 1 format: date-time description: Time the message was delivered to the recipient's device. example: '2026-07-16T12:00:00Z' data: $ref: '#/components/schemas/EventWhatsAppDeliveredData' EventWhatsAppReacted: type: object additionalProperties: false description: A contact placed, changed or took back a reaction on a message. required: - type - timestamp - data properties: type: $ref: '#/components/schemas/WhatsAppReactedEventType' timestamp: type: string minLength: 1 format: date-time description: '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. ' example: '2026-08-28T19:01:10Z' data: $ref: '#/components/schemas/EventWhatsAppReactedData' EventSMSAccepted: type: object additionalProperties: false description: The API accepted the SMS send request and queued it for processing. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - sms.accepted description: Event type. example: sms.accepted timestamp: type: string minLength: 1 format: date-time description: Time the API accepted the request. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventSMSAcceptedData' ContactID: type: string minLength: 1 pattern: ^con_[0-9a-hjkmnp-tv-z]{26}$ example: con_01krdgeqcxet5s7t44vh8rt9mg SMSReceivedEventType: type: string minLength: 1 enum: - sms.received description: Always `sms.received` for this event. example: sms.received EventVerifyAttemptSent: type: object additionalProperties: false description: A one-time passcode was dispatched to the recipient on a channel. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - verify.attempt.sent description: Event type. example: verify.attempt.sent timestamp: type: string minLength: 1 format: date-time description: Time the passcode was dispatched. example: '2026-07-24T12:00:01Z' data: $ref: '#/components/schemas/EventVerifyAttemptSentData' EventSMSReceivedData: type: object description: Payload of the sms.received event. allOf: - $ref: '#/components/schemas/EventSMSBase' - type: object required: - segments anyOf: - required: - text - required: - media properties: text: type: string minLength: 1 description: 'The message body, so you can act on it without a follow-up read. Absent when the message carried only attachments and no text of its own. ' example: STOP segments: $ref: '#/components/schemas/SMSSegments' description: Segment breakdown of the received body. carrier: type: string description: Carrier the message came in over. Absent where the carrier does not report one. example: Verizon mcc_mnc: type: string description: Mobile country code and mobile network code of the carrier. Absent when not known. example: '311480' subject: type: string description: Subject line. Absent when the message carried none. WhatsAppReactedEventType: type: string minLength: 1 enum: - whatsapp.reacted description: Always `whatsapp.reacted` for this event. example: whatsapp.reacted EventEmailMailboxMessageSent: type: object additionalProperties: false description: 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`. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - email_mailbox.message_sent description: Event type. example: email_mailbox.message_sent timestamp: type: string minLength: 1 format: date-time description: When the event occurred. example: '2026-07-08T12:00:00Z' data: $ref: '#/components/schemas/EventEmailMailboxMessageSentData' EmailBounceType: type: string minLength: 1 enum: - hard - soft - undetermined - admin - block description: '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. ' example: hard PreferenceCoverage: type: string minLength: 1 description: 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. enum: - all - non_transactional example: non_transactional WhatsAppVideo: type: object description: 'Video content of a WhatsApp message. ' allOf: - $ref: '#/components/schemas/WhatsAppMedia' - type: object properties: caption: type: string description: Text shown beneath the video. Absent when the sender wrote none. example: How to set it up Tag: type: object additionalProperties: false required: - name - value description: 'Structured key/value label attached to a message or a call. Use tags for low-cardinality filtering dimensions (category, experiment ID, template ID); they surface in the list filter of whatever carries them. On a message they also surface in the event log and in webhook payloads, and a message can carry `metadata` beside them for arbitrary per-send context that does not need to be filterable. A call has none of those three: its tags are set on the wire when the call is placed, and the call record is the one place you read them back. Whatever carries the tags defines how many it may have. Tag names are unique: a send that repeats one is rejected, and on a call the first instance of a name wins. ' properties: name: type: string minLength: 1 maxLength: 32 pattern: ^[A-Za-z0-9_-]+$ description: 'Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters. ' example: category value: type: string minLength: 1 maxLength: 64 pattern: ^[A-Za-z0-9_-]+$ description: 'Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters. ' example: welcome EventEmailSuppressionCreatedData: type: object additionalProperties: false description: Payload of the email_suppression.created event. required: - suppression_id - email - reason - workspace_id properties: suppression_id: $ref: '#/components/schemas/SuppressionID' description: The suppression entry that was created. example: sup_01krdgeqcxet5s7t44vh8rt9mg email: type: string minLength: 1 format: email description: The recipient address that was added to the suppression list. example: user@example.com reason: type: string minLength: 1 x-extensible-enum: - hard_bounce - complaint - unsubscribe - manual description: 'Why the address was suppressed. New values may be added over time; treat unknown values as informational. ' example: hard_bounce workspace_id: $ref: '#/components/schemas/WorkspaceID' description: The workspace the suppression belongs to. example: ws_01krdgeqcxet5s7t44vh8rt9mg EventEmailOutOfBandBounce: type: object additionalProperties: false description: A bounce notification arrived after the message had already been accepted for delivery. Fires once per recipient. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - email.out_of_band_bounce description: Event type. example: email.out_of_band_bounce timestamp: type: string minLength: 1 format: date-time description: Time the bounce notification was recorded. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventEmailOutOfBandBounceData' EventEmailMailboxMessageDeliveredData: type: object additionalProperties: false description: Payload of the email_mailbox.message_delivered event. required: - message_id - mailbox_id - thread_id properties: message_id: $ref: '#/components/schemas/EmailID' description: ID of the delivered message. Per-recipient `email.*` events use this value as `email_id`. Use it to deduplicate events when you subscribe to both event families. mailbox_id: $ref: '#/components/schemas/MailboxID' description: ID of the mailbox the message was sent from. thread_id: $ref: '#/components/schemas/ThreadID' description: ID of the thread the message belongs to. EventDomainVerified: type: object additionalProperties: false description: A sending domain completed DNS verification successfully. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - domain.verified description: Event type. example: domain.verified timestamp: type: string minLength: 1 format: date-time description: When the event occurred. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventDomainVerifiedData' WhatsAppMedia: type: object description: Fields shared by every media content object on a WhatsApp message. properties: id: readOnly: true allOf: - $ref: '#/components/schemas/WhatsAppFileID' description: 'ID of the stored file, to pass as `media_id` when fetching it. Absent on an outbound message, whose file we never stored. ' url: type: string format: uri description: 'Where to fetch the media. On an inbound message 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 an outbound message it is the URL the sender supplied, whose availability is the sender''s to guarantee. ' example: https://platform.bird.com/v1/whatsapp/messages/wam_01kya19eknftrs2s6p82asmvnh/media/waf_01kyb2m4xq7whs0d8n3prv6tez mime_type: type: string description: 'Media type WhatsApp reported for the file, for example `image/jpeg`. Absent on outbound messages. ' example: image/jpeg WebhookSortField: type: string enum: - created_at - url default: created_at description: 'Field to sort webhook endpoints by: `created_at` (the default; newest first with the default `order`) or `url`. ' EventVoiceCallAnswered: type: object additionalProperties: false description: The called party answered and media began flowing. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - voice_call.answered description: Event type. example: voice_call.answered timestamp: type: string minLength: 1 format: date-time description: Time the call was answered. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventVoiceCallAnsweredData' WebhookEndpoint: allOf: - type: object required: - id - url - events - status - created_at - updated_at properties: id: readOnly: true $ref: '#/components/schemas/WebhookEndpointID' description: 'Unique identifier for the endpoint (`whk_` prefix). Accepted as `webhook_id` by every `/v1/webhooks/{webhook_id}` operation. ' url: type: string format: uri minLength: 1 description: HTTPS URL where the API delivers events for this endpoint. example: https://example.com/webhook description: type: string minLength: 1 description: Human-readable label for the endpoint. example: Production webhook endpoint events: type: array items: $ref: '#/components/schemas/WebhookEventType' description: 'Event types this endpoint is subscribed to; only matching events are delivered. Change the set with [Update a webhook endpoint](/docs/api/reference/update-webhook). ' example: - email.delivered - email.bounced status: type: string readOnly: true minLength: 1 description: "Delivery state of the endpoint.\n\n- `active`: The initial state; events are being delivered normally.\n- `degraded`: Recent deliveries are failing. We keep delivering and retrying,\n and the endpoint returns to `active` automatically once deliveries succeed\n again.\n- `paused`: All delivery is stopped, either because an update set `status` to\n `paused` or automatically after sustained delivery failures. A paused endpoint\n never resumes on its own: re-enable it with\n [Update a webhook endpoint](/docs/api/reference/update-webhook), then recover\n the missed events with\n [Replay missed events](/docs/api/reference/create-webhook-replay).\n" enum: - active - degraded - paused - $ref: '#/components/schemas/Timestamps' SMSSuppressionID: type: string minLength: 1 pattern: ^ssu_[0-9a-hjkmnp-tv-z]{26}$ example: ssu_01krdgeqcxet5s7t44vh8rt9mg EventDomainFailed: type: object additionalProperties: false description: A sending domain failed DNS verification. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - domain.failed description: Event type. example: domain.failed timestamp: type: string minLength: 1 format: date-time description: When the event occurred. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventDomainFailedData' EventWhatsAppReadData: type: object description: Payload of the whatsapp.read event. allOf: - $ref: '#/components/schemas/EventWhatsAppBase' - type: object properties: recipient: allOf: - $ref: '#/components/schemas/WhatsAppAddress' description: 'The participant who opened the message, on a group message. A group send raises this event once per participant, so this is what tells the deliveries apart. Absent on a one-to-one message, whose `to` already names its recipient. ' RecipientRole: type: string minLength: 1 enum: - to - cc - bcc description: Envelope position of a recipient on an outbound email event. example: to EventVerifyAttemptDeliveredData: type: object description: Payload of the verify.attempt.delivered event. allOf: - $ref: '#/components/schemas/EventVerifyBase' - type: object required: - channel - address - carrier - mcc_mnc - delivered_at properties: channel: $ref: '#/components/schemas/VerificationChannel' description: The channel this attempt was sent on. example: sms address: type: string minLength: 1 description: The single address this attempt was dispatched to, an E.164 phone number or an email address. example: '+14155550100' carrier: type: - string - 'null' description: Carrier that delivered the message, when the carrier network reports it. Always null for email, WhatsApp, and Telegram. example: Verizon mcc_mnc: type: - string - 'null' description: Mobile country code and mobile network code of the delivering carrier, when reported. Always null for email, WhatsApp, and Telegram. example: '311480' delivered_at: type: string minLength: 1 format: date-time description: Time delivery was confirmed. example: '2026-07-24T12:00:05Z' WebhookRotateSecretResponse: type: object additionalProperties: false required: - secret properties: secret: type: string minLength: 1 x-sensitive: true description: 'The new signing secret (`whsec_` prefix). Shown only in this response: store it immediately, it cannot be retrieved again. Deliveries are signed with both this and the previous secret for 24 hours after rotation, then the previous secret stops signing. ' example: whsec_newbase64encodedvalue VerificationTerminalReason: type: string minLength: 1 x-extensible-enum: - attempts_exhausted - ttl_elapsed - undeliverable description: '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.' WhatsAppInteractiveReply: type: object additionalProperties: false description: '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. ' required: - type properties: type: allOf: - $ref: '#/components/schemas/WhatsAppInteractiveReplyType' description: Which kind of tap this reply came from, and which field carries it. button: allOf: - $ref: '#/components/schemas/WhatsAppInteractiveQuickReplyButton' description: 'The button the contact tapped, as you declared it. On a reply to a template''s quick-reply button, `slug` is the button''s payload, which WhatsApp sets to the button''s own label. ' list: allOf: - $ref: '#/components/schemas/WhatsAppInteractiveListRow' description: 'The row the contact chose, as you declared it. `description` is present only when the row carried one. ' example: type: list list: slug: priority_express text: Priority Mail Express description: Next day to 2 days EventWhatsAppSent: type: object additionalProperties: false description: The API handed the message to Meta for delivery. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - whatsapp.sent description: Event type. example: whatsapp.sent timestamp: type: string minLength: 1 format: date-time description: Time the API handed the message to Meta for delivery. example: '2026-07-16T12:00:00Z' data: $ref: '#/components/schemas/EventWhatsAppSentData' PreferenceGrantedEventType: type: string minLength: 1 enum: - preference.granted description: Always `preference.granted` for this event. example: preference.granted PreferenceDeletedEventType: type: string minLength: 1 enum: - preference.deleted description: Always `preference.deleted` for this event. example: preference.deleted EventPreferenceBase: type: object description: '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`.' required: - preference_id - transition_id - channel - handle - sender_scope - topic_id - coverage - contact_id properties: preference_id: $ref: '#/components/schemas/PreferenceID' description: The preference key this write applied to. example: prf_01krdgeqcxet5s7t44vh8rt9mg transition_id: $ref: '#/components/schemas/PreferenceTransitionID' description: The ledger entry this write appended. example: prt_01krdgeqcxet5s7t44vh8rt9mg channel: allOf: - $ref: '#/components/schemas/PreferenceChannel' handle: type: string minLength: 1 maxLength: 320 description: 'Who the statement is about: an email address on the email channel, a phone number in E.164 format on SMS and WhatsApp.' example: '+15550001234' sender_scope: type: - string - 'null' description: 'The sender the statement is limited to, or null when it covers the whole channel. 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.' example: '+15557654321' topic_id: type: - string - 'null' description: '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`.' example: null coverage: allOf: - $ref: '#/components/schemas/PreferenceCoverage' contact_id: oneOf: - $ref: '#/components/schemas/ContactID' - type: 'null' description: The contact whose handle matched when the statement was recorded. Null when no contact matched at that moment. WhatsAppDocument: type: object description: 'Document content of a WhatsApp message. ' allOf: - $ref: '#/components/schemas/WhatsAppMedia' - type: object properties: caption: type: string description: Text shown beneath the document. Absent when the sender wrote none. example: Signed contract filename: type: string description: The sender's own name for the file. example: contract-a1b2c3.pdf WebhookEndpointCreated: allOf: - $ref: '#/components/schemas/WebhookEndpoint' - type: object required: - secret properties: secret: type: string minLength: 1 x-sensitive: true description: 'Signing secret for this endpoint (`whsec_` prefix), used to verify every delivery signature. Present in this response only: store it immediately, it cannot be retrieved again. If you lose it, mint a new one with [Rotate webhook signing secret](/docs/api/reference/rotate-webhook-secret). ' example: whsec_base64encodedvalue WhatsAppInteractiveQuickReplyButton: type: object additionalProperties: false required: - slug - text description: '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. ' properties: slug: type: string minLength: 1 description: '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. ' example: change-booking text: type: string minLength: 1 description: The label the recipient saw. example: Change EventWhatsAppReactedData: type: object additionalProperties: false description: '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. ' required: - whatsapp_id - emoji - from - to - workspace_id properties: whatsapp_id: $ref: '#/components/schemas/WhatsAppMessageID' description: 'The message the contact reacted to. WhatsApp accepts a reaction on a message up to 30 days old, and we keep provider ids for 15, so a reaction placed on a message older than that cannot be matched to it and raises no event at all. ' emoji: type: - string - 'null' description: '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. ' example: 👍 from: allOf: - $ref: '#/components/schemas/WhatsAppAddress' description: The contact who reacted, as WhatsApp identified them. to: allOf: - $ref: '#/components/schemas/WhatsAppAddress' description: Your WhatsApp number, the business side of the conversation. workspace_id: $ref: '#/components/schemas/WorkspaceID' description: ID of the workspace that owns this event. WhatsAppSuppressionID: type: string minLength: 1 pattern: ^was_[0-9a-hjkmnp-tv-z]{26}$ example: was_01krdgeqcxet5s7t44vh8rt9mg WebhookEvent: description: '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. ' oneOf: - $ref: '#/components/schemas/EventDomainFailed' - $ref: '#/components/schemas/EventDomainVerified' - $ref: '#/components/schemas/EventEmailAccepted' - $ref: '#/components/schemas/EventEmailBounced' - $ref: '#/components/schemas/EventEmailCanceled' - $ref: '#/components/schemas/EventEmailClicked' - $ref: '#/components/schemas/EventEmailComplained' - $ref: '#/components/schemas/EventEmailDeferred' - $ref: '#/components/schemas/EventEmailDelivered' - $ref: '#/components/schemas/EventEmailListUnsubscribed' - $ref: '#/components/schemas/EventEmailOpened' - $ref: '#/components/schemas/EventEmailOutOfBandBounce' - $ref: '#/components/schemas/EventEmailProcessed' - $ref: '#/components/schemas/EventEmailReceived' - $ref: '#/components/schemas/EventEmailRejected' - $ref: '#/components/schemas/EventEmailScheduled' - $ref: '#/components/schemas/EventEmailUnsubscribed' - $ref: '#/components/schemas/EventEmailMailboxMessageDelivered' - $ref: '#/components/schemas/EventEmailMailboxMessageFailed' - $ref: '#/components/schemas/EventEmailMailboxMessageReceived' - $ref: '#/components/schemas/EventEmailMailboxMessageSent' - $ref: '#/components/schemas/EventEmailMailboxSuspended' - $ref: '#/components/schemas/EventEmailMailboxThreadCreated' - $ref: '#/components/schemas/EventEmailSuppressionCreated' - $ref: '#/components/schemas/EventPreferenceDeleted' - $ref: '#/components/schemas/EventPreferenceGranted' - $ref: '#/components/schemas/EventPreferenceRevoked' - $ref: '#/components/schemas/EventSMSAccepted' - $ref: '#/components/schemas/EventSMSDelivered' - $ref: '#/components/schemas/EventSMSExpired' - $ref: '#/components/schemas/EventSMSFailed' - $ref: '#/components/schemas/EventSMSReceived' - $ref: '#/components/schemas/EventSMSRejected' - $ref: '#/components/schemas/EventSMSSent' - $ref: '#/components/schemas/EventSMSUndelivered' - $ref: '#/components/schemas/EventSMSSuppressionCreated' - $ref: '#/components/schemas/EventVerifyAttemptDelivered' - $ref: '#/components/schemas/EventVerifyAttemptSent' - $ref: '#/components/schemas/EventVerifyAttemptUndelivered' - $ref: '#/components/schemas/EventVerifyVerificationCreated' - $ref: '#/components/schemas/EventVerifyVerificationFailed' - $ref: '#/components/schemas/EventVerifyVerificationVerified' - $ref: '#/components/schemas/EventVoiceCallAnswered' - $ref: '#/components/schemas/EventVoiceCallEnded' - $ref: '#/components/schemas/EventVoiceCallInitiated' - $ref: '#/components/schemas/EventWhatsAppAccepted' - $ref: '#/components/schemas/EventWhatsAppDelivered' - $ref: '#/components/schemas/EventWhatsAppFailed' - $ref: '#/components/schemas/EventWhatsAppReacted' - $ref: '#/components/schemas/EventWhatsAppRead' - $ref: '#/components/schemas/EventWhatsAppReceived' - $ref: '#/components/schemas/EventWhatsAppRejected' - $ref: '#/components/schemas/EventWhatsAppSent' - $ref: '#/components/schemas/EventWhatsAppSuppressionCreated' discriminator: propertyName: type mapping: domain.failed: '#/components/schemas/EventDomainFailed' domain.verified: '#/components/schemas/EventDomainVerified' email.accepted: '#/components/schemas/EventEmailAccepted' email.bounced: '#/components/schemas/EventEmailBounced' email.canceled: '#/components/schemas/EventEmailCanceled' email.clicked: '#/components/schemas/EventEmailClicked' email.complained: '#/components/schemas/EventEmailComplained' email.deferred: '#/components/schemas/EventEmailDeferred' email.delivered: '#/components/schemas/EventEmailDelivered' email.list_unsubscribed: '#/components/schemas/EventEmailListUnsubscribed' email.opened: '#/components/schemas/EventEmailOpened' email.out_of_band_bounce: '#/components/schemas/EventEmailOutOfBandBounce' email.processed: '#/components/schemas/EventEmailProcessed' email.received: '#/components/schemas/EventEmailReceived' email.rejected: '#/components/schemas/EventEmailRejected' email.scheduled: '#/components/schemas/EventEmailScheduled' email.unsubscribed: '#/components/schemas/EventEmailUnsubscribed' email_mailbox.message_delivered: '#/components/schemas/EventEmailMailboxMessageDelivered' email_mailbox.message_failed: '#/components/schemas/EventEmailMailboxMessageFailed' email_mailbox.message_received: '#/components/schemas/EventEmailMailboxMessageReceived' email_mailbox.message_sent: '#/components/schemas/EventEmailMailboxMessageSent' email_mailbox.suspended: '#/components/schemas/EventEmailMailboxSuspended' email_mailbox.thread_created: '#/components/schemas/EventEmailMailboxThreadCreated' email_suppression.created: '#/components/schemas/EventEmailSuppressionCreated' preference.deleted: '#/components/schemas/EventPreferenceDeleted' preference.granted: '#/components/schemas/EventPreferenceGranted' preference.revoked: '#/components/schemas/EventPreferenceRevoked' sms.accepted: '#/components/schemas/EventSMSAccepted' sms.delivered: '#/components/schemas/EventSMSDelivered' sms.expired: '#/components/schemas/EventSMSExpired' sms.failed: '#/components/schemas/EventSMSFailed' sms.received: '#/components/schemas/EventSMSReceived' sms.rejected: '#/components/schemas/EventSMSRejected' sms.sent: '#/components/schemas/EventSMSSent' sms.undelivered: '#/components/schemas/EventSMSUndelivered' sms_suppression.created: '#/components/schemas/EventSMSSuppressionCreated' verify.attempt.delivered: '#/components/schemas/EventVerifyAttemptDelivered' verify.attempt.sent: '#/components/schemas/EventVerifyAttemptSent' verify.attempt.undelivered: '#/components/schemas/EventVerifyAttemptUndelivered' verify.verification.created: '#/components/schemas/EventVerifyVerificationCreated' verify.verification.failed: '#/components/schemas/EventVerifyVerificationFailed' verify.verification.verified: '#/components/schemas/EventVerifyVerificationVerified' voice_call.answered: '#/components/schemas/EventVoiceCallAnswered' voice_call.ended: '#/components/schemas/EventVoiceCallEnded' voice_call.initiated: '#/components/schemas/EventVoiceCallInitiated' whatsapp.accepted: '#/components/schemas/EventWhatsAppAccepted' whatsapp.delivered: '#/components/schemas/EventWhatsAppDelivered' whatsapp.failed: '#/components/schemas/EventWhatsAppFailed' whatsapp.reacted: '#/components/schemas/EventWhatsAppReacted' whatsapp.read: '#/components/schemas/EventWhatsAppRead' whatsapp.received: '#/components/schemas/EventWhatsAppReceived' whatsapp.rejected: '#/components/schemas/EventWhatsAppRejected' whatsapp.sent: '#/components/schemas/EventWhatsAppSent' whatsapp_suppression.created: '#/components/schemas/EventWhatsAppSuppressionCreated' VoiceSessionID: type: string minLength: 1 pattern: ^vcs_[0-9a-hjkmnp-tv-z]{26}$ example: vcs_01krdgeqcxet5s7t44vh8rt9mg WhatsAppContactName: type: object additionalProperties: false description: 'The contact''s name, in the parts their device supplied. Every part is optional: WhatsApp sends what the card holds and omits the rest. ' properties: formatted_name: type: string description: The whole name as the contact's device renders it. example: Barbara J. Johnson first_name: type: string example: Barbara middle_name: type: string example: Joana last_name: type: string example: Johnson prefix: type: string example: Dr. suffix: type: string example: Esq. SMSError: type: - object - 'null' additionalProperties: false readOnly: true required: - code - description - occurred_at description: Failure detail for a message that could not be delivered or was rejected. properties: code: $ref: '#/components/schemas/SMSErrorCode' description: type: string minLength: 1 description: 'The failure in words, from whatever refused the message: the carrier''s own reason text on a delivery receipt, or ours on a message stopped before a carrier saw it. Free-form, so branch on `code` and show this to a human.' example: Carrier filtered as spam carrier_error_code: type: - string - 'null' description: 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: type: string format: date-time minLength: 1 description: When the failure occurred. EventWhatsAppSuppressionCreated: type: object additionalProperties: false description: An address was added to the workspace's WhatsApp suppression ledger. required: - type - timestamp - data properties: type: $ref: '#/components/schemas/WhatsAppSuppressionCreatedEventType' timestamp: type: string minLength: 1 format: date-time description: When the episode's opening statement took effect (`effective_at`). example: '2026-08-12T12:00:00Z' data: $ref: '#/components/schemas/EventWhatsAppSuppressionCreatedData' EventVerifyVerificationVerifiedData: type: object description: Payload of the verify.verification.verified event. allOf: - $ref: '#/components/schemas/EventVerifyBase' - type: object required: - status - channel - verified_at properties: status: type: string minLength: 1 x-extensible-enum: - verified description: The verification's state, always `verified`. Open enum for forward compatibility. example: verified channel: oneOf: - $ref: '#/components/schemas/VerificationChannel' - type: 'null' description: The channel whose passcode the recipient confirmed, the channel that converted. Null when the verification was resolved without attributing a channel. example: sms verified_at: type: string minLength: 1 format: date-time description: Time the verification was verified. example: '2026-07-24T12:01:00Z' EventVoiceCallEndedData: type: object description: Payload of the voice_call.ended event. allOf: - $ref: '#/components/schemas/EventVoiceBase' - type: object required: - status - sip_response_code - duration_ms - billable_ms properties: status: $ref: '#/components/schemas/VoiceCallStatus' sip_response_code: type: - integer - 'null' minimum: 100 description: Final SIP response code received from the carrier. Null when no SIP response was received, for example on timeout or DNS failure. example: 200 duration_ms: type: integer minimum: 0 description: Total call duration in milliseconds, measured from the first SIP `INVITE` to the `BYE` or final response. example: 65000 billable_ms: type: integer minimum: 0 description: Billable duration in milliseconds, measured from answer to call end. Zero for unanswered calls. example: 60000 EventWhatsAppSentData: type: object description: Payload of the whatsapp.sent event. allOf: - $ref: '#/components/schemas/EventWhatsAppBase' EventWhatsAppBase: type: object description: Identity fields shared by every WhatsApp lifecycle event payload. required: - whatsapp_id - workspace_id - direction - from - to - tags - metadata properties: whatsapp_id: $ref: '#/components/schemas/WhatsAppMessageID' description: ID of the WhatsApp message. workspace_id: $ref: '#/components/schemas/WorkspaceID' description: ID of the workspace that owns this event. direction: type: string minLength: 1 enum: - outbound - inbound description: Whether the message was sent by the business (`outbound`) or received from the contact (`inbound`). from: $ref: '#/components/schemas/WhatsAppAddress' description: Sender of the message. On outbound messages, the business number it was sent from; on inbound, the WhatsApp contact. to: $ref: '#/components/schemas/WhatsAppAddress' description: Recipient of the message. On outbound messages, the WhatsApp contact; on inbound, the business number. tags: type: - array - 'null' items: $ref: '#/components/schemas/Tag' description: 'Tags provided on the send request, echoed on every event for the message. Null when the message carried no tags. ' metadata: type: - object - 'null' additionalProperties: true description: 'The metadata object provided on the send request, echoed on every event for the message. Null when the message carried no metadata. ' example: order_id: ord_123 in_reply_to_message_id: allOf: - $ref: '#/components/schemas/WhatsAppMessageID' description: 'The message this one answers. On an outbound message it is the `in_reply_to_message_id` the send request quoted. On an inbound message it is what WhatsApp reports as the reply''s target: a tap on a button or a list row, and equally a text or media message the contact sent as a quoted reply. Absent when the message answers nothing, and absent on an inbound message whose target we cannot match to a message we hold, which is the case for one sent before this workspace started recording them or one already past the 15-day window we keep provider ids for. ' EventWhatsAppAcceptedData: type: object description: Payload of the whatsapp.accepted event. allOf: - $ref: '#/components/schemas/EventWhatsAppBase' WebhookEndpointUpdate: type: object additionalProperties: false properties: url: type: string maxLength: 2048 format: uri description: 'Replacement delivery URL. Same rules as at creation: HTTPS, at most 2048 characters, and the host must be publicly reachable (private, loopback, and link-local addresses return a `422`). Omit to keep the current URL. ' example: https://example.com/webhook description: type: string maxLength: 256 description: Human-readable label for this endpoint, up to 256 characters. example: Updated webhook endpoint events: type: array items: $ref: '#/components/schemas/WebhookEventType' minItems: 1 description: 'Replaces all event subscriptions with this list. Omit to keep the current set. Types outside the event catalog return a `422`. ' example: - email.delivered - email.bounced - email.complained status: type: string enum: - active - paused description: '`paused` stops all deliveries; `active` re-enables a paused endpoint. Omit to leave the status unchanged. Events that fire while paused are not delivered; after re-enabling, recover them with [Replay missed events](/docs/api/reference/create-webhook-replay). A `degraded` endpoint cannot be reset through this field: it returns to `active` automatically once deliveries succeed again. ' EventEmailBouncedData: type: object description: Payload of the email.bounced event. allOf: - $ref: '#/components/schemas/EventEmailBase' - type: object required: - bounce_type - bounce_class - bounce_code - bounce_description - sending_ip properties: bounce_type: $ref: '#/components/schemas/EmailBounceType' bounce_class: type: - integer - 'null' minimum: 1 maximum: 255 description: '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`. ' example: 10 bounce_code: type: - string - 'null' description: SMTP reply code returned by the receiving mail server, or null when none was provided. example: '550' bounce_description: type: - string - 'null' description: Human-readable reason the receiving mail server gave for the bounce, or null when none was provided. example: 5.1.1 Unknown user sending_ip: type: - string - 'null' description: The IP address used to send this message, or null when it is not known. example: 192.0.2.10 EventEmailClickedData: type: object description: Payload of the email.clicked event. allOf: - $ref: '#/components/schemas/EventEmailBase' - type: object required: - url - ip_address - user_agent properties: url: type: string minLength: 1 description: The URL the recipient clicked. example: https://bird.com/welcome ip_address: type: - string - 'null' description: IP address of the client that clicked the link, or null when it is not known. example: 203.0.113.9 user_agent: type: - string - 'null' description: User-agent string of the client that clicked the link, or null when it is not known. example: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) DomainID: type: string minLength: 1 pattern: ^dom_[0-9a-hjkmnp-tv-z]{26}$ example: dom_01krdgeqcxet5s7t44vh8rt9mg EventEmailMailboxMessageReceived: type: object additionalProperties: false description: 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`. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - email_mailbox.message_received description: Event type. example: email_mailbox.message_received timestamp: type: string minLength: 1 format: date-time description: When the event occurred. example: '2026-07-08T12:00:00Z' data: $ref: '#/components/schemas/EventEmailMailboxMessageReceivedData' VoiceCallStatus: type: string minLength: 1 enum: - answered - no_answer - busy - canceled - failed - rejected - unknown - ringing - in_progress description: "Call status.\n\nA call that has ended carries one of:\n\n- `answered` means it connected and the far end picked up.\n- `no_answer` means nobody picked up before the call timed out.\n- `rejected` means it was refused rather than attempted. Either we turned it\n away before dialing a carrier, in which case `rejection_reason` names the\n check it failed where there was one, or the far end declined it.\n- `failed` means it was attempted and did not work, and `sip_response_code`\n is what came back.\n- `unknown` means the outcome could not be determined. Contact support with\n the call `id` if you see one.\n\nAn active call carries `ringing` before it is picked up and `in_progress`\nafterward. The call list's `status` filter takes any mix of the two sets.\n\n`busy` and `canceled` are reserved for incoming calls delivered to your own\nnumbers: `busy` for a called party that rejected the call as busy, `canceled`\nfor a caller who hung up before it was picked up. Neither is emitted yet and\nboth outcomes are reported as `failed` today.\n" example: answered WhatsAppSuppressionCreatedEventType: type: string minLength: 1 enum: - whatsapp_suppression.created description: Always `whatsapp_suppression.created` for this event. example: whatsapp_suppression.created EventEmailMailboxMessageSentData: type: object additionalProperties: false description: Payload of the email_mailbox.message_sent event. required: - message_id - mailbox_id - thread_id properties: message_id: $ref: '#/components/schemas/EmailID' description: ID of the sent message. Per-recipient `email.*` events use this value as `email_id`. Use it to deduplicate events when you subscribe to both event families. mailbox_id: $ref: '#/components/schemas/MailboxID' description: ID of the mailbox the message was sent from. thread_id: $ref: '#/components/schemas/ThreadID' description: ID of the thread the message belongs to. WhatsAppInteractiveListRow: type: object additionalProperties: false required: - slug - text description: '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. ' properties: slug: type: string minLength: 1 description: The handle the row carries back, never shown to the recipient. example: priority_express text: type: string minLength: 1 description: The row's label, shown as its title in the menu. example: Priority Mail Express description: type: string description: The second line under the label. Absent when the row carried none. example: Next day to 2 days InboundEmailMessageID: type: string minLength: 1 pattern: ^rem_[0-9a-hjkmnp-tv-z]{26}$ example: rem_01krdgeqcxet5s7t44vh8rt9mg EventEmailScheduledData: type: object description: Payload of the email.scheduled event. allOf: - $ref: '#/components/schemas/EventEmailMessageBase' - type: object required: - scheduled_at properties: scheduled_at: type: string minLength: 1 format: date-time description: When the message is scheduled to send. example: '2026-05-22T09:00:00Z' _ListEnvelope: type: object required: - next_cursor - prev_cursor - refresh_cursor properties: next_cursor: type: - string - 'null' description: Cursor for the next page. Pass back as `starting_after` to advance forward. `null` when no next page exists. example: eyJ2IjoxLCJzIjoiXCIyMDI2LTA1LTI1VDE0OjAzOjEwWlwiIiwiaSI6IjAxOTJmM2IxLTRjN2UtN2EyYi05ZDYxLThmM2E1YzJlN2I0MCJ9 prev_cursor: type: - string - 'null' description: Cursor for the previous page. Pass back as `ending_before` to step backward. `null` when no previous page exists. example: null refresh_cursor: type: - string - 'null' description: Refresh anchor, the first row of this response. Pass back as `ending_before` to fetch what precedes it in the current sort order. On a newest-first sort those are the items that have appeared since; on any other sort they are the items that sort earlier, so refreshing such a list means re-fetching it instead. Non-`null` whenever `data` is non-empty; `null` only on an empty page. Distinct from `prev_cursor`. example: eyJ2IjoxLCJzIjoiXCIyMDI2LTA1LTI1VDE2OjQyOjAxWlwiIiwiaSI6IjAxOTJmM2IxLTllMDQtN2NkMy1iODE3LTJhNmY0ZDFjOGUwOSJ9 EventEmailMailboxThreadCreated: type: object additionalProperties: false description: A new thread was created in a mailbox, from either direction. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - email_mailbox.thread_created description: Event type. example: email_mailbox.thread_created timestamp: type: string minLength: 1 format: date-time description: When the event occurred. example: '2026-07-08T12:00:00Z' data: $ref: '#/components/schemas/EventEmailMailboxThreadCreatedData' WhatsAppAddress: type: object additionalProperties: false description: '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.' properties: phone_number: type: string minLength: 1 description: Phone number in E.164 format, when known. example: '+15550001111' bsuid: type: string minLength: 1 description: 'Business-scoped user ID, Meta''s identifier for the WhatsApp user. Present only on the WhatsApp-user side of the message. ' example: NL.xxxx group_id: allOf: - $ref: '#/components/schemas/WhatsAppGroupID' description: 'The group this address was addressed as, or reached through. It appears on a message''s `to` and nowhere else: never on `from`, and never on an event''s `recipient`. Outbound, it stands in for the recipient, because a group send names no single phone number. Inbound, it qualifies one: `to` carries the business `phone_number` that received the message and the group it arrived through, while `from` stays the participant who wrote it. Its presence on `to` is what tells a group message from a one-to-one one, in either direction. ' username: type: string minLength: 1 description: '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: type: string minLength: 1 description: '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. ' EventEmailUnsubscribed: type: object additionalProperties: false description: Recipient unsubscribed by clicking a tracked unsubscribe link in the email. Fires once per recipient. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - email.unsubscribed description: Event type. example: email.unsubscribed timestamp: type: string minLength: 1 format: date-time description: Time the unsubscribe was recorded. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventEmailUnsubscribedData' EventVoiceCallAnsweredData: type: object description: Payload of the voice_call.answered event. allOf: - $ref: '#/components/schemas/EventVoiceBase' EventSMSSent: type: object additionalProperties: false description: The API handed the message to the carrier for delivery. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - sms.sent description: Event type. example: sms.sent timestamp: type: string minLength: 1 format: date-time description: Time the message was handed to the carrier. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventSMSSentData' EventEmailMailboxSuspendedData: type: object additionalProperties: false description: Payload of the email_mailbox.suspended event. required: - mailbox_id - reason properties: mailbox_id: $ref: '#/components/schemas/MailboxID' description: ID of the suspended mailbox. reason: type: string minLength: 1 description: Why the mailbox was suspended. example: abuse review EmailID: type: string minLength: 1 pattern: ^em_[0-9a-hjkmnp-tv-z]{26}$ example: em_01krdgeqcxet5s7t44vh8rt9mg SortOrder: type: string enum: - asc - desc description: Sort direction, ascending or descending. EventEmailOutOfBandBounceData: type: object description: Payload of the email.out_of_band_bounce event. allOf: - $ref: '#/components/schemas/EventEmailBase' - type: object required: - bounce_type - bounce_class - bounce_code - bounce_description - sending_ip properties: bounce_type: $ref: '#/components/schemas/EmailBounceType' bounce_class: type: - integer - 'null' minimum: 1 maximum: 255 description: 'Numeric bounce classification for fine-grained deliverability triage, or null when the receiving server''s response could not be classified. ' example: 10 bounce_code: type: - string - 'null' description: SMTP reply code returned by the receiving mail server, or null when none was provided. example: '550' bounce_description: type: - string - 'null' description: Human-readable reason the receiving mail server gave for the bounce, or null when none was provided. example: 5.1.1 Unknown user sending_ip: type: - string - 'null' description: The IP address used to send this message, or null when it is not known. example: 192.0.2.10 EventEmailUnsubscribedData: type: object description: Payload of the email.unsubscribed event. allOf: - $ref: '#/components/schemas/EventEmailBase' EventSMSDeliveredData: type: object description: Payload of the sms.delivered event. allOf: - $ref: '#/components/schemas/EventSMSBase' - type: object properties: carrier: type: string description: Carrier that delivered the message. Absent when the carrier does not report one. example: Verizon mcc_mnc: type: string description: Mobile country code and mobile network code of the carrier. Absent when the carrier does not report one. example: '311480' EventDomainFailedData: type: object additionalProperties: false description: Payload of the domain.failed event. required: - domain_id - domain - workspace_id properties: domain_id: $ref: '#/components/schemas/DomainID' description: The sending domain resource whose verification failed. example: dom_01krdgeqcxet5s7t44vh8rt9mg domain: type: string minLength: 1 description: The sending domain hostname. example: mail.example.com workspace_id: $ref: '#/components/schemas/WorkspaceID' description: The workspace the domain is assigned to. example: ws_01krdgeqcxet5s7t44vh8rt9mg failure_reason: type: - string - 'null' description: Why verification failed, when a specific reason is available (for example, the DKIM record was not found at the expected selector). example: DKIM record not found at the expected selector. VerificationAttemptFailureReason: type: string minLength: 1 x-extensible-enum: - carrier_rejected - hard_bounce - soft_bounce - undelivered - channel_unavailable - channel_disabled - channel_restricted - delivery_timeout - not_billable description: "Why a passcode send did not deliver:\n\n- `carrier_rejected`: The SMS carrier rejected the send.\n- `hard_bounce`: The email permanently bounced.\n- `soft_bounce`: The email temporarily bounced, such as when a mailbox is full.\n- `undelivered`: The channel reported a generic delivery failure.\n- `channel_unavailable`: The channel could not be used, so the verification\n moved to the next channel.\n- `channel_disabled`: Sending on the channel is temporarily disabled, so the\n verification moved to the next channel.\n- `channel_restricted`: The channel does not carry passcodes to this\n destination country. The verification moves to the next channel enabled\n there, or fails when the country has no other.\n- `delivery_timeout`: No delivery confirmation arrived before the channel's\n timeout, so the verification moved to the next channel.\n- `not_billable`: The send could not be charged, so it was never handed to the\n channel. Usually the workspace balance is too low to cover it. Topping up\n the balance is what clears this.\n\nNew reasons may be added over time. Treat unrecognized values as reasons added\nlater rather than errors." WhatsAppUnsupported: type: object additionalProperties: false description: 'A message whose content we do not model, named so it is visible in the message log rather than arriving empty. Inbound only. ' required: - type properties: type: type: string minLength: 1 x-extensible-enum: - reaction - interactive - button - order - system - unsupported description: '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. ' example: reaction example: type: reaction PreferenceTransitionID: type: string minLength: 1 pattern: ^prt_[0-9a-hjkmnp-tv-z]{26}$ example: prt_01krdgeqcxet5s7t44vh8rt9mg WhatsAppError: type: - object - 'null' additionalProperties: false readOnly: true required: - code - description - occurred_at description: Failure detail for a message that could not be delivered or was rejected. properties: code: $ref: '#/components/schemas/WhatsAppErrorCode' description: type: string minLength: 1 readOnly: true description: Human-readable explanation of the failure. example: Message could not be delivered. meta_error_code: type: - string - 'null' readOnly: true description: Raw error code from the WhatsApp Cloud API, when available, for low-level debugging. example: '131026' occurred_at: type: string format: date-time minLength: 1 readOnly: true description: When the failure occurred. VerificationChannel: type: string minLength: 1 x-extensible-enum: - email - sms - whatsapp - telegram - voice description: '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.' WebhookEventID: type: string minLength: 1 pattern: ^whe_[0-9a-hjkmnp-tv-z]{26}$ example: whe_01krdgeqcxet5s7t44vh8rt9mg EventEmailRejectedData: type: object description: Payload of the email.rejected event. allOf: - $ref: '#/components/schemas/EventEmailBase' - type: object required: - rejection_reason properties: rejection_reason: $ref: '#/components/schemas/EmailRejectionReason' SMSTemplateContentHash: type: string minLength: 1 readOnly: true description: 'A fingerprint of SMS template text, prefixed with its algorithm. Compare it within this API version to identify the exact source without transferring it. ' example: sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08 EventPreferenceDeletedData: type: object description: Payload of the preference.deleted event. allOf: - $ref: '#/components/schemas/EventPreferenceBase' EventEmailMailboxMessageFailed: type: object additionalProperties: false description: 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`. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - email_mailbox.message_failed description: Event type. example: email_mailbox.message_failed timestamp: type: string minLength: 1 format: date-time description: When the event occurred. example: '2026-07-08T12:00:00Z' data: $ref: '#/components/schemas/EventEmailMailboxMessageFailedData' MessageCost: type: - object - 'null' additionalProperties: false required: - amount - currency_code - transaction_amount - passthrough_amount description: 'What was charged for a message, split into the components that make it up. `null` until at least one component has been priced. ' properties: amount: type: string minLength: 1 readOnly: true description: '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. ' example: '0.00990' currency_code: readOnly: true $ref: '#/components/schemas/CurrencyCode' description: ISO 4217 currency code. Every component is denominated in this currency. example: USD transaction_amount: type: - string - 'null' readOnly: true description: '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. ' example: '0.00790' passthrough_amount: type: - string - 'null' readOnly: true description: '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. ' example: '0.00200' WebhookAttemptList: type: object additionalProperties: false required: - data properties: data: type: array description: Delivery attempts, newest first. items: $ref: '#/components/schemas/WebhookAttempt' EventWhatsAppReceived: type: object additionalProperties: false description: A contact sent the business a WhatsApp message. required: - type - timestamp - data properties: type: $ref: '#/components/schemas/WhatsAppReceivedEventType' timestamp: type: string minLength: 1 format: date-time description: Time the contact sent the message, as reported by WhatsApp. example: '2026-07-16T12:00:00Z' data: $ref: '#/components/schemas/EventWhatsAppReceivedData' SuppressionID: type: string minLength: 1 pattern: ^sup_[0-9a-hjkmnp-tv-z]{26}$ example: sup_01krdgeqcxet5s7t44vh8rt9mg EventWhatsAppAccepted: type: object additionalProperties: false description: The API accepted and charged the send request. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - whatsapp.accepted description: Event type. example: whatsapp.accepted timestamp: type: string minLength: 1 format: date-time description: Time the API accepted and charged the send request. example: '2026-07-16T12:00:00Z' data: $ref: '#/components/schemas/EventWhatsAppAcceptedData' EventVerifyVerificationFailed: type: object additionalProperties: false description: 'The verification ended without the recipient receiving a passcode: every planned channel reported that its send would not arrive.' required: - type - timestamp - data properties: type: $ref: '#/components/schemas/VerifyVerificationFailedEventType' timestamp: type: string minLength: 1 format: date-time description: Time the verification was resolved. example: '2026-07-24T12:00:05Z' data: $ref: '#/components/schemas/EventVerifyVerificationFailedData' EventEmailMessageBase: type: object description: Identity fields shared by the message-level email lifecycle events (scheduled, canceled), which are not tied to a single recipient. required: - email_id - workspace_id - tags - metadata properties: email_id: $ref: '#/components/schemas/EmailID' description: ID of the email send. workspace_id: $ref: '#/components/schemas/WorkspaceID' description: ID of the workspace that owns this event. tags: type: - array - 'null' items: $ref: '#/components/schemas/Tag' description: '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. ' metadata: type: - object - 'null' additionalProperties: true description: '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. ' example: order_id: ord_123 ErrorBody: type: object additionalProperties: false required: - type - code - name - message - doc_url - request_id properties: type: type: string minLength: 1 description: Broad category for coarse client branching. enum: - auth_error - bad_request_error - billing_error - conflict_error - gone_error - internal_error - misdirected_error - not_found_error - not_implemented_error - payload_too_large_error - permission_error - precondition_error - rate_limit_error - service_unavailable_error - too_early_error - validation_error code: type: string minLength: 1 pattern: ^E\d{5}$ description: Opaque, stable, unique error identifier. Never reused. name: type: string minLength: 1 description: Human-readable slug for log readability. Paired with code, never replaces it. message: type: string minLength: 1 description: Human-readable description. Not stable; clients must not parse it. param: type: string minLength: 1 description: Identifies the offending field. Omitted when not applicable. doc_url: type: string minLength: 1 format: uri description: Stable link to the docs page for this error code. request_id: type: string minLength: 1 description: Request correlation ID for support and troubleshooting. Also returned in the `X-Request-Id` response header. vendor_code: type: string minLength: 1 description: 'Verbatim error code from an external system, such as an SMTP response code or a payment decline code. Present only when the code may help you resolve the error. ' details: type: array description: Per-field validation errors. Present only on validation_error responses. items: $ref: '#/components/schemas/ErrorDetail' remediation: type: string minLength: 1 description: A human-readable next step to resolve this error. Present when a recovery is known. next: type: array description: 'The steps that resolve this error. Perform them in order, re-reading after each; a `wait` or `terminal` step is always last. Present for errors with a well-defined recovery, such as unmet preconditions and conflicts. ' items: $ref: '#/components/schemas/NextAction' SMSSuppressionReason: type: string minLength: 1 x-extensible-enum: - keyword_stop - carrier_opted_out - manual description: '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. ' EventSMSSentData: type: object description: Payload of the sms.sent event. allOf: - $ref: '#/components/schemas/EventSMSBase' - type: object properties: carrier: type: string description: Carrier that handled the message. Absent when the carrier does not report one. example: Verizon mcc_mnc: type: string description: Mobile country code and mobile network code of the carrier. Absent when the carrier does not report one. example: '311480' EventSMSRejectedData: type: object description: Payload of the sms.rejected event. allOf: - $ref: '#/components/schemas/EventSMSBase' - type: object required: - error properties: error: $ref: '#/components/schemas/SMSError' description: Why the message was rejected before reaching the carrier. RecipientID: type: string minLength: 1 pattern: ^er_[0-9a-hjkmnp-tv-z]{26}$ example: er_01krdgeqcxet5s7t44vh8rt9mg EventVerifyAttemptUndelivered: type: object additionalProperties: false description: A one-time passcode failed to deliver to the recipient. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - verify.attempt.undelivered description: Event type. example: verify.attempt.undelivered timestamp: type: string minLength: 1 format: date-time description: Time the failure was recorded. example: '2026-07-24T12:00:05Z' data: $ref: '#/components/schemas/EventVerifyAttemptUndeliveredData' SMSSegments: type: object additionalProperties: false required: - count - encoding - characters description: Segment breakdown for the message body. Segment count drives billing. properties: count: type: integer minimum: 1 readOnly: true description: Number of segments the body is split into. Each segment is a billable unit. encoding: type: string minLength: 1 readOnly: true enum: - GSM_7BIT - UCS2 description: '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: type: integer minimum: 0 readOnly: true description: '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. ' WhatsAppContactOrg: type: object additionalProperties: false description: Where the contact works, as their card records it. properties: company: type: string example: Lucky Shrub department: type: string example: Engineering title: type: string example: Software Engineer EventVerifyAttemptDelivered: type: object additionalProperties: false description: The channel confirmed delivery of a one-time passcode to the recipient. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - verify.attempt.delivered description: Event type. example: verify.attempt.delivered timestamp: type: string minLength: 1 format: date-time description: Time delivery was confirmed. example: '2026-07-24T12:00:05Z' data: $ref: '#/components/schemas/EventVerifyAttemptDeliveredData' WebhookAttempt: type: object additionalProperties: false required: - id - event_type - status - url - response_status_code - response_duration_ms - attempted_at properties: id: type: string readOnly: true minLength: 1 description: 'Identifier of this individual delivery attempt. Each retry is a separate attempt with its own id; use `event_id` to group the attempts for one event. ' example: msgatt_3FdaB1NkOmM6m8AxhgEYTJgqHU3 event_id: description: Bird's source event ID, stable across retries of the same event. Null only for older attempts recorded before event IDs were available. oneOf: - $ref: '#/components/schemas/WebhookEventID' - type: 'null' event_type: $ref: '#/components/schemas/WebhookEventType' status: type: string minLength: 1 enum: - delivered - pending - failed description: "Outcome of this attempt.\n\n- `delivered`: your endpoint accepted it with a `2xx` response.\n- `pending`: the attempt is still in flight.\n- `failed`: it returned a non-`2xx` response or no response at all. A `failed`\n attempt is not final for the event: automatic retries appear as further\n attempts with the same `event_id`.\n" url: type: string format: uri minLength: 1 description: 'URL the request was sent to: the endpoint''s `url` at the time of the attempt, which can differ from the current configuration after an update. ' example: https://example.com/webhooks response_status_code: type: - integer - 'null' description: HTTP status returned by the receiver. Null when no response was received (timeout, connection error, DNS failure). example: 200 response_body: type: string description: 'Response body your endpoint returned, which may be truncated. Omitted when no body was returned. ' example: '{"ok":true}' response_duration_ms: type: integer minimum: 0 description: Round-trip duration in milliseconds. example: 87 attempted_at: type: string format: date-time minLength: 1 readOnly: true description: 'When this attempt was made. Attempts are listed newest first by this timestamp, and the list''s `before`/`after` parameters bound it. ' example: '2026-05-22T11:50:38.080Z' WhatsAppAudio: type: object description: 'Audio content of a WhatsApp message. ' allOf: - $ref: '#/components/schemas/WhatsAppMedia' - type: object properties: voice: type: boolean description: '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. ' example: true VerificationID: type: string minLength: 1 pattern: ^vrf_[0-9a-hjkmnp-tv-z]{26}$ example: vrf_01krdgeqcxet5s7t44vh8rt9mg WhatsAppLocation: type: object additionalProperties: false description: 'Location content of a WhatsApp message: a point on the map the recipient can open in their maps app. ' properties: latitude: type: number format: double description: Latitude in decimal degrees. example: 52.3702 longitude: type: number format: double description: Longitude in decimal degrees. example: 4.8952 name: type: string description: Name of the place. Absent when the sender shared a plain pin. example: Bird HQ address: type: string description: Street address of the place. Shown only when `name` is also set. example: Keizersgracht 117, Amsterdam url: type: string format: uri description: '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. ' example: https://www.google.com/maps/place/Statue+of+Liberty/@40.6246301,-74.5291919,124716m/ _ListEnvelopeWithTotal: allOf: - $ref: '#/components/schemas/_ListEnvelope' - type: object properties: total: type: - integer - 'null' format: int64 minimum: 0 description: Total number of items matching the request's filters across all pages. Present only when `include_total=true` was passed; otherwise `null`. VerifyVerificationFailedEventType: type: string minLength: 1 enum: - verify.verification.failed description: Always `verify.verification.failed` for this event. example: verify.verification.failed EventEmailComplainedData: type: object description: Payload of the email.complained event. allOf: - $ref: '#/components/schemas/EventEmailBase' - type: object required: - feedback_type properties: feedback_type: type: - string - 'null' description: The kind of feedback the mailbox provider reported (such as `abuse` or `fraud`), or null when the provider did not specify one. example: abuse EventEmailReceived: type: object additionalProperties: false description: 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}`. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - email.received description: Event type. example: email.received timestamp: type: string minLength: 1 format: date-time description: When the API received the message. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventEmailReceivedData' EventVerifyBase: type: object description: Identity fields shared by every Verify lifecycle event payload. required: - verification_id - workspace_id - to - metadata properties: verification_id: $ref: '#/components/schemas/VerificationID' description: ID of the verification session. workspace_id: $ref: '#/components/schemas/WorkspaceID' description: ID of the workspace that owns this event. to: $ref: '#/components/schemas/VerificationTo' description: The recipient identity of the verification session (email address, phone number, or both), echoed on every event so you can correlate without an extra lookup. An individual attempt reports the single address it was dispatched to in its own `address` field. metadata: type: - object - 'null' additionalProperties: true description: '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. ' example: user_id: usr_123 EventVerifyVerificationCreated: type: object additionalProperties: false description: A verification session was created and its first one-time passcode is being sent. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - verify.verification.created description: Event type. example: verify.verification.created timestamp: type: string minLength: 1 format: date-time description: Time the verification session was created. example: '2026-07-24T12:00:00Z' data: $ref: '#/components/schemas/EventVerifyVerificationCreatedData' SMSTemplateVersionID: type: string minLength: 1 pattern: ^smv_[0-9a-hjkmnp-tv-z]{26}$ example: smv_01krdgeqcxet5s7t44vh8rt9mg EventSMSDelivered: type: object additionalProperties: false description: The carrier confirmed delivery of the message to the recipient handset. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - sms.delivered description: Event type. example: sms.delivered timestamp: type: string minLength: 1 format: date-time description: Time the carrier confirmed delivery. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventSMSDeliveredData' EventEmailBase: type: object description: Identity fields shared by every email lifecycle event payload. required: - email_id - recipient_id - workspace_id - recipient - recipient_role - tags - metadata - broadcast_id properties: email_id: $ref: '#/components/schemas/EmailID' description: ID of the email send. recipient_id: $ref: '#/components/schemas/RecipientID' description: ID of the recipient. workspace_id: $ref: '#/components/schemas/WorkspaceID' description: ID of the workspace that owns this event. recipient: type: string minLength: 1 format: email description: Recipient address as it appeared on the envelope. example: alice@bird.com recipient_role: $ref: '#/components/schemas/RecipientRole' description: Envelope position of the recipient. tags: type: - array - 'null' items: $ref: '#/components/schemas/Tag' description: '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. ' metadata: type: - object - 'null' additionalProperties: true description: '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. ' example: order_id: ord_123 broadcast_id: oneOf: - $ref: '#/components/schemas/EmailBroadcastID' - type: 'null' description: 'The broadcast this send went out as part of, echoed on every per-recipient event for the send so you can attribute engagement to the broadcast without an extra lookup. Null when the send was not part of a broadcast. On `email.unsubscribed` and `email.list_unsubscribed`, null can also mean the recipient used an unsubscribe link that names no broadcast, so on those two events null does not rule a broadcast out. ' example: eb_01krdgeqcxet5s7t44vh8rt9mg EventWhatsAppFailed: type: object additionalProperties: false description: Message delivery failed permanently. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - whatsapp.failed description: Event type. example: whatsapp.failed timestamp: type: string minLength: 1 format: date-time description: Time the failure was recorded. example: '2026-07-16T12:00:00Z' data: $ref: '#/components/schemas/EventWhatsAppFailedData' SMSSuppressionCreatedEventType: type: string minLength: 1 enum: - sms_suppression.created description: Always `sms_suppression.created` for this event. example: sms_suppression.created NextAction: type: object additionalProperties: false required: - kind - description properties: kind: type: string minLength: 1 x-extensible-enum: - operation - external - wait - terminal description: "What you do about this step.\n\n- `operation`: call the operation named in `operation`, then\n read again.\n- `external`: act somewhere this API does not reach, then read\n again.\n- `wait`: nothing is asked of you, so read again later.\n- `terminal`: nothing you do resolves this, so stop retrying.\n\nTolerate a value you do not recognize: show the `description` and\noffer no action.\n" description: type: string minLength: 1 description: A short, human-readable label for the step, suitable for display. operation: type: string minLength: 1 description: 'The operationId to call. Present only when `kind` is `operation`. The operation''s own schema says how to call it; this says only which one, and what to address it with. ' params: type: object additionalProperties: type: string minLength: 1 description: 'The parameters that address the operation, by name: `{"sender_id": "…"}` for an operation on `/v1/sms/senders/{sender_id}/requirements`. A parameter the operation takes in its query string is given the same way, so an operation addressed as `?subject_id=` carries `{"subject_id": "…"}`. Every parameter the call needs is here, whether its value came from the thing you were acting on or is fixed for this step, so you can make the call from this object alone. Present only when `kind` is `operation` and the operation names a subject. A request body, when the operation takes one, is described by the operation''s own schema and never appears here. ' url: type: string format: uri description: 'A URL to open. Present only when `kind` is `external`, and only when the step has one. An external step whose `description` says to go and do something with no URL to open is normal. ' WebhookEndpointList: allOf: - type: object required: - data properties: data: type: array items: $ref: '#/components/schemas/WebhookEndpoint' - $ref: '#/components/schemas/_ListEnvelopeWithTotal' WhatsAppInteractiveReplyType: type: string minLength: 1 x-extensible-enum: - button - list description: "Which kind of tap the reply came from.\n\n- `button`: a reply button on an interactive message, or a quick-reply\n button on a template. Both carry an identifier and a label, so they read\n the same way.\n- `list`: a row chosen from a list's menu. Only this kind carries a\n `description`.\n\nOpen enum: WhatsApp adds interactive kinds over time, so treat an\nunrecognized value as a future kind rather than an error.\n" example: button PreferenceChannel: type: string minLength: 1 description: '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.' x-extensible-enum: - email - sms - whatsapp example: sms EventEmailCanceledData: type: object description: Payload of the email.canceled event. allOf: - $ref: '#/components/schemas/EventEmailMessageBase' EventEmailDeferredData: type: object description: Payload of the email.deferred event. allOf: - $ref: '#/components/schemas/EventEmailBase' - type: object required: - bounce_type - bounce_class - defer_reason - sending_ip properties: bounce_type: $ref: '#/components/schemas/EmailBounceType' bounce_class: type: - integer - 'null' minimum: 1 maximum: 255 description: '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. ' example: 21 defer_reason: type: - string - 'null' description: Human-readable reason the receiving mail server gave for the deferral, or null when none was provided. example: 4.2.1 Mailbox temporarily unavailable, will retry sending_ip: type: - string - 'null' description: The IP address used to send this message, or null when it is not known. example: 192.0.2.10 EventSMSSuppressionCreatedData: type: object additionalProperties: false description: Payload of the sms_suppression.created event. required: - suppression_id - destination - originator - reason - workspace_id properties: suppression_id: $ref: '#/components/schemas/SMSSuppressionID' description: The suppression episode that was opened. example: ssu_01krdgeqcxet5s7t44vh8rt9mg destination: type: string minLength: 2 maxLength: 20 description: The subscriber, in E.164 format. example: '+15550001234' originator: type: string minLength: 1 maxLength: 20 description: The sender this stops. An SMS suppression is the exact (sender, recipient) pair, so your other senders still reach this subscriber. example: '+15557654321' reason: allOf: - $ref: '#/components/schemas/SMSSuppressionReason' workspace_id: $ref: '#/components/schemas/WorkspaceID' description: The workspace the suppression belongs to. example: ws_01krdgeqcxet5s7t44vh8rt9mg WebhookTestRequest: type: object additionalProperties: false properties: event_type: type: string description: '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. ' example: email.delivered example: event_type: email.delivered WhatsAppImage: type: object description: 'Image content of a WhatsApp message. ' allOf: - $ref: '#/components/schemas/WhatsAppMedia' - type: object properties: caption: type: string description: Text shown beneath the image. Absent when the sender wrote none. example: Your receipt for order A1B2C3 WhatsAppFileID: type: string minLength: 1 pattern: ^waf_[0-9a-hjkmnp-tv-z]{26}$ example: waf_01krdgeqcxet5s7t44vh8rt9mg WebhookTestResponse: type: object additionalProperties: false required: - status - response_status_code - response_duration_ms properties: status: type: string minLength: 1 enum: - delivered - failed description: '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: type: - integer - 'null' description: HTTP status returned by your endpoint. Null when no response was received (timeout, connection error, DNS failure). example: 200 response_body: type: string description: 'Response body returned by your endpoint, truncated to the first 1024 bytes. Omitted when your endpoint returned no body or could not be reached. ' example: OK response_duration_ms: type: integer minimum: 0 description: Round-trip delivery latency in milliseconds. example: 142 event_payload: description: 'The full event body delivered to your endpoint. Test sends use a minimal synthetic body rather than a full event payload, so this field is omitted. ' $ref: '#/components/schemas/WebhookEvent' error: type: string minLength: 1 description: A short explanation of why the event could not be delivered. Present only when your endpoint could not be reached. example: connection refused EventWhatsAppFailedData: type: object description: Payload of the whatsapp.failed event. allOf: - $ref: '#/components/schemas/EventWhatsAppBase' - type: object required: - error properties: error: $ref: '#/components/schemas/WhatsAppError' description: Why the message terminally failed. EventSMSExpired: type: object additionalProperties: false description: The message's validity period elapsed before it could be delivered. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - sms.expired description: Event type. example: sms.expired timestamp: type: string minLength: 1 format: date-time description: Time the message expired. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventSMSExpiredData' EventWhatsAppReceivedData: type: object description: 'Payload of the whatsapp.received event. Carries the message''s content so a subscriber can act on it without reading the message back. ' allOf: - $ref: '#/components/schemas/EventWhatsAppBase' - type: object properties: text: allOf: - $ref: '#/components/schemas/WhatsAppText' description: Text the contact sent. image: allOf: - $ref: '#/components/schemas/WhatsAppImage' description: Image the contact sent. video: allOf: - $ref: '#/components/schemas/WhatsAppVideo' description: Video the contact sent. audio: allOf: - $ref: '#/components/schemas/WhatsAppAudio' description: Audio the contact sent. sticker: allOf: - $ref: '#/components/schemas/WhatsAppSticker' description: Sticker the contact sent. document: allOf: - $ref: '#/components/schemas/WhatsAppDocument' description: Document the contact sent. location: allOf: - $ref: '#/components/schemas/WhatsAppLocation' description: Location the contact sent. contact_cards: type: array description: 'Contact cards the contact shared, either by tapping a button that asked for their number or by sending a card from their address book. ' items: $ref: '#/components/schemas/WhatsAppContactCard' interactive_reply: allOf: - $ref: '#/components/schemas/WhatsAppInteractiveReply' description: 'What the contact tapped, when the message answers an interactive message or a template''s quick-reply button. ' unsupported: allOf: - $ref: '#/components/schemas/WhatsAppUnsupported' description: 'Set when the contact sent content the API does not model, naming the WhatsApp content type. ' PreferenceID: type: string minLength: 1 pattern: ^prf_[0-9a-hjkmnp-tv-z]{26}$ example: prf_01krdgeqcxet5s7t44vh8rt9mg EventSMSSuppressionCreated: type: object additionalProperties: false description: 'A destination was added to the workspace''s SMS suppression ledger: a subscriber''s STOP, a carrier opt-out, or a manual add.' required: - type - timestamp - data properties: type: $ref: '#/components/schemas/SMSSuppressionCreatedEventType' timestamp: type: string minLength: 1 format: date-time description: When the episode's opening statement took effect (`effective_at`). example: '2026-08-12T12:00:00Z' data: $ref: '#/components/schemas/EventSMSSuppressionCreatedData' EmailRejectionReason: type: string minLength: 1 enum: - recipient_suppressed - transmission_failed - generation_failure - policy_rejection - domain_unverified - quota_exceeded - recipient_not_allowed x-enum-varnames: - EmailRejectionReasonRecipientSuppressed - EmailRejectionReasonTransmissionFailed - EmailRejectionReasonGenerationFailure - EmailRejectionReasonPolicyRejection - EmailRejectionReasonDomainUnverified - EmailRejectionReasonQuotaExceeded - EmailRejectionReasonRecipientNotAllowed description: "Why an email was rejected before delivery.\n\n- `recipient_suppressed`: The recipient is on the workspace suppression list, so\n delivery was never attempted.\n- `transmission_failed`: The message could not be transmitted for delivery.\n- `generation_failure`: The message could not be built for delivery (template or\n content issue).\n- `policy_rejection`: The message was refused by sending policy.\n- `domain_unverified`: The sending domain was not verified.\n- `quota_exceeded`: The organization's send quota was reached.\n- `recipient_not_allowed`: A recipient was not permitted for this send (for shared\n onboarding-domain sends, recipients must be verified workspace members).\n" example: recipient_suppressed WebhookEndpointCreate: type: object additionalProperties: false required: - url - events properties: url: type: string maxLength: 2048 format: uri minLength: 1 description: 'HTTPS URL to deliver events to, at most 2048 characters. The host must be publicly reachable: URLs on private, loopback, or link-local addresses are rejected with a `422`. ' example: https://example.com/webhook events: type: array items: $ref: '#/components/schemas/WebhookEventType' minItems: 1 description: Event types to subscribe to; the endpoint receives only matching events. Types outside the event catalog return a `422`, and an endpoint holds at most 100 entries. example: - email.delivered - email.bounced description: type: string maxLength: 256 description: Human-readable label for this endpoint, up to 256 characters. example: Production webhook endpoint example: url: https://example.com/webhooks/bird events: - email.delivered - email.bounced description: Production delivery + bounce notifications WhatsAppGroupID: type: string minLength: 1 pattern: ^wag_[0-9a-hjkmnp-tv-z]{26}$ example: wag_01krdgeqcxet5s7t44vh8rt9mg EventSMSUndeliveredData: type: object description: Payload of the sms.undelivered event. allOf: - $ref: '#/components/schemas/EventSMSBase' - type: object required: - error properties: error: $ref: '#/components/schemas/SMSError' description: Why the message was not delivered. EventEmailDeferred: type: object additionalProperties: false description: The recipient's mail server temporarily refused the email. Delivery remains pending and is retried. May fire more than once per recipient. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - email.deferred description: Event type. example: email.deferred timestamp: type: string minLength: 1 format: date-time description: Time the deferral was recorded. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventEmailDeferredData' EventEmailAcceptedData: type: object description: Payload of the email.accepted event. allOf: - $ref: '#/components/schemas/EventEmailBase' VerificationTo: type: object additionalProperties: false minProperties: 1 description: '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. ' properties: email: type: string minLength: 1 format: email description: The recipient's email address. Case does not matter; the address is lowercased before use. example: user@example.com phone_number: type: string minLength: 1 description: 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`). example: '+15551234567' EventEmailOpened: type: object additionalProperties: false description: The recipient opened the email (the tracking pixel was loaded). May fire more than once per recipient. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - email.opened description: Event type. example: email.opened timestamp: type: string minLength: 1 format: date-time description: Time the open was recorded. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventEmailOpenedData' EventEmailMailboxSuspended: type: object additionalProperties: false description: This mailbox-suspension event is reserved and is not currently emitted. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - email_mailbox.suspended description: Event type. example: email_mailbox.suspended timestamp: type: string minLength: 1 format: date-time description: When the event occurred. example: '2026-07-08T12:00:00Z' data: $ref: '#/components/schemas/EventEmailMailboxSuspendedData' EventVerifyVerificationFailedData: type: object description: Payload of the verify.verification.failed event. allOf: - $ref: '#/components/schemas/EventVerifyBase' - type: object required: - status - reason - channel - last_attempt_reason - failed_at properties: status: type: string minLength: 1 x-extensible-enum: - failed description: The verification's state, always `failed`. Open enum for forward compatibility. example: failed reason: $ref: '#/components/schemas/VerificationTerminalReason' description: 'Why the verification ended. Always `undeliverable` on this event: no planned channel delivered a passcode.' example: undeliverable channel: oneOf: - $ref: '#/components/schemas/VerificationChannel' - type: 'null' description: The last channel the verification tried, the one whose failure left it with nowhere else to go. Null when no channel was attributed. example: sms last_attempt_reason: $ref: '#/components/schemas/VerificationAttemptFailureReason' description: 'Why that last send did not deliver. This is the actionable half of the event: `not_billable` means the workspace balance could not cover the send, while the delivery reasons point at the recipient or the channel.' example: not_billable failed_at: type: string minLength: 1 format: date-time description: Time the verification was resolved. example: '2026-07-24T12:00:05Z' EventVerifyVerificationCreatedData: type: object description: Payload of the verify.verification.created event. allOf: - $ref: '#/components/schemas/EventVerifyBase' - type: object required: - channel - status - created_at properties: channel: $ref: '#/components/schemas/VerificationChannel' description: The first channel of the verification's resolved channel plan. example: sms status: type: string minLength: 1 x-extensible-enum: - pending description: The verification's state at creation, always `pending`. Open enum for forward compatibility. example: pending created_at: type: string minLength: 1 format: date-time description: Time the verification session was created. example: '2026-07-24T12:00:00Z' EventSMSBase: type: object description: Identity fields shared by every SMS lifecycle event payload. required: - sms_id - workspace_id - to - from - tags - metadata - requested_language - resolved_language - template_id - template_version_id - template_content_hash properties: sms_id: $ref: '#/components/schemas/SMSMessageID' description: ID of the SMS message. workspace_id: $ref: '#/components/schemas/WorkspaceID' description: ID of the workspace that owns this event. to: type: string minLength: 1 description: '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. ' example: '+15551234567' from: type: string minLength: 1 description: '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. ' example: '+15557654321' tags: type: - array - 'null' items: $ref: '#/components/schemas/Tag' description: '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. ' metadata: type: - object - 'null' additionalProperties: true description: '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. ' example: order_id: ord_123 requested_language: description: 'The template language requested by the send, in canonical form. Null when the send named no language or used no template. ' oneOf: - $ref: '#/components/schemas/LanguageTag' - type: 'null' resolved_language: description: 'The template language rendered at acceptance, in canonical form. Null when the send used no template. ' oneOf: - $ref: '#/components/schemas/LanguageTag' - type: 'null' template_id: description: The template rendered at acceptance, or null for a free-text message. oneOf: - $ref: '#/components/schemas/SMSTemplateID' - type: 'null' template_version_id: description: 'The workspace published version or synthetic built-in version rendered at acceptance, or null for a free-text message. For a built-in template, `template_content_hash` identifies the exact catalogue source. ' oneOf: - $ref: '#/components/schemas/SMSTemplateVersionID' - type: 'null' template_content_hash: description: The rendered language's source fingerprint, or null for a free-text message. oneOf: - $ref: '#/components/schemas/SMSTemplateContentHash' - type: 'null' cost: $ref: '#/components/schemas/MessageCost' description: 'Message cost as of this event, split into the platform charge and any third-party fees passed through. Null on an event that priced nothing. Components are named so you can merge them per component rather than replacing the object: webhook delivery is not ordered, so an older event arriving late would otherwise overwrite a newer figure. Take the latest `occurred_at` you have seen for each component. `amount` is the sum of the components in this payload and does not represent a settled total. ' EventEmailCanceled: type: object additionalProperties: false description: A scheduled send was canceled before it fired. Fires once for each message regardless of its recipient count. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - email.canceled description: Event type. example: email.canceled timestamp: type: string minLength: 1 format: date-time description: Time the scheduled send was canceled. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventEmailCanceledData' EventVerifyAttemptUndeliveredData: type: object description: Payload of the verify.attempt.undelivered event. allOf: - $ref: '#/components/schemas/EventVerifyBase' - type: object required: - channel - address - reason - error - failed_at properties: channel: $ref: '#/components/schemas/VerificationChannel' description: The channel this attempt was sent on. example: sms address: type: string minLength: 1 description: The single address this attempt was dispatched to, an E.164 phone number or an email address. example: '+14155550100' reason: $ref: '#/components/schemas/VerificationAttemptFailureReason' description: Why the attempt failed to reach the recipient. example: carrier_rejected error: type: - string - 'null' description: Diagnostic text describing the failure, for display only. Null when none was reported. example: Carrier rejected the message before delivery failed_at: type: string minLength: 1 format: date-time description: Time the failure was recorded. example: '2026-07-24T12:00:05Z' EventWhatsAppRejectedData: type: object description: Payload of the whatsapp.rejected event. allOf: - $ref: '#/components/schemas/EventWhatsAppBase' - type: object required: - error properties: error: $ref: '#/components/schemas/WhatsAppError' description: Why the message was rejected before sending. EventEmailMailboxMessageFailedData: type: object additionalProperties: false description: Payload of the email_mailbox.message_failed event. required: - message_id - mailbox_id - thread_id - reason properties: message_id: $ref: '#/components/schemas/EmailID' description: ID of the failed message. Per-recipient `email.*` events use this value as `email_id`. Use it to deduplicate events when you subscribe to both event families. mailbox_id: $ref: '#/components/schemas/MailboxID' description: ID of the mailbox the message was sent from. thread_id: $ref: '#/components/schemas/ThreadID' description: ID of the thread the message belongs to. reason: type: string minLength: 1 description: Why the message reached a terminal delivery failure. example: all recipients bounced WhatsAppText: type: object additionalProperties: false description: Text content of a WhatsApp message. required: - body properties: body: type: string minLength: 1 description: The message text. example: Does it come in another color? example: body: Does it come in another color? EmailBroadcastID: type: string minLength: 1 pattern: ^eb_[0-9a-hjkmnp-tv-z]{26}$ example: eb_01krdgeqcxet5s7t44vh8rt9mg EventVerifyAttemptSentData: type: object description: Payload of the verify.attempt.sent event. allOf: - $ref: '#/components/schemas/EventVerifyBase' - type: object required: - channel - address - from - sent_at properties: channel: $ref: '#/components/schemas/VerificationChannel' description: The channel this attempt was sent on. example: sms address: type: string minLength: 1 description: The single address this attempt was dispatched to, an E.164 phone number or an email address. example: '+14155550100' from: type: - string - 'null' description: '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.' example: '29999' sent_at: type: string minLength: 1 format: date-time description: Time the passcode was dispatched. example: '2026-07-24T12:00:01Z' EventSMSUndelivered: type: object additionalProperties: false description: The carrier reported a non-permanent failure to deliver the message. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - sms.undelivered description: Event type. example: sms.undelivered timestamp: type: string minLength: 1 format: date-time description: Time the non-delivery was recorded. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventSMSUndeliveredData' EventSMSFailed: type: object additionalProperties: false description: Message delivery failed permanently. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - sms.failed description: Event type. example: sms.failed timestamp: type: string minLength: 1 format: date-time description: Time the failure was recorded. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventSMSFailedData' EventEmailMailboxThreadCreatedData: type: object additionalProperties: false description: Payload of the email_mailbox.thread_created event. required: - thread_id - mailbox_id - subject - initiated_by properties: thread_id: $ref: '#/components/schemas/ThreadID' description: ID of the thread. mailbox_id: $ref: '#/components/schemas/MailboxID' description: ID of the mailbox the thread was created in. subject: type: - string - 'null' description: Subject of the first message in the thread, or null when it had none. example: Your quote initiated_by: type: string minLength: 1 enum: - inbound - outbound description: Which direction created the thread. example: inbound EventEmailComplained: type: object additionalProperties: false description: The recipient marked the email as spam through their mailbox provider's feedback loop. Fires once per recipient. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - email.complained description: Event type. example: email.complained timestamp: type: string minLength: 1 format: date-time description: Time the complaint was recorded. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventEmailComplainedData' VoiceCallID: type: string minLength: 1 pattern: ^vcl_[0-9a-hjkmnp-tv-z]{26}$ example: vcl_01krdgeqcxet5s7t44vh8rt9mg EventVoiceCallEnded: type: object additionalProperties: false description: The call ended after either party hung up or call setup failed. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - voice_call.ended description: Event type. example: voice_call.ended timestamp: type: string minLength: 1 format: date-time description: Time either party hung up or call setup failed. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventVoiceCallEndedData' EventVerifyVerificationVerified: type: object additionalProperties: false description: 'The verification was successfully resolved: the recipient confirmed the correct code.' required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - verify.verification.verified description: Event type. example: verify.verification.verified timestamp: type: string minLength: 1 format: date-time description: Time the verification was verified. example: '2026-07-24T12:01:00Z' data: $ref: '#/components/schemas/EventVerifyVerificationVerifiedData' EventEmailOpenedData: type: object description: Payload of the email.opened event. allOf: - $ref: '#/components/schemas/EventEmailBase' - type: object required: - ip_address - user_agent properties: ip_address: type: - string - 'null' description: IP address of the client that opened the email, or null when it is not known. example: 203.0.113.9 user_agent: type: - string - 'null' description: User-agent string of the client that opened the email, or null when it is not known. example: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) WorkspaceID: type: string minLength: 1 pattern: ^ws_[0-9a-hjkmnp-tv-z]{26}$ example: ws_01krdgeqcxet5s7t44vh8rt9mg EventEmailDeliveredData: type: object description: Payload of the email.delivered event. allOf: - $ref: '#/components/schemas/EventEmailBase' MailboxID: type: string minLength: 1 pattern: ^mbx_[0-9a-hjkmnp-tv-z]{26}$ example: mbx_01krdgeqcxet5s7t44vh8rt9mg WhatsAppReceivedEventType: type: string minLength: 1 enum: - whatsapp.received description: Event type. example: whatsapp.received WhatsAppContactUrl: type: object additionalProperties: false description: One website on a shared contact card. properties: url: type: string description: '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. ' example: luckyshrub.example.com type: type: string description: '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. ' example: Company EventPreferenceRevokedData: type: object description: Payload of the preference.revoked event. allOf: - $ref: '#/components/schemas/EventPreferenceBase' WebhookReplayRequest: type: object additionalProperties: false properties: since: type: string format: date-time minLength: 1 description: 'Replay events that occurred at or after this timestamp. Defaults to 24 hours before the request when omitted. ' example: '2026-05-07T00:00:00Z' until: type: string format: date-time minLength: 1 description: 'Replay events that occurred before or at this timestamp. Omit to bound the window only by `since`. ' example: '2026-05-07T23:59:59Z' SMSErrorCode: type: string minLength: 1 x-extensible-enum: - invalid_destination - unreachable - blocked_by_carrier - blocked_by_recipient - landline_unreachable - content_rejected - sender_unregistered - recipient_opted_out - provider_unavailable - insufficient_balance - unknown description: '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_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. ' ThreadID: type: string minLength: 1 pattern: ^thr_[0-9a-hjkmnp-tv-z]{26}$ example: thr_01krdgeqcxet5s7t44vh8rt9mg WhatsAppSticker: type: object description: 'Sticker content of a WhatsApp message. ' allOf: - $ref: '#/components/schemas/WhatsAppMedia' - type: object properties: animated: type: boolean description: 'Whether the sticker is animated. Absent on an outbound message. ' example: false EventEmailDelivered: type: object additionalProperties: false description: An outbound email reached the recipient's mail server and was accepted. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - email.delivered description: Event type. example: email.delivered timestamp: type: string minLength: 1 format: date-time description: Time the recipient's mail server accepted the message. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventEmailDeliveredData' EventWhatsAppSuppressionCreatedData: type: object additionalProperties: false description: Payload of the whatsapp_suppression.created event. required: - suppression_id - address - waba - reason - workspace_id properties: suppression_id: $ref: '#/components/schemas/WhatsAppSuppressionID' description: The suppression episode that was opened. example: was_01krdgeqcxet5s7t44vh8rt9mg address: type: string minLength: 1 description: The suppressed WhatsApp address. For a phone number this is canonical E.164 with a leading plus sign, such as `+5511977670804`. example: '+5511977670804' waba: type: - string - 'null' description: The WhatsApp Business Account the suppression is limited to, identified by its WhatsApp-issued account ID, or null when it covers the whole workspace. example: null reason: type: string minLength: 1 x-extensible-enum: - manual description: 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: $ref: '#/components/schemas/WorkspaceID' description: The workspace the suppression belongs to. example: ws_01krdgeqcxet5s7t44vh8rt9mg PreferenceRevokedEventType: type: string minLength: 1 enum: - preference.revoked description: Always `preference.revoked` for this event. example: preference.revoked ErrorDetail: type: object additionalProperties: false required: - param - message properties: param: type: string minLength: 1 description: 'Dotted field path, such as `to[0].email`, `subject`, or `.`. When the request was rejected for a query parameter the endpoint does not declare, this carries that parameter''s name instead of a field path. ' message: type: string minLength: 1 description: What is wrong with this field. EventWhatsAppRead: type: object additionalProperties: false description: The recipient read the message. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - whatsapp.read description: Event type. example: whatsapp.read timestamp: type: string minLength: 1 format: date-time description: Time the recipient read the message. example: '2026-07-16T12:00:00Z' data: $ref: '#/components/schemas/EventWhatsAppReadData' EventVoiceCallInitiated: type: object additionalProperties: false description: Call routing began. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - voice_call.initiated description: Event type. example: voice_call.initiated timestamp: type: string minLength: 1 format: date-time description: Time the call was initiated. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventVoiceCallInitiatedData' WhatsAppContactAddress: type: object additionalProperties: false description: One postal address on a shared contact card. properties: street: type: string example: 1 Hacker Way city: type: string example: Menlo Park state: type: string example: CA zip: type: string example: '94025' country: type: string example: United States country_code: type: string description: 'The country as the card holds it, left exactly as WhatsApp sent it: it describes a postal address rather than a routing destination. ' example: US type: type: string description: '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. ' example: Home EventEmailAccepted: type: object additionalProperties: false description: The API accepted the email send and is preparing it for delivery. Fires once per requested recipient. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - email.accepted description: Event type. example: email.accepted timestamp: type: string minLength: 1 format: date-time description: Time the API accepted the send. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventEmailAcceptedData' Timestamps: type: object required: - created_at - updated_at properties: created_at: type: string format: date-time minLength: 1 readOnly: true example: '2026-05-20T09:14:52Z' updated_at: type: string format: date-time minLength: 1 readOnly: true example: '2026-05-25T16:42:01Z' Error: type: object additionalProperties: false required: - error properties: error: $ref: '#/components/schemas/ErrorBody' VoiceCallDirection: type: string minLength: 1 enum: - inbound - outbound description: Whether the call originated from your PBX (outbound) or arrived from a remote party (inbound). example: outbound EventSMSAcceptedData: type: object description: Payload of the sms.accepted event. allOf: - $ref: '#/components/schemas/EventSMSBase' - type: object required: - segments properties: segments: $ref: '#/components/schemas/SMSSegments' description: Segment breakdown used to calculate the message charge. EventEmailRejected: type: object additionalProperties: false description: The API rejected the email before delivery because of suppression, transmission failure, content, or policy. Fires once per recipient. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - email.rejected description: Event type. example: email.rejected timestamp: type: string minLength: 1 format: date-time description: Time the rejection was recorded. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventEmailRejectedData' EventEmailMailboxMessageDelivered: type: object additionalProperties: false description: 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`. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - email_mailbox.message_delivered description: Event type. example: email_mailbox.message_delivered timestamp: type: string minLength: 1 format: date-time description: When the event occurred. example: '2026-07-08T12:00:00Z' data: $ref: '#/components/schemas/EventEmailMailboxMessageDeliveredData' EventEmailMailboxMessageReceivedData: type: object additionalProperties: false description: 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. required: - message_id - mailbox_id - thread_id - from - to - subject - attachment_count properties: message_id: $ref: '#/components/schemas/InboundEmailMessageID' description: ID of the received message. The corresponding `email.received` event uses this value as `inbound_message_id`. Use it to deduplicate events when you subscribe to both event families. mailbox_id: $ref: '#/components/schemas/MailboxID' description: ID of the mailbox that received the message. thread_id: $ref: '#/components/schemas/ThreadID' description: ID of the thread the message was filed into. route_id: type: - string - 'null' description: ID (ein_…) of the explicit inbound route that matched, or null when the message was delivered by the virtual exact-address route. example: null from: type: string minLength: 1 format: email description: Envelope-from address. example: alice@example.com to: type: array items: type: string format: email description: Recipient addresses the message was sent to. example: - support@inbox.ai subject: type: - string - 'null' description: Subject line as received, or null when the message had no subject. example: 'Re: Your quote' extracted_text: type: - string - 'null' description: 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. example: Sounds good — can you send the invoice? truncated_text: type: boolean description: True when `extracted_text` was truncated to the 64 KB cap. Fetch the full text through the thread-member endpoint. default: false attachment_count: type: integer minimum: 0 description: Number of attachments on the message. Attachment content remains available for the mailbox's retention tier. example: 1 authentication: type: - string - 'null' enum: - pass - fail - unknown - null description: '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: type: - boolean - 'null' description: 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: type: - boolean - 'null' description: 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: type: - boolean - 'null' description: 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`. EventPreferenceGrantedData: type: object description: Payload of the preference.granted event. allOf: - $ref: '#/components/schemas/EventPreferenceBase' EventEmailClicked: type: object additionalProperties: false description: The recipient clicked a tracked link in the email. May fire more than once per recipient. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - email.clicked description: Event type. example: email.clicked timestamp: type: string minLength: 1 format: date-time description: Time the click was recorded. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventEmailClickedData' EventVoiceBase: type: object description: Identity fields shared by every voice call lifecycle event payload. required: - call_id - workspace_id - direction - from - to properties: call_id: $ref: '#/components/schemas/VoiceCallID' description: ID of the call record. session_id: oneOf: - $ref: '#/components/schemas/VoiceSessionID' - type: 'null' description: Session identifier shared across all legs of a multi-party or transferred call. Use this to correlate related call records. Null when session correlation is not available for the call. workspace_id: $ref: '#/components/schemas/WorkspaceID' description: ID of the workspace that owns this event. direction: $ref: '#/components/schemas/VoiceCallDirection' from: type: string minLength: 1 description: Calling party number in E.164 format. example: '+14155551234' to: type: string minLength: 1 description: Called party number in E.164 format. example: '+16505559876' WhatsAppContactPhone: type: object additionalProperties: false description: One phone number on a shared contact card. properties: phone_number: type: string description: '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. ' example: '+16505551234' type: type: string description: '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. ' example: CELL EventDomainVerifiedData: type: object additionalProperties: false description: Payload of the domain.verified event. required: - domain_id - domain - workspace_id properties: domain_id: $ref: '#/components/schemas/DomainID' description: The sending domain resource that verified. example: dom_01krdgeqcxet5s7t44vh8rt9mg domain: type: string minLength: 1 description: The sending domain hostname. example: mail.example.com workspace_id: $ref: '#/components/schemas/WorkspaceID' description: The workspace the domain is assigned to. example: ws_01krdgeqcxet5s7t44vh8rt9mg WhatsAppContactEmail: type: object additionalProperties: false description: One email address on a shared contact card. properties: email: type: string example: barbara@example.com type: type: string description: '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. ' example: Personal EventEmailProcessed: type: object additionalProperties: false description: The API prepared the message for delivery to the recipient's mail server. Fires once per recipient. required: - type - timestamp - data properties: type: type: string minLength: 1 enum: - email.processed description: Event type. example: email.processed timestamp: type: string minLength: 1 format: date-time description: Time the message was prepared for delivery. example: '2026-05-21T12:00:00Z' data: $ref: '#/components/schemas/EventEmailProcessedData' EventSMSExpiredData: type: object description: Payload of the sms.expired event. allOf: - $ref: '#/components/schemas/EventSMSBase' - type: object required: - error properties: error: $ref: '#/components/schemas/SMSError' description: Why the message was still undelivered when its validity period elapsed. Typically `unreachable`, the handset having stayed off or out of coverage for the whole window. WebhookCreate: type: object required: - channelId - url - events properties: channelId: type: string description: The channel to subscribe to. Omit for a generic webhook that receives events from all channels. url: type: string format: uri description: The URL to receive webhook payloads. events: type: array description: The list of events to subscribe to. items: type: string enum: - message.created - message.updated - conversation.created - conversation.updated VoiceWebhookCreate: type: object required: - url properties: url: type: string format: uri description: The URL to receive webhook callbacks. token: type: string description: A token for webhook signature validation. VoiceWebhookResponse: type: object properties: data: type: array items: $ref: '#/components/schemas/VoiceWebhook' VoiceWebhook: type: object properties: id: type: string description: The unique identifier of the webhook. url: type: string format: uri description: The URL that receives webhook callbacks. token: type: string description: The token used for signature validation. createdAt: type: string format: date-time description: The date and time when the webhook was created. updatedAt: type: string format: date-time description: The date and time when the webhook was last updated. WebhookList: type: object properties: offset: type: integer description: The offset of the result set. limit: type: integer description: The limit applied to the result set. count: type: integer description: The number of items returned. totalCount: type: integer description: The total number of webhooks. items: type: array items: $ref: '#/components/schemas/Webhook' Webhook: type: object properties: id: type: string description: The unique identifier of the webhook. channelId: type: string description: The channel the webhook is subscribed to. url: type: string format: uri description: The URL that receives webhook payloads. events: type: array description: The events the webhook is subscribed to. items: type: string status: type: string description: The status of the webhook. enum: - enabled - disabled createdDatetime: type: string format: date-time description: The date and time when the webhook was created. updatedDatetime: type: string format: date-time description: The date and time when the webhook was last updated. responses: Unprocessable: description: '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`. ' content: application/json: schema: $ref: '#/components/schemas/Error' NotFound: description: Resource not found content: application/json: schema: $ref: '#/components/schemas/Error' PreconditionFailed: description: Precondition failed content: application/json: schema: $ref: '#/components/schemas/Error' Unauthorized: description: Authentication required content: application/json: schema: $ref: '#/components/schemas/Error' BadRequest: description: Bad request content: application/json: schema: $ref: '#/components/schemas/Error' RateLimited: description: Rate limit exceeded headers: RateLimit: $ref: '#/components/headers/RateLimit' RateLimit-Policy: $ref: '#/components/headers/RateLimit-Policy' Retry-After: $ref: '#/components/headers/RetryAfter' content: application/json: schema: $ref: '#/components/schemas/Error' Forbidden: description: Insufficient permissions content: application/json: schema: $ref: '#/components/schemas/Error' ServiceUnavailable: description: '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. ' headers: Retry-After: $ref: '#/components/headers/RetryAfter' content: application/json: schema: $ref: '#/components/schemas/Error' InternalError: description: Internal server error content: application/json: schema: $ref: '#/components/schemas/Error' headers: RateLimit: description: 'Remaining capacity for the request''s rate-limit policy as an IETF Structured Field. Format: `"";r=;t=`. ' schema: type: string example: '"email_send";r=842;t=35' RetryAfter: description: 'Number of seconds to wait before retrying the request. ' schema: type: integer minimum: 0 example: 35 RateLimit-Policy: description: 'Effective quota for the request''s rate-limit policy as an IETF Structured Field. Format: `"";q=;w=`. ' schema: type: string example: '"email_send";q=1000;w=60' IdempotencyReplay: description: The API includes this header when it replays the response for an earlier request that used the same `Idempotency-Key`. The API does not process the request again. schema: type: string enum: - 'true' parameters: EndingBefore: name: ending_before in: query required: false description: Cursor from the `prev_cursor` or `refresh_cursor` field of a previous list response. Returns items immediately before the cursor position in the current sort order. `prev_cursor` returns the preceding page. `refresh_cursor` anchors at the first row of that response, which on a newest-first sort is how to fetch the items that have appeared since. schema: type: string PaginationLimit: name: limit in: query required: false description: Maximum number of items to return per page. schema: type: integer minimum: 1 maximum: 100 default: 25 IncludeTotal: name: include_total in: query required: false description: When true, the response includes a `total` field with the total number of items matching the request's filters across all pages. schema: type: boolean default: false IdempotencyKey: name: Idempotency-Key in: header required: false description: "Client-supplied key. On operations supporting request deduplication, a retained\nresponse is replayed for duplicate requests with the same key within the\nidempotency window (3 hours by default). This protection requires a workspace,\norganization, or staff-account scope. User-only and unauthenticated operations,\nstreams, and operations with a separate replay contract do not use this\nresponse replay.\n\nOn a supported operation, if idempotency protection is unavailable before execution, the API returns\n`503 IdempotencyUnavailable` (E01033) without executing this attempt. Retry with\nbackoff using the same key and request. An operation that takes effect before\nits response is retained can still execute again on retry.\n\nTwo distinct 409 errors signal misuse:\n\n- `request_in_progress` (E01004): The same key is currently being\n processed by a concurrent request. Wait briefly and retry. The lock expires within 30 seconds.\n- `idempotency_key_reuse` (E01005): The same key has already completed\n against a different request body or method. Generate a new key.\n\nRecommended key format is `/` (for example `welcome-user/usr_abc123`).\n" schema: type: string maxLength: 255 StartingAfter: name: starting_after in: query required: false description: Cursor from the `next_cursor` field of a previous list response. Returns items immediately after the cursor position in the current sort order. schema: type: string OrderDesc: name: order in: query required: false description: 'Sort direction. Defaults to `desc`, which sorts from newest to oldest or largest to smallest, depending on the selected sort field. ' schema: $ref: '#/components/schemas/SortOrder' default: desc limitParam: name: limit in: query required: false description: The maximum number of items to return. schema: type: integer default: 20 webhookIdParam: name: webhookId in: path required: true description: The unique identifier of the webhook. schema: type: string offsetParam: name: offset in: query required: false description: The number of items to skip. schema: type: integer default: 0 securitySchemes: BearerAuth: type: http scheme: bearer description: 'Pass the API key as a bearer token in the `Authorization` header. Keys use the format `bk_{region}_*`. The prefix identifies the region and selects the API endpoint. Official Bird SDKs and the CLI derive the region from the key. ' CookieAuth: type: apiKey in: cookie name: bird_session description: 'Session cookie set after signing in to the Bird dashboard. The cookie value is an opaque session token; no session data is stored in the cookie itself. ' RealtimeKey: type: apiKey in: header name: X-Realtime-Key description: 'The Realtime app key. Together with `X-Realtime-Secret`, it authenticates a request to the Realtime API in addition to the workspace credential. Both values come from the app''s credentials and must belong to the calling workspace. Official Bird SDKs accept the pair as client configuration. ' RealtimeSecret: type: apiKey in: header name: X-Realtime-Secret description: 'The Realtime app secret paired with `X-Realtime-Key`. The API returns the secret only when the key is created and does not store it. Create a new key and revoke the current key if you lose the secret. Official Bird SDKs accept the pair as client configuration. ' accessKey: type: apiKey in: header name: Authorization description: Access key authentication in the form of 'AccessKey {accessKey}'. x-refined-from: - messagebird-bird-api-openapi.yml - messagebird-webhooks-api-openapi.yml