Every WhatsApp integration guide eventually hits the same wall: register a business, wait on Meta to verify it, get issued a phone number that isn't the one your customers already have saved in their contacts. If you just want to send a WhatsApp message from your own code today, from the number you already use, that wall is optional. This is the REST API path that skips it.
What does "your own number" mean on a WhatsApp REST API, and why skip Meta Business verification?
"Your own number" means the API sends through the WhatsApp account already on your phone, not a dedicated Meta-issued Business number. You skip business verification, template approval, and Meta's per-message billing, in exchange for running on personal-account scale rather than enterprise throughput.
There are two different products people mean when they say "WhatsApp API," and mixing them up wastes a sprint.
Meta's official WhatsApp Business Platform (the Cloud API) is the sanctioned route. You register a business, get it verified, and Meta issues you a dedicated phone number that becomes your sending identity, separate from any personal WhatsApp you already run. Since July 1, 2025, Meta bills that platform per message rather than per conversation, and the pricing sits on Meta's own developer pricing page. Outside a 24-hour customer-service window after a user last messaged you, you're limited to pre-approved templates. It's the right call at real enterprise scale, and it's also days to weeks of setup before your first send.
An own-number REST API, which is what a whatsapp automation api like Blueticks provides, takes the other route. It drives your existing, already-active WhatsApp account (through a browser extension or a 24/7 cloud gateway) instead of Meta's Cloud API servers. No business verification, no template queue, no per-message fee, and messages arrive from a number your contacts already recognize. The honest trade: you're operating at personal-account scale, and because the transport isn't Meta's sanctioned Business Platform, unauthorized bulk or automated messaging is a WhatsApp Terms of Service violation if you abuse it. Pace your sends and this is a non-issue for the vast majority of real integrations; ignore it and you're gambling with a phone number.
Mint your key at dev.blueticks.co, the developer console for the rest of this walkthrough.
How do you authenticate? What does a bt_live_ API key actually unlock?
Authentication is one bearer token in the Authorization header. A bt_live_ key identifies your workspace and your connected WhatsApp number, and every /v1 call needs it, whether you're sending a message, scheduling one, or registering a webhook.
You generate the key in the developer console at dev.blueticks.co. It's a single string, and it goes on every request the same way:
curl https://api.blueticks.co/v1/chats \
-H "Authorization: Bearer bt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Four things to know before you wire it into a service:
- The key is your identity, not a per-request password. It authenticates as your workspace and your connected WhatsApp number, so it belongs server-side, never in a mobile app bundle or a browser script where anyone can read it.
- The transport underneath is your own account. Blueticks runs on your existing WhatsApp, connected once via the browser extension or the 24/7 cloud gateway (the gateway keeps sending even when your laptop is closed), and the API key just gives your code a way to drive it.
- A free plan exists. You can build and test against it without a card on file; a paid plan removes the "Powered by blueticks.co" footer and unlocks the always-on gateway mode.
- No Meta step in this chain at all. There's no business verification, no app review, no waiting period between minting the key and making your first call.
How do you send a WhatsApp message from the API?
Send a POST to /v1/messages/{chat_id} with a JSON body carrying a required type discriminator (text, media, or poll) and the content for that type. This single endpoint is how you send whatsapp message from api for every message shape the platform supports.
The chat_id is the recipient in WhatsApp's own addressing format: a phone number followed by @c.us, like 14155551234@c.us. For a plain text message, the body is just the type and the text:
curl -X POST https://api.blueticks.co/v1/messages/14155551234@c.us \
-H "Authorization: Bearer bt_live_..." \
-H "Content-Type: application/json" \
-d '{
"type": "text",
"text": "Your order #1024 has shipped. Track it here: https://example.com/t/1024"
}'
Same call in Python:
import requests
resp = requests.post(
"https://api.blueticks.co/v1/messages/14155551234@c.us",
headers={"Authorization": "Bearer bt_live_..."},
json={
"type": "text",
"text": "Your order #1024 has shipped. Track it here: https://example.com/t/1024",
},
)
print(resp.json())
type: "media" swaps text for a mediaUrl (plus an optional caption in text and a mediaKind like image or document); type: "poll" takes a pollQuestion and a pollOptions array. The discriminator is required either way, so a request without type fails validation before it ever reaches WhatsApp.
Going from zero to a sent message is genuinely four steps:
- Mint a
bt_live_key at dev.blueticks.co. - Connect your WhatsApp number once (extension or gateway).
- Build the
chat_idfrom the recipient's number plus@c.us. POSTthe typed body above and read theidandstatusback.
That's a whatsapp api send message workflow that runs in one HTTP call, no queue or worker of your own required for the immediate case.
How do you schedule a WhatsApp message for later?
Scheduling is a separate call: POST /v1/scheduled-messages, with a sendAt timestamp instead of sending on the spot. The API holds the message and dispatches it when the time comes, and it enforces a real window: at least 10 seconds in the future, no more than 365 days out.
curl -X POST https://api.blueticks.co/v1/scheduled-messages \
-H "Authorization: Bearer bt_live_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: appt-4471-reminder" \
-d '{
"to": "14155551234@c.us",
"type": "text",
"text": "Reminder: your appointment is tomorrow at 10:00am.",
"sendAt": "2026-07-14T09:00:00+00:00"
}'
This is the whatsapp api python schedule pattern in practice, computing the timestamp instead of hardcoding it:
from datetime import datetime, timedelta, timezone
import requests
send_at = (datetime.now(timezone.utc) + timedelta(hours=20)).isoformat()
requests.post(
"https://api.blueticks.co/v1/scheduled-messages",
headers={
"Authorization": "Bearer bt_live_...",
"Idempotency-Key": "appt-4471-reminder",
},
json={
"to": "14155551234@c.us",
"type": "text",
"text": "Reminder: your appointment is tomorrow at 10:00am.",
"sendAt": send_at,
},
)
Because a scheduled message is a real record, not a fire-and-forget timer, you can GET /v1/scheduled-messages/{id} to read its status and PATCH it while it's still pending: change the text, swap the media, or push the sendAt back. That's what makes "remind them tomorrow, an hour later if they're still quiet" a two-endpoint pattern instead of a background job you have to babysit. We went deeper on the full scheduling lifecycle, including the audience and campaign variants, in our dedicated scheduling API guide.

