Send WhatsApp messages.
From your own application.
Connect your website, CRM, ERP or store to your business number with one secure, send-only API.
/api/v1/messages/send1. Prepare your workspace
- Sign in with your mobile OTP and connect your WhatsApp Business Account.
- Open WhatsApp numbers and copy the Sender ID for a ready number.
- Synchronise an approved template. Copy its exact name and language.
- Add your recipients in Contacts and record their actual consent. The API does not create contacts or accept consent booleans.
- Create a
messages.sendkey in API Access. Copy it once and store it in your backend’s environment.
2. Authenticate from your server
Authorization: Bearer sst_YOUR_API_KEY
Base URL: https://wab.sohansoft.in/api/v1
Never embed your key in browser JavaScript, Shopify theme code or public mobile bundles. Your Sohan key is separate from Meta tokens. The key determines the tenant; sending a tenant ID is not supported.
3. Send a message
Use the exact approved template name and language for your sender. This release supports positional text parameters in body and text header components, plus static URL/phone buttons. Media headers, named variables and dynamic/quick-reply buttons are rejected.
{
"sender_id": "SENDER_ID_FROM_DASHBOARD",
"to": "+919876543210",
"type": "template",
"template": {
"name": "order_confirmation",
"language": "en_US",
"components": [
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "Customer name"
},
{
"type": "text",
"text": "ORD-1001"
}
]
}
]
},
"idempotency_key": "order-1001-confirmation"
}curl --request POST 'https://wab.sohansoft.in/api/v1/messages/send' \
--header 'Authorization: Bearer YOUR_SOHAN_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"sender_id": "SENDER_ID_FROM_DASHBOARD",
"to": "+919876543210",
"type": "template",
"template": {
"name": "order_confirmation",
"language": "en_US",
"components": [
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "Customer name"
},
{
"type": "text",
"text": "ORD-1001"
}
]
}
]
},
"idempotency_key": "order-1001-confirmation"
}'Examples contain illustrative input. Replace the sender, recipient, template and parameters with your own records. The recipient must have appropriate recorded consent and must not be suppressed.
Download the send-only OpenAPI 3.1 contract ↗4. Understand the result
202 Accepted means queued, not delivered. The following is a documented example shape, not a live API response:
{"message_id":"SOHAN_MESSAGE_ID","status":"QUEUED","request_id":"REQUEST_UUID"}The response includes an X-Request-Id header. Follow delivery in your workspace. Status may become SENT, DELIVERED, READ or FAILED; UNKNOWN needs operator reconciliation. An exact retry returns the existing message and its current status.
Wallet pricing remains ₹0.23 + 18% GST = ₹0.2714 per delivered message; minimum recharge ₹200. A hold is reserved by the sender worker and captured once on delivery/read. Meta commercial charges remain separate.
Retry safely
Send an 8–120 character idempotency_key in JSON or an Idempotency-Key header. If you supply both, they must match. Reuse the same key and content for the same logical send. Different content returns 409. Never blindly resend UNKNOWN results.
| Status | Action |
|---|---|
| 400 / 415 | Fix JSON, E.164 number or template parameters. |
| 401 | Check your key, expiry and revocation. |
| 403 | Check plan, scope and active business status. |
| 404 | Use a sender belonging to your workspace. |
| 409 | Resolve consent, opt-out, service window, readiness or idempotency conflict. |
| 429 | Back off and retry with the same idempotency key. |
| 503 | Complete service setup before sending. |
Limits: 120 authorizations/minute per key and 600/minute per business. Provider throughput and additional controls also apply.
{"error":{"code":"WINDOW_CLOSED","message":"Use an approved template outside the customer service window"},"request_id":"REQUEST_UUID"}