Quickstart
From a fresh account to a delivered message. You'll need a phone number that is not registered on a regular WhatsApp account — either unconnected, or already in use in the WhatsApp Business app (coexistence mode).
1. Connect a number
Go to app.joinotify.com, create your account and click Connect number. The flow is Meta's own Embedded Signup: you authorize through the Facebook window and come back to the dashboard with the number already active.
At the end, the dashboard shows two identifiers that appear across the API:
| Identifier | What it is |
|---|---|
phone_number_id | The connected number. Used for sending and for the business profile. |
waba_id | The business account (WhatsApp Business Account). Used for templates. |
2. Generate an API key
Under API keys, click New key. The full secret is shown once — copy it and put it in a secrets manager.
{
"data": {
"id": "key_01J8ZK...",
"name": "production",
"prefix": "sk_live_AbCdEf",
"environment": "live",
"createdAt": "2026-07-27T14:02:11.482Z",
"secret": "sk_live_AbCdEf0123456789abcdefgh"
},
"warning": "Store the \"secret\" now — it will not be shown again."
}
We only keep the key's hash in our database. If you lose the secret there is no way to recover it — only to create a new key and revoke the old one.
3. Send your first message
Replace sk_live_xxx with your token and 5541987111527 with a number that has messaged
you in the last 24 hours.
curl -X POST https://api.joinotify.com/messages \
-H 'Authorization: Bearer sk_live_xxx' \
-H 'Content-Type: application/json' \
-d '{
"type": "text",
"to": "5541987111527",
"body": "Hi! This is the first message sent through the Joinotify API."
}'
const response = await fetch('https://api.joinotify.com/messages', {
method: 'POST',
headers: {
Authorization: 'Bearer sk_live_xxx',
'Content-Type': 'application/json',
},
body: JSON.stringify({
type: 'text',
to: '5541987111527',
body: 'Hi! This is the first message sent through the Joinotify API.',
}),
});
const payload = await response.json();
console.log(payload.data.messages[0].id); // wamid.HBgN...
import requests
response = requests.post(
"https://api.joinotify.com/messages",
headers={"Authorization": "Bearer sk_live_xxx"},
json={
"type": "text",
"to": "5541987111527",
"body": "Hi! This is the first message sent through the Joinotify API.",
},
timeout=30,
)
print(response.json()["data"]["messages"][0]["id"])
A 201 response carries the message WAMID — the identifier that later shows up in
the status events (sent, delivered, read).
4. Receive the replies
Sending is half the job. To know when the customer answers, register a webhook endpoint:
curl -X POST https://api.joinotify.com/webhook-endpoints \
-H 'Authorization: Bearer sk_live_xxx' \
-H 'Content-Type: application/json' \
-d '{
"name": "production",
"url": "https://your-server.com/webhooks/joinotify",
"events": ["messages"]
}'
The response carries a whsec_... secret, also shown only once, used to validate the
signature on every delivery. The walkthrough is in Webhooks.
What if it fails?
| Code | What happened |
|---|---|
401 authentication | Token missing, malformed, unknown or revoked. |
409 no_phone_number | No number connected to the account. Back to step 1. |
422 meta_error | Meta refused. The body carries their original error in error.meta. |
429 rate_limit | You went over the category limit. See Rate limits. |
The full table is in Errors.
Outside the 24-hour window
WhatsApp only allows free-form messages within 24 hours of the customer's last message. Outside that window you need an approved template:
curl -X POST https://api.joinotify.com/messages \
-H 'Authorization: Bearer sk_live_xxx' \
-H 'Content-Type: application/json' \
-d '{
"type": "text",
"to": "5541987111527",
"name": "confirmacao_pedido",
"language": "pt_BR"
}'