Get a bt_live_ API key and send your first message in under 5 minutes. Sign up, grab a key from the developer console, and run the curl call from above; there's no Meta application to file and no per-message invoice waiting for you at the end of the month.
How do you receive messages and delivery status?
Sending is a push; receiving needs something listening. Register a webhook URL and Blueticks POSTs to it as events happen: message delivered, message read, message failed, and inbound replies to your number.
Every delivery is signed, so you can confirm it actually came from Blueticks before you trust the payload, and failed deliveries retry rather than vanish. Registering one takes a single authenticated call:
curl -X POST https://api.blueticks.co/v1/webhooks \
-H "Authorization: Bearer bt_live_..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/hook",
"events": ["new_message_received_webhook", "message.delivered", "message.failed"]
}'
Signature verification, the exact HMAC scheme, and a full Flask/Express handler that reads inbound replies and auto-responds are covered end to end in our webhooks and auto-reply guide; this is the endpoint reference, that's the build. The short version worth knowing here: verify against the raw request body before any JSON middleware touches it, or your signature check will fail on every single delivery.

How do you avoid duplicate sends on retries?
Pass a stable Idempotency-Key header on POST /v1/scheduled-messages. If a network blip makes your client retry the same call, Blueticks recognizes the repeated key and returns the original result instead of queuing the message twice.
This matters more than it sounds like it should. A timeout on your end doesn't mean the request didn't land, it just means you didn't hear back in time. Retrying blind doubles the send; retrying with the same key is safe:
curl -X POST https://api.blueticks.co/v1/scheduled-messages \
-H "Authorization: Bearer bt_live_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: appt-4471-reminder" \
-d '{
"to": "14155551234@c.us",
"type": "text",
"text": "See you at 3pm.",
"sendAt": "2026-07-14T15:00:00+00:00"
}'
Pick a key that's stable across retries of the same logical send, an order id plus a message purpose works well, and generate a new one for each genuinely new message. The semantics are strict and, usefully, loud: an identical body with the same key replays the original response, while a different body under a key you've already used comes back as a 409. You can't quietly overwrite a send by recycling a key, which is exactly the failure mode you want the API to refuse.
Note the shape here: the idempotency guarantee lives on the scheduled-messages endpoint, which is also the one that accepts a send-now timestamp. If exactly-once matters to your integration, and for anything triggered by a webhook or a payment event it should, route those sends through /v1/scheduled-messages with a key rather than the immediate endpoint.
How do you target audiences and run campaigns from the API, not just single sends?
For one-to-many sends, build an audience (a named contact list) and point a campaign at it. Campaigns paced-send to every contact and substitute per-contact variables like {firstName}, and they can be paused, resumed, or cancelled mid-flight through their own endpoints.
Creating an audience and adding contacts, in E.164 format, is two calls:
curl -X POST https://api.blueticks.co/v1/audiences \
-H "Authorization: Bearer bt_live_..." \
-H "Content-Type: application/json" \
-d '{"name": "July renewal reminders"}'
curl -X POST https://api.blueticks.co/v1/audiences/aud_123/contacts \
-H "Authorization: Bearer bt_live_..." \
-H "Content-Type: application/json" \
-d '{"contacts": [{"to": "+972500000000", "variables": {"firstName": "Noa"}}]}'
Then a campaign sends the templated message across the whole list, at a pace the platform controls rather than one you hand-roll:
curl -X POST https://api.blueticks.co/v1/campaigns \
-H "Authorization: Bearer bt_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "July renewal blast",
"audience_id": "aud_123",
"text": "Hi {firstName}, your renewal is coming up this week."
}'
A running campaign isn't a fire-and-forget blast either. POST /v1/campaigns/{id}/pause, /resume, and /cancel let you stop a send mid-flight, which is the endpoint you'll reach for the first time someone spots a typo in a message already going out to four hundred people.
Two limits worth planning around, both WhatsApp's, not Blueticks': a broadcast list itself is capped at 256 recipients on the platform level, which is why campaigns are paced sends to individual chats rather than one giant group blast, and WhatsApp caps any account at 4 linked devices at once. If you're running both the browser extension and the cloud gateway against the same number for redundancy, that counts against the same limit, so check your linked-devices list before you wonder why a third integration won't connect.

