How to Use WhatsApp Business API for Free (2026)
Send messages programmatically without upfront costs
Start Building with Hypereal
Access Kling, Flux, Sora, Veo & more through a single API. Free credits to start, scale to millions.
No credit card required • 100k+ developers • Enterprise ready
How to Use WhatsApp Business API for Free (2026)
The WhatsApp Business API lets you send and receive messages programmatically, automate customer support, and build chatbots. Previously, accessing this API required an expensive Business Solution Provider (BSP). In 2026, Meta's Cloud API makes it possible to get started for free. This guide walks through the complete setup process with working code examples.
WhatsApp Business API: Free Tier Overview
Meta offers a free tier for the WhatsApp Business Cloud API with the following limits:
| Feature | Free Tier | Paid Tier |
|---|---|---|
| Service conversations (user-initiated) | 1,000/month free | $0.005-0.08 per conversation |
| Marketing conversations | Not included | $0.01-0.15 per conversation |
| Test phone numbers | 1 test number included | Unlimited verified numbers |
| Message templates | 250 templates | 250 templates |
| Media messages | Supported | Supported |
| Webhook notifications | Supported | Supported |
| Rate limit | 80 messages/second | 500+ messages/second |
The 1,000 free service conversations per month reset on the first of each month. Service conversations are those initiated by users (they message you first), and each conversation window lasts 24 hours.
Prerequisites
Before you start, you need:
- A Meta (Facebook) account
- A Meta Business account (free to create)
- A phone number that can receive SMS or voice calls for verification
- Basic knowledge of REST APIs
Step-by-Step Setup
Step 1: Create a Meta Developer Account
1. Go to https://developers.facebook.com
2. Click "Get Started" or "My Apps"
3. Sign in with your Facebook account
4. Accept the developer terms
5. Verify your account with a phone number
Step 2: Create a New App
1. Click "Create App" in the developer dashboard
2. Select "Business" as the app type
3. Enter an app name (e.g., "My WhatsApp Bot")
4. Select your Meta Business account (or create one)
5. Click "Create App"
Step 3: Add WhatsApp to Your App
1. In the app dashboard, find "Add Products"
2. Click "Set Up" on the WhatsApp card
3. This creates a test WhatsApp Business Account automatically
4. You will see a test phone number and a temporary access token
Step 4: Get Your Access Token
The temporary token from the dashboard expires after 24 hours. For production use, generate a permanent System User token:
1. Go to Meta Business Suite > Settings > Business Settings
2. Navigate to System Users
3. Click "Add" to create a new System User
4. Set the role to "Admin"
5. Click "Generate Token"
6. Select your WhatsApp app
7. Grant these permissions:
- whatsapp_business_management
- whatsapp_business_messaging
8. Copy and save the token securely
Step 5: Add a Test Recipient
Before sending messages, you must add recipient phone numbers to your test list:
1. In the WhatsApp section of your app dashboard
2. Go to "API Setup"
3. Under "Send Messages", click "Manage phone number list"
4. Add the phone numbers you want to send test messages to
5. Each recipient must confirm by replying to the verification message
Sending Your First Message
Using cURL
curl -X POST \
"https://graph.facebook.com/v21.0/YOUR_PHONE_NUMBER_ID/messages" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"messaging_product": "whatsapp",
"to": "1234567890",
"type": "text",
"text": {
"body": "Hello from the WhatsApp Business API!"
}
}'
Using Node.js
const axios = require("axios");
const PHONE_NUMBER_ID = "your_phone_number_id";
const ACCESS_TOKEN = "your_access_token";
async function sendWhatsAppMessage(to, message) {
try {
const response = await axios.post(
`https://graph.facebook.com/v21.0/${PHONE_NUMBER_ID}/messages`,
{
messaging_product: "whatsapp",
to: to,
type: "text",
text: { body: message }
},
{
headers: {
Authorization: `Bearer ${ACCESS_TOKEN}`,
"Content-Type": "application/json"
}
}
);
console.log("Message sent:", response.data);
return response.data;
} catch (error) {
console.error("Error:", error.response?.data || error.message);
throw error;
}
}
// Send a message
sendWhatsAppMessage("1234567890", "Hello from Node.js!");
Using Python
import requests
PHONE_NUMBER_ID = "your_phone_number_id"
ACCESS_TOKEN = "your_access_token"
def send_whatsapp_message(to: str, message: str):
url = f"https://graph.facebook.com/v21.0/{PHONE_NUMBER_ID}/messages"
headers = {
"Authorization": f"Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json"
}
payload = {
"messaging_product": "whatsapp",
"to": to,
"type": "text",
"text": {"body": message}
}
response = requests.post(url, json=payload, headers=headers)
response.raise_for_status()
print("Message sent:", response.json())
return response.json()
# Send a message
send_whatsapp_message("1234567890", "Hello from Python!")
Sending Rich Messages
Image Message
def send_image(to: str, image_url: str, caption: str = ""):
payload = {
"messaging_product": "whatsapp",
"to": to,
"type": "image",
"image": {
"link": image_url,
"caption": caption
}
}
response = requests.post(
f"https://graph.facebook.com/v21.0/{PHONE_NUMBER_ID}/messages",
json=payload,
headers={"Authorization": f"Bearer {ACCESS_TOKEN}"}
)
return response.json()
Interactive Button Message
def send_buttons(to: str, body_text: str, buttons: list):
payload = {
"messaging_product": "whatsapp",
"to": to,
"type": "interactive",
"interactive": {
"type": "button",
"body": {"text": body_text},
"action": {
"buttons": [
{
"type": "reply",
"reply": {"id": btn["id"], "title": btn["title"]}
}
for btn in buttons
]
}
}
}
response = requests.post(
f"https://graph.facebook.com/v21.0/{PHONE_NUMBER_ID}/messages",
json=payload,
headers={"Authorization": f"Bearer {ACCESS_TOKEN}"}
)
return response.json()
# Send a message with buttons
send_buttons(
"1234567890",
"How can we help you today?",
[
{"id": "support", "title": "Get Support"},
{"id": "pricing", "title": "View Pricing"},
{"id": "demo", "title": "Book a Demo"}
]
)
Template Message (For Outbound Notifications)
To message users first (outside the 24-hour window), you must use approved templates:
def send_template(to: str, template_name: str, language: str = "en_US"):
payload = {
"messaging_product": "whatsapp",
"to": to,
"type": "template",
"template": {
"name": template_name,
"language": {"code": language},
"components": [
{
"type": "body",
"parameters": [
{"type": "text", "text": "John"},
{"type": "text", "text": "your order #12345"}
]
}
]
}
}
response = requests.post(
f"https://graph.facebook.com/v21.0/{PHONE_NUMBER_ID}/messages",
json=payload,
headers={"Authorization": f"Bearer {ACCESS_TOKEN}"}
)
return response.json()
Setting Up Webhooks
To receive incoming messages, you need to configure a webhook endpoint.
Express.js Webhook Server
const express = require("express");
const app = express();
app.use(express.json());
const VERIFY_TOKEN = "your_custom_verify_token";
// Webhook verification (GET)
app.get("/webhook", (req, res) => {
const mode = req.query["hub.mode"];
const token = req.query["hub.verify_token"];
const challenge = req.query["hub.challenge"];
if (mode === "subscribe" && token === VERIFY_TOKEN) {
console.log("Webhook verified");
res.status(200).send(challenge);
} else {
res.sendStatus(403);
}
});
// Receive messages (POST)
app.post("/webhook", (req, res) => {
const body = req.body;
if (body.object === "whatsapp_business_account") {
body.entry?.forEach((entry) => {
entry.changes?.forEach((change) => {
const messages = change.value?.messages;
if (messages) {
messages.forEach((message) => {
console.log("From:", message.from);
console.log("Type:", message.type);
if (message.type === "text") {
console.log("Text:", message.text.body);
}
});
}
});
});
res.sendStatus(200);
} else {
res.sendStatus(404);
}
});
app.listen(3000, () => {
console.log("Webhook server running on port 3000");
});
Expose Your Local Server
For development, use a tunneling service to expose your local webhook:
# Using ngrok
ngrok http 3000
# Using Cloudflare Tunnel
cloudflared tunnel --url http://localhost:3000
Then register the public URL in your Meta app dashboard under WhatsApp > Configuration > Webhook URL.
Free Alternatives and Supplements
If the free tier limits are too restrictive, consider these options:
| Option | Free Messages | Notes |
|---|---|---|
| Meta Cloud API (official) | 1,000 service conversations/month | Best for small projects |
| Twilio WhatsApp Sandbox | Free during development | Requires Twilio account; paid in production |
| WhatsApp Business App (manual) | Unlimited | No API access; manual sending only |
| WATI free trial | 14-day trial | BSP with dashboard and chatbot builder |
Common Errors and Solutions
| Error Code | Message | Solution |
|---|---|---|
| 131030 | "Recipient phone number not in allowed list" | Add the number to your test recipients |
| 131047 | "Re-engagement message" | Use an approved template for first contact |
| 100 | "Invalid parameter" | Check phone number format (include country code, no + or spaces) |
| 190 | "Access token expired" | Generate a new System User token |
| 368 | "Temporarily blocked for policies" | Review Meta's commerce and messaging policies |
Conclusion
The WhatsApp Business API is accessible for free through Meta's Cloud API, with 1,000 service conversations per month at no cost. This is enough for small businesses, prototypes, and personal projects. The setup process through Meta's developer portal takes about 30 minutes, and from there you can send text, media, and interactive messages programmatically.
For businesses that want to enhance their WhatsApp communications with AI-generated video content -- such as personalized product demo videos or AI talking avatar greetings -- Hypereal AI provides affordable APIs for video generation and avatar creation that pair well with rich media WhatsApp messages.
Related Articles
Start Building Today
Get 35 free credits on signup. No credit card required. Generate your first image in under 5 minutes.
