bird whatsapp send [flags]
Send a WhatsApp message to one recipient
Sending is outbound and irreversible: it reports "accepted", not "delivered".
Read the message back with "bird whatsapp get" to confirm delivery. Carry exactly
one kind of content: a template, or free-form text, image, video, audio, sticker,
document, location, contact cards, or interactive buttons, a list, a link button
or cards.
Free-form content, interactive content included, is deliverable only inside an
open 24-hour customer service window. A Bird-managed template picks its own
sender and omits --from; every other send, free-form content or a template your
workspace authored, requires it.
Build the request from flags, a JSON WhatsAppMessageSendRequest body via --body-file ("-" reads
stdin), or both — a flag overrides the matching body field. Run --example to
print a ready-to-edit body, or --dry-run to print the resolved request without
sending it.
# print the body shape (no credentials needed)
bird whatsapp send --example
# the body it prints:
{
"template": {
"components": [
{
"parameters": [
{
"text": "1234",
"type": "text"
}
],
"type": "body"
},
{
"parameters": [
{
"text": "1234",
"type": "text"
}
],
"type": "button"
}
],
"language": "en",
"slug": "bird_otp"
},
"to": "+31612345678"
}
# send a template with body placeholders
bird whatsapp send --to +15551234567 --template bird_order_confirmation --language en --components '[{"type":"body","parameters":[{"type":"text","name":"ref","text":"ORD-1042"},{"type":"text","name":"amount","text":"US$ 99.99"}]}]'
# reply with free text inside an open customer service window
bird whatsapp send --to +15551234567 --from +31612340001 --text 'Your driver is 2 minutes away.'
# send a document with a caption
bird whatsapp send --to +15551234567 --from +31612340001 --document https://cdn.example.com/invoices/a1b2c3.pdf --filename invoice-a1b2c3.pdf --caption 'Your invoice'
# ask a yes/no question with reply buttons
bird whatsapp send --to +15551234567 --from +31612340001 --interactive '{"type":"button","body_text":"Your workshop is at 9am tomorrow. Need to change it?","buttons":[{"type":"quick_reply","quick_reply":{"slug":"change","text":"Change"}},{"type":"quick_reply","quick_reply":{"slug":"cancel","text":"Cancel"}}]}'
# share a colleague's contact card
bird whatsapp send --to +15551234567 --from +31612340001 --contact-cards '[{"name":{"formatted_name":"Barbara J. Johnson","first_name":"Barbara","last_name":"Johnson"},"phone_numbers":[{"phone_number":"+16505551234","type":"Mobile"}]}]'
# quote the message you are answering
bird whatsapp send --to +15551234567 --from +31612340001 --text 'Your driver is 2 minutes away.' --in-reply-to wam_01kya19eknftrs2s6p82asmvnh
# preview the resolved request without sending
bird whatsapp send --body-file body.json --dry-run
| Name | Description |
|---|
| --to | Recipient phone number in E.164 format (e.g. +15551234567), or their business-scoped user ID (e.g. US.13491208655302741918) |
| --from | Sender in E.164 format. Required for free-form content and a template your workspace authored; omit it for a Bird-managed template, which picks its own sender |
| Name | Description |
|---|
| --template | The template to send, by its slug (e.g. bird_otp) |
| --template-id | The template to send, by its id (wat_…); alternative to --template |
| --language | Language code of the template variant to send (e.g. en or pt-BR); omit when the template has a single language |
| --components | The values that fill the template's placeholders, as a JSON array (e.g. body/header/button component objects) |
| Name | Description |
|---|
| --text | Free-text message body, up to 4096 characters |
| --preview-url | Render a link preview for the first URL in --text |
| --image | Public https URL of an image to send |
| --video | Public https URL of a video to send |
| --audio | Public https URL of an audio file to send |
| --sticker | Public https URL of a sticker to send |
| --document | Public https URL of a document to send |
| --caption | Caption shown with --image, --video or --document |
| --filename | Filename shown for --document |
| --voice | Render --audio as a voice note rather than an audio file |
| --latitude | Latitude in decimal degrees; send a location with --longitude |
| --longitude | Longitude in decimal degrees; send a location with --latitude |
| --location-name | Place name shown on the location |
| --location-address | Street address shown beneath --location-name; ignored without it |
| Name | Description |
|---|
| --interactive | Interactive content as a JSON object: reply buttons, a list menu, a link button, media cards, or a request for the recipient's location or contact details |
| --contact-cards | Contact cards as a JSON array, up to five. Each card needs a name with formatted_name plus one other part; a phone number in E.164 earns the card a button that opens a chat |
| Name | Description |
|---|
| --in-reply-to | Quote an earlier message from the same conversation, by its id (wam_…) |
| Name | Description |
|---|
| --tag <key=value> | Tag as name=value; repeatable |
| --metadata | Arbitrary JSON metadata object |
| Name | Description |
|---|
| --body-file | Read the JSON request body from this file; "-" reads stdin |
| --example | Print a complete example request body, then exit |
| --dry-run | Print the resolved request without sending it, then exit |
| --idempotency-key | Deduplication key; a retry with the same key won't act twice |
| Name | Description |
|---|
| --response-schema | Print the fields this command returns, then exit |