--- title: WhatsApp Cloud API: Complete Developer Tutorial (2026) description: Step-by-step WhatsApp Cloud API tutorial: setup, auth, sending messages, templates, webhooks and code in Python and Node.js. date: 2026-05-17 author: Victor Villalobos locale: en source: https://www.zavu.dev/en/blog/whatsapp-cloud-api-tutorial tags: WhatsApp, API, Tutorial, Developers --- # WhatsApp Cloud API: Complete Developer Tutorial (2026) The **WhatsApp Cloud API** is Meta's official API to send and receive WhatsApp Business messages, hosted by Meta itself (no need to self-host). This tutorial walks you from zero to first message sent, with real code in Python and Node.js. ## What the WhatsApp Cloud API is Cloud API replaced the older "On-Premises API" in 2022. Differences: | Cloud API (current) | On-Premises (legacy) | |---|---| | Hosted by Meta | You host it | | Setup in hours | Setup in weeks | | No servers to maintain | VPS + Docker + maintenance | | Same performance | More complex | | Recommended for 99% of cases | Only specific enterprise cases | **You don't have to deal with the Cloud API directly.** Official providers (BSPs) like [Zavu](https://www.zavu.dev/en) abstract the complexity. But understanding what's underneath is useful. ## Prerequisites Before you start: 1. **Meta Business Manager** account (free, create at [business.facebook.com](https://business.facebook.com)) 2. A **phone number** that is **NOT** active on regular WhatsApp or WhatsApp Business app 3. A **verified website** for the business 4. A server with HTTPS for webhooks (Vercel, AWS, Cloudflare Workers) ## Path 1: Direct via Meta (complex) If you want to go direct via Meta without a BSP: 1. Register your **App** at developers.facebook.com 2. Add the **WhatsApp** product 3. Enable a WhatsApp Business account and add the number 4. Generate a **temporary token** (24h) for testing or a permanent one via System User 5. First request: ```bash curl -X POST \ "https://graph.facebook.com/v18.0//messages" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "messaging_product": "whatsapp", "to": "14155551234", "type": "template", "template": { "name": "hello_world", "language": { "code": "en_US" } } }' ``` That path **works**, but you still need to: - Approve templates manually in Meta Business Suite - Handle token renewal - Implement signed webhooks - Manage errors and retries - Migrate numbers if Meta limits you ## Path 2: Via official BSP (recommended) Official BSPs solve 90% of the complexity. Here's how with Zavu: ### 1. Create free account [zavu.dev/en](https://dashboard.zavu.dev) — no credit card. ### 2. Connect Meta Business In the dashboard, click **Add WhatsApp Sender** and follow the OAuth flow. You're redirected to Meta, authorize Zavu as BSP, return. Takes 5 minutes. ### 3. Install SDK ```bash # Node.js npm install @zavudev/sdk ``` ```bash # Python pip install zavudev ``` ### 4. Send first message **Node.js / TypeScript:** ```typescript import 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 Zavu 🎉" }) console.log(result.message.id, result.message.status) ``` **Python:** ```python from 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 Zavu 🎉" ) print(result.message.id, result.message.status) ``` ## Free messages vs templates The **24-hour window** is central to the Cloud API: - **Within 24h** of customer replying: send **anything** (text, media, buttons) - **Outside 24h**: only approved templates ### Sending a template ```typescript await zavu.messages.send({ to: "+14155551234", channel: "whatsapp", messageType: "template", content: { templateId: "tpl_order_confirmed", templateVariables: { "1": "John", "2": "12345", "3": "$89.90" } } }) ``` Template categories (US): - **Utility** (transactional) — confirmations, reminders — $0.015 - **Authentication** (OTP) — codes — $0.005 - **Marketing** (promotional) — offers — $0.025 ## Rich media ```typescript // Image await zavu.messages.send({ to: "+14155551234", channel: "whatsapp", messageType: "image", text: "Check out our new product!", content: { mediaUrl: "https://example.com/product.jpg" } }) // Document (PDF) await zavu.messages.send({ to: "+14155551234", channel: "whatsapp", messageType: "document", content: { mediaUrl: "https://example.com/invoice.pdf", filename: "invoice.pdf" } }) // Interactive buttons await zavu.messages.send({ to: "+14155551234", channel: "whatsapp", messageType: "buttons", text: "How can we help?", content: { buttons: [ { id: "buy", title: "I want to buy" }, { id: "question", title: "Ask a question" }, { id: "tracking", title: "Track order" } ] } }) ``` ## Receiving messages (webhooks) Configure an HTTPS endpoint in the Zavu Dashboard. Every incoming message generates a POST: ```typescript // app/api/whatsapp-webhook/route.ts (Next.js) export async function POST(req: Request) { const event = await req.json() const signature = req.headers.get("x-zavu-signature") if (!verifySignature(signature, event)) { return new Response("Unauthorized", { status: 401 }) } switch (event.type) { case "message.inbound": console.log(`Customer ${event.message.from}: ${event.message.text}`) break case "message.delivered": console.log(`Message ${event.message.id} delivered`) break case "message.read": console.log(`Message ${event.message.id} read`) break } return new Response("ok") } ``` ## Common errors **`131056` - Number not registered**: number isn't enabled in WhatsApp Business. Check Meta Business Suite. **`131005` - Access denied**: token wrong or expired. Use System User token (permanent) in production. **`132000` - Template not approved**: template still in review. Wait for approval or use free text within the 24h window. **Message doesn't arrive**: destination may not have WhatsApp, or blocked your number. Check via `message.failed` webhook. **Webhook doesn't respond in 2s**: Meta retries up to 3 times. Structure your endpoint to respond fast and process async. ## WhatsApp Cloud API costs (US, 2026) Meta charges **per initiated 24h conversation**, not per message: | Category | Meta cost | |---|---| | Utility (transactional) | ~$0.015 | | Authentication (OTP) | ~$0.005 | | Marketing | ~$0.025 | | Service (customer initiates) | Free | BSPs add platform cost. Zavu passes Meta's cost **without markup** — you [see full pricing](/en/pricing) before starting. ## Related resources - [How WhatsApp Business works](/en/blog/whatsapp-business-como-funciona) - [WhatsApp Business auto-reply](/en/blog/mensagem-automatica-whatsapp-business) - [Build a WhatsApp AI agent with FastAPI](/en/blog/whatsapp-ai-agents-fastapi) - [Technical documentation](https://docs.zavu.dev/guides/whatsapp/overview) - [Zavu vs Twilio for WhatsApp](/en/vs/twilio) ## Conclusion WhatsApp Cloud API trades the phone app for a programmable REST endpoint. You can go direct to Meta (more work, more control) or use an official BSP like Zavu (simpler, no token/template/migration headaches). The API gives you everything the app lacks: multi-agent, CRM integration, template automation, webhooks and rich media. Start with the tutorial above — in 30 minutes you send your first message.