Blog/WhatsApp Business

WhatsApp API: Send Messages

Learn how to send messages with the WhatsApp Cloud API – with code examples for Python, Node.js, and PHP. Incl. permanent token setup, interactive buttons, messaging limits, error codes, and the most important pricing and compliance updates for 2026.

Blog Header Image

By Johannes Mansbart

CEO & Co-Founder, chatarmin.com

Last updated at: March 05, 2026

WhatsApp Business

☝️ The most important facts in brief

  • Endpoint: All messages go through POST https://graph.facebook.com/v21.0/{PHONE_NUMBER_ID}/messages
  • Authentication: You need a permanent access token (via System User in Business Manager) – the temporary token expires after 24h
  • 24-Hour Rule: Free-form messages only within 24h of the customer's last reply, after that only templates work
  • Cost Hack: Utility templates are free when sent within an open 24h window
  • Messaging Limits: New numbers start at 250 msg/24h – scale to unlimited through business verification and high quality ratings
  • AI Policy 2026: "General Purpose AI" bots have been banned since January 2026, task-specific bots (support, sales) remain allowed
  • Interactive Messages: Reply buttons (max 3) and list messages (max 10 options) significantly increase conversion

The WhatsApp Cloud API has a documentation problem. Not because the information is missing – but because it's scattered across 47 subpages, contradicts itself, and hides the most important stuff (like how to get a token that lasts longer than 24 hours) somewhere deep in the Business Manager.

This guide is the opposite: One document. Everything included. Working code for Python, Node.js, and PHP. The pricing hacks for 2026. And the one thing Meta doesn't show you on the landing page – but that can get you banned instantly if you ignore it.

The Basics: What You Actually Need

Before you write a single line of code, you need four things:

Meta Developer Account – Free at developers.facebook.com

WhatsApp Business Account (WABA) – Created automatically during app setup

Verified Phone Number – Cannot already be used for personal WhatsApp

Permanent Access Token – This is where 80% of developers fail on their first attempt

The first three are click-click-done. The token is not.

Creating a Permanent Access Token (Step-by-Step)

The temporary token from the API setup lasts 24 hours. Then your bot is dead. For production, you need a System User token without an expiration date.

Here's how:

Open the Meta Business Manager

Go to Business Settings → Users → System Users

Click Add and create a new system user with the role Admin

Select the created user and click Assign Assets

Under "Apps," select your WhatsApp app and grant Full Control

Click Generate Token

Select these permissions:

whatsapp_business_messaging

whatsapp_business_management

Copy the token – it's only shown once

This token never expires. Treat it like a password: Never in the frontend, never in a Git repository, always as an environment variable.

The Messages Endpoint

All messages – text, images, documents, buttons – go through a single endpoint:

POST https://graph.facebook.com/v21.0/{PHONE_NUMBER_ID}/messages

The current API version is v21.0 (as of February 2026). You'll find your PHONE_NUMBER_ID in the Meta Developer Dashboard under WhatsApp → API Setup.

Authentication

Authorization: Bearer {YOUR_PERMANENT_TOKEN}
Content-Type: application/json

Session Messages vs. Template Messages

This is the biggest stumbling block for developers. WhatsApp strictly distinguishes between:

Session messages can only be sent if the customer has messaged you within the last 24 hours. Within this window, anything goes: free text, images, documents, buttons.

Template messages are predefined templates that Meta must approve first (24–48h review time). This is the only way to contact customers outside the 24h window.

The Utility Hack for 2026

Here's where it gets interesting: Utility templates (order confirmations, shipping updates, appointment reminders) are free when sent within an open 24h window.

This means: Customer messages you → You respond with a utility template instead of free text → Free instead of paid.

Sounds like a small detail? At 10,000 messages per month, this saves several hundred euros depending on the region. Our WhatsApp Business API Guide explains the exact cost structure in detail.

Code Examples: Sending a Text Message

cURL (for testing)

curl -X POST "https://graph.facebook.com/v21.0/PHONE_NUMBER_ID/messages" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "14155551234",
"type": "text",
"text": {
"preview_url": false,
"body": "Your order #12345 is on its way!"
}
}'

The phone number must be in E.164 format: country code without +, no spaces, no leading zero (so 14155551234, not +1 (415) 555-1234).

