WhatsInfinity Messaging API
Send WhatsApp messages and media (images, videos, audio, PDFs, and documents) programmatically from any platform: web apps, mobile apps, backend services, and automation tools.
Introduction
What this API does
This API helps you create a WhatsApp session and then send messages or media files to recipients. Sessions are authenticated using a per-session API key.
Base URL
Base URL for this API: http://api.whatsinfinity.com
Quick start (3 steps)
- Create a session with POST /create-session (set an API key).
- Connect WhatsApp by scanning a QR (GET /qr/:sessionId) or using a pairing code.
- Send your first message with POST /send.
Use dryRun: true during development to validate payloads without sending real messages.
Authentication
This API uses a per-session API key. Most endpoints require the x-api-key header.
- Header name: x-api-key
- Minimum length: 16 characters
- Exception: POST /create-session (API key is provided in the request body)
Example header
cURLcurl -X GET "http://api.whatsinfinity.com/check-session/mysession" \ -H "x-api-key: your-session-api-key"
JavaScript (fetch)await fetch("http://api.whatsinfinity.com/check-session/mysession", { headers: { "x-api-key": "your-session-api-key" } });
401 Unauthorized
If the API key is missing or invalid, you may receive:
JSON{ "success": false, "requestId": "c2fd2c4a-....", "error": "Unauthorized", "details": "Invalid or missing API key" }
Session Management
Sessions represent a connected WhatsApp device. Each session has its own API key and connection state.
Create Session
Creates a new WhatsApp session and stores the session API key. After creation, connect the device using QR or pairing code.
| Field | Type | Required | Description |
|---|---|---|---|
| sessionId | string | Yes | Unique identifier for this session (letters, numbers, -, _). |
| apiKey | string | Yes | Per-session API key (minimum 16 characters). |
JavaScript (fetch)const baseUrl = "http://api.whatsinfinity.com"; const res = await fetch(`${baseUrl}/create-session`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ sessionId: "mysession", apiKey: "your-session-api-key" // min 16 chars }) }); const json = await res.json(); console.log(json);
Python (requests)import requests base_url = "http://api.whatsinfinity.com" r = requests.post( f"{base_url}/create-session", json={"sessionId": "mysession", "apiKey": "your-session-api-key"} ) print(r.json())
PHP (cURL)<?php $baseUrl = "http://api.whatsinfinity.com"; $payload = json_encode([ "sessionId" => "mysession", "apiKey" => "your-session-api-key" ]); $ch = curl_init("$baseUrl/create-session"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => ["Content-Type: application/json"], CURLOPT_POSTFIELDS => $payload ]); $resp = curl_exec($ch); curl_close($ch); echo $resp;
cURLcurl -X POST "http://api.whatsinfinity.com/create-session" \ -H "Content-Type: application/json" \ -d '{"sessionId":"mysession","apiKey":"your-session-api-key"}'
Get QR Code
Returns a QR code PNG image that the user scans in WhatsApp to connect the session. QR codes expire in 60 seconds.
Display QR in a browser: <img src="http://api.whatsinfinity.com/qr/mysession" />
HTML<img src="http://api.whatsinfinity.com/qr/mysession" alt="Scan to connect WhatsApp session" style="max-width: 320px; border-radius: 12px;" />
cURLcurl -L "http://api.whatsinfinity.com/qr/mysession" \ -H "x-api-key: your-session-api-key" \ --output qr.png
Pairing Code
Alternative to QR. Provide a phone number to get an 8-digit pairing code. The user enters this code in WhatsApp under Linked Devices.
| Field | Type | Required | Description |
|---|---|---|---|
| sessionId | string | Yes | Session identifier. |
| phoneNumber | string | Yes | Country code + number, no + (example: 919999999999). |
JavaScript (fetch)const baseUrl = "http://api.whatsinfinity.com"; const apiKey = "your-session-api-key"; const res = await fetch(`${baseUrl}/pairing-code`, { method: "POST", headers: { "content-type": "application/json", "x-api-key": apiKey }, body: JSON.stringify({ sessionId: "mysession", phoneNumber: "919999999999" }) }); console.log(await res.json());
Python (requests)import requests base_url = "http://api.whatsinfinity.com" api_key = "your-session-api-key" r = requests.post( f"{base_url}/pairing-code", headers={"x-api-key": api_key}, json={"sessionId": "mysession", "phoneNumber": "919999999999"}, ) print(r.json())
PHP (cURL)<?php $baseUrl = "http://api.whatsinfinity.com"; $apiKey = "your-session-api-key"; $payload = json_encode([ "sessionId" => "mysession", "phoneNumber" => "919999999999" ]); $ch = curl_init("$baseUrl/pairing-code"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: $apiKey" ], CURLOPT_POSTFIELDS => $payload ]); echo curl_exec($ch); curl_close($ch);
cURLcurl -X POST "http://api.whatsinfinity.com/pairing-code" \ -H "Content-Type: application/json" \ -H "x-api-key: your-session-api-key" \ -d '{"sessionId":"mysession","phoneNumber":"919999999999"}'
Check Session
Returns the current status and health of a session.
| Field | Type | Description |
|---|---|---|
| status | string | One of: active, connecting, qr, pairing, disconnected, disabled. |
| isReady | boolean | Whether the session is connected and ready to send. |
| hasQR | boolean | Whether a QR is currently available to scan. |
| queueSize | number | How many messages are queued for delivery. |
| rateLimitRemaining | number | How many messages remain for the current minute window. |
| lastActiveAt | string (timestamp) | Last time the session was active (useful for monitoring). |
| warning | string | Optional warnings, e.g., if the same number is active elsewhere. |
JavaScript (fetch)const baseUrl = "http://api.whatsinfinity.com"; const sessionId = "mysession"; const apiKey = "your-session-api-key"; const res = await fetch(`${baseUrl}/check-session/${encodeURIComponent(sessionId)}`, { headers: { "x-api-key": apiKey } }); console.log(await res.json());
cURLcurl -X GET "http://api.whatsinfinity.com/check-session/mysession" \ -H "x-api-key: your-session-api-key"
All Sessions
Lists all sessions and their current status.
Python (requests)import requests base_url = "http://api.whatsinfinity.com" r = requests.get(f"{base_url}/all-sessions") print(r.json())
cURLcurl -X GET "http://api.whatsinfinity.com/all-sessions"
Restart Session
Restarts a session. Use wipe: true only when you want to clear authentication and reconnect again.
| Field | Type | Required | Description |
|---|---|---|---|
| sessionId | string | Yes | Session identifier. |
| wipe | boolean | No | If true, clears auth and requires reconnect (QR or pairing). |
JavaScript (fetch)await fetch("http://api.whatsinfinity.com/restart-session", { method: "POST", headers: { "content-type": "application/json", "x-api-key": "your-session-api-key" }, body: JSON.stringify({ sessionId: "mysession", wipe: false }) });
cURLcurl -X POST "http://api.whatsinfinity.com/restart-session" \ -H "Content-Type: application/json" \ -H "x-api-key: your-session-api-key" \ -d '{"sessionId":"mysession","wipe":false}'
Delete Session
Permanently deletes the session. You will need to create it again to reconnect.
Python (requests)import requests base_url = "http://api.whatsinfinity.com" api_key = "your-session-api-key" r = requests.post( f"{base_url}/delete-session", headers={"x-api-key": api_key}, json={"sessionId": "mysession"}, ) print(r.json())
cURLcurl -X POST "http://api.whatsinfinity.com/delete-session" \ -H "Content-Type: application/json" \ -H "x-api-key: your-session-api-key" \ -d '{"sessionId":"mysession"}'
Rotate API Key
Rotates the session API key without disconnecting the session. Use the current key in x-api-key, and store the new key securely.
JavaScript (fetch)const res = await fetch("http://api.whatsinfinity.com/rotate-key", { method: "POST", headers: { "content-type": "application/json", "x-api-key": "your-current-api-key" }, body: JSON.stringify({ sessionId: "mysession" }) }); const json = await res.json(); console.log("New apiKey:", json?.data?.apiKey);
cURLcurl -X POST "http://api.whatsinfinity.com/rotate-key" \ -H "Content-Type: application/json" \ -H "x-api-key: your-current-api-key" \ -d '{"sessionId":"mysession"}'
Sending Messages
Send Text Message
Sends a text message. Recipient phone numbers must be in full international format (country code + number), without + (example: 919999999999).
| Field | Type | Required | Description |
|---|---|---|---|
| sessionId | string | Yes | Session identifier. |
| to | string | Yes | Recipient number, 7–15 digits (example: 919999999999). |
| type | string | Yes | Use "text". |
| message | string | Yes | Message content (max 65000 characters). |
| typing | boolean | No | If true, shows a typing indicator briefly before sending. |
| dryRun | boolean | No | If true, validates the payload without sending. |
Response fields
Successful responses follow the standard format. The data object includes: queued (boolean) and messageId (string) when available.
JavaScript (fetch)const baseUrl = "http://api.whatsinfinity.com"; const apiKey = "your-session-api-key"; const res = await fetch(`${baseUrl}/send`, { method: "POST", headers: { "content-type": "application/json", "x-api-key": apiKey }, body: JSON.stringify({ sessionId: "mysession", to: "919999999999", type: "text", message: "Hello from my app!", typing: true }) }); console.log(await res.json());
Python (requests)import requests base_url = "http://api.whatsinfinity.com" api_key = "your-session-api-key" r = requests.post( f"{base_url}/send", headers={"x-api-key": api_key}, json={ "sessionId": "mysession", "to": "919999999999", "type": "text", "message": "Hello from my app!", "typing": True, }, ) print(r.json())
PHP (cURL)<?php $baseUrl = "http://api.whatsinfinity.com"; $apiKey = "your-session-api-key"; $payload = json_encode([ "sessionId" => "mysession", "to" => "919999999999", "type" => "text", "message" => "Hello from my app!", "typing" => true ]); $ch = curl_init("$baseUrl/send"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: $apiKey" ], CURLOPT_POSTFIELDS => $payload ]); echo curl_exec($ch); curl_close($ch);
cURLcurl -X POST "http://api.whatsinfinity.com/send" \ -H "Content-Type: application/json" \ -H "x-api-key: your-session-api-key" \ -d '{"sessionId":"mysession","to":"919999999999","type":"text","message":"Hello from my app!","typing":true}'
Send Media (Image / Video / PDF / Audio)
Send a publicly accessible file URL. You can use: type: "media" to auto-detect, or explicitly choose "image", "video", "audio", "document".
| Field | Type | Required | Description |
|---|---|---|---|
| sessionId | string | Yes | Session identifier. |
| to | string | Yes | Recipient number, 7–15 digits. |
| type | string | Yes | media (auto) or image/video/audio/document. |
| url | string | Yes | Publicly accessible http(s) URL. |
| caption | string | No | Optional caption for images, videos, and documents. |
| fileName | string | No | Optional file name for documents (e.g. invoice.pdf). |
Supported formats
| Type | Examples |
|---|---|
| image | jpg, png, gif |
| video | mp4 |
| audio | mp3, ogg |
| document | pdf, docx, xlsx |
JavaScript (fetch)const baseUrl = "http://api.whatsinfinity.com"; const apiKey = "your-session-api-key"; const res = await fetch(`${baseUrl}/send`, { method: "POST", headers: { "content-type": "application/json", "x-api-key": apiKey }, body: JSON.stringify({ sessionId: "mysession", to: "919999999999", type: "document", url: "https://files.example.com/invoice.pdf", fileName: "invoice.pdf", caption: "April invoice" }) }); console.log(await res.json());
Python (requests)import requests base_url = "http://api.whatsinfinity.com" api_key = "your-session-api-key" r = requests.post( f"{base_url}/send", headers={"x-api-key": api_key}, json={ "sessionId": "mysession", "to": "919999999999", "type": "media", # auto-detect "url": "https://files.example.com/photo.jpg", "caption": "Here you go" }, ) print(r.json())
PHP (cURL)<?php $baseUrl = "http://api.whatsinfinity.com"; $apiKey = "your-session-api-key"; $payload = json_encode([ "sessionId" => "mysession", "to" => "919999999999", "type" => "audio", "url" => "https://files.example.com/voice.mp3" ]); $ch = curl_init("$baseUrl/send"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => ["Content-Type: application/json", "x-api-key: $apiKey"], CURLOPT_POSTFIELDS => $payload ]); echo curl_exec($ch); curl_close($ch);
cURLcurl -X POST "http://api.whatsinfinity.com/send" \ -H "Content-Type: application/json" \ -H "x-api-key: your-session-api-key" \ -d '{"sessionId":"mysession","to":"919999999999","type":"media","url":"https://files.example.com/photo.jpg","caption":"Here you go"}'
Features
Message Queue
If a session temporarily disconnects, messages are queued automatically and sent when the session reconnects.
- Queue max: 100 messages per session
- Behavior: queued messages auto-send when the session becomes active again
- Queue full: API returns 503 if the queue is full
Rate Limits
Rate limits are applied per session to ensure consistent delivery.
- Limit: 10 messages per minute per session
- On limit: 429 response with retryAfter
429 example
JSON{ "success": false, "requestId": "b9c3a0f2-....", "error": "Rate limit exceeded", "details": "Too many requests", "retryAfter": 30 }
Spread sends across time to avoid 429s. For high-volume use, implement your own batching and backoff strategy.
Dry Run Mode
Add dryRun: true to POST /send to validate payloads without sending real messages. This is useful for integration testing and UI validation.
JavaScript (fetch)const res = await fetch("http://api.whatsinfinity.com/send", { method: "POST", headers: { "content-type": "application/json", "x-api-key": "your-session-api-key" }, body: JSON.stringify({ sessionId: "mysession", to: "919999999999", type: "text", message: "Dry run test", dryRun: true }) }); console.log(await res.json());
JSON (example response){ "success": true, "requestId": "0bb2e5c1-....", "data": { "queued": true, "dryRun": true, "to": "919999999999@s.whatsapp.net", "payload": { "text": "Dry run test" } } }
Reference
Error Reference
All error responses follow the standard format. Use the table below to identify the cause and remediation.
| HTTP | error | Meaning | How to fix |
|---|---|---|---|
| 400 | Bad Request | Missing required fields / invalid payload | Check required fields and types, ensure all inputs match this documentation. |
| 400 | Invalid sessionId | Session ID contains invalid characters or is too long | Use only letters, numbers, -, _. Keep it short and stable. |
| 400 | Bad Request | Invalid phone number | Send 7–15 digits, include country code, and omit +. |
| 400 | Bad Request | Message too long | Text messages must be ≤ 65000 characters. |
| 400 | Bad Request | Invalid URL format | Use a valid http(s) URL that is publicly accessible. |
| 401 | Unauthorized | Missing or invalid API key | Provide x-api-key for protected endpoints. Rotate key if needed. |
| 422 | Request failed | Number not registered on WhatsApp | Verify recipient number. Only registered numbers can receive messages. |
| 429 | Rate limit exceeded | Too many messages in a short time | Backoff using retryAfter, spread sends across time. |
| 503 | Request failed | Message queue full | Wait for the session to reconnect, reduce send volume, or retry later. |
| 500 | Internal server error | Unexpected error | Retry with the same requestId when reporting issues. |
Response Format
All endpoints return a consistent JSON shape.
Success{ "success": true, "requestId": "a7b9fe4c-....", "data": { } }
Error{ "success": false, "requestId": "a7b9fe4c-....", "error": "Bad Request", "details": "Explain what went wrong" }
Every response includes a requestId. When reporting an issue, include this value so the request can be traced quickly.
Session Lifecycle
Sessions move through clear states from creation to active messaging. Use this as a mental model for monitoring and reconnection logic.
How to handle states
- QR / Pairing: show QR or pairing code to the user and wait for connection.
- Active: safe to call /send.
- Disconnected: sends may queue automatically; monitor queueSize.
- Disabled: stop sending; restart or re-create session as appropriate.
Quick Integration Guide
Step-by-step
- Create a session using POST /create-session.
- Display the QR using GET /qr/:sessionId and have a user scan it.
- Confirm readiness with GET /check-session/:sessionId.
- Send your first message with POST /send.
Full working example (JavaScript)
JavaScript (Node or Browser)const baseUrl = "http://api.whatsinfinity.com"; const sessionId = "mysession"; const apiKey = "your-session-api-key"; // min 16 chars async function createSession() { const res = await fetch(`${baseUrl}/create-session`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ sessionId, apiKey }) }); return res.json(); } function qrImageUrl() { // Note: /qr requires x-api-key, so for browser display you may proxy it. // For server-side integrations, download the PNG using fetch/cURL with x-api-key. return `${baseUrl}/qr/${encodeURIComponent(sessionId)}`; } async function checkSession() { const res = await fetch(`${baseUrl}/check-session/${encodeURIComponent(sessionId)}`, { headers: { "x-api-key": apiKey } }); return res.json(); } async function sendText(to, message) { const res = await fetch(`${baseUrl}/send`, { method: "POST", headers: { "content-type": "application/json", "x-api-key": apiKey }, body: JSON.stringify({ sessionId, to, type: "text", message, typing: true }) }); return res.json(); } async function main() { console.log("1) Creating session..."); console.log(await createSession()); console.log("2) Scan the QR to connect:"); console.log(" QR URL:", qrImageUrl()); console.log("3) Polling readiness..."); for (let i = 0; i < 60; i++) { const s = await checkSession(); if (s?.data?.isReady) { console.log("Ready:", s.data); break; } await new Promise(r => setTimeout(r, 1000)); } console.log("4) Sending message..."); console.log(await sendText("919999999999", "Hello from my integration!")); } main().catch(console.error);
Production tips
- Store credentials securely: keep sessionId and apiKey in a secrets manager.
- Check readiness: call /check-session before sending.
- Handle queue full: if you receive 503, retry later with backoff.
- Use dry runs: validate your payloads in development with dryRun: true.
FAQ
Can I have multiple sessions?
Yes. Create multiple sessions with different sessionId values and keys.
What happens if my server restarts?
Sessions typically reconnect automatically after restart. If not, fetch a QR or pairing code again.
How do I know if a message was sent?
The API returns a success response and a requestId. For high-volume use, build delivery tracking in your application and treat responses + logs as your source of truth.
What file types can I send?
Common image/video/audio/document types are supported. Use type: "media" for auto-detect or force image/video/audio/document.
My session keeps disconnecting, what do I do?
Ensure the phone has network connectivity and WhatsApp is up-to-date. If disconnects persist, restart the session or wipe and reconnect.
What is the difference between QR and Pairing Code?
QR is a scan flow, pairing code is an 8-digit entry flow. Both link the device to the session.
Can I send to any WhatsApp number?
Only to numbers that are registered on WhatsApp.
What happens when rate limit is hit?
You receive 429. Wait for the retryAfter time and retry.