API reference
Send WhatsApp messages from any app. All endpoints use JSON and an API key from Dashboard → API & webhooks.
Authentication
Send your key in the Authorization header. Keys start with nt_live_. Limit: 120 requests per minute per key.
Authorization: Bearer nt_live_xxxxxxxxxxxxxxxx
Send a message
Queues a message. It goes out respecting your number's pacing (≥ 2 min) and daily limit. 1 credit is charged when queued and refunded if it fails.
POST https://notific.app/api/v1/messages
Content-Type: application/json
Idempotency-Key: order-1042-shipped
{
"from": "num_8f2aXk…",
"to": "+573001234567",
"text": "{Hi|Hello} {{name}}! Order #{{order}} shipped 🚚",
"variables": { "name": "Ana", "order": "1042" },
"send_at": "2026-11-02T09:00:00",
"timezone": "America/Bogota"
}
→ 202 Accepted
{ "id": "msg_…", "status": "queued", "scheduled_at": "2026-11-02T14:00:00.000Z", … }| from | Number ID (num_…) that sends the message |
| to | Recipient with country code, e.g. +573001234567 |
| text | Up to 4,000 characters. Supports {{variables}} and {spin|tax} |
| variables | Optional object with values for {{variables}} |
| send_at | Optional ISO date-time. Without offset it's local to `timezone` |
| timezone | Optional IANA zone of the recipient (default: your account's) |
Other endpoints
GET https://notific.app/api/v1/messages/:id → message
GET https://notific.app/api/v1/messages?status=queued&limit=50
DELETE https://notific.app/api/v1/messages/:id → cancel a queued message (refunds 1 credit)
GET https://notific.app/api/v1/numbers → your numbers and their ids
GET https://notific.app/api/v1/balance → { "credits": 1234 }Status webhooks
Set a URL in Dashboard → API & webhooks. We POST every status change. Verify the signature: HMAC-SHA256 of `${X-Notific-Timestamp}.${raw body}` with your signing secret, hex-encoded, in X-Notific-Signature.
POST https://your-app.com/webhooks/notific
X-Notific-Timestamp: 1792161000
X-Notific-Signature: 5f2c…
{ "event": "message.status",
"data": { "id": "msg_…", "number_id": "num_…", "to": "+573001234567",
"status": "delivered", "error": null },
"timestamp": 1792161000 }
// Node.js
const expected = crypto.createHmac("sha256", secret)
.update(`${req.headers["x-notific-timestamp"]}.${rawBody}`).digest("hex");Errors
Errors return { error: { code, message } } with a 4xx status: 401 unauthorized, 402 insufficient_credits, 403 consent_required, 404 number_not_found, 409 recipient_opted_out, 422 content_blocked (promotional message, with a `reasons` array) and invalid_*, 429 rate_limited.