Skip to content
ChatfuelSDK
All posts

WhatsApp Business API for Developers: the Cloud API, BSPs, Webhooks and What Meta Review Costs

Oleg Krasikov2 September 2026WhatsApp

The short version:

  • Meta charges per delivered message, by category and by the recipient's country. Marketing $0.025 in the US; utility and authentication $0.0034. Replies inside the 24-hour window are free until October 1, 2026, then billed at the utility rate.
  • A BSP connects the number, fronts Meta's bill and adds a fee. Twilio $0.005 a message in either direction, Landbot €0.05 a template, Chatfuel 10% on Meta's rate from October 1, 2026.
  • Direct to Meta means a webhook server. Public HTTPS with a real certificate, a verify-token handshake, a signature check, a 200 to everything, and Meta retrying for 7 days when you're down.
  • App Review is only for apps other businesses use. Business verification first, up to 14 business days; then the review, about 24 hours on average.
  • The messaging limit follows the number, whoever connects it. 250 unique customers a day to start, 2,000 after verification, then 10,000, 100,000 and unlimited by automatic scaling.

What Meta sells

The Cloud API is Meta's hosted way to "programmatically message and call on WhatsApp". A business number sends up to 80 messages a second by default, and one message every 6 seconds to the same person.

There's no price on the API. The price is on the message. Since July 1, 2025 Meta bills per delivered template message, by category and by the country code of the number you're sending to.

CategoryCounts whenNorth AmericaIndiaGermany
Marketingany template that promotes: an offer, a related product, an abandoned cart$0.025$0.0118$0.1365
Utilitya template the customer's own action triggered: an order, a delivery update$0.0034$0.0014$0.055
Authenticationa one-time password$0.0034$0.0014$0.055
Servicea reply inside the 24-hour window, from October 1, 2026$0.0034$0.0014$0.055

The 24-hour window is the whole economics of a support bot. A customer writes to you, and for 24 hours you can answer with anything: free text, images, documents, no template. Outside that window the only thing you can send is an approved template, and every template is billed.

Two things change on October 1, 2026. Replies inside the window stop being free and get the utility rate. And utility templates you send inside the window, free since July 2025, get billed too. Meta's words: "rates for service messages will be the same as those of utility and authentication, by market".

Volume tiers exist, for utility and authentication only. In North America the list rate holds to 80,000 messages a month; in the United Kingdom and Germany to 100,000; in India to 25 million.

The full card for every market, what each BSP adds to it, and a calculator for your own mix are in the WhatsApp pricing post.

"Do I need a BSP?"

Meta has three kinds of partner, and its own definitions are more useful than anyone's marketing.

A Solution Partner provides "a full range of WhatsApp Business Platform services to other businesses (clients), such as messaging services, billing, integration support, and customer support". Solution Partners "have credit lines which can be extended to clients", so a client never enters a payment method with Meta, and the partner invoices them. Meta adds: "becoming a Solution Partner is a lengthy process".

A Tech Provider offers the same services without the credit line. Its clients "must provide their own payment method after onboarding is complete. Meta will then bill these clients for API usage, and the Tech Provider will bill for other services".

A Tech Partner is a Tech Provider that became a Meta Business Partner.

So a BSP in the everyday sense is a Solution Partner: the company that connects your number through Embedded Signup, carries Meta's bill on its credit line, and puts its fee on top. Chatfuel is one. So is Twilio.

If you go direct, you're your own tech provider. What that means in practice:

Cloud API, directThrough a BSP's API, TwilioChatfuel SDK
Connect the numberA Meta business portfolio, a Meta app, a system userThe BSP's onboardingEmbedded Signup, through Chatfuel
Verify the businessYou, in Meta Business SuiteYou, or your partner does it for youYou; the submission goes through Chatfuel
App ReviewOnly if other businesses use your appNone; the BSP passed itNone; it's not a Meta app
Receive messagesYour webhook serverYour webhook serverA GraphQL subscription over the proxy's WebSocket
Keep the tokenA system user token, on your serverAn API key, on your serverA dashboard token in .env, read by the proxy only
TemplatesMeta's APIThe BSP's APIApproved templates, sent from the Inbox
Inbox, contacts, agentYours to buildYours to buildModules the wizard writes
Who bills Meta's feeMeta, to your cardThe BSP, plus $0.005 a messageChatfuel, plus 10%, off the balance from October 1, 2026

What a webhook costs you

Meta's inbound path is a webhook: "HTTP requests containing JSON payloads that Meta's servers send to a server of your designation". Yours has to be a public HTTPS endpoint with "a valid TLS or SSL certificate correctly configured and installed". Self-signed doesn't count.

Before Meta sends anything it checks you own the endpoint: a GET with hub.mode=subscribe, a hub.verify_token you set in the app dashboard, and a hub.challenge you echo back. Every event after that carries an X-Hub-Signature-256 header, a SHA-256 over the body with your app secret, and you're supposed to check it. You answer 200 OK to everything. Answer anything else, or go down, and "Meta retries delivery with decreasing frequency until the request succeeds, for up to 7 days".

That's a server. Always on, on a domain, with a certificate, a secret, a queue if you don't want to lose a message during a deploy, and idempotency, because a retry of a message you already processed is still that message.

On Chatfuel SDK there's no webhook. The app subscribes: one WebSocket to the Chatfuel API on the graphql-transport-ws subprotocol, and for each open conversation two subscriptions, MessageAdded and MessageUpdated. The second carries the status changes, sent to delivered to read, and the delivery failures, because on WhatsApp a failed send doesn't come back as an error to the mutation. It arrives later as Message.errors[] on the message. The 24-hour window error is one of them.

