Introduction
The Voxio Chat API follows RESTful architecture standards, offering clear and consistent resource-based endpoints. All requests and responses are transmitted in JSON format, leveraging standard HTTP verbs, status codes, and authentication protocols to enable secure, efficient, and scalable integrations.
API Base URL
Please note that Voxio Chat does not provide a sandbox or test environment. All API requests are processed in the live environment, so ensure that all request data and parameters are accurate before making any calls.
https://www.voxio.chat/external-api
Authentication
All requests to the Voxio Chat API require authentication. Each API request must include a valid client-id and client-secret to the request header, which can be obtained from your Voxio Chat Dashboard under Developer Tools.
In addition to credentials, Voxio Chat enforces IP-based security. You must register and enable your server’s public IP address in the IP Whitelist section of the dashboard. Requests originating from non-whitelisted IP addresses will be automatically rejected.
Both valid API credentials and an approved IP address are mandatory. Without completing these two steps, authentication will fail and API access will not be granted.
Response Format
All responses from the Voxio Chat API are returned in JSON format. Each response follows a consistent structure and includes a status indicator, message, and relevant data payload when applicable. Standard HTTP status codes are used to represent the outcome of each request.
Sample Success Response
{
"status": "success",
"remark": "contact-list",
"message":[
"Contact data fetched successfully."
],
"data": {
...you get all data here
}
}
Error Sample Response
{
"remark": "Unauthorized",
"status": "error",
"message": [
"The client secret is required"
]
}
{
"remark": "Unauthorized",
"status": "error",
"message": [
"Access to this API endpoint is restricted to IP addresses that have been explicitly whitelisted.",
"In order to access this API endpoint, please add your IP address (::1) to the white list from the user dashboard."
]
}
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://www.voxio.chat/external-api/contact/list?whatsapp_account_id=24',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'client-id: YOUR-CLIENT-ID',
'client-secret: YOUR-CLIENT-SECRET',
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
Get Contact List
This endpoint allows you to retrieve a complete list of contacts associated with your Voxio Chat account.
Query Parameters
Query parameters that allow you to customize the API response.
| Name | Description | Required | Default |
|---|---|---|---|
page |
Specifies the page number to retrieve. | No | 1 |
paginate |
Defines the number of items returned per page. | No | 20 |
search |
Searches for contacts by firstname, lastname or mobile number. | No | - |
whatsapp_account_id |
Filter contacts by sender account scope (via linked conversations). | No | All |
from_number |
Filter contacts by sender phone number scope. | No | All |
Tip: In multi-number usage, use one of these filters so results match /inbox/conversation-list scope.
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://www.voxio.chat/external-api/contact/store',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => array(
'firstname' => 'John',
'lastname' => 'Doe',
'mobile_code' => '62',
'mobile' => '85712345678',
'whatsapp_account_id' => '24'
),
CURLOPT_HTTPHEADER => array(
'client-id: YOUR-CLIENT-ID',
'client-secret: YOUR-CLIENT-SECRET',
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
Create New Contact
This endpoint allows you to add a new contact to your Voxio Chat account. Provide the necessary contact details, and upon successful request, the API returns the created contact’s information in JSON format for easy integration.
Note: For multi-number accounts, send whatsapp_account_id or
from_number so the contact is linked to the correct sender scope and appears in
/inbox/conversation-list.
Required Fields
The following fields are required to create a new contact in the system.
| Name | Required | Default |
|---|---|---|
firstname |
Yes | - |
lastname |
Yes | - |
mobile_code |
Yes | - |
mobile |
Yes | - |
city |
No | - |
state |
No | - |
post_code |
No | - |
address |
No | - |
profile_image |
No | - |
whatsapp_account_id |
No | Auto-resolved to default account |
from_number |
No | Auto-resolved to default account |
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://www.voxio.chat/external-api/contact/update/{contactId}',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => array(
'firstname' => 'John',
'lastname' => 'Doe',
'mobile_code' => '62',
'mobile' => '85712345678',
'whatsapp_account_id' => '24'
),
CURLOPT_HTTPHEADER => array(
'client-id: YOUR-CLIENT-ID',
'client-secret: YOUR-CLIENT-SECRET',
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
Update Contact
This endpoint updates an existing contact by ID. Send all required fields (firstname, lastname, mobile_code, mobile) plus any optional fields you want to update.
Note: For multi-number accounts, include whatsapp_account_id or
from_number to bind/update the contact scope so it appears in
/inbox/conversation-list filters.
Required Fields
The following fields are required to update a contact in the system.
| Name | Required | Default |
|---|---|---|
firstname |
Yes | - |
lastname |
Yes | - |
mobile_code |
Yes | - |
mobile |
Yes | - |
city |
No | - |
state |
No | - |
post_code |
No | - |
address |
No | - |
profile_image |
No | - |
whatsapp_account_id |
No | Keep current/default account |
from_number |
No | Keep current/default account |
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://www.voxio.chat/external-api/contact/delete/{contactId}',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => array(
'client-id: YOUR-CLIENT-ID',
'client-secret: YOUR-CLIENT-SECRET',
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
Delete Contact
This endpoint allows you to delete a contact by its unique ID. Deletion may be restricted if the contact has associated messages or is blocked.
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://www.voxio.chat/external-api/inbox/conversation-list',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'client-id: YOUR-CLIENT-ID',
'client-secret: YOUR-CLIENT-SECRET',
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
Conversation List
Retrieve a paginated list of conversations for the authenticated user, including contact info and conversation status.
Query Parameters
| Name | Description | Default |
|---|---|---|
status |
Filter conversations by status. Use below value for the filter conversation via status. Done = 1; Pending = 2; Important = 3; Unread = 4; Reset/All = 0; | All |
whatsapp_account_id |
Filter conversations by specific sender account ID. | All |
from_number |
Filter conversations by specific sender number. | All |
page |
Specifies the page number to retrieve. | 1 |
paginate |
Defines the number of items returned per page. | 20 |
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://www.voxio.chat/external-api/inbox/conversation-messages/{conversation_id}',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'client-id: YOUR-CLIENT-ID',
'client-secret: YOUR-CLIENT-SECRET'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
Conversation Messages
Fetch all messages of a specific conversation along with contact and media related information.
URL Parameters
| Parameter | Type | Description |
|---|---|---|
conversation_id |
integer | Unique ID of the conversation |
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://www.voxio.chat/external-api/inbox/change-conversation-status/2',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => array('status' => '1'),
CURLOPT_HTTPHEADER => array(
'client-id: YOUR-CLIENT-ID',
'client-secret: YOUR-CLIENT-SECRET',
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
Change Conversation Status
Update the status of a conversation. Allowed values: Done = 1, Pending = 2, Important = 3, Reset = 0.
URL Parameters
| Parameter | Type | Description |
|---|---|---|
conversation_id |
integer | Unique ID of the conversation |
Request Body
| Field | Type | Required |
|---|---|---|
status |
integer | Yes |
Allowed status values: 1 (Done), 2 (Pending), 3 (Important), 0 (Reset/None).
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://www.voxio.chat/external-api/inbox/conversation-details/2',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'client-id: YOUR-CLIENT-ID',
'client-secret: YOUR-CLIENT-SECRET',
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
Conversation Details
Retrieve complete details of a conversation including contact information, notes, tags, and list associations.
URL Parameters
| Parameter | Type | Description |
|---|---|---|
conversation_id |
integer | Unique ID of the conversation |
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://www.voxio.chat/external-api/inbox/send-message',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => array(
'mobile_code' => '880',
'mobile' => 'xxxxxxxxx',
'message' => 'Hello world',
'from_number' => '6281234567890'
),
CURLOPT_HTTPHEADER => array(
'client-id: YOUR-CLIENT-ID',
'client-secret: YOUR-CLIENT-SECRET',
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
Send Message
Send WhatsApp messages to a mobile number. This endpoint supports text, media, location, interactive lists, CTA URLs, and e-commerce messages. If no existing contact or conversation is found for the provided phone number, a new contact and conversation will be created automatically.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
mobile_code |
string | yes | Mobile country code. Must be a valid numeric country code without the plus (+) sign. |
mobile |
string | yes | A valid mobile phone number associated with the provided country code. |
from_number |
string | conditional | Optional sender number. Must match one of your connected WhatsApp numbers. Use this when your account has more than one number. |
whatsapp_account_id |
integer | Conditional | Optional sender account ID. If both whatsapp_account_id and from_number are provided, whatsapp_account_id is prioritized. |
message |
string | Conditional | Text message body. Required if no media, location, or interactive data is provided |
image |
file | No | Image file (jpg, jpeg, png – max 5MB) |
document |
file | No | Document file (pdf, doc, docx, xls, xlsx, txt – max 100MB) |
video |
file | No | Video file (mp4 – max 16MB) |
audio |
file | No | Audio file – max 16MB |
latitude |
decimal | Conditional | Latitude for location message |
longitude |
decimal | Conditional | Longitude for location message |
name |
string | No | Optional location label used with latitude/longitude. |
address |
string | No | Optional location address used with latitude/longitude. |
cta_url_id |
integer | No | CTA URL ID for interactive button messages |
interactive_list_id |
integer | No | Interactive list ID |
product |
json string | No | WooCommerce product payload. When provided, message is sent as interactive CTA product message. |
created_order_data |
json string | No | Created order payload for e-commerce CTA message generation. |
Notes
At least one message type must be provided.
When using multiple sender numbers, always set from_number or whatsapp_account_id to avoid sending from the wrong number.
Interactive messages require an active plan.
Blocked contacts cannot send or receive messages.
Response Status (Success / Failed)
| Field | Possible Value | Description |
|---|---|---|
status |
success / error |
Main request result. success = accepted for send, error = failed to send request. |
remark |
success, validation_error, not_found, exception |
Error or success category returned by API. |
data.message.status |
1, 2, 3, 9 |
Message state code in system: 1=SENT, 2=DELIVERED, 3=READ, 9=FAILED. |
Sample Success Response
{
"remark": "success",
"status": "success",
"message": [
"Message sent successfully"
],
"data": {
"conversation_id": 123,
"message": {
"id": 456,
"status": 1
}
}
}
Sample Failed Response
{
"remark": "exception",
"status": "error",
"message": [
"Something went wrong while sending message"
]
}
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://www.voxio.chat/external-api/inbox/send-template-message',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => array(
'mobile_code' => '880',
'mobile' => 'xxxxxx',
'template_id' => 'your template id',
'from_number' => '6281234567890'
),
CURLOPT_HTTPHEADER => array(
'client-id: YOUR-CLIENT-ID',
'client-secret: YOUR-CLIENT-SECRET',
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
Send Template Message
Send an approved WhatsApp template message using destination mobile number and sender account context. If no existing conversation is found, the system creates it automatically.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
mobile_code |
string | yes | Mobile country code. Must be a valid numeric country code without the plus (+) sign. |
mobile |
string | yes | A valid mobile phone number associated with the provided country code. |
from_number |
string | conditional | Optional sender number. Must match one of your connected WhatsApp numbers. Use this when your account has more than one number. |
whatsapp_account_id |
integer | conditional | Optional sender account ID. If both whatsapp_account_id and from_number are provided, whatsapp_account_id is prioritized. |
template_id |
integer | Yes | Approved WhatsApp template ID |
Notes
Only approved WhatsApp templates can be sent.
Template ID must belong to the selected sender number/account.
Template messages are typically used for business-initiated conversations.
Blocked contacts cannot receive template messages.
WhatsApp account must be connected before sending messages.
Response Status (Success / Failed)
| Field | Possible Value | Description |
|---|---|---|
status |
success / error |
Main request result. success = accepted for send, error = failed to send request. |
remark |
template_sent, validation_error, not_found, insufficient_balance, exception |
Error or success category returned by API. |
Sample Success Response
{
"remark": "template_sent",
"status": "success",
"message": [
"Message sent successfully"
],
"data": {
"conversation_id": 123
}
}
Sample Failed Response
{
"remark": "insufficient_balance",
"status": "error",
"message": [
"Insufficient template balance."
]
}
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://www.voxio.chat/external-api/inbox/template-list',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'client-id: YOUR-CLIENT-ID',
'client-secret: YOUR-CLIENT-SECRET',
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
Get Template List
This endpoint allows you to fetch all WhatsApp templates associated with your account.
Query Parameters
| Name | Description | Required |
|---|---|---|
whatsapp_account_id |
Filter templates by a specific sender account ID. | No |
from_number |
Filter templates by a specific sender number. | No |
conversation_id |
Filter templates using the sender account from a conversation. Used when sending template from chat context. | No |
Notes
For multi-number accounts, use one of the filter parameters above to avoid mixed template lists.
$payload = file_get_contents('php://input');
$timestamp = $_SERVER['HTTP_X_VOXIO_TIMESTAMP'] ?? '';
$signature = $_SERVER['HTTP_X_VOXIO_SIGNATURE'] ?? '';
$clientId = $_SERVER['HTTP_X_VOXIO_CLIENT_ID'] ?? '';
$clientSecret = $_SERVER['HTTP_X_VOXIO_CLIENT_SECRET'] ?? '';
// Relay Secret is configured in Voxio Inbound Relay settings.
// It is NOT sent in the request. It is used only as the HMAC signing key.
$relaySecret = 'YOUR_RELAY_SECRET';
$expectedClientId = 'YOUR_ACTIVE_CLIENT_ID';
$expectedClientSecret = 'YOUR_ACTIVE_CLIENT_SECRET';
$expected = 'sha256=' . hash_hmac('sha256', $timestamp . '.' . $payload, $relaySecret);
if (!hash_equals($expected, $signature)) {
http_response_code(401);
exit('Invalid signature');
}
if (!hash_equals($expectedClientId, $clientId) || !hash_equals($expectedClientSecret, $clientSecret)) {
http_response_code(401);
exit('Invalid client credential');
}
$event = $_SERVER['HTTP_X_VOXIO_EVENT'] ?? 'unknown';
$data = json_decode($payload, true);
http_response_code(200);
echo json_encode(['ok' => true, 'event' => $event]);
WhatsApp Inbound Relay
Inbound Relay forwards incoming WhatsApp events from Voxio to your own application endpoint. This is a server-to-server webhook delivery feature. It is different from calling the External API endpoints, but it still requires API Access to be enabled, active API credentials, and an IP whitelist on your Voxio account before it can be activated.
Activation Requirements
| Requirement | Description |
|---|---|
| Plan / Add-on | Your pricing plan or PAYG add-on must support WhatsApp Inbound Relay. |
| API Access | API Access must be enabled for your account. |
| Client ID / Secret | At least one active Client ID and Client Secret must exist in Developer Tools. |
| IP Whitelist | Your application server IP must be whitelisted in Voxio. |
| Relay URL | Your endpoint must be publicly reachable over HTTPS and should return HTTP 2xx quickly. |
| Relay Secret | Required when enabling Inbound Relay. This secret is configured in Voxio and used as the HMAC signing key for X-Voxio-Signature. It is never sent as a request header. |
Relay Secret vs Client Secret
| Secret | Purpose | Sent in Header? |
|---|---|---|
| Relay Secret | Used by Voxio to generate X-Voxio-Signature and by your server to verify the raw payload. This should be unique per relay endpoint. | No |
| Client Secret | Your active External API credential secret. Voxio sends it as an additional account-level access layer when dispatching relay events. | Yes, as X-Voxio-Client-Secret |
Headers Sent by Voxio
| Header | Description |
|---|---|
X-Voxio-Event |
Event name, for example incoming_message or message_status depending on your selected relay events. |
X-Voxio-Timestamp |
Unix timestamp used in signature verification. Reject old timestamps in your application to prevent replay. |
X-Voxio-Signature |
HMAC SHA-256 signature. Format: sha256=<hash>. |
X-Voxio-Client-Id |
Your active API Client ID. Use it as an extra account-level verification layer. |
X-Voxio-Client-Secret |
Your active API Client Secret. Store it securely and rotate it when needed. |
Signature Formula
To verify payload integrity, compute this value on your server with the Relay Secret configured in Voxio, then compare it with X-Voxio-Signature using a timing-safe comparison. Do not use the External API Client Secret as the HMAC key.
X-Voxio-Signature = sha256=HMAC_SHA256(X-Voxio-Timestamp + "." + raw_request_body, relay_secret)
Sample Payload
{
"event": "incoming_message",
"channel": "whatsapp",
"user_id": 11,
"whatsapp_account_id": 24,
"conversation": {
"id": 101,
"status": "open"
},
"contact": {
"id": 55,
"name": "Customer Name",
"mobile": "628123456789"
},
"message": {
"id": 9001,
"type": "text",
"text": "Hello",
"direction": "inbound",
"provider_message_id": "wamid.xxx"
},
"sent_at": "2026-06-16T14:30:00+07:00"
}
Recommended Receiver Behavior
Return HTTP 2xx as soon as the payload has been accepted. Process slow tasks asynchronously in your own system. Voxio treats non-2xx responses or timeouts as failed delivery attempts.
Always verify the HMAC signature, timestamp, Client ID, and Client Secret before trusting the payload. Keep your Relay Secret and Client Secret private. Rotate both secrets if they are exposed.