Introduction
Welcome to the sidobe.com WhatsApp API v1 documentation. Before using the API service, make sure you have successfully registered your WhatsApp Devices on the dashboard and have obtained the Secret Key
for authentication.
Production URL: https://api.sidobe.com/wa/v1
Rate Limit
Response body JSON if reach limit rate limitting:
{
"message": "rate limit exceeded"
}
To provide a stable and reliable API service, we have introduced a rate limiter for our services that restricts the number of requests that can be made within a specific time frame.
If you exceed this limit, you will receive a http status code 429
indicating that you have exceeded the rate limit. To avoid this, we strongly recommend that you implement batch processing.
Please be aware that the rate limit is subject to change based on system load and performance, and we reserve the right to adjust the limit as necessary to maintain the stability of our API service.
Asynchronous (Async)
By default, sending a message is a synchronous operation where the API waits for the message to be processed before returning a response.
We provide asynchronous (async) processing in several features such as Send Message
, Send Message Image
, Send Message Doc
, etc.
Processing as async means handing over the process (ex: sending messages) to the Sidobe queue system, this will provide a faster API response, because your request is only registered in the Sidobe queue system, and waits for your request to be processed (as soon as possible ).
In contrast, if you request as synchronous (sync) or is_async = false
or do not include the is_async
payload, your request will be processed immediately but usually the API response will be slower, because there is some logic that must be carried out (ex : device verification, sending messages to WhatsApp, waiting for WhatsApp response, etc.). However, the advantage of this method is that you can immediately see the results of your request (ex: WhatsApp messages are sent immediately)
Authentication
curl --location 'https://api.sidobe.com/wa/v1' \
--header 'X-Secret-Key: 1234567' \
--header 'Content-Type: application/json'
Make sure to replace
1234567
with your Secret key.
For API authentication, we use a header to place the secret key with the header key X-Secret-Key
and all API requests must be included, for example:
X-Secret-Key: 1234567
You can get the Secret Key via the Developer Tools -> Credential menu on the dashboard
WhatsApp Messages
Send Message
curl --location 'https://api.sidobe.com/wa/v1/send-message' \
--header 'X-Secret-Key: 123123' \
--header 'Content-Type: application/json' \
--data '{
"phone": "+628123123123",
"message": "example message"
}'
The above command returns JSON structured like this:
{
"is_success": true,
"data": {
"id": "1",
"message_type": "TEXT",
"status": "SUCCESS",
"is_async": false
}
}
This endpoint is used to send WhatsApp messages to your destination/customer number.
HTTP Request
POST https://api.sidobe.com/wa/v1/send-message
Body params
Parameter | Type | Description |
---|---|---|
phone * | string | required The destination W.A number is in the format e164 (ex. +628xxxxxx) |
message * | string | required Messages WhatsApp |
is_async | boolean | optional When true , the message is sent asynchronously and status updates are delivered via webhook. See the Asynchronous section for details. Defaults to false . |
Response Body
Key | Type | Description |
---|---|---|
is_success | boolean | true if request successfully and false if request failed |
data.id | string | Unique ID for the message. This ID will be returned as data.whatsapp_message_id in the webhook payload. |
data.message_type | string | The type of message sent. Currently, there are 3 message types: TEXT , IMAGE , and DOCS . |
data.status | string | The delivery status of the message: whether it was successfully sent, is pending, or failed. Possible values: PENDING , SUCCESS , FAILED . |
data.is_async | boolean | Indicates whether the message was sent asynchronously (true ) or synchronously (false ). |
Send Message Image
curl --location 'https://api.sidobe.com/wa/v1/send-message-image' \
--header 'X-Secret-Key: 123123' \
--header 'Content-Type: application/json' \
--data '{
"phone": "+628123123123",
"message": "example message",
"image_url": "https://sidobe.com/wp-content/uploads/2023/09/logo-2.png"
}'
The above command returns JSON structured like this:
{
"is_success": true,
"data": {
"id": "1",
"message_type": "IMAGE",
"status": "SUCCESS",
"is_async": false
}
}
This endpoint is used to send WhatsApp messages with image to your destination/customer number.
HTTP Request
POST https://api.sidobe.com/wa/v1/send-message-image
Body params
Parameter | Type | Description |
---|---|---|
phone * | string | required The destination W.A number is in the format e164 (ex. +628xxxxxx) |
message | string | optional Messages or caption for the image |
image_url * | string | required URL of image, only image type jpg/jpeg & png are allowed, maximum size is 10 MB. |
is_async | boolean | optional When true , the message is sent asynchronously and status updates are delivered via webhook. See the Asynchronous section for details. Defaults to false . |
Response Body
Key | Type | Description |
---|---|---|
is_success | boolean | true if request successfully and false if request failed |
data.id | string | Unique ID for the message. This ID will be returned as data.whatsapp_message_id in the webhook payload. |
data.message_type | string | The type of message sent. Currently, there are 3 message types: TEXT , IMAGE , and DOCS . |
data.status | string | The delivery status of the message: whether it was successfully sent, is pending, or failed. Possible values: PENDING , SUCCESS , FAILED . |
data.is_async | boolean | Indicates whether the message was sent asynchronously (true ) or synchronously (false ). |
Send Message Document
curl --location 'https://api.sidobe.com/wa/v1/send-message-doc' \
--header 'X-Secret-Key: 123123' \
--header 'Content-Type: application/json' \
--data '{
"phone": "+628123123123",
"message": "example message",
"document_url": "https://sidobe.com/example.pdf",
"document_name": "Document Name Example"
}'
The above command returns JSON structured like this:
{
"is_success": true,
"data": {
"id": "1",
"message_type": "DOCS",
"status": "SUCCESS",
"is_async": false
}
}
This endpoint is used to send WhatsApp messages with document to your destination/customer number.
HTTP Request
POST https://api.sidobe.com/wa/v1/send-message-doc
Body params
Parameter | Type | Description |
---|---|---|
phone * | string | required The destination W.A number is in the format e164 (ex. +628xxxxxx) |
message | string | optional Messages or caption for the document |
document_url * | string | required URL of document, only docs type PDF , DOC , DOCX , PPT , PPTX , XLS and XLSX are allowed, maximum size is 10 MB. |
document_name * | string | required Name for the document to be sent, the name of this document will appear in the chat and as the file name when saved. There is no need to write the file extension, just the name. |
is_async | boolean | optional When true , the message is sent asynchronously and status updates are delivered via webhook. See the Asynchronous section for details. Defaults to false . |
Response Body
Key | Type | Description |
---|---|---|
is_success | boolean | true if request successfully and false if request failed |
data.id | string | Unique ID for the message. This ID will be returned as data.whatsapp_message_id in the webhook payload. |
data.message_type | string | The type of message sent. Currently, there are 3 message types: TEXT , IMAGE , and DOCS . |
data.status | string | The delivery status of the message: whether it was successfully sent, is pending, or failed. Possible values: PENDING , SUCCESS , FAILED . |
data.is_async | boolean | Indicates whether the message was sent asynchronously (true ) or synchronously (false ). |
Message Detail / Check Status
curl --location 'https://api.sidobe.com/wa/v1/whatsapp-messages/3c509654-1c28-4f27-81eb-0d129a5d6ecf' \
--header 'X-Secret-Key: 123123'
The above command returns JSON structured like this:
{
"is_success": true,
"data": {
"id": "3c509654-1c28-4f27-81eb-0d129a5d6ecf",
"whatsapp_device": {
"id": "cb8f65f7-6107-4fcb-a5e9-d9b2b87417a9",
"phone": "+6281123123123",
"name": "CS Number 1"
},
"message_type": "TEXT",
"status": "SUCCESS",
"is_async": false
}
}
This endpoint is used to retrieve the details and current status of a specific WhatsApp message that has been sent.
HTTP Request
GET https://api.sidobe.com/wa/v1/whatsapp-messages/:id
URL Parameters
Parameter | Type | Description |
---|---|---|
id * | string | required The unique identifier of the message, which you received in the data.id field when you first sent the message. |
Response Body
Key | Type | Description |
---|---|---|
is_success | boolean | true if request successfully and false if request failed |
data.id | string | Unique ID for the message. |
data.whatsapp_device | object | Contains details about the WhatsApp device used to send the message. |
data.whatsapp_device.id | string | The unique identifier for the WhatsApp device. |
data.whatsapp_device.phone | string | The phone number associated with the WhatsApp device. |
data.whatsapp_device.name | string | The name assigned to the WhatsApp device in the dashboard. |
data.message_type | string | The type of message sent. Possible values: TEXT , IMAGE , DOCS . |
data.status | string | The delivery status of the message. Possible values: PENDING , SUCCESS , FAILED . |
data.is_async | boolean | Indicates whether the message was sent asynchronously (true ) or synchronously (false ). |
WhatsApp Utilities
Check Phone Number
curl --location 'https://api.sidobe.com/wa/v1/utilities/check-number' \
--header 'X-Secret-Key: 123123' \
--header 'Content-Type: application/json' \
--data '{
"phone": "+628123123123"
}'
The above command returns JSON structured like this:
{
"is_success": true,
"data": {
"is_registered": true
}
}
This endpoint is used to check phone number is registered or used WhatsApp or not.
HTTP Request
POST https://api.sidobe.com/wa/v1/utilities/check-number
Body params
Parameter | Type | Description |
---|---|---|
phone * | string | required The phone number you want to check is whether it is registered on WhatsApp or not, format e164 (ex. +628xxxxxx) |
Response Body
Key | Type | Description |
---|---|---|
is_success | boolean | true if request successfully and false if request failed |
data.is_registered | boolean | true if phone number registered using WhatsApp and false if phone number not registered |
Webhook
Example webhook request with signature header:
POST /your-webhook-endpoint HTTP/1.1
Host: your-domain.com
Content-Type: application/json
X-Webhook-Signature: 26b2...a94f
{
"id": "816332ca-b91a-469d-b4f6-9a17f440c05e",
"event": "SEND_MESSAGE_STATUS",
"created_at": "2025-08-11T23:41:43.889693+07:00",
"data": {
"whatsapp_message_id": "4da0cb47-9059-4074-ae64-8a1c659693a0",
"status": "SUCCESS",
"send_at": "2025-08-11T23:41:43+07:00",
"message_type": "TEXT"
}
}
A webhook allows you to receive real-time HTTP notifications about events happening in the Sidobe system, such as message delivery status.
To start using webhooks, you must first configure your webhook endpoint URL in the Sidobe dashboard.
Setup
- Navigate to Sidobe Console.
- Open
Developer Tools -> Settings -> Webhook WhatsApp
. - Enter your publicly accessible endpoint URL and save.
Signature Verification
Example signature verification in Node.js
const crypto = require('crypto');
// Your secret key from the dashboard
const secretKey = 'YOUR_SECRET_KEY';
// Signature from request header
const receivedSignature = request.headers['x-webhook-signature'];
// Webhook ID from request body
const webhookId = request.body.id;
// Payload to be hashed
const payload = `${secretKey}|${webhookId}`;
const expectedSignature = crypto
.createHash('sha256')
.update(payload)
.digest('hex');
if (crypto.timingSafeEqual(Buffer.from(receivedSignature), Buffer.from(expectedSignature))) {
// Signature is valid, process webhook
console.log('Signature is valid.');
} else {
// Invalid signature, ignore request
console.error('Invalid signature.');
}
Sidobe signs each webhook event sent to your endpoint by including a signature in the X-Webhook-Signature
header.
This allows you to verify that the event was sent by Sidobe and not by a third party.
The signature is a SHA256 hash generated using your Secret Key
and the id
from the webhook payload.
The formula is: sha256(secretKey + "|" + webhookID)
Before you can verify the signature, you need to retrieve your Secret Key
from the dashboard.
Note: It is critical to verify the signature to ensure the request is legitimate and originated from Sidobe.
Webhook Events
Currently, we support the following webhook events:
Event | Description |
---|---|
SEND_MESSAGE_STATUS |
Triggered whenever the status of a sent message changes. |
SEND_MESSAGE_STATUS
Example
SEND_MESSAGE_STATUS
payload:
{
"id": "816332ca-b91a-469d-b4f6-9a17f440c05e",
"event": "SEND_MESSAGE_STATUS",
"created_at": "2025-08-11T23:41:43.889693+07:00",
"data": {
"whatsapp_message_id": "4da0cb47-9059-4074-ae64-8a1c659693a0",
"status": "SUCCESS",
"send_at": "2025-08-11T23:41:43+07:00",
"message_type": "TEXT"
}
}
This event is triggered whenever the status of a sent message changes.
Payload
Key | Type | Description |
---|---|---|
id | string | Unique identifier for the webhook event. This ID is used for signature verification. |
event | string | Type of event. In this case, it will always be SEND_MESSAGE_STATUS . |
created_at | string | Timestamp in ISO 8601 format indicating when the event was created. |
data.whatsapp_message_id | string | Message ID, which corresponds to the data.id you received when first sending the message. |
data.status | string | The new status of the message. Possible values: PENDING , SUCCESS , FAILED . |
data.send_at | string | Timestamp in ISO 8601 format indicating when the message was sent or when the sending attempt occurred. |
data.message_type | string | Type of message sent. Possible values: TEXT , IMAGE , DOCS . |
Delivery Rules
To ensure reliable delivery, Sidobe’s webhook system follows these rules:
- Success: Any HTTP status code in the
2xx
range (e.g.,200
,202
,204
) will be considered a successful delivery, and no retries will be attempted. - Retries: If your endpoint does not respond with a
2xx
HTTP status code, we will retry sending the webhook up to 3 times. - Timeout: We will wait up to 1 minute (60 seconds) for a response from your endpoint before considering the attempt failed.
Errors
HTTP Status Code
Sidobe.com uses conventional HTTP response codes to indicate the success or failure of an API request. In general: Codes in the 2xx range indicate success. Codes in the 4xx range indicate an error that failed given the information provided (e.g., a required parameter was omitted, invalid secret key, etc). Codes in the 5xx range indicate an error with servers.
Status Code | Description |
---|---|
2xx | Everything worked as expected |
400 | Bad Request -- Your request is invalid, please read Error Code section. |
401 | Unauthorized -- Your Secret Key is wrong. |
404 | Not Found -- The specified resource could not be found. |
429 | You have exceeded the rate limit. |
500 | Internal Server Error -- We had a problem with our server. Try again later. |
503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later. |
Error Code
Example failed request with error code:
{
"is_success": false,
"message": "The API key provided is invalid. Please make sure to use the secret/public API key that you can obtain from the Dashboard.",
"error_code": "INVALID_API_KEY"
}
Explanation of the error code in the API response:
Error Code | Meaning |
---|---|
API_VALIDATION_ERROR | Invalid request errors arise when your request has invalid parameters. |
INVALID_API_KEY | Unauthorized -- Your API key is wrong or issue. |
INVALID_REQUEST | Invalid request you can retry your request, If the request still fails, contact us to get a solution. |
INVALID_DEVICE_WHATSAPP | There is a problem with the WhatsApp device/account that you registered on the dashboard, please check whether your WhatsApp account has a problem, if there is no problem, please delete it and re-register it on the dashboard. |