The server doesn't replay what you missed while disconnected. On reconnect the app refetches the list and the open thread. Both rules are in the transport reference.

The token you keep out of the browser

Direct to Meta, the temporary token from the dashboard "expires quickly and is not suitable for development purposes". The real one belongs to a system user and carries three permissions: whatsapp_business_messaging, whatsapp_business_management and business_management. Keep it on a server. It's the number.

Chatfuel's token is worse in one way: it's a dashboard user token that can read and change every bot in the account, no scoping, no read-only version. So the app the wizard writes never has it. The browser calls its own origin at /chatfuel/graphql, and a proxy the wizard copies into your project attaches the token on the way out. This is the whole of it:

await forward(ctx, res, `${upstream}/graphql${searchOf(req)}`, {
  method: 'POST',
  // Built from scratch: client Authorization/cookies are stripped by
  // construction, never merged — the browser's session JWT stays here.
  headers: { 'content-type': 'application/json', authorization: `Bearer ${token}` },
  body,
  ...(slow ? { timeoutMs: slowTimeoutMs } : {}),
});

The upstream request is built from nothing, so the browser's headers never travel. The WebSocket is relayed the same way: the proxy opens its own socket upstream and sends its own connection_init with the token. The token lives in .env, written with mode 0600 by the wizard and read by the proxy alone. Anything you name VITE_* is compiled into the bundle, so a secret with that prefix isn't one. The API allows 25 requests a second on a token. The rest is in the token boundary and the proxy reference.

One caveat: without the auth module the proxy is an open relay to that account, fenced only by which bot ids a request may name. Put the app behind a login before you put it on a public URL.

What app review costs you

Meta's rule: "If your app will be used by anyone without a Role on the app or a role in a Business that has claimed the app, it must first undergo App Review. If your app will only be used by app users who have a role on the app itself, App Review is not required."

So one business messaging its own customers from its own number doesn't need it. A Business-type app is "automatically approved for Standard Access". App Review starts when other businesses connect their numbers through your app, which is the moment you're a tech provider.

Then the order is fixed. "Your business must be verified before you can start the app review process", and "a decision on your verification submission may take up to 14 business days". Then the review: one screen recording per permission, Advanced access requested for whatsapp_business_messaging and whatsapp_business_management, and "the average turnaround time for App Review is about 24 hours". Without Advanced access on the management permission, calls to a client's account "return error code 200".

What nobody puts on the sales page is the ladder after that. A messaging limit is how many unique customers you can message outside the window in a moving 24 hours. It's set per business portfolio and shared by every number in it. A new portfolio starts at 250. It goes to 2,000 by verifying the business, by a partner verifying it, or by delivering 2,000 template messages to unique numbers within 30 days at a high quality rating. Past that it's automatic: use at least half your limit for 7 days with good quality and the next level, 10,000, then 100,000, then unlimited, arrives within 6 hours. The cap on phone numbers rises to 20 at the same point.

On Chatfuel SDK the app "is not a Meta app and never goes through app review". The number connects through Embedded Signup inside Chatfuel, an official Meta partner and WhatsApp Business Solution Provider. Two things don't go away, because they're Meta's and attach to the number: business verification, which you submit through Chatfuel with a limited number of attempts, and the display name approval. The limit ladder is the same ladder.

Where Chatfuel SDK sits

npx @chatfuel/wizard writes a Vite + React + TypeScript app, MIT, on Node 20.18.1 or newer, with the modules you pick: --modules livechat,contacts,auth for an inbox with sign-in. Every call goes through the proxy above.

The 24-hour window is computed in the composer from the clock and the contact's last message, so an operator finds out before typing, not after sending. Outside the window the template button is the way back in: the app sends an approved template and the delivery result comes back on messageUpdated. The Inbox page has the rest.

The bill is three lines: the workspace plan, from $20 a month; AI tokens, at the rates on the pricing page; and, from October 1, 2026, Meta's per-message rate plus 10%, off the same balance, with Chatfuel's credit line on the WhatsApp Business Account. A reply to a US customer from that day is $0.0034 at Meta and $0.00374 on the balance. Twilio's fee on the same reply is $0.005, more than the reply costs at Meta.

How to Price a White-Label WhatsApp SaaS: Three Models That Actually WorkTen customers at $99 a month is either a 77% margin or a $1,060 hole, and the only difference is how usage moved. Here's the arithmetic behind the three pricing models.

If the app is a support agent, the cost of the agent itself, tokens against the vendors' per-resolution prices, is in the rent-versus-own post.

Which route, by what you're building

  • A product other businesses connect their numbers to. You're a tech provider: verification, up to 14 business days; App Review, about 24 hours, one video per permission; Advanced access on two permissions; a webhook server to Meta's rules; and Meta bills each client's card, unless a Solution Partner shares its credit line with you.
  • One business, its own number, engineers on hand. The Cloud API direct: Meta's list rate and nothing on top, your webhook, your token, your inbox.
  • One business, or an agency running client bots, that wants the inbox and the agent and no Meta app. Chatfuel SDK: from October 1, 2026 Meta's rate plus 10% from the balance, a plan from $20, no webhook, no App Review. Verification and the display name are still Meta's.

Corrections go to Discord. A Meta page that says something different from this one gets this one updated.

Get the next post by email

I’ll send it when it’s out. No digest, no schedule, nothing else.