Can an AI agent use the API directly?
Yes, through a Model Context Protocol server: npx -y @blueticks/mcp (Node 20+) exposes the same /v1 backend as tools an MCP client, Claude Desktop, Claude Code, or any other MCP-compatible agent, can call directly, without you writing a REST wrapper.
Anthropic open-sourced MCP as a standard for connecting AI models to external tools and data in November 2024, and the pattern has since become the default way agent frameworks reach outside services rather than everyone inventing their own plugin format. The Blueticks MCP server is a thin layer over the exact same audiences, campaigns, chats, and scheduled-messages endpoints covered above, so an agent that can read a chat and draft a reply can also schedule the follow-up, all through tool calls instead of you gluing an HTTP client into your agent code.
One regulatory wrinkle worth flagging honestly, since it's adjacent even if it doesn't apply here: as of January 15, 2026, WhatsApp's terms bar general-purpose AI chatbots from the official Business API, the rule that pushed assistants like Perplexity's off Meta's platform. That restriction is scoped to the Business Platform specifically. It doesn't touch an own-number automation layer like Blueticks, because there's no Business API in this path to begin with, but it's a sign of how seriously WhatsApp is policing what gets built on top of it, official or not, and it's one more reason to keep any AI-driven sending on the human-paced side of the line.
REST API vs a Python bot vs the WhatsApp Business API: which fits your build?
Pick by scale and risk tolerance, not preference. A REST API on your own number is fastest to a working send and cheapest per message; a self-hosted Python bot gives you the most local control at the cost of running your own process; the official Business API is the only zero-ban-risk path and the slowest to stand up.
| Blueticks REST API | Self-hosted Python bot | WhatsApp Business API (Meta) | |
|---|---|---|---|
| Sending number | Your own, already active | Your own, already active | Dedicated Meta-issued number |
| Meta business verification | Not required | Not required | Required |
| Setup time | Minutes | Hours to a day (bridge, QR pairing, hosting) | Days to weeks |
| Who runs the process | Blueticks' managed engine | You, on your own server | Meta's infrastructure |
| Pricing model | Flat plan, free tier available | Free, but you host it | Per message, tiered by verification level |
| Message volume ceiling | Personal-account scale | Personal-account scale | 250 new conversations/day, rising to 2,000, 10,000, 100,000, then unlimited as you verify |
| Ban / ToS risk | Real if you cold-bulk-blast; low for paced, expected sends | Same, and it's entirely on you to self-manage | None, when used within Meta's rules |
A backend engineer who migrated a reminder bot off a homemade cron worker put the trade-off to us bluntly: "I didn't need Meta's throughput, I needed one POST that fires on a timestamp. The verification queue was the actual bottleneck, not the message volume." (A composite of operator conversations, not a named source.) That's the shape of workload this API targets: transactional and mid-volume sending where the own-number identity and the skip-Meta setup matter more than a six-figure daily ceiling.
If you'd rather run your own process end to end, with full control over the WhatsApp connection and no managed layer in between, our Python bot build walkthrough covers that path from a bare connection up. If you're past personal-account scale entirely, sending to genuine enterprise volume with a verified business identity, Meta's pricing documentation is where you start instead.
FAQ
Do I need to verify a business with Meta to use this WhatsApp REST API?
No. That's the entire point of an own-number transport. You authenticate with a bt_live_ key tied to your WhatsApp account, not a Meta Business Manager verification, so there's no application, no review queue, and no waiting period before your first send.
How do I send a WhatsApp message from the API in one call?
POST /v1/messages/{chat_id} with a type discriminator (text, media, or poll) and the content for that type, authenticated with your bt_live_ key in the Authorization header. For text, the body is just {"type": "text", "text": "..."}.
Can I schedule a WhatsApp message from Python?
Yes, POST /v1/scheduled-messages with a sendAt ISO 8601 timestamp, computed however you like in Python (datetime.now(timezone.utc) + timedelta(...)). The window is at least 10 seconds out and up to 365 days ahead, and you can PATCH the message (text, media, or sendAt) any time before it fires.
Will sending through this API get my WhatsApp number banned?
It can, if you send unsolicited bulk volume to people who never opted in; unauthorized bulk or automated messaging violates WhatsApp's Terms of Service regardless of which tool sends it. Paced, expected sends to people who know you carry low practical risk. Nobody, including us, can promise zero risk on an own-number transport, and pretending otherwise would be dishonest.
What's the difference between this and the official WhatsApp Business API?
This runs on your own already-active WhatsApp number, with no Meta business verification, no template approval, and no per-message fee. The official Business API issues you a separate dedicated number, requires verification, and bills per message on a tiered volume ladder. Pick the official API when you need Meta's compliance guarantees and enterprise throughput; pick this when you want a working send today from the number your contacts already have.
Can an AI agent send WhatsApp messages through this API without custom code?
Yes, via the MCP server (npx -y @blueticks/mcp, Node 20+), which exposes the same send, schedule, audience, and webhook endpoints as callable tools for any MCP-compatible AI client.



