WhatsApp API
Send WhatsApp messages programmatically using the Voxvaani WhatsApp API. This API supports single messages, template messages, media messages, bulk sends, campaign tracking, webhooks, and media upload.
Base URL
https://voxvaani.com/api/v1Authentication
All requests require an API key. Use either header:
x-api-key: YOUR_API_KEYor
Authorization: Bearer YOUR_API_KEYRequired scopes: whatsapp:send, whatsapp:send-template, whatsapp:bulk-send, whatsapp:campaigns depending on the endpoint.
All phone numbers in API requests must use E.164 international format with country code. Examples:
| Country | Correct Format | Incorrect |
|---|---|---|
| India | 919876543210 | 09876543210, +91-9876543210 |
| USA | 12125551234 | 212-555-1234, (212) 555-1234 |
| UK | 447700900123 | 07700900123, +44-7700900123 |
Strip all spaces, dashes, parentheses, and leading zeros. Include the country code without the + prefix.
List WhatsApp Numbers
Returns all connected WhatsApp Business numbers you can send from. Use the returned id as configId in other endpoints.
Endpoint: GET /whatsapp/configs
Required scope: whatsapp:send
Response
{
"configs": [
{
"id": "uuid-string",
"phoneNumber": "+919876543210",
"phoneNumberId": "123456789012345",
"wabaId": "987654321",
"qualityRating": "GREEN",
"isDefault": true,
"createdAt": "2026-07-14T12:00:00.000Z"
}
]
}Example
curl -X GET "https://voxvaani.com/api/v1/whatsapp/configs" \
-H "x-api-key: YOUR_API_KEY"Send WhatsApp Message (Browser-based)
Send a single text or image message using browser-based WhatsApp Web automation. This endpoint does not use the Meta Cloud API and requires an active WhatsApp Web session in your Voxvaani dashboard.
Endpoint: POST /whatsapp/send
Required scope: whatsapp:send
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
phone | string | Yes | Recipient phone in E.164 format |
message | string | Yes | Message text content |
file | string | No | File path or URL for image attachment |
Success Response
{
"success": true,
"message": "Message delivered successfully.",
"cost": 0,
"remainingBalance": 24999
}Example
curl -X POST "https://voxvaani.com/api/v1/whatsapp/send" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone": "919876543210",
"message": "Hello from Voxvaani API!"
}'Send Template Message (Meta Cloud API)
Send a single pre-approved WhatsApp template message via the Meta Cloud API (WABA). Supports JSON and multipart/form-data modes.
Endpoint: POST /whatsapp/send-template
Required scope: whatsapp:send-template
JSON Mode
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
phone | string | Yes | Recipient phone in E.164 format |
templateName | string | Yes | Name of the approved template |
configId | string | No | WhatsApp number UUID or phone number (omit to use default) |
language | string | No | Template language code, default "en" |
parameters | string[] | No | Body parameter values for {{1}}, {{2}}, etc. |
headerParameters | object | No | Header media/text configuration |
Success Response
{
"success": true,
"message": "Template message sent successfully.",
"metaMessageId": "wamid.HBgLM...",
"cost": 1,
"remainingBalance": 24999
}JSON Example
curl -X POST "https://voxvaani.com/api/v1/whatsapp/send-template" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone": "919876543210",
"templateName": "welcome_message",
"language": "en",
"parameters": ["John", "Order #12345"]
}'Multipart Mode (File Upload)
curl -X POST "https://voxvaani.com/api/v1/whatsapp/send-template" \
-H "x-api-key: YOUR_API_KEY" \
-F "phone=919876543210" \
-F "templateName=order_invoice" \
-F "language=en" \
-F 'parameters=["INV-52412"]' \
-F "file=@/path/to/invoice.pdf" \
-F "headerType=document" \
-F "headerFilename=Invoice-52412.pdf"Cost Per Message
- Marketing templates: 3 credits
- Utility templates: 1 credit
Send Media Message (Meta Cloud API)
Send image, video, audio, or document messages via the Meta Cloud API.
Endpoint: POST /whatsapp/send-media
Required scope: whatsapp:send
JSON Mode
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
phone | string | Yes | Recipient phone in E.164 format |
type | string | Yes | Media type: image, video, audio, document |
mediaUrl | string | One of | Publicly accessible HTTPS URL of the media file |
mediaId | string | One of | Pre-uploaded media ID from /whatsapp/upload |
caption | string | No | Caption text (image, video, document) |
filename | string | No | Display filename (document type) |
configId | string | No | WhatsApp number UUID or phone number |
JSON Example
curl -X POST "https://voxvaani.com/api/v1/whatsapp/send-media" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone": "919876543210",
"type": "image",
"mediaUrl": "https://example.com/invoice.jpg",
"caption": "Your invoice is ready"
}'Supported MIME Types
image: JPEG, PNG, GIF, WEBPvideo: MP4, MKV, AVIaudio: MP3, WAV, OGG, M4Adocument: PDF, DOC, DOCX, XLS, PPT (and many others)
Cost: 1 credit per media message
Upload Media File
Upload a local file to Meta’s servers and get a media ID for use in subsequent send-template or send-media calls.
Endpoint: POST /whatsapp/upload
Required scope: whatsapp:send
Request (Multipart)
| Field | Type | Required | Description |
|---|---|---|---|
file | File | Yes | Media file to upload |
configId | string | No | WhatsApp number UUID or phone number |
Response
{
"success": true,
"mediaId": "123456789012345",
"type": "image",
"mimeType": "image/jpeg",
"filename": "invoice.jpg",
"size": 54200,
"message": "File uploaded. Use the mediaId in send-template or send-media."
}Example
curl -X POST "https://voxvaani.com/api/v1/whatsapp/upload" \
-H "x-api-key: YOUR_API_KEY" \
-F "file=@/path/to/invoice.jpg"Bulk Send Template Messages
Send template messages to multiple recipients asynchronously. Accepts up to 10,000 recipients per request.
Endpoint: POST /whatsapp/bulk-send
Required scope: whatsapp:bulk-send
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
templateName | string | Yes | Name of the approved template |
recipients | array | Yes | Array of recipient objects (max 10,000) |
configId | string | No | WhatsApp number UUID or phone number |
language | string | No | Template language code, default "en" |
Recipient object:
| Field | Type | Required | Description |
|---|---|---|---|
phone | string | Yes | Recipient phone in E.164 format |
params | string[] | No | Body parameter values for {{1}}, {{2}}, etc. |
headerValue | string | No | Optional header media URL or text |
headerMediaId | string | No | Optional pre-uploaded media ID |
name | string | No | Optional recipient name (for reference) |
Response (200 OK)
The job is queued and processed asynchronously, but this endpoint returns 200 OK immediately rather than 202 Accepted.
{
"success": true,
"campaignId": "uuid-string",
"total": 2,
"status": "processing",
"message": "Bulk send started for 2 recipient(s). Use GET /api/v1/whatsapp/campaigns to check status."
}Example
curl -X POST "https://voxvaani.com/api/v1/whatsapp/bulk-send" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"templateName": "welcome_message",
"language": "en",
"recipients": [
{"phone": "919876543210", "params": ["John", "Order #100"]},
{"phone": "919876543211", "params": ["Jane", "Order #101"]}
]
}'Cost per message:
- Marketing templates: 3 credits each
- Utility templates: 1 credit each
Query Campaign Status
Poll delivery status for messages sent via bulk-send.
Endpoint: GET /whatsapp/campaigns
Required scope: whatsapp:campaigns
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
status | string | No | Filter by status: Sent, Delivered, Read, Failed (PascalCase) |
limit | integer | No | Max results (default 20, max 100) |
offset | integer | No | Pagination offset |
The campaignId parameter is not supported by this endpoint.
Response
{
"total": 150,
"limit": 20,
"offset": 0,
"stats": {
"Sent": 145,
"Delivered": 132,
"Read": 89,
"Failed": 5
},
"messages": [
{
"id": "msg-uuid",
"to": "919876543210",
"status": "Delivered",
"metaMessageId": "wamid.HBgLM...",
"content": "Hello, this is the message content",
"type": "template",
"sentAt": "2026-07-14T12:00:00.000Z",
"updatedAt": "2026-07-14T12:00:05.000Z"
}
]
}Example
curl -X GET "https://voxvaani.com/api/v1/whatsapp/campaigns?limit=10" \
-H "x-api-key: YOUR_API_KEY"Webhooks
Register HTTPS URLs to receive real-time delivery status updates. Webhooks eliminate the need for polling campaigns.
Register a Webhook
Endpoint: POST /whatsapp/webhooks
Required scope: whatsapp:send
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | HTTPS URL to receive webhook payloads |
events | string[] | No | Events to subscribe to. Default: ["message.sent", "message.delivered", "message.failed"] |
Available events: message.sent, message.delivered, message.read, message.failed
Response (201 Created)
{
"webhook": {
"id": "uuid-string",
"url": "https://example.com/webhooks/whatsapp",
"secret": "generated-hmac-secret",
"events": ["message.sent", "message.delivered"],
"isActive": true,
"createdAt": "2026-07-14T12:00:00.000Z"
}
}Save the secret — it is returned only on creation and is used to verify webhook signatures.
Webhook Payload Format
{
"event": "message.delivered",
"timestamp": "2026-07-14T12:00:00.000Z",
"data": {
"metaMessageId": "wamid.HBgLM...",
"status": "delivered",
"to": "919876543210",
"from": "919876543209",
"templateName": "welcome_message"
}
}Verification: Each webhook request includes an X-Webhook-Signature header. Compute HMAC-SHA256 of the raw request body using your webhook secret and compare to verify authenticity.
List Webhooks
Endpoint: GET /whatsapp/webhooks
Required scope: whatsapp:send
Delete a Webhook
Endpoint: DELETE /whatsapp/webhooks?id={webhookId}
Required scope: whatsapp:send
Error Codes
| Status | Meaning |
|---|---|
200 | Success |
201 | Created — a webhook was registered |
400 | Bad request — invalid or missing parameters, unsupported media type, or a file that exceeds its size limit |
401 | Unauthorized — invalid or missing API key |
402 | Insufficient balance — need more credits |
403 | Forbidden — API key lacks required permission scope |
404 | Not found — resource doesn’t exist |
500 | Internal server error |
No 202, 415, 422, or 429 responses are returned by these endpoints. Asynchronous jobs such as bulk send respond 200 OK immediately, unsupported or oversized media and unapproved templates are reported as 400, and request rate limiting is not enforced.
Error Response Format
{
"error": "Descriptive error message"
}Tips
- Ensure the recipient’s phone number includes the country code in E.164 format without the
+prefix - Message sending is limited by your account’s WhatsApp balance — check balance before batch operations
- Monitor your balance to avoid service interruptions during campaigns
- For bulk sends, use the
/whatsapp/bulk-sendendpoint instead of looping individual send-template calls GET /whatsapp/campaignsreturns individual message records and per-status counts, not per-campaign summaries — there is no way to poll a singlecampaignId, so use webhooks for reliable delivery tracking- Use the default WhatsApp number by omitting
configIdif you have only one connected number