API, Testing & Error Codes
Authentication
https://sipesan.com/api/v1/business
Every request must include two authentication headers:
- Client-Key — Public Key — The Client-Key header holds your Public Key (starts with pk_). It identifies your API account and can be treated as public.
- Authorization — Secret Key — The Authorization header holds your Secret Key (starts with sk_) — with NO "Bearer" prefix. Keep it secret; never put it in frontend code.
Client-Key: pk_your_public_key
Authorization: sk_your_secret_key
Content-Type: application/json
Where to get your keys: Open the business panel → Developers menu group → API Access. There you will see your Public Key (pk_…) and Secret Key (sk_…). Create a new API Access if you do not have one yet.
How to Get channel_id
The channel_id parameter selects the sending channel. Each channel has a unique Channel ID you can copy from the business panel:
| Channel | How to get the Channel ID |
|---|---|
| Business panel → WhatsApp Channels menu. On the target channel row, click the Channel ID column value to copy it. | |
| WhatsApp Web (QR) | Business panel → WhatsApp Web menu. The channel must be Connected. Click the Channel ID column value on the target channel to copy it — use it as channel_id on the /waweb/broadcasts endpoint. |
| Telegram | Business panel → Telegram Channels menu. Click the Channel ID column value on the target channel to copy it. |
| Business panel → Instagram Channels menu. Click the Channel ID column value on the target channel to copy it. |
Endpoints
POST /api/v1/business/messages/send
/api/v1/business/messages/send
Send a message to a customer via a configured channel (WhatsApp, Telegram, etc). Supports text messages and rich media templates.
Auth: Client-Key + Authorization
Parameters
| Name | Type | Description |
|---|---|---|
channel_id
Required
|
string | The UUID of the sending channel. |
to
Required
|
string | Recipient's phone number (with country code) or Customer ID. |
message_body
|
string | The text content of the message. Used for plain text messages. |
message_components
|
object | Used for sending templates. Requires template_name and optional template_parameters. |
Text message
bashcurl --location 'https://chat.sipesan.com/api/v1/business/messages/send' \
--header 'Client-Key: pk_your_public_key' \
--header 'Authorization: sk_your_secret_key' \
--header 'Content-Type: application/json' \
--data '{
"channel_id": "a0da9833-97a2-4df8-9ef2-22ca0a97362b",
"to": "6285274784558",
"message_body": "Halo, pesanan Anda sudah dikirim."
}'
Template message (WhatsApp)
json{
"channel_id": "a0da9833-97a2-4df8-9ef2-22ca0a97362b",
"to": "6285274784558",
"message_components": {
"template_name": "pengiriman_paket",
"template_parameters": {
"header": {
"type": "IMAGE",
"image": { "link": "https://example.com/image.png" }
},
"body": [
{ "type": "text", "text": "pelanggan" },
{ "type": "text", "text": "JNE" },
{ "type": "text", "text": "airways1234656" }
]
}
}
}
Example Response
201{
"message": "Message is being processed",
"data": {
"id": "e145f8a2-...",
"phone_number": "6285274784558",
"status": "pending"
}
}
POST /api/v1/business/broadcasts
/api/v1/business/broadcasts
Create a WhatsApp template broadcast. The returned id is used as broadcast_id when sending per-recipient messages.
Auth: Client-Key + Authorization
Parameters
| Name | Type | Description |
|---|---|---|
name
Required
|
string | Broadcast name. |
channel_id
Required
|
string | WhatsApp channel UUID. |
template_name
Required
|
string | An APPROVED WhatsApp template name. |
template_language
|
string | Template language code, e.g. id / en_US. |
template_category
|
string | Template category (MARKETING/UTILITY). |
template_parameters
|
object | Default template parameters. |
Create broadcast
bashcurl --location 'https://chat.sipesan.com/api/v1/business/broadcasts' \
--header 'Client-Key: pk_your_public_key' \
--header 'Authorization: sk_your_secret_key' \
--header 'Content-Type: application/json' \
--data '{
"name": "Promo Juni",
"channel_id": "a0da9833-97a2-4df8-9ef2-22ca0a97362b",
"template_name": "promo_juni",
"template_language": "id",
"template_category": "MARKETING"
}'
Example Response
201{
"data": {
"id": "8d7c0b1e-...",
"name": "Promo Juni",
"template_name": "promo_juni",
"template_category": "MARKETING",
"status": "draft",
"created_at": "2026-06-05T12:00:00.000000Z"
},
"message": "Broadcast created. Use the id as broadcast_id when sending messages."
}
GET /api/v1/business/broadcasts/{broadcastId}
/api/v1/business/broadcasts/{broadcastId}
Fetch the status and delivery stats of a broadcast.
Auth: Client-Key + Authorization
Parameters
| Name | Type | Description |
|---|---|---|
broadcastId
Required
|
string | Broadcast UUID (path parameter). |
Check status
bashcurl --location 'https://chat.sipesan.com/api/v1/business/broadcasts/8d7c0b1e-...' \
--header 'Client-Key: pk_your_public_key' \
--header 'Authorization: sk_your_secret_key'
Example Response
200{
"data": {
"id": "8d7c0b1e-...",
"name": "Promo Juni",
"template_name": "promo_juni",
"status": "sending",
"total_recipients": 1200,
"sent_count": 800,
"delivered_count": 760,
"read_count": 540,
"replied_count": 32,
"failed_count": 8
}
}
POST /api/v1/business/waweb/broadcasts
/api/v1/business/waweb/broadcasts
Send a broadcast over the WhatsApp Web (QR) channel. Sending is auto-paced (anti-block): one message per randomised delay, with hourly/daily caps + optional business-hours/warmup. Text-only (v1), free. Spintax {a|b} is supported for message variation.
Auth: Client-Key + Authorization
Parameters
| Name | Type | Description |
|---|---|---|
channel_id
Required
|
string | UUID of a connected WhatsApp Web channel. |
message
Required
|
string | Text message body. Supports {a|b} spintax for variation. |
recipients
Required
|
array<string> | List of destination numbers (free format, auto-normalised & deduped). |
name
|
string | Broadcast name (optional). |
Send WA-Web broadcast
bashcurl --location 'https://chat.sipesan.com/api/v1/business/waweb/broadcasts' \
--header 'Client-Key: pk_your_public_key' \
--header 'Authorization: sk_your_secret_key' \
--header 'Content-Type: application/json' \
--data '{
"channel_id": "a0da9833-97a2-4df8-9ef2-22ca0a97362b",
"name": "Promo Juni",
"message": "{Halo|Hai} kak, ada promo Juni nih!",
"recipients": ["628111111111", "628222222222"]
}'
Example Response
201{
"data": {
"id": "8d7c0b1e-...",
"status": "sending",
"total_recipients": 2,
"created_at": "2026-06-19T12:00:00.000000Z"
},
"message": "WA-Web broadcast accepted and sending (paced)."
}
GET /api/v1/business/waweb/broadcasts/{broadcastId}
/api/v1/business/waweb/broadcasts/{broadcastId}
Fetch the status & delivery stats of a WhatsApp Web broadcast (sent/delivered/read/failed). Delivered & read are also pushed in real time to your delivery-status webhook.
Auth: Client-Key + Authorization
Parameters
| Name | Type | Description |
|---|---|---|
broadcastId
Required
|
string | Broadcast UUID (path parameter). |
Check status
bashcurl --location 'https://chat.sipesan.com/api/v1/business/waweb/broadcasts/8d7c0b1e-...' \
--header 'Client-Key: pk_your_public_key' \
--header 'Authorization: sk_your_secret_key'
Example Response
200{
"data": {
"id": "8d7c0b1e-...",
"status": "sending",
"total_recipients": 2,
"sent_count": 1,
"delivered_count": 1,
"read_count": 0,
"failed_count": 0,
"started_at": "2026-06-19T12:00:00.000000Z",
"completed_at": null
}
}
Error Codes
| Status | Code | Meaning | When |
|---|---|---|---|
| 401 | unauthenticated |
Missing or invalid token. | Wrong Authorization header or expired token. |
| 403 | forbidden |
No permission for this resource. | Cross-tenant access or insufficient role. |
| 404 | not_found |
Resource not found. | Wrong ID or belongs to another business. |
| 422 | validation_error |
Input failed validation. | Body returns {message, errors:{field:[...]}}. |
| 429 | too_many_requests |
Rate limit exceeded. | See the Retry-After header. |
| 500 | server_error |
Unexpected server error. | Check logs; contact support if persistent. |
| 0 | ai_provider_not_configured |
AI provider not configured (internal). | AiProviderException::notConfigured() — API key missing. |