Skip to main content

Documentation

One contract for
SMS, WhatsApp, and OTP.

REST, JSON, and bearer tokens. This page covers the parts you will use most. The full contract, response examples, and field list live in the app documentation.

/api/v1Base path
Bearer tokenAuth
JSONFormat
120 / minuteRate limit

01 / Authentication

A token carries permissions, not just an identity.

Send the token in the Authorization header. Permissions are checked per endpoint, so a token with only sms:read cannot create a batch. Create one token per integration so you can revoke it without touching the others.

Authentication
Authorization: Bearer notif.<64 hex characters>Content-Type: application/jsonAccept: application/jsonIdempotency-Key: <unique per write operation>

02 / OTP

Send, verify, track.

SMS and WhatsApp use the same request shape. Templates are capped at 255 characters and must contain {otp} or {code}. Codes stay valid for 60 to 900 seconds.

  • POST/api/v1/otp/sms/send

    Create an OTP request over SMS.

    otp-sms:create
  • POST/api/v1/otp/whatsapp/send

    Create an OTP request over WhatsApp.

    otp-whatsapp:create
  • POST/api/v1/otp/verify

    Verify a code for a number and channel.

    otp-sms:verify | otp-whatsapp:verify
  • GET/api/v1/otp/{id}

    Check the status of one request.

    otp-sms:read | otp-whatsapp:read
OTP flow
curl -s -X POST "$NOTIF_API_URL/api/v1/otp/sms/send" \  -H "Authorization: Bearer $NOTIF_TOKEN" \  -H "Content-Type: application/json" \  -H "Idempotency-Key: login-2026-11-07-001" \  -d '{"recipient":"081234567890","ttl":300}'

03 / SMS, RCS, MMS

One endpoint, three message types.

The Idempotency-Key header is required when creating a batch. Set type to SMS, RCS, or MMS. RCS allows media, MMS requires it. Each request takes 1 to 1,000 recipients, and they must be unique.

  • POST/api/v1/sms

    Create an SMS, RCS, or MMS batch.

    sms:create
  • GET/api/v1/sms

    List batches, 20 per page.

    sms:read
  • GET/api/v1/sms/{id}

    Batch details and the messages inside it.

    sms:read
  • GET/api/v1/sms/batches/{id}

    List the messages in one batch.

    sms:read

04 / WhatsApp

One recipient per request.

The WhatsApp endpoint creates a batch with a single recipient. For large lists, use a blast session in the dashboard. Media is sent as an HTTPS URL, not base64.

  • POST/api/v1/whatsapp

    Send a single WhatsApp message.

    whatsapp:create
  • GET/api/v1/whatsapp

    List WhatsApp batches.

    whatsapp:read
  • GET/api/v1/whatsapp/{id}

    Details for one batch.

    whatsapp:read
  • GET/api/v1/whatsapp/batches/{id}

    List the messages in a batch.

    whatsapp:read

05 / Virtual Numbers

Order statuses you need to know.

Virtual numbers are managed from the notif. panel, not from the public SMS or WhatsApp endpoints. Order status and OTP codes appear in the dashboard, and the code can be forwarded to a WhatsApp device through the integration.

Scroll the table sideways to see the other columns.

Virtual number order statuses
ItemValueNotes
ACTIVEWaiting for SMSThe number is ready. Cancellation follows the window the partner allows.
OTP_RECEIVEDCode receivedThe code is available. The order can be completed or re-requested if the flag allows it.
COMPLETEDCompletedThe order closes once the code is used.
CANCELEDCanceledThe order stopped before a code arrived.
EXPIREDExpiredThe active window ended without a code.

06 / Webhooks

Verify the signature before you trust the payload.

Batch webhooks send sms.batch.updated and whatsapp.batch.updated events to a public HTTPS URL on port 443. Every request carries X-Webhook-Id, X-Webhook-Timestamp, and X-Webhook-Signature in the format sha256=HMAC(timestamp.body, secret).

Batch webhooks
{  "id": "9a51d6de-7f0c-4c1b-9f8a-2f7b5a6d8c31",  "event": "sms.batch.updated",  "created_at": "2026-11-07T09:30:00+00:00",  "data": {    "id": "01JBCDEFGHJKMNPQRSTVWXYZ",    "status": "running",    "lifecycle_status": "running"  }}

Verify signatures against the raw body, not the parsed JSON. Reject requests with an old timestamp, and do not follow redirects.

07 / Limits

The numbers that define the API contract.

Scroll the table sideways to see the other columns.

notif. API limits
ItemValueNotes
Request limit120 / minutePer token and per account. A 429 response includes Retry-After.
Recipients per SMS batch1 to 1,000Must be unique within one request.
Message length5,000 charactersApplies to SMS, RCS, and WhatsApp.
MediaHTTPS URLUp to 2,048 characters. The 25 MB file limit applies to RCS and MMS.
OTP validity60 to 900 secondsDefaults to 300 seconds.
OTP attempts5After that, the request is marked failed.
OTP cooldown60 secondsAt most 5 requests per hour for the same number and channel.
Message page size1 to 1,000Defaults to 100 messages per page in batch details.

08 / Error codes

Decide what to do from the error code, not the message.

Error messages can change. Error codes are a stable enum, and they are what you should branch on.

Scroll the table sideways to see the other columns.

API error codes
ItemValueNotes
UNAUTHORIZED401The token is missing, invalid, revoked, or expired.
FORBIDDEN403The token lacks permission for this endpoint.
NOT_FOUND404The ID does not exist or belongs to another account.
IDEMPOTENCY_KEY_REUSED409The same key was used with a different body.
VALIDATION_ERROR422A required field is empty, malformed, or over a limit.
RATE_LIMIT_EXCEEDED429Wait for Retry-After before trying again.
SERVICE_UNAVAILABLE503The service is off or the WhatsApp device is unavailable.
OTP_DISABLED503The OTP service is currently disabled.
WHATSAPP_DISABLED503The WhatsApp service is currently disabled.

The full list, including channel-specific codes, is in the app documentation.

Need another example?

The app documentation has response examples, per-endpoint fields, and an explanation of every enum value. Start there before writing a new integration.

Open the app documentation

Start with the right token.

Create a token with narrow permissions, then send your first request from your server.