Send Message API Documentation
Overview
The /v2/send endpoint allows you to send messages through various channels, supporting both direct messages and template-based messages. It supports attachments, variable substitution via templates, and advanced message customization.
Note:
Each successful call to /v2/send will return a unique message key for the sent message. Any updates regarding the status or delivery of that message (such as delivered, failed, read, etc.) will be sent asynchronously to your webhook endpoint.
See Webhook Documentation for details on webhook payloads and message status updates.
Endpoint
- Method: POST
- Path:
/v2/send - Content-Type:
multipart/form-data
Form Fields
| Field | Type | Required | Description |
|---|---|---|---|
| message | string | No* | Message text. Required unless using tempMsgID with template auto-fill |
| messageType | string | Yes | Type of message (e.g., "whatsapp", etc.) |
| tempMsgID | string | No | Template message ID. If provided, can auto-fill json and message |
| username | string | No | Username of the sender |
| json | string | No* | JSON payload for advanced/template messages. Required unless using tempMsgID |
| params | string | No | Comma-separated values to substitute template variables ({{N}}) in json/message |
| forceSend | string | No | Boolean string ("true"/"false"). When "true", delivers the message even if the recipient has an ongoing session with an agent. Defaults to false. |
| attachmentList | file[] | No | One or more files to attach to the message |
* Either message or json must be provided unless tempMsgID is used to auto-fill them.
Validation & Business Rules
- If
tempMsgIDis present and bothjsonandmessageare missing, the handler will retrieve them from the template. - If the template contains variables (
{{N}}), theparamsfield must be provided. The number of params must match the number of unique variables in the template. - Each
{{N}}in the template will be replaced by the corresponding value fromparams(in order). - If the number of params does not match the number of variables, the request will be rejected.
- Attachments are supported via the
attachmentListfield (multiple files allowed). messageOutKeyis auto-generated for each message.- All form fields are sent as part of a
multipart/form-datarequest.
Example Requests
1. Simple Direct Message - WhatsApp
Form Data:
- message:
Hello, this is a direct message! - messageType:
whatsapp - username:
966500000000
2. Template Message with Variable Substitution - WhatsApp
Form Data:
- tempMsgID:
TEMPLATE_ID - params:
John,ORD-12345 - messageType:
whatsapp - username:
966500000000
Behavior: The handler will fetch the template by tempMsgID, substitute {{1}} with "John" and {{2}} with "ORD-12345" in the template's JSON/message, and send the result.
3. Message with Attachments - WhatsApp
Form Data:
- message:
Here is your document. - messageType:
whatsapp - username:
966500000000 - attachmentList:
[file1.pdf, file2.jpg]
4. direct Message For instagram
Form Data:
- message:
Hello, this is a direct message! - messageType:
instagram - username:
instagram_user - attachmentList:
[image1.jpg, video1.mp4]
Authentication (OTP) Messages
Authentication / one-time-password (OTP) messages are sent through the same /v2/send endpoint as any other message — there is no separate OTP endpoint. An OTP message is simply a template message whose template was created with the category AUTHENTICATION, and the code is passed in as a template variable via params.
How it works
- Create (and get approved) a template with category
AUTHENTICATIONwhose body contains a variable for the code, e.g.Your verification code is {{1}}. See the WhatsApp Templates documentation. - Generate the one-time code in your application.
- Call
/v2/sendwith the template'stempMsgIDand pass the code inparams. The value replaces{{1}}in the message the recipient receives.
Required fields
| Field | Required | Description |
|---|---|---|
| tempMsgID | Yes | ID of the approved AUTHENTICATION template |
| params | Yes | The one-time code (plus any other template variables, in order) |
| messageType | Yes | Channel to send on, e.g. whatsapp |
| username | No | Recipient identifier as used by your channel (see other examples above) |
Example — send a 6-digit OTP
Form Data:
- tempMsgID:
AUTH_TEMPLATE_ID - params:
483921 - messageType:
whatsapp - username:
966500000000 - forceSend:
true
Behavior: The handler fetches the AUTHENTICATION template by tempMsgID, substitutes {{1}} with 483921, and delivers "Your verification code is 483921" to the recipient.
Tip: Set
forceSend: trueon OTP messages. This guarantees the code is delivered to the customer even if they currently have an ongoing session with an agent, so time-sensitive verification codes are never held back. See the forceSend Parameter section below.
forceSend Parameter
forceSend is an optional boolean string ("true" / "false") on the /v2/send request. It guarantees the message is delivered even if the recipient currently has an ongoing session with an agent.
By default, when a customer is in an active conversation with a live agent, the gateway holds back automated / API messages so they do not interrupt that session. Setting forceSend to "true" overrides this behavior and delivers the message regardless of any ongoing agent session.
- Default:
false— omit the field for normal behavior (the message is held while the customer has an active agent session). "true": delivers the message even if the customer has an ongoing session with any agent.
When to use it
Use forceSend: "true" for messages that must always reach the customer regardless of agent activity — for example authentication / OTP codes, time-sensitive verification, or critical transactional alerts.
Impact on delivery
When forceSend is "true", the message is delivered even while the customer is in an active session with an agent. Use it deliberately, since it bypasses the safeguard that normally prevents automated messages from interrupting a live agent conversation.
Example
Form Data:
- message:
Hello, this is a direct message! - messageType:
whatsapp - username:
966500000000 - forceSend:
true
Error Handling
- 400 Bad Request:
- Failed to parse multipart form data
- Params count does not match number of variables in template
- 500 Internal Server Error:
- Failed to retrieve template by
tempMsgID - Failed to marshal or process data
- Failed to retrieve template by
- 502 Bad Gateway:
- Failed to call upstream service
Rate Limiting
Requests are rate limited at the API gateway (APISIX), per consumer (API key).
- Limit: 200 requests per hour per consumer
- Headers returned:
X-RateLimit-Limit: Maximum requests allowedX-RateLimit-Remaining: Remaining requests in the current windowX-RateLimit-Reset: Seconds until the rate limit resets
- When the limit is exceeded, the gateway responds with HTTP
429 Too Many Requests.