Introduction
The WhatsRay 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 WhatsRay 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://wpp.raybeamdigital.com/external-api
Authentication
All requests to the WhatsRay 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 WhatsRay Dashboard under Developer Tools.
In addition to credentials, WhatsRay 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.
How API Access Works
Your application sends requests to the WhatsRay External API. WhatsRay authenticates the request, selects your connected WhatsApp number, sends the request to Meta's WhatsApp Cloud API, and saves the resulting conversation and message in your WhatsRay inbox.
Your application
→ WhatsRay External API
→ Your connected WhatsApp Business number
→ Meta WhatsApp Cloud API
→ Recipient
Your application does not need direct access to the Meta access token stored by WhatsRay. Keep your
WhatsRay client-id and client-secret on your server and never expose them in
browser JavaScript, a mobile application, a public repository, or screenshots.
Before You Start
Complete all of the following before making your first request:
- Activate a WhatsRay subscription that includes API access.
- Connect and verify at least one WhatsApp Business number in WhatsRay.
- Create or synchronize the required WhatsApp template and confirm that Meta has approved it.
- Copy your
client-idandclient-secretfrom Developer Tools. - Add the public outbound IP address of the server running your application to API IP Address White List.
- Call
GET /external-api/whatsapp-account/listto obtain the sending account ID. - Call
GET /external-api/inbox/template-list?whatsapp_account_id=ACCOUNT_ID&status=approvedto obtain a usable template ID.
API requests use the live environment; there is currently no sandbox. Test with a controlled recipient and verified request values before using the integration in production.
IP Whitelisting Explained
The whitelist must contain the public outbound IP address of the server that calls this API.
It is not the recipient's IP, the connected WhatsApp number, or a private network address such as
192.168.x.x, 10.x.x.x, or 172.16.x.x.
Application server public outbound IP: 203.0.113.50 IP saved in WhatsRay whitelist: 203.0.113.50
How to identify the correct IP
Make a test API request from the same server and network that will run the production integration. If the IP is not approved, the API error response displays the address detected by WhatsRay. Add that exact address in Dashboard → API IP Address White List, then retry.
When the API is reached through Cloudflare, WhatsRay accepts the forwarded client address only when the direct connection comes from Cloudflare's trusted network ranges. Forwarded IP headers sent directly by an untrusted caller are ignored, preventing them from impersonating a whitelisted address.
Changing or dynamic IP addresses
Whitelist entries are exact IP addresses. CIDR ranges and wildcard addresses are not supported. If your hosting provider rotates outbound IPs, requests will stop working when the address changes. Use a static public IP, static NAT gateway, or fixed-egress proxy. You may add multiple fixed server IPs when your integration legitimately sends requests from more than one server.
Do not solve a changing-IP problem by sharing API credentials or adding unrelated addresses. Rotate the client secret immediately if it is exposed.
Send Your First Template Message
1. Get the WhatsApp account ID
Call GET /external-api/whatsapp-account/list. Select an account whose
connection_status is connected, and use its id as
whatsapp_account_id.
curl --request GET 'https://wpp.raybeamdigital.com/external-api/whatsapp-account/list' \
--header 'client-id: YOUR-CLIENT-ID' \
--header 'client-secret: YOUR-CLIENT-SECRET'2. Get the template ID
Call the template-list endpoint using your credentials. The id returned for a template is the
WhatsRay template ID required by send-template-message. Do not substitute
the Meta template name or another Meta identifier.
curl --request GET 'https://wpp.raybeamdigital.com/external-api/inbox/template-list?whatsapp_account_id=12&status=approved' \
--header 'client-id: YOUR-CLIENT-ID' \
--header 'client-secret: YOUR-CLIENT-SECRET'3. Send the approved template
Supply the recipient, the returned template ID, and every required header/body variable. When more than one
WhatsApp number is connected, always provide whatsapp_account_id so the sending number is explicit.
curl --request POST 'https://wpp.raybeamdigital.com/external-api/inbox/send-template-message' \
--header 'client-id: YOUR-CLIENT-ID' \
--header 'client-secret: YOUR-CLIENT-SECRET' \
--form 'whatsapp_account_id=12' \
--form 'mobile_code=94' \
--form 'mobile=771234567' \
--form 'template_id=45' \
--form 'body_variables[name]=John' \
--form 'body_variables[date]=2026-08-11'The API finds or creates the contact and conversation, verifies that the template is approved for the selected WhatsApp account, sends it through Meta, records the outgoing message, and returns the conversation and message data.
Common Problems
| Error | Meaning and action |
|---|---|
401 Unauthorized | Check both credential headers and whitelist the public IP shown in the response. |
subscription_required | The account has no active subscription. Renew or activate an eligible plan. |
not_available | The current plan does not include External API access. |
The whatsapp account is not found | Use an account ID, Meta phone-number ID, or sending number that belongs to this WhatsRay account. |
The template is not found | Confirm the WhatsRay template ID, selected WhatsApp account, and Meta approval status. |
validation_error | Review required recipient fields and provide all template placeholder variables using the correct names or numbers. |
Response Format
All responses from the WhatsRay 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 list 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 (203.0.113.50) to the white list from the user dashboard."
]
}
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://wpp.raybeamdigital.com/external-api/contact/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 Contact List
This endpoint allows you to retrieve a complete list of contacts associated with your WhatsRay 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 | - |
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://wpp.raybeamdigital.com/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' => '880','mobile' => '01988'),
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 WhatsRay account. Provide the necessary contact details, and upon successful request, the API returns the created contact’s information in JSON format for easy integration.
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 | - |
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://wpp.raybeamdigital.com/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' => '880','mobile' => '01988'),
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 allows you to update an existing contact. You only need to send the fields you want to modify. Any field not included in the request will remain unchanged.
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 | - |
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://wpp.raybeamdigital.com/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_POSTFIELDS => array('firstname' => 'John','lastname' => 'Doe','mobile_code' => '880','mobile' => '01988'),
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 --request GET 'https://wpp.raybeamdigital.com/external-api/whatsapp-account/list' \
--header 'client-id: YOUR-CLIENT-ID' \
--header 'client-secret: YOUR-CLIENT-SECRET'Get WhatsApp Account List
List the WhatsApp Business numbers available to your API credentials. Use the returned id as whatsapp_account_id in message and template requests.
Example Response
{
"status": "success",
"data": {
"whatsapp_accounts": [
{
"id": 12,
"business_name": "Example Business",
"phone_number": "+94 77 123 4567",
"phone_number_id": "123456789012345",
"is_default": true,
"connection_status": "connected",
"verification_status": "verified"
}
]
}
}id is the WhatsRay WhatsApp account ID used as whatsapp_account_id.
phone_number_id is Meta's phone-number ID. It can also select a sending account where an endpoint supports it.
is_default identifies the account used when no sending-account selector is supplied.
No Meta access tokens or private account credentials are returned by this endpoint.
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://wpp.raybeamdigital.com/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; | 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://wpp.raybeamdigital.com/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 such as pending, done, or important. Here Done = 1, Pending = 2 and Important = 3,UnRead=4
URL Parameters
| Parameter | Type | Description |
|---|---|---|
conversation_id |
integer | Unique ID of the conversation |
Request Body
| Field | Type | Required |
|---|---|---|
status |
integer | YEs |
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://wpp.raybeamdigital.com/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_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;
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://wpp.raybeamdigital.com/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'),
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 | A valid WhatsApp Business phone number registered on your account and in the Meta dashboard is required. If no ID is provided, the message will be sent using your default registered WhatsApp account. |
whatsapp_account_id |
integer | conditional | Connected WhatsRay WhatsApp account ID to send from. Prefer this field when your account has multiple connected numbers. |
phone_number_id |
string | conditional | Meta WhatsApp phone number ID to send from. This can be used instead of from_number. |
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 – 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 |
cta_url_id |
integer | No | CTA URL ID for interactive button messages |
interactive_list_id |
integer | No | Interactive list ID |
Notes
At least one message type must be provided.
Interactive messages require an active plan.
Blocked contacts cannot send or receive messages.
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://wpp.raybeamdigital.com/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' => '94',
'mobile' => '771234567',
'template_id' => 'your template id',
'body_variables[date]' => '2026-05-27',
'body_variables[time]' => '20:00 PM',
'body_variables[number]' => '0771234567',
'body_variables[name]' => 'Pasindu',
'body_variables[package]' => 'Panchakarma',
'body_variables[amount]' => '9000.00'
),
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 to a recipient. If the contact or conversation does not already exist, WhatsRay creates it automatically before sending.
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 | A valid WhatsApp Business phone number registered on your account and in the Meta dashboard is required. If no ID is provided, the message will be sent using your default registered WhatsApp account. |
whatsapp_account_id |
integer | conditional | Connected WhatsRay WhatsApp account ID to send from. Prefer this field when your account has multiple connected numbers. |
phone_number_id |
string | conditional | Meta WhatsApp phone number ID to send from. This can be used instead of from_number. |
template_id |
integer | Yes | Approved WhatsRay template ID returned by GET /external-api/inbox/template-list. This is not the Meta template name. |
body_variables |
array | conditional | Body variable values for templates with placeholders. For named placeholders, use the placeholder name as the key, for example body_variables[date]. For numeric placeholders, use the number as the key, for example body_variables[1]. |
header_variables |
array | conditional | Header variable values for templates with text header placeholders. Use the same key style as body_variables. |
Notes
Only approved WhatsApp templates can be sent.
If your template has variables, every required header/body variable must be provided. Named placeholders such as {{date}} must be sent using the same name as the array key.
Template messages are typically used for business-initiated conversations.
Blocked contacts cannot receive template messages.
WhatsApp account must be connected before sending messages.
When multiple WhatsApp numbers are connected, provide whatsapp_account_id to explicitly select the sending number.
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://wpp.raybeamdigital.com/external-api/inbox/template-list?whatsapp_account_id=12&status=approved',
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
Fetch templates stored in your WhatsRay account. Use the returned id value as template_id when calling the Send Template Message endpoint. Only templates approved for the selected sending account can be sent.
Query Parameters
| Field | Required | Description |
|---|---|---|
whatsapp_account_id | No | Return templates belonging to one connected WhatsApp account. |
status | No | One of all, approved, pending, rejected, or disabled. Default: all. |
For sending, use status=approved and pass the same whatsapp_account_id to the send-template request.