sms-messages

Get an SMS message

Returns a single SMS message: its current delivery status, segment breakdown, cost, and failure detail when it failed. The status advances asynchronously as delivery progresses, and cost is null until the message has been priced, so poll this operation (or subscribe to sms.* webhook events) after a send to confirm delivery. To scan messages in bulk, use List SMS messages instead.

get/v1/sms/messages/{message_id}

Request

  • Base URL: https://us1.platform.bird.com
  • URL: https://us1.platform.bird.com/v1/sms/messages/{message_id}
  • Auth: one of:
    • HTTP bearer
    • API key in cookie bird_session

Path parameters

message_idstring required
Example:sms_01krdgeqcxet5s7t44vh8rt9mg

ID of the message, as returned in the send response's id field.

Headers

X-Workspace-Idstring

Workspace context for the request. Required for dashboard authentication and master keys. Workspace keys and access tokens already identify their workspace; send that workspace or omit the header. A different one is rejected.

X-Organization-Idstring

Organization context for the request. Required for dashboard authentication. An API key or access token carries its own organization, so send either that organization or no header at all; a different one is rejected.

Response

SMS message with its current delivery status.

idstring required
direction'outbound' | 'inbound' required

Whether the message was sent from a Bird sender (outbound) or received from a subscriber (inbound).

status'scheduled' | 'accepted' | 'sent' | 'delivered' | 'undelivered' | 'failed' | 'rejected' | 'canceled' | 'expired' | 'received' required

Delivery status:

  • accepted: Accepted and awaiting carrier handoff.
  • sent: Handed to the carrier and awaiting a delivery receipt.
  • delivered: Confirmed as delivered.
  • undelivered: The carrier reported delivery as failed for a reason that may clear later, such as a handset out of coverage or a carrier at capacity. Final all the same: the message is not retried, so reaching the recipient means sending again.
  • failed: The carrier reported delivery as failed for a reason that will not clear, such as an unassigned number, a recipient who has opted out, or content the carrier refused.
  • rejected: Refused before carrier handoff.
  • expired: Reached its validity limit without a final receipt.
  • received: Received as an inbound message.

scheduled and canceled are declared ahead of the send-later scheduling feature that produces them, so their arrival is not a breaking change. No message carries either status today.

tostring required

Where the message went. On an outbound message this is the recipient's phone number in E.164 format; on an inbound one it is your own number that received it.

fromstring required

Where the message came from. On an outbound message this is the sender you sent it from: an E.164 number, an alphanumeric sender ID, or a short code. On an inbound message, this is the phone number that sent it to you.

textstring

The message body. Every message carries body text, attachments, or both, so this is absent only on a received message that carried attachments and no text. For a template send, this is the rendered text after parameter substitution. When category is authentication (a message carrying a one-time code), this is **REDACTED**: the code still reaches the recipient, but the API does not retain it for later reads.

category'transactional' | 'marketing' | 'authentication' | 'service'

Content classification: why you are sending. Carriers see it, and where a destination country requires the sender to be registered, that registration is approved for a category: a send outside what it covers returns a 422 SenderCategoryNotPermitted. A registration approved for marketing covers all four values; one approved for transactional, authentication, or service covers those three and not marketing. Use authentication for a one-time passcode and marketing for a promotion; otherwise pick the value matching the message's purpose.

requested_languagestring required

A language tag in BCP-47 form, for example en or pt-BR.

resolved_languagestring required

A language tag in BCP-47 form, for example en or pt-BR.

template_idstring required
template_version_idstring required
template_content_hashstring required

A fingerprint of SMS template text, prefixed with its algorithm. Compare it within this API version to identify the exact source without transferring it.

metadataobject

Arbitrary JSON metadata stored on the message and echoed in webhook payloads.

validity_periodinteger

Preview feature: how long, in seconds, the carrier may keep attempting delivery before the message is marked expired. Not returned yet.

carrierstring

Carrier that handled the message. Absent until a delivery receipt identifies it, and on a received message the carrier reports it only where a carrier fee applies.

mcc_mncstring

Mobile country code and mobile network code of the carrier. Absent until the carrier is identified.

created_atstring date-time required

When the message was accepted (outbound) or received (inbound).

sent_atstring date-time nullable

When the message was handed to the carrier. Null until then.

delivered_atstring date-time nullable

When delivery was confirmed. Null until then.

Example response

{
  "id": "sms_01krdgeqcxet5s7t44vh8rt9mg",
  "to": "+15551234567",
  "from": "+15557654321",
  "text": "Your order has shipped and is on its way.",
  "requested_language": "pt-BR",
  "resolved_language": "pt-BR",
  "template_id": "smt_01krdgeqcxet5s7t44vh8rt9mg",
  "template_version_id": "smv_01krdgeqcxet5s7t44vh8rt9mg",
  "template_content_hash": "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
  "segments": {
    "count": 1,
    "characters": 41
  },
  "cost": {
    "amount": "0.00990",
    "currency_code": "EUR",
    "transaction_amount": "0.00790",
    "passthrough_amount": "0.00200"
  },
  "tags": [
    {
      "name": "category",
      "value": "welcome"
    }
  ],
  "options": {
    "smart_encoding": true
  },
  "carrier": "Verizon",
  "mcc_mnc": "311480",
  "last_error": {
    "description": "Carrier filtered as spam"
  },
  "created_at": "2026-05-21T12:00:00Z"
}

Changes

No recorded changes to this operation across all 3 revisions of this API.