- Official
- Meta Tech Partner
- 600 req/min
- per API key
- 8 retries
- on every webhook
- 30 days
- of delivery logs
Every message type, one endpoint.
POST /v1/whatsapp/messages with a type. That's the whole mental model.
Templates
Approved templates with variables, media headers and buttons. Send any time.
"template": {
"name": "order_confirmation",
"language": "en",
"body": ["John", "#1234"],
"buttons": [{ "url": "1234" }]
}Text
Up to 4,096 characters, inside the 24h service window.
"text": { "body": "Your order has shipped 🚚" }Images & video
Pass a public URL or a media_id from /v1/media.
"image": {
"url": "https://cdn.acme.com/receipt.png",
"caption": "Your receipt"
}Documents
Invoices, tickets, PDFs, with a custom filename.
"document": {
"url": "https://cdn.acme.com/inv-1234.pdf",
"filename": "invoice.pdf"
}Carousels
Swipeable cards, each with its own media and buttons.
"cards": [
{ "header": { "type": "image", "url": "…" },
"body": ["Type 45"], "buttons": [{ "payload": "t45" }] }
]Broadcasts
Target contacts by tag, personalise per contact and schedule ahead.
await notizy.broadcasts.create({
account_id, template: { name: "promo_october", language: "en" },
audience: { tags_any: ["customer"] },
scheduled_at: "2026-10-12T09:00:00+07:00",
});Know the moment it's read.
Subscribe an HTTPS endpoint and get a signed POST for every status change and every reply. Same object as the API, no polling.
- 10:00:00.312
message.sent
Accepted by WhatsApp
- 10:00:01.104
message.delivered
Reached the phone
- 10:00:03.020
message.read
Opened by John
- 10:00:41.877
message.received
“Can I change the address?”
- 10:05:12.009
broadcast.completed
12,480 sent · 97.2% delivered
{
"id": "0199d0c4-7e2a-7c1b-9f3e-5a1d2c3b4e5f",
"event": "message.read",
"created_at": "2026-10-11T10:00:03.000Z",
"data": {
"id": "0199d0c4-6a11-7b02-8e4f-1c2d3e4f5a6b",
"channel": "whatsapp",
"direction": "outbound",
"status": "READ",
"to": "6281234567890",
"delivered_at": "2026-10-11T10:00:01.000Z",
"read_at": "2026-10-11T10:00:03.000Z"
}
}import { verifyWebhook } from "notizy";
app.post("/webhooks/notizy", express.raw({ type: "application/json" }),
async (req, res) => {
try {
const event = await verifyWebhook({
payload: req.body.toString(),
signature: req.header("X-Notizy-Signature"),
secret: process.env.NOTIZY_WEBHOOK_SECRET,
});
if (event.event === "message.received") {
await reply(event.data.from, event.data.text);
}
res.sendStatus(200);
} catch {
res.sendStatus(400); // bad signature
}
},
);- X-Notizy-Signature: t=…,v1=…
- At-least-once, dedupe on data.id
- Send test events from the dashboard
- Public HTTPS URLs only, SSRF-checked
The boring parts, already done.
Everything you'd otherwise build yourself before going live.
Idempotent by design
Send an Idempotency-Key and retry freely. Replays return the original message, never a duplicate.
Signed webhooks
Every delivery carries an HMAC-SHA256 signature with a timestamp, so you can drop forged or replayed calls.
Automatic retries
Failed deliveries retry 8 times with exponential backoff. Inspect every attempt for 30 days.
Predictable limits
600 requests per minute per key, with X-RateLimit headers and Retry-After when you hit the ceiling.
Errors you can act on
Field-level validation errors and a request_id on every failure. The SDK returns { data, error } and never throws.
Cursor pagination
Stable, cursor-based lists for messages, contacts and broadcasts. No skipped or repeated rows.
24h window, handled
Templates go out any time. Free-form text and media inside the service window, with a clear 422 outside it.
OpenAPI spec
Generate a client in any language from /openapi.json, or explore it in the interactive reference.
From zero to delivered in three steps.
- 1
Create an API key in your dashboard.
.envNOTIZY_API_KEY=nzy_3f9a… - 2
Install the SDK, or use plain HTTP.
terminalnpm install notizy - 3
Send your first message.
send.tsawait notizy.whatsapp.send({ account_id, to: "6281234567890", type: "text", text: { body: "Hello from my app 👋" }, });
Ship your first message in 5 minutes.
Start free, then pay as you grow. See pricing.
https://api.notizy.id