<Intro>

<EndpointHeader />

<Description>

Returns the lifecycle event timeline for a message, in chronological order.

</Description>

</Intro>

<Parameters in="path">

<Parameter name="message_id" type="string">

<Description>

Message ID.

</Description>

</Parameter>

</Parameters>

<Parameters in="query">

<Parameter name="type" type="string">

<Description>

Filter by event type (e.g. `sms.delivered`, `sms.failed`).

</Description>

</Parameter>

</Parameters>

<Payload kind="response">

<Field name="data" type="array of object" required>

<Description>

Timeline events for this SMS message, in chronological order. The timeline is bounded and returned in full — this list is not paginated.

</Description>

<FieldChildren kind="response">

<Field name="id" type="string" prefix="data." required>

<Description>

Event ID.

</Description>

</Field>

<Field name="type" type="string" prefix="data." required>

<Description>

Lifecycle event type. `sms.accepted` — Bird accepted the request. `sms.sent` — handed to the carrier. `sms.delivered` — delivery confirmed. `sms.undelivered` — non-permanent non-delivery. `sms.failed` — terminal permanent failure. `sms.rejected` — refused before reaching the carrier. `sms.expired` — the validity period elapsed. Open enum — new event types may be added over time, so treat any unrecognized value as a future event rather than an error.

</Description>

<Description>

Possible values (may grow over time): `sms.accepted`, `sms.sent`, `sms.delivered`, `sms.undelivered`, `sms.failed`, `sms.rejected`, `sms.expired`

</Description>

</Field>

<Field name="occurred_at" type="string" prefix="data." required>

<Description>

When this event occurred.

</Description>

</Field>

<Field name="carrier" type="string" prefix="data.">

<Description>

Carrier that handled the message. Present on `sms.sent` and `sms.delivered` once identified, absent otherwise.

</Description>

</Field>

<Field name="mcc_mnc" type="string" prefix="data.">

<Description>

Mobile country code and mobile network code of the carrier. Present on `sms.sent` and `sms.delivered` once identified, absent otherwise.

</Description>

</Field>

<Field name="error" type="nullable object" prefix="data.">

<Description>

Failure detail. Present only on `sms.failed`, `sms.undelivered`, `sms.rejected`, and `sms.expired` events.

</Description>

<FieldChildren kind="response">

<Field name="code" type="string" prefix="data.error." required>

<Description>

Bird-stable failure reason. Open enum: Bird adds reasons as the carrier platform's own buckets are covered, so treat an unrecognized value as a future reason rather than an error. `invalid_destination`: the number is not assigned, ported out, or malformed. `unreachable`: handset off or out of 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`: an upstream failure after retries. `insufficient_balance`: the workspace wallet had insufficient balance to send the message. `unknown`: an unmapped failure.

</Description>

<Description>

Possible values (may grow over time): `invalid_destination`, `unreachable`, `blocked_by_carrier`, `blocked_by_recipient`, `landline_unreachable`, `content_rejected`, `sender_unregistered`, `recipient_opted_out`, `provider_unavailable`, `insufficient_balance`, `unknown`

</Description>

</Field>

<Field name="description" type="string" prefix="data.error." required>

<Description>

Human-readable explanation of the failure.

</Description>

</Field>

<Field name="carrier_error_code" type="nullable string" prefix="data.error.">

<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.

</Description>

</Field>

<Field name="occurred_at" type="string" prefix="data.error." required>

<Description>

When the failure occurred.

</Description>

</Field>

</FieldChildren>

</Field>

</FieldChildren>

</Field>

</Payload>