API Documentation
Send and receive WhatsApp messages over a single REST API. All endpoints are scoped to your own connected number — you never manage sessions or IDs.
Introduction
The Paisha API base URL is:
https://api.paisha.africa/whatsapp
Create an account, activate a plan, connect your WhatsApp number, and generate an API key from your dashboard. Every request returns JSON.
Authentication
Send your API key in the X-API-Key header on every request. Keep it secret — treat it like a password.
X-API-Key: pa_live_xxxxxxxxxxxxxxxxxxxx
Requests without a valid key return 401. Without an active subscription you'll get 402. Suspended accounts get 403.
Connect a number
Start a session and get a QR code to scan from WhatsApp → Linked devices. You can also do this visually in the dashboard.
curl -X POST https://api.paisha.africa/whatsapp/session/connect \
-H "X-API-Key: $PAISHA_KEY"
Connection status
curl https://api.paisha.africa/whatsapp/session/status \
-H "X-API-Key: $PAISHA_KEY"
# { "session": "...", "status": "connected", "phone_number": "2557..." }
Send a text message
curl -X POST https://api.paisha.africa/whatsapp/messages/send-text \
-H "X-API-Key: $PAISHA_KEY" \
-H "Content-Type: application/json" \
-d '{ "chatId": "255700000000@c.us", "text": "Hello from Paisha 👋" }'
# 200 OK
# { "id": "wamid.HBgL...", "status": "sent" }
Address recipients as <number>@c.us for people and <id>@g.us for groups — international number, no + or 00.
Send media
Images, documents and other types follow the same pattern — just change the endpoint.
curl -X POST https://api.paisha.africa/whatsapp/messages/send-image \
-H "X-API-Key: $PAISHA_KEY" \
-H "Content-Type: application/json" \
-d '{ "chatId": "255700000000@c.us", "url": "https://example.com/receipt.jpg", "caption": "Your receipt" }'
Receive messages (webhooks)
Set a webhook URL in your dashboard. Paisha then POSTs a JSON event to that URL in real time whenever your number receives a message or its connection status changes. Your endpoint should respond 2xx quickly; failed deliveries are retried.
Event types
| event | When |
|---|---|
| message.received | An inbound message arrived on your number |
| session.status | Your connection status changed (connected / disconnected) |
Payload
Paisha forwards the event exactly as received. A message.received body looks like:
POST https://your-app.com/webhook
Content-Type: application/json
{
"event": "message.received",
"sessionId": "<your session id>",
"timestamp": "2026-06-14T11:09:22.521Z",
"idempotencyKey": "evt_a1b2c3d4",
"deliveryId": "dlv_5e6f7a8b",
"data": {
"id": "true_2557...@c.us_3EB0...",
"from": "255742779292@c.us",
"to": "255626796707@c.us",
"fromMe": false,
"type": "text",
"body": "Hello!"
}
}
| Field | Description |
|---|---|
| event | Event type (e.g. message.received) |
| sessionId | Your session id |
| timestamp | ISO-8601 time the event fired |
| idempotencyKey | Stable id for the event — dedupe on this to avoid double-processing retries |
| deliveryId | Unique id for this delivery attempt |
| data.from | Sender chat id (<number>@c.us) |
| data.fromMe | true if your number sent it (skip these for inbound) |
| data.type | Message type: text, image, video, document, … |
| data.body | Text content (or caption for media) |
| data.id | Unique WhatsApp message id |
Tip: ignore events where data.fromMe is true and any sender ending in @broadcast (WhatsApp status updates).
Usage
Check how many messages you've sent and received.
curl https://api.paisha.africa/whatsapp/usage \
-H "X-API-Key: $PAISHA_KEY"
# { "sent": 1280, "received": 642 }
Errors
| Code | Meaning |
|---|---|
| 401 | Missing or invalid API key |
| 402 | No active subscription |
| 403 | Account suspended |
| 4xx / 5xx | Errors from the messaging layer are passed through with their status |