whatsapp-messages

Get a WhatsApp message

Returns a single WhatsApp message: its current delivery status, per-stage timestamps (sent_at, delivered_at, read_at), and failure detail when it failed. It carries the one content object it was built from: template, or free-form text, image, video, audio, sticker, document, location, interactive or contact_cards. An inbound message carries interactive_reply when the contact tapped a reply button or a list row. An inbound message whose content WhatsApp models and we do not carries unsupported instead, naming the type rather than reading back empty. The status advances asynchronously as delivery progresses, so poll this endpoint (or subscribe to whatsapp.* webhook events) after a send to confirm delivery. For the per-event timeline, use List events for a WhatsApp message instead.

get/v1/whatsapp/messages/{message_id}

Request

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

Path parameters

message_idstring required
Example:wam_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

WhatsApp message object.

idstring required
direction'outbound' | 'inbound' required

Whether the message was sent by the business (outbound) or received from the contact (inbound).

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

Delivery status:

  • accepted: Accepted and queued for sending.
  • sent: Handed to the WhatsApp network.
  • delivered: Confirmed as delivered to the recipient's device.
  • failed: Permanently failed.
  • rejected: Refused before sending and not charged.
  • received: Received as an inbound message.
  • scheduled: Reserved and not returned.
  • canceled: Reserved and not returned.

Read receipts appear in read_at and whatsapp.read events, in both directions: the recipient opening an outbound message, and the business acknowledging an inbound one.

originstring

Where a message came from when it did not come through Bird live: its provenance. It does not say who answers the contact. On a number shared with the WhatsApp Business app, a message can come from the app while Bird keeps answering.

  • business_agent_echo: the Meta Business Agent on this number composed it.
  • business_app_echo: someone sent it from the WhatsApp Business app on a number shared with it.
  • history_sync: WhatsApp copied it, in either direction, from the WhatsApp Business app's chat history when the number was shared. Neither /v1/whatsapp/messages nor a webhook event reports an imported message, so neither carries this value.
recipient_countinteger

How many recipients a group send was addressed to, taken when the send was accepted. It is the group's membership at that moment, not its membership now: someone joining through the invite link while the message is in flight does not receive it and does not change this count.

Absent on a one-to-one message, along with delivered_count and read_count. A message with one recipient has no fan-out to report, and its delivery is what status, delivered_at and read_at already say. Absent for the same reason on a group message sent before Bird recorded the count, and on a send to a group nobody had joined yet: there is no denominator to report, and none can be recovered after the fact, since membership has moved on. to.group_id is what tells a group message from a one-to-one one in every case, including those two. With no denominator to resolve against, status is read as stored, the way a one-to-one message's is: it reaches sent when the message is handed to WhatsApp and stops there, because delivery is confirmed per participant and a send with no participants collects no confirmations.

It is also the denominator status is resolved against: on a group message status reports the furthest point every recipient has reached, so it turns delivered only once delivered_count equals this number, and stays sent while some have confirmed and others have not. failed and rejected are never per recipient: there is one hand-off to the WhatsApp network and one way for that to be refused. delivered_at and read_at are the first recipient's, not the last.

delivered_countinteger

How many of the recipient_count recipients WhatsApp has confirmed the message reached. A recipient who reported only a read counts here too: WhatsApp skips the delivery receipt when someone is already looking at the chat, so waiting for one would leave that person uncounted for ever.

Absent on a one-to-one message, which has no fan-out to count, and on a group message with no recipient_count to count against.

read_countinteger

How many of the recipient_count recipients have opened the message. Read receipts do not move status, which has no read value; they surface here and in read_at.

Absent on a one-to-one message, which has no fan-out to count, and on a group message with no recipient_count to count against.

created_atstring date-time required

When the message was accepted for delivery.

sent_atstring date-time nullable

When the message was handed to the WhatsApp network. Null until then.

delivered_atstring date-time nullable

When delivery was confirmed. Null until then.

read_atstring date-time nullable

When the message was read. On an outbound message this is the recipient opening it. On an inbound one it is when Bird acknowledged the message to WhatsApp for the business, which a read receipt sets. Null until then.

metadataobject

Arbitrary JSON metadata stored on the message.

Changes

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