DEVELOPER API

Integrate WhatsApp with the software you already run

We don't ship a wall of one-click connectors. We ship an API. Your CRM, your ERP, your accounting package, your storefront, the bespoke thing your developer wrote in 2019 — if it can make an HTTPS request, it can send WhatsApp messages and read the replies.

Create an account See the endpoints
BASE URL
/api/v1
AUTH
X-Api-Key header
ENDPOINTS
26 across 6 resources
RATE LIMIT
60 requests/min per key

What businesses build with it

Every one of these is a handful of calls against the endpoints listed further down — no connector required, and nothing here that the API cannot already do today.

Order and dispatch alerts

Your ecommerce store or ERP fires a template message the moment an order is confirmed, packed or shipped.

POST /messages

Two-way CRM sync

Push new leads in as contacts with tags and custom attributes; pull conversations back to log activity against the record.

POST /contacts/sync · GET /conversations

Invoice and payment reminders

Your accounting system sends a utility template when a bill falls due, and marks it settled when the customer replies.

POST /messages · GET /messages

Helpdesk ticketing

A message.received webhook opens a ticket in your existing helpdesk; your agent's reply goes back out through the API.

webhook + POST /messages

Delivery reconciliation

Store the WAMID you get back, then reconcile against message.status events to prove what actually landed.

message.status

Consent and opt-out hygiene

Mirror your own consent record into NaWaBiz, and get told the moment someone replies STOP.

PATCH /contacts · contact.optin
SEND YOUR FIRST MESSAGE

One POST, four languages

A template send to a customer. The reply is 202 Accepted, not 201 — Meta has taken the message, but delivery is still ahead of it. The wamId you get back is what later message.status events refer to.

curl -X POST https://nawabiz.com/api/v1/messages \
  -H "X-Api-Key: $NAWABIZ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+919876543210",
    "type": "template",
    "template": {
      "name": "order_shipped",
      "language": "en_US",
      "components": [
        { "type": "body",
          "parameters": [
            { "type": "text", "text": "10482" },
            { "type": "text", "text": "Thursday" }
          ] }
      ]
    }
  }'
const res = await fetch("https://nawabiz.com/api/v1/messages", {
  method: "POST",
  headers: {
    "X-Api-Key": process.env.NAWABIZ_API_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    to: "+919876543210",
    type: "template",
    template: {
      name: "order_shipped",
      language: "en_US",
      components: [
        { type: "body", parameters: [
          { type: "text", text: "10482" },
          { type: "text", text: "Thursday" },
        ] },
      ],
    },
  }),
});

const message = await res.json();   // 202 Accepted
console.log(message.id, message.wamId, message.status);
import os, requests

res = requests.post(
    "https://nawabiz.com/api/v1/messages",
    headers={"X-Api-Key": os.environ["NAWABIZ_API_KEY"]},
    json={
        "to": "+919876543210",
        "type": "template",
        "template": {
            "name": "order_shipped",
            "language": "en_US",
            "components": [
                {"type": "body", "parameters": [
                    {"type": "text", "text": "10482"},
                    {"type": "text", "text": "Thursday"},
                ]},
            ],
        },
    },
)

message = res.json()            # 202 Accepted
print(message["id"], message["wamId"], message["status"])
using var http = new HttpClient();
http.DefaultRequestHeaders.Add(
    "X-Api-Key", Environment.GetEnvironmentVariable("NAWABIZ_API_KEY"));

var response = await http.PostAsJsonAsync(
    "https://nawabiz.com/api/v1/messages",
    new
    {
        to = "+919876543210",
        type = "template",
        template = new
        {
            name = "order_shipped",
            language = "en_US",
            components = new object[]
            {
                new { type = "body", parameters = new object[]
                {
                    new { type = "text", text = "10482" },
                    new { type = "text", text = "Thursday" }
                } }
            }
        }
    });

// 202 Accepted
var message = await response.Content.ReadFromJsonAsync<JsonElement>();
Rules the API enforces for you

A free-form text or media send outside WhatsApp's 24-hour customer service window is refused with 409 and the reason outside_window — only an approved template reopens the conversation. A contact marked OptedOut is never messaged by any route. Both rules are applied server-side, in the same place the inbox applies them, so your integration cannot drift from the app.

REFERENCE

26 endpoints, six resources

Every path below is relative to /api/v1. This is the whole public surface — there is nothing else behind a flag.

Account

Confirm a key works and see which business it belongs to.

GET /me Who am I

Contacts

Keep your customer list and NaWaBiz in step, one row or in bulk.

GET /contacts List contacts
GET /contacts/{contact} Get a contact
POST /contacts Create or update a contact
PATCH /contacts/{contact} Update a contact
DELETE /contacts/{contact} Delete a contact
POST /contacts/sync Sync contacts

Messages

Send, read back and reconcile everything on a thread.

