Skip to content
InfiQ glossary · Reference sheetGraph API & SDKs

Messages Endpoint

POST /{PHONE_NUMBER_ID}/messages: the single WhatsApp Cloud API call that sends every outbound message type, from text and media to templates.

Properties

Term
Messages Endpoint
Abbreviation
None
Level
Foundation
Audience
Developers
Reviewed
Also called
POST /messages · Send message API · /{phone-number-id}/messages

01 · Definition

What is the messages endpoint?

The messages endpoint is the WhatsApp Cloud API call that sends messages: POST https://graph.facebook.com/v26.0/{PHONE_NUMBER_ID}/messages, where the Phone Number ID identifies the business number doing the sending. Every outbound message — text, image, video, audio, document, sticker, location, contacts, reaction, interactive buttons and lists, Flows and message templates — goes through this one URL, and the body's type field decides which kind it is.

The JSON body always carries messaging_product: "whatsapp", the recipient in to (the customer's number in international format with its country code, as in the E.164 Phone Number Format, or a group ID when recipient_type is group), the type, and an object named after that type holding the content: "text": {"body": "..."}, or "template": {"name": "...", "language": {"code": "en"}, "components": [...]}. Optional fields include recipient_type (defaults to individual) and context.message_id to reply to a specific message.

A successful call returns HTTP 200 with contacts[0].input (what you sent), contacts[0].wa_id (the recipient's WhatsApp ID) and messages[0].id — the WhatsApp Message ID (WAMID) used to match later status webhooks. Template sends can also carry message_status: accepted, held_for_quality_assessment or paused. Acceptance is not delivery: sent, delivered, read and failed arrive afterwards on the Statuses Webhook. The endpoint is distinct from the other edges on the same phone number node, such as /media for uploads and /register for registration.

Key takeaways

  • The messages endpoint is POST /{PHONE_NUMBER_ID}/messages: one call for text, media, interactive, template, reaction and location messages.
  • Every body needs messaging_product: "whatsapp", the recipient in to, a type and an object named after that type.
  • A 200 response returns the recipient's wa_id and the message's wamid; it means accepted, not delivered.
  • Outside the 24-hour customer service window only template messages go through; free-form sends fail with error 131047.
  • The same endpoint marks inbound messages as read, with status: "read" and the customer message's message_id.

See InfiQ pricing

02 · Code samples

The messages endpoint in code

curl -X POST "https://graph.facebook.com/v26.0/{PHONE_NUMBER_ID}/messages" \
-H "Authorization: Bearer {ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "919812345678",
"type": "template",
"template": {
"name": "order_dispatched",
"language": { "code": "en" },
"components": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "Ananya" },
{ "type": "text", "text": "A1043" }
]
}
]
}
}'

03Playground

A working model of Messages Endpoint. Use its controls to replay it step by step.

Send a template and read what comes back

2 / 2
POSThttps://graph.facebook.com/v26.0/106540352242922/messages

POST 200 in 650 ms

Request

3 headers · body
POST /v26.0/106540352242922/messages HTTP/1.1
Host: graph.facebook.com
Authorization: Bearer {ACCESS_TOKEN}
Content-Type: application/json
{
"messaging_product": "whatsapp",
"to": "919812345678",
"type": "template",
"template": {
"name": "order_dispatched",
"language": {
"code": "en"
},
"components": [
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "Ananya"
},
{
"type": "text",
"text": "A1043"
}
]
}
]
}
}

Response

200 OK
HTTP/1.1 200 OK
Content-Type: application/json
{
"messaging_product": "whatsapp",
"contacts": [
{
"input": "919812345678",
"wa_id": "919812345678"
}
],
"messages": [
{
"id": "wamid.HBgMOTE5ODEyMzQ1Njc4FQIAERgSQzVGNkE3QjhDOUQwRTFGMjMA",
"message_status": "accepted"
}
]
}
Try another response
A real-shaped template send to the messages endpoint. Press Send to see the 200 with wa_id and wamid, then toggle the parameter, throughput and token errors integrations meet first.

Response: 200 OK after 650 ms.

04 · Specifications

The messages endpoint: key facts and limits

