WhatsApp Cloud API
When to Use
Activate this skill when:
- Building or modifying WhatsApp messaging features
- Sending messages (text, media, templates, interactive)
- Processing incoming webhooks from WhatsApp
- Working with template messages or conversation windows
- Handling phone number formatting (E.164)
- Debugging WhatsApp API errors or status updates
- Implementing message status tracking (sent, delivered, read)
- Running a number on both the WhatsApp Business App and Cloud API (Coexistence)
Quick Reference
| Item |
Value |
| Base URL |
https://graph.facebook.com/v21.0 |
| Send Message |
POST /{phone-number-id}/messages |
| Upload Media |
POST /{phone-number-id}/media |
| Auth |
Authorization: Bearer {access-token} |
| Required Field |
"messaging_product": "whatsapp" |
| Phone Format |
E.164: +{country}{number} (e.g., +18091234567) |
| Rate Limit |
80 messages/second (Cloud API) |
Core API — Send Message
All messages go through a single endpoint:
POST https://graph.facebook.com/v21.0/{phone-number-id}/messages
Authorization: Bearer {access-token}
Content-Type: application/json
Response:
{
"messaging_product": "whatsapp",
"contacts": [{ "input": "+16505555555", "wa_id": "16505555555" }],
"messages": [{ "id": "wamid.HBgL..." }]
}
Message Types
| Type |
type Field |
Details |
| Text |
text |
Plain text, max 4096 chars, supports URL preview |
| Image |
image |
JPEG/PNG, max 5MB, optional caption |
| Video |
video |
MP4, max 16MB, optional caption |
| Audio |
audio |
AAC/MP3/OGG, max 16MB |
| Document |
document |
Any format, max 100MB, optional filename |
| Sticker |
sticker |
WebP, static 100KB / animated 500KB |
| Location |
location |
latitude, longitude, name, address |
| Contacts |
contacts |
Structured contact cards |
| Reaction |
reaction |
Emoji reaction to a message |
| Interactive |
interactive |
Buttons, lists, products |
| Template |
template |
Pre-approved message templates |
For full specs and code examples, see references/MESSAGING.md.
Webhooks
Your server receives POST requests for incoming messages and status updates.
Incoming message structure:
{
"object": "whatsapp_business_account",
"entry": [{
"changes": [{
"value": {
"messaging_product": "whatsapp",
"metadata": { "phone_number_id": "ID", "display_phone_number": "NUM" },
"contacts": [{ "profile": { "name": "John" }, "wa_id": "16315551234" }],
"messages": [{
"from": "16315551234",
"id": "wamid.ABC...",
"timestamp": "1683229471",
"type": "text",
"text": { "body": "Hello" }
}]
},
"field": "messages"
}]
}]
}
Status update types: sent → delivered → read | failed
For webhook verification, payload parsing, and all status types, see references/WEBHOOKS.md.
Conversation Window
- When a customer messages you, a 24-hour service window opens
- Inside the window: send any message type freely (service messages are FREE)
- Outside the window: only template messages can be sent (paid per message)
- No API endpoint to "close" a conversation — windows expire automatically
- Template messages open their own 24h window per category (marketing, utility, auth)
For full lifecycle, pricing, and category rules, see references/CONVERSATIONS.md.
Coexistence
Run one number on the WhatsApp Business App and the Cloud API simultaneously — the business keeps chatting from the app while you integrate via the API.
- Onboard via a customized Embedded Signup flow (
featureType: "whatsapp_business_app_onboarding"), not standard registration
- Onboarding triggers a one-time sync of past messages (
history, up to 180 days) and contacts (smb_app_state_sync)
- Messages the business sends from the app are mirrored to your webhook via
smb_message_echoes
- App-sent messages are FREE; coexistence numbers are capped at 20 msg/sec
- Chat history is preserved; template messages and the 24h window still apply
For onboarding, sync, status checks, and webhook payloads, see references/COEXISTENCE.md.
Common Patterns
Send a text message
{
"messaging_product": "whatsapp",
"to": "+18091234567",
"type": "text",
"text": { "body": "Hello! How can we help you?" }
}
Send a template message
{
"messaging_product": "whatsapp",
"to": "+18091234567",
"type": "template",
"template": {
"name": "hello_world",
"language": { "code": "en_US" }
}
}
Mark a message as read
{
"messaging_product": "whatsapp",
"status": "read",
"message_id": "wamid.HBgL..."
}
Error Handling
| Code |
Error |
Action |
| 131030 |
Recipient not on WhatsApp |
Validate number before sending |
| 131047 |
Re-engagement required |
Send a template message first |
| 131050 |
User stopped marketing messages |
Respect opt-out, send only service/utility |
| 131056 |
Pair rate limit hit |
Slow down, implement backoff |
| 130429 |
Rate limit exceeded |
Queue messages, max 80/sec |
For full error reference and retry strategies, see references/ERROR-CODES.md.
Best Practices
- Always use E.164 phone format —
+{country}{number}, no spaces or dashes
- Verify webhooks — Respond to GET challenge with
hub.challenge value
- Return 200 immediately on webhook POST — process asynchronously
- Store
wamid IDs — Needed for replies, reactions, and read receipts
- Use template messages to re-engage after the 24h window expires
- Handle idempotency — Webhook may deliver the same event multiple times
- Check
wa_id vs input — The API normalizes phone numbers; wa_id is canonical
- Rate limit awareness — 80 msg/sec for Cloud API; implement queue + backoff
References
- Messaging — All message types
- Webhooks — Setup and payloads
- Templates — Management and sending
- Conversations — Window lifecycle and pricing
- Coexistence — Business App + Cloud API on one number
- Media — Upload, download, formats
- Interactive — Buttons, lists, products
- Phone Numbers — E.164, IDs, verification
- Error Codes — Common errors and retries
1---2name: whatsapp-cloud-api3description: Official WhatsApp Cloud API reference for building messaging integrations. Covers sending messages (text, media, templates, interactive), receiving webhooks, conversation lifecycle, phone number management, and error handling. Use when building WhatsApp integrations, sending messages, processing webhooks, or working with the Meta WhatsApp Business Platform API.4license: MIT5---6
7# WhatsApp Cloud API
8
9## When to Use
10
11Activate this skill when:
12- Building or modifying WhatsApp messaging features
13- Sending messages (text, media, templates, interactive)
14- Processing incoming webhooks from WhatsApp
15- Working with template messages or conversation windows
16- Handling phone number formatting (E.164)
17- Debugging WhatsApp API errors or status updates
18- Implementing message status tracking (sent, delivered, read)
19- Running a number on both the WhatsApp Business App and Cloud API (Coexistence)
20
21## Quick Reference
22
23| Item | Value |
24|------|-------|
25| **Base URL** | `https://graph.facebook.com/v21.0` |
26| **Send Message** | `POST /{phone-number-id}/messages` |
27| **Upload Media** | `POST /{phone-number-id}/media` |
28| **Auth** | `Authorization: Bearer {access-token}` |
29| **Required Field** | `"messaging_product": "whatsapp"` |
30| **Phone Format** | E.164: `+{country}{number}` (e.g., `+18091234567`) |
31| **Rate Limit** | 80 messages/second (Cloud API) |
32
33## Core API — Send Message
34
35All messages go through a single endpoint:
36
37```
38POST https://graph.facebook.com/v21.0/{phone-number-id}/messages
39Authorization: Bearer {access-token}
40Content-Type: application/json
41```
42
43**Response:**
44```json
45{
46 "messaging_product": "whatsapp",
47 "contacts": [{ "input": "+16505555555", "wa_id": "16505555555" }],
48 "messages": [{ "id": "wamid.HBgL..." }]
49}
50```
51
52## Message Types
53
54| Type | `type` Field | Details |
55|------|-------------|---------|
56| Text | `text` | Plain text, max 4096 chars, supports URL preview |
57| Image | `image` | JPEG/PNG, max 5MB, optional caption |
58| Video | `video` | MP4, max 16MB, optional caption |
59| Audio | `audio` | AAC/MP3/OGG, max 16MB |
60| Document | `document` | Any format, max 100MB, optional filename |
61| Sticker | `sticker` | WebP, static 100KB / animated 500KB |
62| Location | `location` | latitude, longitude, name, address |
63| Contacts | `contacts` | Structured contact cards |
64| Reaction | `reaction` | Emoji reaction to a message |
65| Interactive | `interactive` | Buttons, lists, products |
66| Template | `template` | Pre-approved message templates |
67
68For full specs and code examples, see [references/MESSAGING.md](references/MESSAGING.md).
69
70## Webhooks
71
72Your server receives POST requests for incoming messages and status updates.
73
74**Incoming message structure:**
75```json
76{
77 "object": "whatsapp_business_account",
78 "entry": [{
79 "changes": [{
80 "value": {
81 "messaging_product": "whatsapp",
82 "metadata": { "phone_number_id": "ID", "display_phone_number": "NUM" },
83 "contacts": [{ "profile": { "name": "John" }, "wa_id": "16315551234" }],
84 "messages": [{
85 "from": "16315551234",
86 "id": "wamid.ABC...",
87 "timestamp": "1683229471",
88 "type": "text",
89 "text": { "body": "Hello" }
90 }]
91 },
92 "field": "messages"
93 }]
94 }]
95}
96```
97
98**Status update types:** `sent` → `delivered` → `read` | `failed`
99
100For webhook verification, payload parsing, and all status types, see [references/WEBHOOKS.md](references/WEBHOOKS.md).
101
102## Conversation Window
103
104- When a customer messages you, a **24-hour service window** opens
105- Inside the window: send any message type freely (service messages are **FREE**)
106- Outside the window: only **template messages** can be sent (paid per message)
107- No API endpoint to "close" a conversation — windows expire automatically
108- Template messages open their own 24h window per category (marketing, utility, auth)
109
110For full lifecycle, pricing, and category rules, see [references/CONVERSATIONS.md](references/CONVERSATIONS.md).
111
112## Coexistence
113
114Run one number on the **WhatsApp Business App and the Cloud API simultaneously** — the business keeps chatting from the app while you integrate via the API.
115
116- Onboard via a customized **Embedded Signup** flow (`featureType: "whatsapp_business_app_onboarding"`), not standard registration
117- Onboarding triggers a one-time sync of past messages (`history`, up to 180 days) and contacts (`smb_app_state_sync`)
118- Messages the business sends from the app are mirrored to your webhook via **`smb_message_echoes`**
119- App-sent messages are **FREE**; coexistence numbers are capped at **20 msg/sec**
120- Chat history is preserved; template messages and the 24h window still apply
121
122For onboarding, sync, status checks, and webhook payloads, see [references/COEXISTENCE.md](references/COEXISTENCE.md).
123
124## Common Patterns
125
126### Send a text message
127```json
128{
129 "messaging_product": "whatsapp",
130 "to": "+18091234567",
131 "type": "text",
132 "text": { "body": "Hello! How can we help you?" }
133}
134```
135
136### Send a template message
137```json
138{
139 "messaging_product": "whatsapp",
140 "to": "+18091234567",
141 "type": "template",
142 "template": {
143 "name": "hello_world",
144 "language": { "code": "en_US" }
145 }
146}
147```
148
149### Mark a message as read
150```json
151{
152 "messaging_product": "whatsapp",
153 "status": "read",
154 "message_id": "wamid.HBgL..."
155}
156```
157
158## Error Handling
159
160| Code | Error | Action |
161|------|-------|--------|
162| 131030 | Recipient not on WhatsApp | Validate number before sending |
163| 131047 | Re-engagement required | Send a template message first |
164| 131050 | User stopped marketing messages | Respect opt-out, send only service/utility |
165| 131056 | Pair rate limit hit | Slow down, implement backoff |
166| 130429 | Rate limit exceeded | Queue messages, max 80/sec |
167
168For full error reference and retry strategies, see [references/ERROR-CODES.md](references/ERROR-CODES.md).
169
170## Best Practices
171
1721. **Always use E.164 phone format** — `+{country}{number}`, no spaces or dashes
1732. **Verify webhooks** — Respond to GET challenge with `hub.challenge` value
1743. **Return 200 immediately** on webhook POST — process asynchronously
1754. **Store `wamid` IDs** — Needed for replies, reactions, and read receipts
1765. **Use template messages** to re-engage after the 24h window expires
1776. **Handle idempotency** — Webhook may deliver the same event multiple times
1787. **Check `wa_id` vs input** — The API normalizes phone numbers; `wa_id` is canonical
1798. **Rate limit awareness** — 80 msg/sec for Cloud API; implement queue + backoff
180
181## References
182
183- [Messaging — All message types](references/MESSAGING.md)
184- [Webhooks — Setup and payloads](references/WEBHOOKS.md)
185- [Templates — Management and sending](references/TEMPLATES.md)
186- [Conversations — Window lifecycle and pricing](references/CONVERSATIONS.md)
187- [Coexistence — Business App + Cloud API on one number](references/COEXISTENCE.md)
188- [Media — Upload, download, formats](references/MEDIA.md)
189- [Interactive — Buttons, lists, products](references/INTERACTIVE.md)
190- [Phone Numbers — E.164, IDs, verification](references/PHONE-NUMBERS.md)
191- [Error Codes — Common errors and retries](references/ERROR-CODES.md)