WhatsApp Cloud API basics: first message, tokens, templates
WhatsApp Cloud API basics from Meta's own sample code: send a first message, swap the temporary token for a system user token, then send approved templates.
The WhatsApp Cloud API is the version of the WhatsApp Business Platform that Meta hosts for you: your code sends a message with one POST to /{phone-number-id}/messages on graph.facebook.com, and Meta delivers it. A first test needs a Meta app with the WhatsApp product, a phone number ID and an access token. Anything beyond a test also needs a system user token, approved message templates and a webhook for replies.
This guide covers the first hour, and nothing on it comes from Meta's websites. Every fact is from Meta's official GitHub repositories: the Jasper's Market sample (updated September 2026), the WhatsApp Cloud API examples, the archived WhatsApp Node.js SDK and Meta's Python Business SDK. Where those sources stop, the page says so. For the other Meta APIs, start at Meta API use cases.
What this means for you
The WhatsApp Cloud API is for software that sends and answers WhatsApp messages. Meta's own sample apps show the kind of jobs it does: flight confirmations, movie tickets, orders in an online shop, course offers and a grocery bot, plus connections to Salesforce and to an Amazon Lex chatbot.
If you answer customers yourself from your phone, you don't need any of this. Meta's GitHub sources only describe the API, so this page can't tell you what the WhatsApp Business app does. It can tell you what the API takes: a Meta developer account, a Meta app, a Meta business, a WhatsApp Business Account and a server that stays online to receive messages. That setup pays off when a program has to send or answer messages for you.
The details: how the WhatsApp Cloud API works
What you need before the first call
Meta's Jasper's Market sample lists four requirements: a Meta developer account, a Meta app, a Meta business ("a pre-requisite for building with WhatsApp") and a WhatsApp Business Account, "needed to send and receive messages in WhatsApp". To give the app WhatsApp access, you open the app dashboard and choose WhatsApp, then Set Up, under Add Product.
Four IDs and secrets come up again and again:
| Value | What Meta's samples use it for |
|---|---|
| App ID and App Secret | Your Meta app. The secret also checks webhook signatures. |
| WhatsApp Business Account ID (WABA ID) | Message templates live here: /{waba-id}/message_templates |
| Phone number ID | The sender. Messages go to /{phone-number-id}/messages |
| Access token | Sent as Authorization: Bearer on every call |
The phone number ID isn't the phone number. Meta's 2023 SDK quickstart says to find it in the App Dashboard under WhatsApp, Getting started, Phone number ID. The menu may have moved since.
Send your first message
Meta's SDK quickstart picks up where Meta's own getting started steps end, once you have sent a test message from your test sender number. It then asks the recipient to reply to that message from WhatsApp. After the reply, your own code can send a text message. Meta's Python sample sends this body to https://graph.facebook.com/{version}/{phone-number-id}/messages:
{
"messaging_product": "whatsapp",
"preview_url": false,
"recipient_type": "individual",
"to": "<recipient phone number>",
"type": "text",
"text": { "body": "<your text>" }
}
A few details from the samples:
- The recipient is a phone number with its country code. One sample's settings file says to write it without the "+" symbol.
- The version goes in the path. The quickstart says to set it to the latest Graph API version. The older samples are pinned to v13.0, v15.0 and v16.0, so don't copy their version number. Meta Graph API versions lists the current one and every end date.
- The response carries a message ID (
messages[0].idin Jasper's Market). Status webhooks for that message refer to the same ID, so store it. - A 200 response doesn't mean the message arrived. The quickstart warns that the API can return 200 while the message never reaches WhatsApp, and puts it down to the 24-hour session described below.
Temporary token or system user token
The App Dashboard gives you a temporary access token for testing. Meta's 2023 quickstart says you can use it for the first exercise, but Meta's settings files keep repeating the same advice: "System user access token. Recommended: Do not use a temporary access token", and in another sample, "System User Access Token. Not temporary access token". The Jasper's Market README tells you to "create a system user token for your app" before you start.
Meta's Python Business SDK shows the call behind it: POST /{business-id}/system_user_access_tokens, with the system user's ID, the assets the token covers, the permissions (scope) and an option named set_token_expires_in_60_days.
What Meta's GitHub sources don't state:
- how long the temporary token lasts;
- how long a system user token lasts without that option;
- the exact permission names a WhatsApp token needs.
Check the permissions and the expiry on the screen where you create the token. Keep the token on your server, never in an app or a web page.
Message templates
A template is a message you register in advance and then fill in at send time. Meta's samples create one with POST /{waba-id}/message_templates and four fields: name, language, category and components (header, body, footer, buttons). The Jasper's Market README says you can do this with its script or in WhatsApp Manager instead.
Meta's Business SDK lists three template categories:
AUTHENTICATIONMARKETINGUTILITY
A template also has a status. The SDK's filter values include PENDING, APPROVED, REJECTED, PAUSED and DISABLED. Meta's Node.js SDK describes its send function as sending "an existing approved and enabled message template", so check that the status reads APPROVED before your code relies on it. The sources don't describe how Meta reviews a template or how long it takes.
To send one, the message type is template, with the template's name, a language.code such as en_US, and components holding the values for the template's variables. Jasper's Market fills an image header this way.
Images in templates need two different IDs, and the sample spells out the difference:
- When you create the template, the example image is a handle from Meta's upload endpoint (
/{app-id}/uploads). - When you send it, you use a media ID uploaded for the phone number that sends the message. The README says media IDs "are scoped to the phone number that uploaded them and expire after 30 days", so re-upload before then.
Meta moved its own sample to media IDs on September 14, 2026. The commit says the Cloud API rewrote the old Meta CDN image links to an address that returns 400 Invalid Handle, so the sends were accepted and then failed.
The 24-hour window
Meta's 2023 quickstart describes the rule like this: when a person sends you a message, the conversation becomes a user-initiated session, "which allows other messages to be received via API calls for 24-hours". After that, a reply can return 200 and still not arrive.
Meta's current Business SDK names a pricing type FREE_CUSTOMER_SERVICE, which matches the window people search for as the customer service window. The GitHub sources don't say in one place which message types work outside the 24 hours, so watch the status webhooks: Jasper's Market reads statuses such as sent, delivered, read and failed.
Webhooks: receiving messages
Replies and delivery statuses reach you as webhooks. Meta's samples set them up like this:
- Put your server on a public HTTPS address. The SDK asks for "a publicly accessible HTTPS (not HTTP) URL". For testing, the samples use a tunnel such as ngrok.
- Answer the verification request. Meta sends a
GETwithhub.modeset tosubscribe,hub.verify_tokenandhub.challenge. Your server checks the token against one you chose and returns thehub.challengevalue. - Subscribe. In the app's WhatsApp Configuration tab, enter the URL and your verify token and subscribe to the
messagesfield. - Read the payload. Notifications arrive as a
POSTwhereobjectiswhatsapp_business_account. Eachentryhaschanges, and each change'svaluecarriesmetadata.phone_number_idplusmessages(incoming) orstatuses(sent, delivered, read, failed). - Check the signature in the
X-Hub-Signature-256header. It is an HMAC SHA256 of the raw body, keyed with your App Secret, after thesha256=prefix. Jasper's Market and the Node.js SDK both check it this way. One older sample in the Cloud API examples keys the hash with its verify token instead, so follow the newer code. - Return 200. The SDK says a 200 tells the service not to send that notification again.
Expect duplicates anyway. The Jasper's Market README says "WhatsApp can retry the same webhook", and deduplicates by the incoming message ID. To show the customer you've seen a message, Jasper's Market posts status: "read" with the message_id, and can add a typing indicator in the same call.
If your server checks Meta's client certificate, note that Meta's webhook mTLS certificate moved to a Meta-owned CA on March 31, 2026. That entry doesn't name WhatsApp, so test your endpoint rather than assume.
Cloud API or On-Premises API
New projects use the Cloud API. On November 26, 2025, Meta added this warning to the README of its On-Premises setup scripts: "The WhatsApp Business On-premises API is now deprecated. Please use the WhatsApp Business Cloud API instead." On December 4, 2025, it removed the On-Premises client code from that repository. The sources don't give a final shutdown date.
Pricing and limits
Meta's GitHub sources state no prices, and WhatsApp pricing is set per country and per category, so this page quotes none. What the Business SDK shows is how Meta counts: the pricing_analytics edge on a WhatsApp Business Account returns COST and VOLUME, split by country, pricing category and pricing type (REGULAR, FREE_CUSTOMER_SERVICE, FREE_ENTRY_POINT and one more). Current rates for your account are in WhatsApp Manager.
On limits, the SDK shows a field named whatsapp_business_manager_messaging_limit on the account, with tier values from TIER_50 to TIER_UNLIMITED. It doesn't say what each tier allows or how an account moves between them, and the sources give no limit for the test number.
Building for other businesses
Jasper's Market assumes you send for your own business. If your app will connect other companies' WhatsApp accounts, Meta's access levels and review apply. Meta App Review: the minimum rules to go live covers them from Meta's Instagram and Messenger samples; the WhatsApp samples used here don't describe review for WhatsApp.
What to do next
- Business owners: If you reply to customers yourself, you don't need the API. Consider the WhatsApp Cloud API when software has to send or answer messages, and plan for a developer and a server.
- Marketers and agencies: Templates need an approved status before they send, so register them early. Check current rates per country and category in WhatsApp Manager before you plan a campaign.
- Developers: Send the dashboard test message, then your own text message. Replace the temporary token with a system user token, verify
X-Hub-Signature-256with your App Secret, deduplicate webhooks by message ID and re-upload template media before 30 days.
Questions people ask
Is the WhatsApp Cloud API free?
Meta's public GitHub sources don't publish a price list, so we don't quote one. They do show how costs are tracked: Meta's Business SDK reports cost and volume per WhatsApp Business Account, split by country, pricing category and pricing type, and one of the pricing types is named FREE_CUSTOMER_SERVICE. Current rates for your account are in WhatsApp Manager.
How long does the WhatsApp temporary access token last?
Meta's GitHub sources don't say. They do say not to rely on it: Meta's SDK configuration reads "Recommended: Do not use a temporary access token", and the newer samples ask for a system user token instead. Meta's Business SDK creates system user tokens with an option called set_token_expires_in_60_days, but it doesn't state how long a token lasts without it.
What is the 24-hour window in the WhatsApp Cloud API?
Meta's 2023 SDK quickstart says that when a person replies to your test message, the conversation becomes a user-initiated session, which allows other messages to reach them via API calls for 24 hours. If the API returns 200 but the message never arrives, it says the session may have passed those 24 hours, and the fix is for the recipient to message again.
Is the WhatsApp On-Premises API still available?
Meta says it is deprecated. Since November 26, 2025, the README of Meta's On-Premises setup scripts has read: "The WhatsApp Business On-premises API is now deprecated. Please use the WhatsApp Business Cloud API instead." Meta removed the On-Premises client code from that repository on December 4, 2025. New projects should start on the Cloud API.
How many people can I message from the WhatsApp test number?
Meta's GitHub sources don't state a limit for the test number, so we don't give one. For real numbers, Meta's Business SDK shows a messaging limit field on the WhatsApp Business Account with named tiers, but not what each tier allows.
Sources
- Meta on GitHub: Jasper's Market WhatsApp sample README (fbsamples/whatsapp-business-jaspers-market)
- Meta on GitHub: Jasper's Market webhook server, app.js (fbsamples/whatsapp-business-jaspers-market)
- Meta on GitHub: Jasper's Market template setup script, template.sh (fbsamples/whatsapp-business-jaspers-market)
- Meta on GitHub: Jasper's Market message payloads (fbsamples/whatsapp-business-jaspers-market)
- Meta on GitHub: WhatsApp Cloud API examples, Python message helper (fbsamples/whatsapp-api-examples)
- Meta on GitHub: WhatsApp Cloud API examples, message templates controller (fbsamples/whatsapp-api-examples)
- Meta on GitHub: WhatsApp Node.js SDK quickstart, archived (WhatsApp/WhatsApp-Nodejs-SDK)
- Meta on GitHub: WhatsApp Node.js SDK, receiving messages, archived (WhatsApp/WhatsApp-Nodejs-SDK)
- Meta on GitHub: WhatsApp Business API Setup Scripts README, On-Premises API deprecation (WhatsApp/WhatsApp-Business-API-Setup-Scripts)
- Meta on GitHub: WhatsApp Business Account object in the Python Business SDK (facebook/facebook-python-business-sdk)
- Meta on GitHub: Business object in the Python Business SDK, system user tokens (facebook/facebook-python-business-sdk)
Related
- API
LinkedIn Posts API: what you can schedule and how
LinkedIn's Posts API publishes text, images, video, documents, polls and multi-image posts but has no schedule field. How tools schedule, permissions, limits.
- API
Instagram Content Publishing API: posts, reels, carousels
How the Instagram Content Publishing API works on both logins: containers, reels, carousels of up to 10, stories, and why Meta gives 100, 50 or 25 posts a day.
- API
Meta access tokens: Instagram, Facebook Page and Threads
Meta access tokens for Instagram, Facebook Pages and Threads: what Meta's own code and Postman collections show, and the token lifetimes they leave unstated.
- API
Instagram API rate limit: Meta's quotas and usage headers
The Instagram API rate limit from Meta's own sample code: the daily publishing quota, the Threads quotas, the X-App-Usage headers and the error codes to watch.