EndpointPOST /v26.0/{PHONE_NUMBER_ID}/messages
Required fieldsmessaging_product, to, type + the type's object
recipient_typeindividual (default) or group
Success200 with contacts[].wa_id and messages[].id (wamid)
Template message_statusaccepted, held_for_quality_assessment, paused
Text body limit4,096 characters
Default throughputUp to 80 messages per second per number
Outside the service windowTemplates only (error 131047 otherwise)

05 · Operation

How does the messages endpoint work?

  1. Choose the sending number

    Put that number's Phone Number ID in the path. Each registered business number has its own ID, and the token needs whatsapp_business_messaging access to its WABA.

  2. Normalise the recipient

    Write to in international format with the country code — 919812345678 for an Indian mobile — never with a leading 0, spaces or brackets.

  3. Pick the type and build its object

    Inside an open customer service window any type works, including a free-form Session Message. Outside it, send type: "template" with an approved message template's name, language.code and parameters in components.

  4. POST and read the response

    On 200, store messages[0].id (the wamid) and contacts[0].wa_id against your own record. On an error, branch on error.code and keep the fbtrace_id.

  5. Track delivery by webhook

    Match incoming status webhooks to the stored wamid to move the message through sent, delivered, read or failed — and never move it backwards when events arrive out of order.

06 · Rationale

Why does the messages endpoint matter?

Almost every WhatsApp feature you build ends in this call — order updates, OTPs, support replies, chatbot answers, campaign sends. Knowing its contract precisely — required fields, which types are allowed when, what the response does and does not promise — prevents the most common integration failures: free-form messages sent after the window has closed, template parameter mismatches, numbers in local format, and systems that mark a message delivered the moment the API returns 200.

07 · Cautions

Common mistakes with the messages endpoint

  • Treating 200 as delivered

    The response confirms acceptance only. Mark messages delivered or read when the statuses webhook says so, and handle failed statuses with their error codes.

  • Local-format phone numbers

    09812345678 or 98123 45678 can fail or reach the wrong country. Normalise every number to country code plus subscriber number before calling.

  • Free-form messages after the window

    Text, media and interactive messages fail with Error 131047 (Re-engagement Message) once 24 hours have passed since the customer's last message. Check the window and fall back to an approved template.

  • Template parameter mismatch

    Sending more or fewer body parameters than the template defines fails with error 132000. Build components from the template's stored definition, not by hand.

  • Bursting past throughput

    Firing a whole campaign at once exceeds the number's throughput and returns error 130429. Queue sends and pace them below the number's limit.

08 · Worked example: An order update and a reply in Indore

Example: An order update and a reply in Indore

An Indore home-appliance store's order system calls the messages endpoint with an order_dispatched utility template when a refrigerator leaves the warehouse. The 200 response returns a wamid, which the system stores against order A1043. A status webhook marks it delivered four seconds later and read after ten minutes. The customer then replies asking for an evening slot, which opens a customer service window; the agent's free-form answer goes to the same endpoint with type: "text" and context.message_id set to the customer's question, so it appears as a quoted reply.

09 · Recommended practice

Best practices for the messages endpoint

  • Keep one request builder per message type and unit-test the JSON it produces.
  • Store the wamid next to your own message ID so webhooks and support tools can find the record.
  • Use context.message_id when answering a specific question so the customer sees what you are replying to.
  • Add biz_opaque_callback_data when you need your own tracking value echoed back in status webhooks.

10 · Questions and answers

Messages Endpoint FAQs

How do I send a WhatsApp message with the Cloud API?
POST JSON to https://graph.facebook.com/v26.0/{PHONE_NUMBER_ID}/messages with a bearer token, messaging_product: "whatsapp", to, type and the matching type object. Outside a service window, the type must be template.
What does the messages endpoint return?
On success, HTTP 200 with the recipient's wa_id in contacts and the message's wamid in messages[0].id, plus message_status for template sends. Delivery outcomes arrive later by webhook.
Can I send to a number without the country code?
No — include the country code. Write to in international format, such as 919812345678 for India, with no leading 0 or spaces, or the send can fail or go to the wrong person.
Is there a separate endpoint for templates or media?
No. Templates, media, interactive and text messages are all sent through the same messages endpoint; only type changes. Uploading a file first uses the separate /media edge, which returns an ID you then send.

Put Messages Endpoint to work

InfiQ is an official Meta Business Partner. Start a 7-day free trial — no card needed — and see this running on your own number.