POST /messages Send a message
GET /messages List messages
GET /messages/{id} Get a message
GET /conversations List conversations
GET /conversations/{conversation} Get a conversation
POST /conversations/{conversation}/read Mark a conversation read

Templates

Read the approved templates you can send, and their variables.

GET /templates List templates
GET /templates/{name} Get a template
POST /templates/sync Sync templates

Numbers

Check which numbers can send, and how much headroom they have.

GET /numbers List numbers
GET /numbers/{phoneNumberId} Get a number
GET /messaging-limits List messaging limits

Webhooks

Register endpoints, rotate secrets and audit what we delivered.

GET /webhooks List webhooks
POST /webhooks Register a webhook
PATCH /webhooks/{id} Update a webhook
POST /webhooks/{id}/rotate-secret Rotate a webhook secret
POST /webhooks/{id}/test Send a test event
GET /webhooks/deliveries List webhook deliveries
DELETE /webhooks/{id} Delete a webhook
WEBHOOKS

Five events, pushed to your endpoint

Register an HTTPS endpoint and subscribe to what you care about, or to * for everything, including events added later. Plain HTTP and private or loopback addresses are refused — these payloads carry your customers' phone numbers and message content.

message.received
A customer sends you a message.
The full message, same shape as GET /messages/{id}.
message.status
An outbound message moves to Sent, Delivered, Read or Failed.
One event covers all four — switch on the status field.
template.status
Meta approves, rejects, pauses or re-categorises a template.
The template's name, language, category and new status.
contact.created
A number you have never seen messages you for the first time.
The newly created contact.
contact.optin
A contact opts in or out, including by replying STOP.
The contact and its new opt-in status.
A message.status delivery
POST /your-endpoint HTTP/1.1
X-NaWaBiz-Event: message.status
X-NaWaBiz-Timestamp: 1774598400
X-NaWaBiz-Signature: sha256=9f2c…
X-NaWaBiz-Delivery: 4e6b1f9c-…
X-NaWaBiz-Attempt: 1
Content-Type: application/json

{
  "event": "message.status",
  "eventId": "status:wamid.HBgM…:Delivered",
  "tenantId": "1f0a…",
  "createdUtc": "2026-08-27T05:20:00.1234567Z",
  "data": {
    "messageId": "8c1d…",
    "wamId": "wamid.HBgM…",
    "conversationId": "b73e…",
    "waId": "+919876543210",
    "status": "Delivered",
    "errorCode": null,
    "campaignId": null,
    "occurredUtc": "2026-08-27T05:20:00Z",
    "sentUtc": "2026-08-27T05:19:58Z",
    "deliveredUtc": "2026-08-27T05:20:00Z",
    "readUtc": null
  }
}
Verifying the signature

X-NaWaBiz-Signature is sha256= plus a lowercase-hex HMAC-SHA256, keyed on your endpoint's secret, over the exact string timestamp + "." + body — using the timestamp header's characters verbatim. Signing the timestamp too is what stops a captured payload being replayed at you later. Rotate the secret whenever you like; every attempt, and the response we got, is kept in a delivery log you can read back over the API.

AUTHENTICATION & LIMITS

Keys, scoping and throughput

How you authenticate

Send your key as X-Api-Key, or as Authorization: Bearer. Never in the query string — a secret in a URL ends up in logs, proxies and browser history, so we don't read one from there.

What a key can reach

The key identifies your business, and every query that follows is filtered to it — you cannot read another business's data even by guessing an id. Keys are stored hashed, shown once at creation, and revocable from the dashboard.

Rate limits

60 requests per minute, budgeted per key in a fixed window, so one busy integration cannot starve another. Over the line you get a 429 with a Retry-After header to honour.

GETTING ACCESS

What it costs, and what you get

Being straight about this: the API is not included in signup. It is a one-time unlock of ₹ 4,999.00 per business, charged once, on top of an active subscription. If either the unlock or the subscription lapses, existing keys stop authenticating — so plan for it before you build against us.

Message costs are separate and unchanged: sends through the API draw on the same prepaid wallet at the same per-message rate as the rest of the platform.

Create an account See pricing

Once you're signed in

Two things are waiting in the dashboard. Both need a signed-in account — we're not linking you to a page that would just turn you away.

Interactive reference

Every endpoint, every field, with a request builder you can fire against your own account. Generated from the API itself, so it never describes a version that isn't live.

Downloadable API kit

A zip with a ready-to-import Postman collection — every request filled in, your key inherited as the X-Api-Key header on all of them, plus the OpenAPI document and a README.

Keys and webhook endpoints

Create and revoke keys, register webhook endpoints, rotate secrets, fire a test event, and read the delivery log when something on your side stops answering.

Building something and want to talk it through first? Get in touch — we'll answer specifics about the endpoints before you commit.

Ready to grow on WhatsApp?

Join businesses using NaWaBiz to broadcast, automate and support customers on the channel they check first. Get started in minutes — keep your number, keep your app.

Start free Talk to us