Python

import requests
import os

def send_whatsapp_message(phone_number: str, message: str) -> dict:
"""
Sends a WhatsApp text message via the Cloud API.

Args:
phone_number: Recipient in format 14155551234
message: The message text (max 4096 characters)

Returns:
API response with message_id on success
"""
url = f"https://graph.facebook.com/v21.0/{os.environ['WA_PHONE_NUMBER_ID']}/messages"

headers = {
"Authorization": f"Bearer {os.environ['WA_ACCESS_TOKEN']}",
"Content-Type": "application/json"
}

payload = {
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": phone_number,
"type": "text",
"text": {
"preview_url": False,
"body": message
}
}

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()  # Raises exception on 4xx/5xx
return response.json()

# Example
result = send_whatsapp_message("14155551234", "Your order is on its way!")
print(f"Message sent: {result['messages'][0]['id']}")

Node.js

const axios = require('axios');

async function sendWhatsAppMessage(phoneNumber, message) {
const url = `https://graph.facebook.com/v21.0/${process.env.WA_PHONE_NUMBER_ID}/messages`;

const payload = {
messaging_product: 'whatsapp',
recipient_type: 'individual',
to: phoneNumber,
type: 'text',
text: {
preview_url: false,
body: message
}
};

const response = await axios.post(url, payload, {
headers: {
'Authorization': `Bearer ${process.env.WA_ACCESS_TOKEN}`,
'Content-Type': 'application/json'
}
});

return response.data;
}

// Example
sendWhatsAppMessage('14155551234', 'Your order is on its way!')
.then(res => console.log('Sent:', res.messages[0].id))
.catch(err => console.error('Error:', err.response?.data || err.message));

PHP

<?php

function sendWhatsAppMessage(string $phoneNumber, string $message): array
{
$url = 'https://graph.facebook.com/v21.0/' . getenv('WA_PHONE_NUMBER_ID') . '/messages';

$payload = [
'messaging_product' => 'whatsapp',
'recipient_type' => 'individual',
'to' => $phoneNumber,
'type' => 'text',
'text' => [
'preview_url' => false,
'body' => $message
]
];

$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('WA_ACCESS_TOKEN'),
'Content-Type: application/json'
],
CURLOPT_RETURNTRANSFER => true
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($httpCode >= 400) {
throw new Exception("API Error: $response");
}

return json_decode($response, true);
}

// Example
$result = sendWhatsAppMessage('14155551234', 'Your order is on its way!');
echo "Sent: " . $result['messages'][0]['id'];

Interactive Messages: Buttons & Lists

This is where it gets interesting. Buttons massively increase interaction rates – users prefer tapping a button over typing a response. WhatsApp offers two types:

Reply Buttons (max 3 buttons)

payload = {
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "14155551234",
"type": "interactive",
"interactive": {
"type": "button",
"header": {
"type": "text",
"text": "Order Status"
},
"body": {
"text": "Your order #12345 is out for delivery. What would you like to do?"
},
"footer": {
"text": "Powered by Chatarmin"
},
"action": {
"buttons": [
{
"type": "reply",
"reply": {
"id": "track_order",
"title": "📍 Track Shipment"
}
},
{
"type": "reply",
"reply": {
"id": "contact_support",
"title": "💬 Contact Support"
}
},
{
"type": "reply",
"reply": {
"id": "change_address",
"title": "📝 Change Address"
}
}
]
}
}
}

List Messages (max 10 options)

Perfect for selection menus with more options:

payload = {
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "14155551234",
"type": "interactive",
"interactive": {
"type": "list",
"header": {
"type": "text",
"text": "Help & Support"
},
"body": {
"text": "How can we help you? Select a topic:"
},
"action": {
"button": "Select Topic",
"sections": [
{
"title": "Orders",
"rows": [
{"id": "order_status", "title": "Order Status", "description": "Where is my package?"},
{"id": "order_cancel", "title": "Cancellation", "description": "Cancel my order"},
{"id": "order_return", "title": "Returns", "description": "Return an item"}
]
},
{
"title": "Products",
"rows": [
{"id": "product_info", "title": "Product Advice", "description": "Help choosing"},
{"id": "product_stock", "title": "Availability", "description": "Is item X in stock?"}
]
}
]
}
}
}

