Send a WhatsApp message
POST
/v1/whatsapp/messages
curl -X POST "https://us1.platform.bird.com/v1/whatsapp/messages" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"to": "+31612345678",
"template": {
"name": "bird_otp",
"language": "en",
"components": [
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "1234"
}
]
},
{
"type": "button",
"parameters": [
{
"type": "text",
"text": "1234"
}
]
}
]
}
}'Sends a WhatsApp message built from a message template to one recipient.
Name the template, optionally pick its language variant, and fill its
placeholders in components; Bird selects the sender number from the
template's category, so the request carries no sender field. Templates are
the only supported content type: a request without template is rejected
with a 422. Browse what you can send with
List available message templates.
The 202 response is the accepted message, echoing the resolved template
and language; it is not a delivery confirmation. Follow delivery with
Get a WhatsApp message, the
per-message timeline from
List events for a WhatsApp message,
or whatsapp.* webhook events.
A template name or language the catalogue does not stock, parameter values
that do not match the template's declared placeholders, and a recipient
that is not a valid phone number each return a 422.
Anfrage-Nutzlast
to
string
erforderlich
The message recipient's phone number in E.164 format (for example +31612345678). A value that is not a valid phone number returns a 422 WhatsAppInvalidRecipient.
template
object
The template to send. Bird selects the sender number from the template's category, so there is no sender field on this request. Templates are the only supported content type today: a request without one is rejected with a 422.
Untergeordnete Parameter anzeigen
template.name
object
erforderlich
The template to send, by its name (for example bird_otp).
template.language
object
Language code of the template variant to send (for example en or pt_BR). May be omitted when the template has a single language; when it is stocked in several, omitting the language returns a 422 that names the available codes. The accepted message echoes the resolved language.
template.components
array of object
The values that fill the template's placeholders: one entry per content block that has placeholders, each carrying its parameters in {{n}} order. Parameter counts must match the template's declared placeholders exactly, or the send returns a 422 WhatsAppTemplateParameterMismatch.
Untergeordnete Parameter anzeigen
template.components.type
string
erforderlich
Which part of the template this fills in: body for the main text, button for a button's variable, header for the header. Bird manages header values itself, so a header entry supplied on a send is ignored.
Possible values (may grow over time): header, body, button
template.components.parameters
array of object
The values that fill this part's placeholders, in {{n}} placeholder order.
Untergeordnete Parameter anzeigen
template.components.parameters.type
object
erforderlich
The kind of value this parameter carries. text is the only kind today.
template.components.parameters.text
string
erforderlich
The value substituted into the placeholder, as a plain string.
template.components.parameters.name
string
For named-parameter templates: the placeholder this value fills (for example first_name). Omit for positional templates.
tags
array of object
Structured {name, value} labels for filtering. Tags become first-class query dimensions: filter the list endpoint by tag name. Maximum 20 tags per send. Use tags for low-cardinality dimensions (category, experiment_variant). For arbitrary structured context you do not need as a filter dimension, use metadata instead.
Untergeordnete Parameter anzeigen
tags.name
string
erforderlich
Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
tags.value
string
erforderlich
Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
metadata
object
Arbitrary JSON object stored on the message and returned on API reads. Maximum 2 KB serialized. Use metadata for per-send context like internal IDs and foreign keys. For low-cardinality filterable labels, use tags instead.
Antwort-Payload
id
string
erforderlich
ID of the message (wam_-prefixed), assigned when the send is accepted. Pass it as message_id to the get-message and list-events endpoints.
direction
string
erforderlich
Whether the message was sent by the business (outbound) or received from the contact (inbound).
Possible values: outbound, inbound
from
object
erforderlich
Sender of the message. On outbound messages, the business number it was sent from; on inbound, the WhatsApp contact.
Untergeordnete Attribute anzeigen
from.phone_number
string
Phone number in E.164 format, when known.
from.bsuid
string
Business-scoped user ID, Meta's identifier for the WhatsApp user. Present only on the WhatsApp-user side of the message.
to
object
erforderlich
Recipient of the message. On outbound messages, the WhatsApp contact; on inbound, the business number.
Untergeordnete Attribute anzeigen
to.phone_number
string
Phone number in E.164 format, when known.
to.bsuid
string
Business-scoped user ID, Meta's identifier for the WhatsApp user. Present only on the WhatsApp-user side of the message.
template
object
The template the message was sent from. For authentication templates the filled-in values are not returned.
Untergeordnete Attribute anzeigen
template.name
object
erforderlich
The template's stable handle (for example bird_otp).
template.category
object
erforderlich
Content classification applied to messages sent from this template.
template.language
string
erforderlich
The language code of the template variant that was sent (for example en).
template.components
array of object
erforderlich
The values that filled the template's placeholders. Empty for an authentication template, whose content is never returned.
Untergeordnete Attribute anzeigen
template.components.type
string
erforderlich
Which part of the template this fills in: body for the main text, button for a button's variable, header for the header. Bird manages header values itself, so a header entry supplied on a send is ignored.
Possible values (may grow over time): header, body, button
template.components.parameters
array of object
The values that fill this part's placeholders, in {{n}} placeholder order.
Untergeordnete Attribute anzeigen
template.components.parameters.type
object
erforderlich
The kind of value this parameter carries. text is the only kind today.
template.components.parameters.text
string
erforderlich
The value substituted into the placeholder, as a plain string.
template.components.parameters.name
string
For named-parameter templates: the placeholder this value fills (for example first_name). Omit for positional templates.
status
object
erforderlich
last_error
nullable object
Failure detail for a message that did not reach the recipient. Present only when the message failed.
Untergeordnete Attribute anzeigen
last_error.code
string
erforderlich
Failure reason, uniform whether the failure happened internally or was reported by the WhatsApp network. insufficient_balance: the workspace could not afford the send. price_not_found: no price was configured for this destination/template combination. internal_error: an unexpected Bird-side failure. undeliverable: the recipient could not be reached (for example not on WhatsApp, or the number is invalid). service_window_expired: the 24-hour customer care window has closed and a free-form message cannot be sent; send a template instead. rate_limited: the send was throttled. recipient_suppressed: the recipient is on the workspace's suppression list; the message was rejected before sending. Open enum: new codes may be added over time, so treat any unrecognized value as a future code rather than an error.
Possible values (may grow over time): insufficient_balance, price_not_found, internal_error, undeliverable, service_window_expired, rate_limited, recipient_suppressed
last_error.description
string
erforderlich
Human-readable explanation of the failure.
last_error.meta_error_code
nullable string
Raw error code from the WhatsApp Cloud API, when available, for low-level debugging.
last_error.occurred_at
string
erforderlich
When the failure occurred.
created_at
string
erforderlich
When the message was accepted for delivery.
sent_at
nullable string
When the message was handed to the WhatsApp network. Null until then.
delivered_at
nullable string
When delivery was confirmed. Null until then.
read_at
nullable string
When the message was read by the recipient. Null until then.
tags
array of object
Structured {name, value} filter labels applied to this message.
Untergeordnete Attribute anzeigen
tags.name
string
erforderlich
Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
tags.value
string
erforderlich
Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
metadata
object
Arbitrary JSON metadata stored on the message.