If you're a developer searching for "WhatsApp API", there are three paths: WhatsApp Cloud API direct from Meta, WhatsApp Business API via BSP (official provider) and unofficial APIs (avoid). This guide covers each, when to use which, and shows real code in Python, Node.js and cURL for the recommended path.In Zavu Dashboard, Templates → Create Pick category (Utility, Marketing, Authentication) Submit to Meta for approval (24-48h) Use in code:
BSPs charge on top:Verified Meta Business Manager (free) Phone number not on another WhatsApp Verified website for the business Approved templates (to send business-initiated messages) Published privacy policy Tax registration (LLC, EIN, etc.)
For 99% of cases, going via BSP saves weeks of work.
The 3 WhatsApp APIs in 2026
1. WhatsApp Cloud API (Meta official)
- Hosted by Meta
- Direct Graph API access
- You handle tokens, templates, webhooks
- Good for: teams with strong DevOps
2. WhatsApp Business API via BSP (recommended)
- Official BSPs like Zavu, Twilio, MessageBird
- Abstract complexity (tokens, retries, templates)
- Official SDK in multiple languages
- Good for: 99% of cases
3. Unofficial APIs (don't use)
- Libraries reverse-engineering WhatsApp Web
- Work until Meta blocks them
- No support, no warranty, no green badge
- Can permanently ban your number
How to start with WhatsApp API in 5 minutes
Easiest path: official BSP. Here with Zavu:
1. Free account
Create at zavu.dev. No credit card.
2. Connect Meta Business
In the dashboard, Add WhatsApp Sender → OAuth with Meta → authorize Zavu as BSP. ~5 min.
3. Install SDK
bash# Node.js / TypeScript npm install @zavudev/sdk # Python pip install zavudev # Ruby gem install zavudev # Go go get github.com/zavudev/zavudev-go
4. Send first message
Node.js:Python:typescriptimport Zavu from "@zavudev/sdk" const zavu = new Zavu({ apiKey: process.env.ZAVU_API_KEY }) const result = await zavu.messages.send({ to: "+14155551234", channel: "whatsapp", text: "Hi! First message via API." }) console.log(result.message.id, result.message.status)
cURL:pythonfrom zavudev import Zavu import os zavu = Zavu(api_key=os.environ["ZAVU_API_KEY"]) result = zavu.messages.send( to="+14155551234", channel="whatsapp", text="Hi! First message via API." ) print(result.message.id, result.message.status)
bashcurl -X POST https://api.zavu.dev/v1/messages \ -H "Authorization: Bearer $ZAVU_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "to": "+14155551234", "channel": "whatsapp", "text": "Hi!" }'
Response:
json{ "message": { "id": "msg_01HXY...", "status": "queued", "channel": "whatsapp", "to": "+14155551234" } }
Message types the API accepts
Text
typescriptawait zavu.messages.send({ to: "+14155551234", channel: "whatsapp", text: "Order confirmed! ID: #12345" })
Media (image, video, document)
typescript// Image await zavu.messages.send({ to: "+14155551234", channel: "whatsapp", messageType: "image", text: "Product photo", content: { mediaUrl: "https://example.com/img.jpg" } }) // PDF await zavu.messages.send({ to: "+14155551234", channel: "whatsapp", messageType: "document", content: { mediaUrl: "https://example.com/invoice.pdf", filename: "invoice.pdf" } })
Interactive buttons
typescriptawait zavu.messages.send({ to: "+14155551234", channel: "whatsapp", messageType: "buttons", text: "How can I help you?", content: { buttons: [ { id: "tracking", title: "Track order" }, { id: "returns", title: "Return policy" }, { id: "human", title: "Talk to agent" } ] } })
List (up to 10 options)
typescriptawait zavu.messages.send({ to: "+14155551234", channel: "whatsapp", messageType: "list", text: "Pick a product:", content: { listButton: "View products", sections: [{ title: "Best sellers", rows: [ { id: "p1", title: "Product A", description: "$99" }, { id: "p2", title: "Product B", description: "$149" } ] }] } })
Template (outside 24h window)
typescriptawait zavu.messages.send({ to: "+14155551234", channel: "whatsapp", messageType: "template", content: { templateId: "tpl_order_confirmed", templateVariables: { "1": "John", "2": "12345" } } })
The 24-hour window: the most important rule
Meta has a strict rule:
- Within 24h of the customer replying: you can send any type of message (free text, media, buttons).
- Outside 24h: only approved templates.
typescripttemplateId: "tpl_approved"
Receiving messages (webhooks)
Configure webhook URL in the dashboard. Every incoming message:
typescript// Next.js endpoint export async function POST(req: Request) { const event = await req.json() if (event.type === "message.inbound") { console.log("Customer:", event.message.from) console.log("Text:", event.message.text) // Reply await zavu.messages.send({ to: event.message.from, channel: "whatsapp", text: "Got it! Replying shortly." }) } return new Response("ok") }
Available events:
message.inbound— customer sent messagemessage.delivered— message deliveredmessage.read— customer readmessage.failed— failed (reason in payload)conversation.new— first conversation with this customertemplate.status_changed— template approved/rejected
WhatsApp API pricing in US
Meta charges per 24h conversation, not per message:
| Category | US Price |
|---|
| Marketing | $0.025 |
|---|---|
| Utility (transactional) | $0.015 |
| Authentication (OTP) | $0.005 |
| Service (customer initiates) | $0.00 |
- Zavu: $0 markup
- Twilio: 5-20% markup
- MessageBird: $600 setup + platform
Requirements to use WhatsApp API
Common errors and fixes
Error 131005 - Access denied: invalid or expired token. In production, use System User token (permanent).Error 131056 - Number not registered: number not enabled in WhatsApp Business account. Verify in Meta Business Suite.Error 132000 - Template not approved: template still in review. Wait or use free text in 24h window.Error 470 - Re-engagement required: passed the 24h window. Use template to reopen.Webhook not called: URL must be valid HTTPS and respond 200 in < 2s. Use Cloudflare Workers or Vercel for reliability.Message "queued" and not delivering: customer may not have WhatsApp, blocked you, or invalid number. Check viamessage.failed webhook.Direct Cloud API vs via BSP
| Cloud API direct | Via Zavu (BSP) |
|---|
| Setup time | 1-2 weeks | 30 min |
|---|---|---|
| Business verification | You do it | Zavu guides |
| Token renewal | You manage | Automatic |
| Template approval | Manual in Business Suite | API + dashboard |
| Signed webhooks | You implement | SDK validates |
| Multi-channel (SMS + WhatsApp) | WhatsApp only | All unified |
| Automatic retries | You implement | Included |
| Official SDK | No (only REST) | Yes (TS, Py, Go, Ruby, PHP) |
Related resources
- WhatsApp Cloud API: step-by-step tutorial
- WhatsApp Business API pricing
- How WhatsApp Business works
- Complete technical documentation
- AI agents for WhatsApp