The button ID (track_order, order_status, etc.) is returned as a webhook payload when the user clicks. This is how you control your bot flow. Our Chatbot API Guide shows how to set up webhooks and process responses.

Sending Template Messages

For messages outside the 24h window, you need an approved template:

payload = {
"messaging_product": "whatsapp",
"to": "14155551234",
"type": "template",
"template": {
"name": "order_shipped",
"language": {
"code": "en"
},
"components": [
{
"type": "body",
"parameters": [
{"type": "text", "text": "John"},           # {{1}} = Customer name
{"type": "text", "text": "12345"},          # {{2}} = Order number
{"type": "text", "text": "FedEx Express"}   # {{3}} = Shipping method
]
}
]
}
}

You create templates in WhatsApp Manager under Account Tools → Message Templates. Expect 24–48 hours review time from Meta.

Messaging Limits: Why Your Messages Suddenly Stop

New WhatsApp Business numbers start with a limit of 250 messages per 24 hours. That's enough for testing – but not for production.

Here's how to scale:

Tier Limit/24h Requirement
Tier 1 1,000 Phone number verified
Tier 2 10,000 Business verified + good quality rating
Tier 3 100,000 Stable high quality over several weeks
Unlimited Consistently high quality, no spam feedback

You can see your quality rating in WhatsApp Manager under Phone Numbers → Quality Rating. If it drops to "Low," your limit is automatically reduced or your number gets suspended.

AI Policy 2026: What You Need to Know

Warning: Since January 15, 2026, Meta prohibits so-called "General Purpose AI Assistants" on WhatsApp. This affects open ChatGPT wrappers without a clear business purpose – bots that answer any arbitrary question.

Allowed are task-specific bots with a defined scope:

Customer service bots (FAQ, ticket status)

Sales bots (product advice, orders)

Booking bots (appointments, reminders)

Prohibited are:

"Ask me anything" bots without business context

Bots that impersonate human employees

At Chatarmin, we focus precisely on this compliance: Every bot has a clear purpose, defined flows, and transparent bot labeling. Our WhatsApp Automation Guide shows what this looks like in practice.

Error Handling: The Most Common Error Codes

Code Meaning Solution
131030 Invalid recipient number Check E.164 format (14155551234)
131031 No active 24h window Use a template message
131047 Re-engagement required Customer must reply first (opt-in)
131053 Media URL not reachable Make URL publicly accessible
130429 Rate limit reached Throttle send rate to max 80 msg/sec
131026 Message undeliverable Number not on WhatsApp or blocked
368 Temporary suspension Wait 24h, then improve quality

For persistent errors: Check WhatsApp Manager → Insights → Logs.

Real-World Usage: How Companies Use the API

The code snippets above are just the beginning. In practice, there's a system behind it that automatically decides: Which message? To whom? When? With which template?

Waterdrop processes thousands of WhatsApp inquiries daily – automated first responses, intelligent routing to the right teams, escalation for complex cases.

Luxusbetten24 uses the API for the complete customer journey: Order confirmation → Shipping update → Delivery notification → Review request. All automated, all measurable.

Cusbclo shows how welcome flows work: New customer writes → Automatic greeting with buttons → Qualification questions → Direct routing to the matching product.

Build vs. Buy: An Honest Assessment

You can build everything yourself. Set up servers, configure webhooks, implement retry logic for failed messages, status tracking, template management with Meta sync, GDPR-compliant opt-in documentation.

Realistically: That's 3–6 months of development time for a team doing it for the first time. Plus ongoing maintenance with API updates (Meta releases a new version roughly every 3 months).

At Chatarmin, we solve exactly this: The technical complexity disappears behind a UI. Flow builder instead of code for every message type. Template management with direct Meta integration. Analytics that show which messages convert and which don't.

That doesn't mean API knowledge is useless – quite the opposite. Those who understand what's happening under the hood make better decisions. But there's a significant difference in time and budget between "understanding" and "having to maintain it yourself."

FAQ: The 10 Most Common Questions

Is the WhatsApp Business API free?

The API itself has no base fee, but Meta charges per conversation (conversation-based pricing). However, the first 1,000 service conversations per month are free.

What's the difference between Cloud API and On-Premise API?

