WhatsApp Cloud API
When to Use
Activate this skill when:
- Implementing WhatsApp Embedded Signup (onboarding businesses to WABA)
- 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)
Quick Reference
| Item |
Value |
| Base URL |
https://graph.facebook.com/v22.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/v22.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 | deleted | warning
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
- The window resets from the customer's last incoming message only — your replies do NOT extend it
- 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.
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 |
| 131026 |
Message undeliverable |
Verify recipient has WhatsApp and is reachable |
| 131047 |
Re-engagement required |
Send a template message first |
| 131049 |
Meta chose not to deliver |
Per-user marketing limit; wait 24h |
| 131050 |
User stopped marketing messages |
Respect opt-out, do not retry |
| 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
- Download media immediately — Incoming media URLs expire in ~5 minutes; a 401 means expiry, not auth failure
- Use
context.message_id for replies — Without it, recipients see a standalone message instead of a threaded reply
- Template parameters must match exactly — Count, format (positional vs named), and type must match the approved template definition
References
- Messaging — All message types
- Webhooks — Setup and payloads
- Templates — Management and sending
- Conversations — Window lifecycle and pricing
- Media — Upload, download, formats
- Interactive — Buttons, lists, products
- Phone Numbers — E.164, IDs, verification
- Error Codes — Common errors and retries
- Embedded Signup — WhatsApp onboarding flow
- Coexistence — Business App + Cloud API on same number
- Groups — Group chat management API
- Webhook Overrides — Per-WABA and per-phone callback URLs
Sources
1---2name: whatsapp-cloud-api3description: Official WhatsApp Cloud API reference for building messaging integrations. Covers Embedded Signup (primary onboarding flow), sending messages (text, media, templates, interactive), receiving webhooks, conversation lifecycle, phone number management, and error handling. Use when building WhatsApp integrations, implementing Embedded Signup, sending messages, processing webhooks, or working with the Meta WhatsApp Business Platform API.4license: MIT5---67# WhatsApp Cloud API89## When to Use1011Activate this skill when:12- Implementing WhatsApp Embedded Signup (onboarding businesses to WABA)13- Building or modifying WhatsApp messaging features14- Sending messages (text, media, templates, interactive)15- Processing incoming webhooks from WhatsApp16- Working with template messages or conversation windows17- Handling phone number formatting (E.164)18- Debugging WhatsApp API errors or status updates19- Implementing message status tracking (sent, delivered, read)2021## Quick Reference2223| Item | Value |24|------|-------|25| **Base URL** | `https://graph.facebook.com/v22.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) |3233## Core API — Send Message3435All messages go through a single endpoint:3637```38POST https://graph.facebook.com/v22.0/{phone-number-id}/messages39Authorization: Bearer {access-token}40Content-Type: application/json41```4243**Response:**44```json45{46 "messaging_product": "whatsapp",47 "contacts": [{ "input": "+16505555555", "wa_id": "16505555555" }],48 "messages": [{ "id": "wamid.HBgL..." }]49}50```5152## Message Types5354| 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 |6768For full specs and code examples, see [references/messaging.md](references/messaging.md).6970## Webhooks7172Your server receives POST requests for incoming messages and status updates.7374**Incoming message structure:**75```json76{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```9798**Status update types:** `sent` → `delivered` → `read` | `failed` | `deleted` | `warning`99100For webhook verification, payload parsing, and all status types, see [references/webhooks.md](references/webhooks.md).101102## Conversation Window103104- When a customer messages you, a **24-hour service window** opens105- The window resets from the customer's **last incoming message** only — your replies do NOT extend it106- Inside the window: send any message type freely (service messages are **FREE**)107- Outside the window: only **template messages** can be sent (paid per message)108- No API endpoint to "close" a conversation — windows expire automatically109- Template messages open their own 24h window per category (marketing, utility, auth)110111For full lifecycle, pricing, and category rules, see [references/conversations.md](references/conversations.md).112113## Common Patterns114115### Send a text message116```json117{118 "messaging_product": "whatsapp",119 "to": "+18091234567",120 "type": "text",121 "text": { "body": "Hello! How can we help you?" }122}123```124125### Send a template message126```json127{128 "messaging_product": "whatsapp",129 "to": "+18091234567",130 "type": "template",131 "template": {132 "name": "hello_world",133 "language": { "code": "en_US" }134 }135}136```137138### Mark a message as read139```json140{141 "messaging_product": "whatsapp",142 "status": "read",143 "message_id": "wamid.HBgL..."144}145```146147## Error Handling148149| Code | Error | Action |150|------|-------|--------|151| 131026 | Message undeliverable | Verify recipient has WhatsApp and is reachable |152| 131047 | Re-engagement required | Send a template message first |153| 131049 | Meta chose not to deliver | Per-user marketing limit; wait 24h |154| 131050 | User stopped marketing messages | Respect opt-out, do not retry |155| 130429 | Rate limit exceeded | Queue messages, max 80/sec |156157For full error reference and retry strategies, see [references/error-codes.md](references/error-codes.md).158159## Best Practices1601611. **Always use E.164 phone format** — `+{country}{number}`, no spaces or dashes1622. **Verify webhooks** — Respond to GET challenge with `hub.challenge` value1633. **Return 200 immediately** on webhook POST — process asynchronously1644. **Store `wamid` IDs** — Needed for replies, reactions, and read receipts1655. **Use template messages** to re-engage after the 24h window expires1666. **Handle idempotency** — Webhook may deliver the same event multiple times1677. **Check `wa_id` vs input** — The API normalizes phone numbers; `wa_id` is canonical1688. **Rate limit awareness** — 80 msg/sec for Cloud API; implement queue + backoff1699. **Download media immediately** — Incoming media URLs expire in ~5 minutes; a 401 means expiry, not auth failure17010. **Use `context.message_id` for replies** — Without it, recipients see a standalone message instead of a threaded reply17111. **Template parameters must match exactly** — Count, format (positional vs named), and type must match the approved template definition172173## References174175- [Messaging — All message types](references/messaging.md)176- [Webhooks — Setup and payloads](references/webhooks.md)177- [Templates — Management and sending](references/templates.md)178- [Conversations — Window lifecycle and pricing](references/conversations.md)179- [Media — Upload, download, formats](references/media.md)180- [Interactive — Buttons, lists, products](references/interactive.md)181- [Phone Numbers — E.164, IDs, verification](references/phone-numbers.md)182- [Error Codes — Common errors and retries](references/error-codes.md)183- [Embedded Signup — WhatsApp onboarding flow](references/embedded-signup.md)184- [Coexistence — Business App + Cloud API on same number](references/coexistence.md)185- [Groups — Group chat management API](references/groups.md)186- [Webhook Overrides — Per-WABA and per-phone callback URLs](references/webhook-overrides.md)187188## Sources189190- [WhatsApp Cloud API — Overview](https://developers.facebook.com/docs/whatsapp/cloud-api)191- [WhatsApp Cloud API — Get Started](https://developers.facebook.com/docs/whatsapp/cloud-api/get-started)192- [WhatsApp Cloud API — Reference](https://developers.facebook.com/docs/whatsapp/cloud-api/reference)193- [WhatsApp Embedded Signup](https://developers.facebook.com/docs/whatsapp/embedded-signup)194- [WhatsApp Pricing](https://developers.facebook.com/docs/whatsapp/pricing)195- [Graph API v22.0 Changelog](https://developers.facebook.com/docs/graph-api/changelog/version22.0)