WhatsApp API & Developers

WhatsApp Cloud API Explained: How Meta's API Works

You have decided to integrate WhatsApp directly with Meta. Before the first line of code, learn how the pieces fit, because the mistakes that cost a day are rarely in the code. They are in the model: treating an accepted request as delivered, building on the phone number instead of its ID, or hitting a rate limit you did not know existed.

The WhatsApp Cloud API is Meta's hosted interface for sending and receiving WhatsApp messages from your own software. It runs on Meta's Graph API, Meta operates the infrastructure, and you pay per delivered message.

Below: hosting, IDs, a request and response, rate limits, costs and fit. For the wider picture, including unofficial options, see our complete guide to the WhatsApp API.

What "cloud" means here

The Cloud API is hosted by Meta: you never run WhatsApp servers, containers or databases. You make HTTPS calls to graph.facebook.com and Meta delivers the messages, then calls your webhook with replies and delivery updates.

It replaced the self-hosted On-Premises API, which got its last new features in January 2024 and stopped delivering messages when its final version expired on October 23, 2025. Our post on the On-Premises API sunset covers that move. Every new platform feature since then has shipped only on the Cloud API.

A few platform facts, from Meta's About the platform page as of October 2026:

  • Scope. The Cloud API covers messaging, calling and the newer Groups API.
  • Protocol. It is built on the Graph API: versioned URLs, JSON bodies and Bearer tokens.
  • Encryption. Messages keep Signal protocol encryption, and traffic runs over TLS.
  • Scaling. Meta scales usage automatically within your rate limits.
  • Data location. An optional local storage setting per phone number keeps message content at rest in a chosen region. Content may be processed elsewhere for up to 60 minutes first.

The objects and IDs you will touch

Most early bugs come from using the wrong ID. Here is what each one is, using Meta's account model as it stands after the September 2026 change, when the old WhatsApp Business Account (WABA) was split in two.

ObjectWhat it isWhere you meet it
Business portfolioThe owner of everything; carries business verificationMeta Business Suite
WhatsApp accountHolds one business phone number, its display name and profileBusiness Suite; its own ID arrives with a new Graph API version in 2027
Messaging accountHolds templates, billing and webhook subscriptions; keeps the old WABA IDWhatsApp Manager; /WABA_ID/message_templates
Phone number IDA numeric ID for your number, used in every send URLApp Dashboard, WhatsApp, API Setup
System user tokenLong-lived credential for your serverBusiness settings, System users
wamidThe ID of one message, linking sends to their status updatesAPI responses and webhooks
wa_id and BSUIDUser identifiers; a BSUID looks like US.13491208655302741918Inbound webhooks

Three practical notes. The phone number ID is not the phone number; store both. If one token can bill more than one Messaging account on the same number, pass messaging_account_id on sends. And users who adopt usernames may arrive with a BSUID and no phone number, so never assume wa_id is present. Our guide to the WhatsApp Business Account explains the split, and the BSUID guide covers the identifier change.

For tokens, Meta recommends a system user access token for direct developers, generated in Business settings with whatsapp_business_messaging, whatsapp_business_management and business_management permissions. The temporary token on the API Setup page expires and is only for testing.

Anatomy of a request

Every send is a POST to the phone number's /messages edge. This is a free-form text message, which is only allowed while a customer service window is open:

curl https://graph.facebook.com/v23.0/PHONE_NUMBER_ID/messages \
  -H "Authorization: Bearer $WHATSAPP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "messaging_product": "whatsapp",
    "recipient_type": "individual",
    "to": "+919811122233",
    "type": "text",
    "text": { "body": "Order 4821 is packed. Deliver tomorrow or Friday?" }
  }'

The example uses v23.0; use the current Graph API version listed in Meta's changelog. A success looks like this:

{
  "messaging_product": "whatsapp",
  "contacts": [{ "input": "+919811122233", "wa_id": "919811122233" }],
  "messages": [{ "id": "wamid.HBgMOTE5ODExMTIyMjMzFQIAERgS" }]
}

What the response does and does not tell you:

  • Accepted, not delivered. Meta's docs are explicit that this response only means the request was accepted. Delivery arrives later.
  • Store the wamid. Every later status for this message carries it.
  • Always send the plus sign and country code. If you leave off the plus, Meta prepends your business number's country code, which can deliver to the wrong person.
  • Pacing flag. Template sends can include a message_status field when Meta is pacing that template.

Delivery updates arrive at your webhook as status objects, trimmed here:

{
  "object": "whatsapp_business_account",
  "entry": [{
    "id": "WABA_ID",
    "changes": [{
      "field": "messages",
      "value": {
        "messaging_product": "whatsapp",
        "metadata": { "display_phone_number": "919800000000", "phone_number_id": "PHONE_NUMBER_ID" },
        "statuses": [{
          "id": "wamid.HBgMOTE5ODExMTIyMjMzFQIAERgS",
          "status": "delivered",
          "timestamp": "1761724800",
          "recipient_id": "919811122233",
          "pricing": { "billable": true, "pricing_model": "PMP", "type": "regular", "category": "utility" }
        }]
      }
    }]
  }]
}

Log the pricing object; it shows how each message was categorized and billed. Verify every webhook's X-Hub-Signature-256 header before trusting it. Our guide to WhatsApp API webhooks covers subscription and signatures.

Throughput and rate limits

The Cloud API has four separate ceilings, and each returns a different error.

Throughput per number. Each registered number handles up to 80 messages per second by default, counting inbound and outbound. Meta upgrades a number to 1,000 per second automatically and at no cost when its portfolio has an unlimited messaging limit, the number has messaged 100,000 or more unique users outside a customer service window in a moving 24 hours, and its quality is yellow or better. Going over returns 130429. During the upgrade, which can take up to a minute, requests return 131057. Numbers shared with the WhatsApp Business app through coexistence are fixed at 20 per second.