The Cloud API is hosted by Meta and scales automatically. The On-Premise API must be operated on your own servers (Docker). For 99% of companies, the Cloud API is the standard in 2026 – Meta itself recommends migrating.

How do I get a permanent access token?

In Meta Business Manager under System Users: Create a new admin user, assign the app, generate a token with the permissions whatsapp_business_messaging and whatsapp_business_management. This token doesn't expire.

What are WhatsApp Messaging Limits?

New numbers start with 250 or 1,000 messages per 24 hours. Through business verification and high quality ratings, this limit automatically scales to 10k, 100k, or unlimited.

Are AI chatbots allowed on WhatsApp?

Yes, as long as they have a clear business purpose (support, sales, booking). Since January 2026, pure "General Purpose AI" bots without a specific focus are prohibited according to Meta's guidelines.

Can I send WhatsApp newsletters without opt-in?

No. This leads to immediate suspension of your number. Every recipient must have explicitly consented to receiving messages – documented and GDPR-compliant.

How much does a WhatsApp Business message cost in 2026?

Costs vary by country and category. Marketing messages to the US cost approximately $0.025, utility messages around $0.015. Service replies within the 24h window are free.

What happens when the 24-hour window expires?

You can no longer send free-text messages. To reopen the conversation, you need an approved template – which then costs depending on the category.

Do I need my own phone number for the API?

Yes. The number cannot be simultaneously linked to the personal WhatsApp app or WhatsApp Business app on a phone. One number = one channel.

Why are my WhatsApp templates being rejected?

Most common reasons: Promotional content in utility templates, missing variable examples, violation of commerce policies (e.g., alcohol, tobacco), or the template name contains special characters.

Conclusion

The WhatsApp Cloud API isn't technically complicated – one POST request, JSON payload, done. The complexity lies elsewhere: Token management, the 24h window, messaging limits, template approval, AI policy.

For a quick test, the code snippets above are enough. For production with thousands of customers, you need more: Monitoring, error handling, compliance checks, retry logic.

Next step: Test the API with your test number in the Meta Developer Dashboard. Once the first message arrives, decide: Build it yourself or buy it ready-made?

Related Articles

More articles from the same category, sorted by most recent updates

View All Articles →
Use two WhatsApp accounts

Use two WhatsApp accounts

Find out how you can use two WhatsApp accounts on one device, both business and personal.

WhatsApp BusinessUpdated March 05, 2026
WhatsApp Quick Reply Activate: Set It Up Easily

WhatsApp Quick Reply Activate: Set It Up Easily

Learn how to activate WhatsApp Quick Reply and respond to messages faster.

WhatsApp BusinessUpdated March 05, 2026
WhatsApp Image Size Guide 2026: Formats, Dimensions & Pro Tips for Marketing

WhatsApp Image Size Guide 2026: Formats, Dimensions & Pro Tips for Marketing

All WhatsApp image sizes 2026: Profile pictures, Status, Stickers, Carousel & Video Notes. Including Safe Zones, HD tips and the 2GB document trick for professional B2B marketing.

WhatsApp BusinessUpdated March 05, 2026

More Articles

Read More →
Sinch Engage Pricing 2026: Complete Guide & Plans Overview

Sinch Engage Pricing 2026: Complete Guide & Plans Overview

Sinch Engage pricing 2026: All plans, hidden costs for WhatsApp add-ons, Meta fees, AI chatbot surcharges, and cancellation terms – an honest breakdown for e-commerce businesses.

Trengo Pricing 2026: What Does the Inbox Really Cost? (Analysis)

Trengo Pricing 2026: What Does the Inbox Really Cost? (Analysis)

Trengo starts at €299/month – but real costs are often much higher. This analysis reveals what's behind the conversations model, auto top-up and AI surcharges.

Wati Pricing 2026: What Does the Tool Actually Cost?

Wati Pricing 2026: What Does the Tool Actually Cost?

Wati starts at $59/mo but adds ~20% markup on Meta messages, caps automation triggers, charges $4.99 for Shopify. Growth plan locks you to 3 users with no option to add more. Honest cost analysis for e-commerce teams.

Turn conversations into revenue

Launch WhatsApp campaigns and AI-powered support in only a few days. GDPR-compliant & built for DACH E-Commerce.