Official WhatsApp Cloud API
Go live on WhatsApp in a day.
Connect your WhatsApp Business account in one dialog and send your first message today. No Meta app of your own, no app review, no access token to rotate — and the account stays in your name.
- Free plan, one number
- No card
- No sales call
- Sent today
- 1,248
- Delivered
- 99.1%
- Open windows
- 37
What you are actually building on
Your own WhatsApp account
Connected through Meta's signup dialog and held in your name, never ours
Official Cloud API
Built directly on WhatsApp's Cloud API — no unofficial automation
Signed webhooks
HMAC-SHA256 over the raw body, under your endpoint's own secret
Scoped API keys
Send, read, media and conversations are separate, revocable scopes
Public documentation
The whole contract is readable before you create an account
No lock-in
Withdraw our access in Meta Business settings and your numbers keep sending
The problem
Getting a number approved is the hard part
Meta wants an app, a verified business, an access token and a review to pass — and then reviews every template after that. Most teams lose a month to it before the first message goes out.
Weeks of back-and-forth
Going direct to Meta
- Create and submit a Meta app for review
- Pass business verification with documents
- Hold and rotate your own access token
- Build webhook signature verification
- Re-do all of it for the next brand you launch
Live the same day
Going through Vaarto
- Connect your own business account in one Facebook dialog
- Get an API key the same day
- POST to one endpoint with your number as sender
- Receive signed webhooks we already verify against Meta
- Keep the account — withdraw our access whenever you want
Direct with Meta vs. Vaarto
The same channel, minus the approval queue
Nothing below is a feature we invented. It is the work Meta puts between you and your first message, and which side of it we have already done.
Scroll to compare
| What it involves | Direct with Meta | With Vaarto |
|---|---|---|
| Meta app | You create one and submit it for review | Ours, already reviewed |
| Business verification | Your documents, and Meta's queue | Not required to start sending |
| Access token | Yours to store, refresh and rotate | None — you hold a scoped API key instead |
| Webhook signatures | You implement and verify Meta's scheme | Verified against Meta before we forward |
| Time to first message | Weeks of back-and-forth | The same day |
| Who owns the number | You | You — withdraw our access and it keeps sending |
| Launching a second brand | Start the whole process again | One more dialog |
How it works
Three steps between you and a live number
No Meta app of your own, no app review to sit through, no access token to rotate. You sign in with Facebook once; everything on the other side of that dialog is already built and reviewed.
- 01Minutes
Connect your account
Sign in with Facebook. Meta's own dialog creates or connects your WhatsApp Business account and takes the number you want customers to see. The account is in your name from that moment on.
- 02Immediate
Collect your API key
A scoped key is waiting in the console the moment the number goes live. Issue one per job — the key that polls delivery status cannot read your conversations.
- 03Same day
Send, and start receiving
One POST sends a template, free text or media. Replies land in the shared inbox, at your webhook, or both — you decide per number.
Platform
Everything the channel actually needs
Sending is the easy half. What takes the time is windows, templates, receipts, routing and keys — so those are the parts we built properly.
One endpoint for every send
Templates, free text and media go through POST /messages/whatsapp. Idempotency keys make a retry safe, and your own metadata comes back on every read.
A shared inbox for replies
Inbound messages become conversations your team answers together. The composer tracks the 24-hour customer service window and tells you when only a template will deliver.
Routing decided per number
Each number does one of three things with an incoming message: ignore it, answer with one fixed reply, or send it to one of your webhook endpoints.
Scoped, revocable API keys
Sending, reading the log, downloading media and listing conversations are separate scopes, so a key that polls delivery status cannot read your conversations.
Every message, every status
Sent, delivered, read and failed are all recorded against the message, with Meta's own reason when a send is refused. Query it by API or read it in the console.
The account is yours, not ours
Try the API on our number and our name, with nothing to set up. When you are ready, one Facebook dialog connects a WhatsApp Business account held in your name — and withdrawing our access later leaves it running.
Shared inbox
Replies land somewhere your team can answer
A customer who replies is not a webhook you forgot to handle. Inbound messages become conversations, and the composer knows whether a free-text reply will actually deliver.
What your team sees
What your customer sees
Your brand. Your number. Not ours.
- Threads are keyed per workspace, so two teams on one number never read each other's conversations
- The window timer is on the thread, not in your head
- Attachments a customer sends are downloadable from the message
- Delivery and read receipts land on the message as Meta reports them
Inbound routing
Each number decides what happens to a reply
Support lines belong in the inbox. A no-reply notification number should say so. An ops number should land in your own system. One setting per number, changed whenever.
- 01
Ignore
Store the message and do nothing. The inbox is the only place it surfaces.
Inbound → stored → inbox only
- 02
Fixed reply
Answer every inbound message on this number with one set message.
Inbound → your one set reply
- 03
Send to a webhook
Goes to one of your endpoints, signed and retried — over HTTPS, or a socket we hold open.
Inbound → POST your endpoint
What teams send
The messages people actually open
WhatsApp is read because it is where your customer already is. These are the sends the API is shaped for — each one a template, a window reply, or a webhook you already have.
Order and delivery updates
Shipped, out for delivery, delayed. Carry your own order id on the message and match the delivery receipt straight back to it.
One-time passwords
Authentication templates deliver outside the window, and an idempotency key means a retried request never sends a second code.
Support conversations
Inbound messages become threads your whole team answers from, with the 24-hour window counted down on the thread itself.
Appointment reminders
Send the reminder as a template, then take the reply as free text for the 24 hours the customer's answer opens up.
Payment and renewal nudges
Utility templates with a link. Delivered, read and failed are all recorded against the message with Meta's own reason.
Alerts into your own systems
Point a number at one of your endpoints and inbound messages arrive signed and retried — over HTTPS or a socket we hold open.
For developers
An API your engineers will not fight
One endpoint sends a message. Delivery and read receipts arrive as webhooks. Failures name the reason Meta gave rather than a generic 500 — and the whole contract is documented in public.
Public reference — no sign-up to read it.
Post/v1/messages/whatsapp
curl https://vaarto.com/api/v1/messages/whatsapp \
-H "Authorization: Bearer $VAARTO_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+919876543210",
"template": {
"name": "order_shipped",
"language": "en_US",
"variables": { "name": "Ravi", "order_id": "BLR-4471" }
},
"idempotencyKey": "order-4471-shipped"
}'const res = await fetch("https://vaarto.com/api/v1/messages/whatsapp", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.VAARTO_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
to: "+919876543210",
template: {
name: "order_shipped",
language: "en_US",
variables: { name: "Ravi", order_id: "BLR-4471" },
},
idempotencyKey: "order-4471-shipped",
}),
});
const { data } = await res.json();
console.log(data.status); // "SENT"import os, requests
res = requests.post(
"https://vaarto.com/api/v1/messages/whatsapp",
headers={"Authorization": f"Bearer {os.environ['VAARTO_KEY']}"},
json={
"to": "+919876543210",
"template": {
"name": "order_shipped",
"language": "en_US",
"variables": {"name": "Ravi", "order_id": "BLR-4471"},
},
"idempotencyKey": "order-4471-shipped",
},
)
print(res.json()["data"]["status"]) # "SENT"Response201 Created
{
"data": {
"id": "cmu102948182741",
"channel": "WHATSAPP",
"status": "SENT",
"to": "+919876543210",
"from": "+919812345678",
"providerMessageId": "wamid.HBgM109…",
"error": null,
"createdAt": "2026-09-27T10:00:00.000Z"
},
"meta": { "replayed": false }
}Posthttps://your-app.com/hooks/vaarto
message.received{
"event": "message.received",
"sentAt": "2026-09-27T10:00:04.221Z",
"data": {
"messageId": "cmu…",
"conversationId": "cmu…",
"text": "where is my order?",
"from": "919876543210",
"fromName": "Ravi",
"to": "+919812345678"
}
}Signed webhooks
Every forward carries an HMAC-SHA256 of the raw body under your endpoint's secret — the same scheme Meta uses on us.
Scopes, not all-or-nothing
Sending, reading the log, downloading media and listing conversations are separate. Issue a key with only what the job needs.
Safe to retry
Pass an idempotency key and a retried request returns the first result instead of sending a second message.
FAQ
Questions people actually ask
Still stuck on something?
Email [email protected] and a person answers — not a bot, and not a ticket number.
Do I need my own Meta app or business verification?
You do not need a Meta app. That one is ours, along with the app review, the access token and the webhook plumbing. You do need a WhatsApp Business account, but it is created inside Meta's signup dialog while you connect, which takes minutes rather than weeks. Business verification is separate: Meta lets an unverified business start messaging at a reduced limit, and verifying lifts it. You do that in your own Meta Business settings, in your own time.
Who owns the WhatsApp Business account?
You do, on every plan. It sits in your Meta business portfolio, not ours, and we hold only the access you grant in the signup dialog. Withdraw that access from your Meta Business settings and we stop reading and sending at once — the account, the numbers and the approved templates stay exactly where they are. Before you connect one, a workspace sends from our number under our name, which is there for trying the API out rather than for talking to your customers.
What does Meta charge on top?
WhatsApp bills per 24-hour conversation at a rate set by the recipient's country and the conversation category. We pass that through at cost and show the rate and the count on your invoice.
What is the 24-hour customer service window?
Once a customer messages you, you can reply with free text or media for 24 hours. Outside that window WhatsApp only delivers approved templates. The inbox shows the remaining time on each thread, and the API refuses a free-text send with WINDOW_CLOSED rather than failing silently.
Is there a contact list and a campaign builder?
Yes, both, and they live in the console rather than the API. Contacts carry a name, a company and groups, and import or export as CSV. A campaign sends an approved template to a group or an uploaded list, fills the variables per contact, skips anyone who has opted out, and pauses and resumes whenever you want. The API itself stays stateless — one recipient per request — and no key scope reaches your contacts, so a broadcast is started by a person who signed in, never by a key.
Send your first WhatsApp message today
Create an account, register your number, and curl the endpoint. The free plan covers one number and the whole API.
- No Meta app to submit
- No card required
- No sales call