Pair rate limit. Per Meta's overview, a number can send one message every 6 seconds to the same user, with bursts of up to 45 messages in 6 seconds that borrow from future quota. Exceeding it returns 131056.

Messaging limit. The number of unique users you can reach outside a customer service window in a moving 24 hours, set per business portfolio: 250 to start, then 2,000, 10,000, 100,000 and unlimited. See our guide to WhatsApp API messaging limits.

Management API calls. Endpoints such as templates and phone numbers allow 200 requests per hour per app per Messaging account by default, rising to 5,000 for active accounts with a registered number.

A send helper should treat the first two as retryable:

const URL = `https://graph.facebook.com/v23.0/${process.env.PHONE_NUMBER_ID}/messages`;

async function send(payload, attempt = 0) {
  const res = await fetch(URL, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.WHATSAPP_TOKEN}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ messaging_product: "whatsapp", ...payload }),
  });
  const body = await res.json();
  if (res.ok) return body.messages[0].id;

  const code = body.error?.code;
  if ((code === 130429 || code === 131056) && attempt < 5) {
    await new Promise((r) => setTimeout(r, 2 ** attempt * 1000));
    return send(payload, attempt + 1);
  }
  throw new Error(`WhatsApp error ${code}: ${body.error?.message}`);
}

For 131056, back off for that one recipient rather than pausing the whole queue. Our post on WhatsApp API throughput goes deeper on queue design.

What it costs

Cloud API access is free. Meta charges per delivered message, priced by category (marketing, utility, authentication, service or Meta Business Agent) and by the recipient's country calling code. Messages from users are free, a free entry point window after a Click-to-WhatsApp ad makes most business messages free for up to 7 days, and each number gets 1,000 free service messages a month.

Since October 1, 2026, service messages beyond that free tier are charged, as are utility templates sent inside an open window. Going direct means only Meta's rates, with no provider markup, but you build the inbox, template tooling and monitoring yourself.

One planning note: Meta says the Cloud API stops supporting marketing messages on October 13, 2027, and Messaging accounts created from April 13, 2027 cannot send marketing through it at all. Marketing moves to the Marketing Messages API, so design your template layer to switch endpoints. Full numbers are in our WhatsApp API pricing guide.

Who it suits, and who it does not

It suits teams with engineers and a reason to want control.

Good fitPoor fit
Product teams adding WhatsApp to their own appTeams with no developer time
High-volume OTPs and transactional alertsBusinesses whose customers live in existing groups
Interactive buttons, lists, Flows or callingOwners who want to keep using the number on a normal phone
Regulated industries that need local storageSolo businesses with a few dozen chats a day
Companies that want no provider in the billing chainAnyone wanting results this week without a build

If you have the volume but not the engineers, a Business Solution Provider wraps the same API in a dashboard. Our comparison of Cloud API vs a BSP lays out that choice, and the Cloud API setup guide walks through sending your first test message.

Where Tenashi fits

Some teams look at the Cloud API because they want programmatic access to the number their customers already use, including its groups, and discover that registering the number takes it off WhatsApp and leaves the groups behind. Tenashi takes the other route. You link your existing WhatsApp or WhatsApp Business number by QR scan, and the Tenashi API gives you a similar shape to work with: POST /api/v1/messages to a phone number or to an existing DM or group by conversationId, plus signed webhooks for received, sent, delivered, read and failed messages.

The differences matter. There are no templates, no 24-hour window and no per-message fees, and every API send shows up in a shared team inbox with a CRM under each chat. In exchange, sends are paced at one every 4 to 12 seconds per number, with 50 new chats per number per day through the API, and there are no buttons, lists or Flows. Tenashi is not Meta's platform, so it is the wrong choice for OTPs or thousands of alerts a minute.

Read the API docs · Get started

FAQ

Is the WhatsApp Cloud API free?

Access is free: Meta charges no fee to create an app, register a number or call the API. Delivered messages are billed by category and recipient country. Inbound messages are free, as are messages in a free entry point window and the first 1,000 service messages per number each month. Providers, if you use one, add their own fees.

What is the difference between the Cloud API and the WhatsApp Business API?

"WhatsApp Business API" was the older name for Meta's business messaging platform, which once came in two flavours: self-hosted On-Premises and Meta-hosted Cloud. On-Premises was retired in October 2025, so today the Cloud API is the WhatsApp Business API for practical purposes, alongside the separate Marketing Messages API.

What is a phone number ID?

It is the numeric identifier Meta assigns to your registered business number, and it goes in the URL of every send request. It is different from the phone number itself and from your Messaging account ID. Find it in the App Dashboard under WhatsApp and API Setup, or by listing phone numbers through the Business Management API.

Can I use the Cloud API without business verification?

Yes. An unverified business portfolio can register numbers and send messages, but it starts at a messaging limit of 250 unique users per 24 hours and two registered numbers. Verifying the business is one path to the 2,000 limit and raises the number cap to 20. Official Business Account status also requires verification.

Which Graph API version should I use?

Use the latest version listed in Meta's Graph API changelog, and pin it explicitly in your URLs rather than relying on defaults. Meta retires old versions on a schedule, so plan an upgrade at least once a year. Examples in older tutorials, including v17.0 calls, still show the right shape but may miss newer fields.


The Cloud API rewards teams that respect its model: IDs over numbers, webhooks over responses, queues over loops. If what you need is your existing number and your team in one inbox, see how Tenashi works.