Send your first WhatsApp message
Connect a device, make an API request, then check delivery. Keep your API key on your server.
Before your first request
- Sign in and connect your WhatsApp device from Overview.
- Get an active key from API Keys and store it in your server environment.
- List your devices and choose a connected, active device ID.
- Send to a number you control. Sending uses your message allowance.
- Use the returned message ID to check delivery and confirm receipt on the phone.
For OTP messages, your application generates, expires, rate-limits, and verifies the code. WatConnexio transports the message.
# WatConnexio API Documentation
Base URL: https://api-wat.tryconnexio.com
## Authentication
Include this header on every request:
```http
Authorization: Bearer YOUR_API_KEY
```
Keep API keys private. Rotating a key immediately invalidates the previous key.
All examples use placeholders, not live credentials or account data.
## Response structure
All endpoints below return JSON with these fields:
| Field | Type | Meaning |
| --- | --- | --- |
| code | number | HTTP status code, matching the response status |
| message | string | Human-readable result or error |
| data | object, array, or null | Useful result data; null on errors |
## Get devices
GET /whatsapp/devices
No request body or query parameters. Returns devices belonging to the authenticated account.
```json
{
"code": 200,
"message": "Devices retrieved.",
"data": [
{
"id": "DEVICE_ID",
"name": "Work phone",
"phoneNumber": "2348012345678",
"status": "connected",
"isActive": true,
"lastSeen": "2026-01-01T12:00:00.000Z"
}
]
}
```
An account with no devices receives an empty data array.
Device status is connected, connecting, or disconnected.
phoneNumber and lastSeen can be null.
A Safari Com arrival guide also includes "agentRole": "safaricom". Ordinary send devices omit that field.
## Get device by ID
GET /whatsapp/devices/:deviceId
Replace :deviceId with a device ID from the list endpoint.
Returns HTTP 200 with one device object in data and message "Device retrieved.".
Returns HTTP 404 if the device is unavailable to the authenticated account.
## Send message
POST /whatsapp/send-message
Content-Type: application/json
```json
{
"deviceId": "DEVICE_ID",
"phone": "2348012345678",
"message": "Hello from WatConnexio!"
}
```
deviceId, phone, and message are required. Use an international recipient number
including its country code. The device must be connected and active.
Successful send response (also used for file URLs and uploads):
```json
{
"code": 201,
"message": "Message accepted. Delivery is not yet confirmed.",
"data": {
"messageId": "MESSAGE_ID",
"deviceId": "DEVICE_ID",
"status": "accepted"
}
}
```
Acceptance is not a delivery receipt. Use the delivery-status endpoint below.
## Send file by URL
POST /whatsapp/send-file
Content-Type: application/json
```json
{
"deviceId": "DEVICE_ID",
"phone": "2348012345678",
"fileUrl": "https://example.com/document.pdf",
"caption": "Your document"
}
```
deviceId, phone, and fileUrl are required; caption is optional.
The file URL must be publicly accessible to the backend.
The 2 MB multipart upload limit below does not apply to this URL endpoint.
## Upload a document
POST /whatsapp/send-upload
Content-Type: multipart/form-data
| Form field | Required | Meaning |
| --- | --- | --- |
| deviceId | Yes | Device ID |
| phone | Yes | International number with 7-15 digits, optional leading + |
| file | Yes | One non-empty document; maximum 2,097,152 bytes (2 MB) |
| caption | No | Document caption |
Let the HTTP client generate the multipart boundary. Do not manually set the
Content-Type header when using browser FormData.
Example using a POSIX shell:
```sh
curl -X POST 'https://api-wat.tryconnexio.com/whatsapp/send-upload' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Idempotency-Key: YOUR_UNIQUE_REQUEST_ID' \
-F 'deviceId=DEVICE_ID' \
-F 'phone=2348012345678' \
--form-string 'caption=Your document' \
-F 'file=@/path/to/document.pdf'
```
Oversized uploads return HTTP 413:
```json
{
"code": 413,
"message": "File is too large. Maximum upload size is 2 MB (2,097,152 bytes).",
"data": null
}
```
## Check delivery status
GET /whatsapp/sessions/:deviceId/messages/:messageId/status
Use the deviceId and messageId from the send response. No request body.
```json
{
"code": 200,
"message": "Delivery status retrieved.",
"data": {
"messageId": "MESSAGE_ID",
"status": "delivered",
"updatedAt": "2026-01-01T12:00:00.000Z"
}
}
```
Possible statuses: pending, server_ack, delivered, read, played, error, unknown.
updatedAt may be null. Receipt history is in memory, expires after 24 hours,
and is lost when the backend restarts. Unknown does not prove delivery failure.
## Safe retries
For every send endpoint, optionally include Idempotency-Key (maximum 200 characters).
Use a unique key for each intended message. Retrying the identical request with
the same key replays a completed result instead of sending again.
For uploads, retain identical file contents, filename, MIME type, and form values.
HTTP 409 indicates a conflicting payload or a pending/uncertain outcome.
After a timeout or uncertain result, do not switch to a new key to bypass protection:
that could send a duplicate message. Reservations currently have no automatic expiry.
## Errors
| HTTP code | Meaning |
| --- | --- |
| 400 | Missing or invalid request fields, or empty upload |
| 401 | Authentication required or invalid credentials |
| 403 | Plan or usage limit reached |
| 404 | Device not found or unavailable to the account |
| 409 | Idempotency conflict or uncertain send outcome |
| 413 | Upload exceeds 2 MB |
| 429 | Rate limit reached |
| 500 | Request could not be completed; a send outcome may be uncertain |
```json
{
"code": 404,
"message": "Device not found",
"data": null
}
```
## Sandbox modes
Simulation validates locally and displays example responses. It does not send
messages, charge usage, or verify authentication or delivery.
Live API mode calls production endpoints. Live sends reach actual recipients
and count toward account usage. Read-only device queries do not send messages.