WhatsApp plain text messages
Plain text is the simplest free-form content arm: a body with no attachment, and an optional preview for the first link inside it.
Send a text message
Set text.body:
const msg = await bird.whatsapp.send({
to: "+16505551234",
from: "+13124495648",
text: { body: "Your driver is 2 minutes away." },
});
console.log(msg.id, msg.status);msg = client.whatsapp.send(
to="+16505551234",
from_="+13124495648",
text={"body": "Your driver is 2 minutes away."},
)
print(msg.id, msg.status)package main
import (
"context"
"fmt"
"log"
"os"
bird "github.com/messagebird/bird-sdk-go"
"github.com/messagebird/bird-sdk-go/option"
)
func main() {
client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
if err != nil {
log.Fatal(err)
}
msg, err := client.Whatsapp.Send(context.Background(), bird.WhatsappSendParams{
To: "+16505551234",
From: "+13124495648",
Text: &bird.WhatsAppTextSend{Body: "Your driver is 2 minutes away."},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(msg.Id, *msg.Status)
}$text = (new WhatsAppMessageSendRequestText())
->setBody('Your driver is 2 minutes away.');
$message = $bird->whatsapp->send(
to: '+16505551234',
from: '+13124495648',
text: $text,
);
echo $message->getId(), ' ', $message->getStatus();bird whatsapp send \
--from +13124495648 \
--text 'Your driver is 2 minutes away.' \
--to +16505551234curl -X POST "https://us1.platform.bird.com/v1/whatsapp/messages" \
-H "Authorization: Bearer $BIRD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+16505551234",
"from": "+13124495648",
"text": {
"body": "Your driver is 2 minutes away."
}
}'The full shape adds preview_url plus the fields any free-form send can carry:
Code example
{
"to": "+16505551234",
"from": "+13124495648",
"text": {
"body": "Your order shipped: https://example.com/track/A1B2C3",
"preview_url": true
},
"in_reply_to_message_id": "wam_01kya19eknftrs2s6p82asmvnh",
"tags": [{ "name": "category", "value": "shipping" }],
"metadata": { "order_id": "A1B2C3" }
}from is required on every service message: a number your workspace owns, not a Bird-managed one. in_reply_to_message_id quotes an earlier message in the same conversation; see Quoting a message for what it resolves against and what it can miss.
Limits
| Field | Bound | Enforced by |
|---|---|---|
| body | 1 to 4096 characters | Bird, at accept (422) |
| preview_url | boolean, defaults to false | N/A, informational |
A whitespace-only body passes the schema's own minLength: 1, but Bird still catches it: body that is empty after trimming is refused with 422 E15015 WhatsAppContentRequired. A body over 4096 characters is refused with a plain 422 and no dedicated catalog code.
Reading an inbound text message
An inbound text message carries the same text.body field, and nothing else on the arm. See Receiving WhatsApp text messages for the inbound read in full, the whatsapp.received payload, and what to watch for.
Limits and edge cases
- The customer service window has to be open. Plain text is a service message, deliverable only inside an open window; see the hub's customer service window.
- preview_url only affects the first link, and only what the recipient's client renders. It defaults to false. Set it to preview the first URL in body; a later URL in the same body never gets one. If the recipient's client can't fetch a preview for that link, it falls back silently to a plain clickable link. Nothing on read tells you whether a preview actually rendered.
- WhatsApp markdown is the recipient's client rendering body, not part of the API contract. Bird passes body through untouched; it does not validate, strip, or encode *bold*, _italic_, ~strikethrough~, or triple-backtick monospace. Whether those markers render is entirely up to the client that opens the message.
- An inbound body is not guaranteed to be non-empty, despite what the read schema says. Meta can report an inbound message as "text": {} or with an empty body, and Bird stores it verbatim rather than synthesizing a placeholder. This is a known, open gap: don't write a consumer that trusts the schema's required: body here.
Next steps
- WhatsApp service messages: the customer service window and the model every service message shares
- Sending WhatsApp messages: the request envelope, the 202 model, and safe retries
- Interactive messages: when you want a tap instead of a typed reply
Related resources
Continue with the documentation, guides and examples for this topic. Resources are in English.
Watch the guideConnecting WhatsApp to Bird: from buying a number to a live channelUnderstand the conceptWhat is the 24-hour customer service window on WhatsApp?Use the toolWhatsApp message builderExplore the capabilityWhatsApp
Try the practice and get an implementation brief