// POST /messages
Send a message
Send an SMS to one or many recipients. The request returns immediately; delivery happens in the background so nothing fails at the caller side.
curl -X POST https://api.eksms.com/v1/messages \
-H "X-API-Key: eksms_live_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-2048-otp" \
-d '{
"recipients": ["9818000000", "9808000001"],
"text": "Your EK SMS code is 481920",
"senderId": "EKSMS",
"callbackUrl": "https://your-app.com/webhooks/sms"
}'
Request parameters
| Field | Type | Description |
|---|---|---|
| recipients | string[] | Required. 1-1000 Nepali mobile numbers, 10 digits (e.g. 9818000000). +977 / 977 prefixes are normalized away. |
| text | string | Required. The message body, 1-2000 chars. Unicode (Nepali/Devanagari) is supported. |
| senderId | string | Optional, max 11 chars. Falls back to your account default (a shared approved sender ID) when omitted. |
| callbackUrl | string | Optional HTTPS URL. Receives HMAC-signed delivery webhooks for this batch. |
Headers
| Header | Description |
|---|---|
| X-API-Key | Required. Your API key with the messages:send scope. |
| Idempotency-Key | Recommended. Makes retries exactly-once (see below). |
| Content-Type | application/json |
Response
On success the API returns 202 with the batch summary. The message rows are created and credits debited atomically before the call returns; the actual send happens on a background queue.
{
"status": "success",
"statusCode": 202,
"message": "OK",
"data": {
"batchId": "28750054-c6f9-4ade-9ebd-6f87bd108c09",
"accepted": 2,
"totalCostNpr": 2.8,
"segments": 1,
"encoding": "GSM7",
"status": "QUEUED",
"replayed": false
}
}
Idempotency
Pass a unique Idempotency-Key header to guarantee a message is sent exactly once, even if your request times out and you retry. A replay with the same key returns the original batch with replayed: true and is never charged twice.
Use a natural key
otp-<userId>-<timestamp> or order-<id>-confirm - so a retry of the same business action reuses it automatically.Billing & segments
You are charged per segment, per recipient, in NPR. Segment count depends on encoding:
| Encoding | Single segment | Per concatenated segment |
|---|---|---|
| GSM-7 | 160 chars | 153 chars |
| Unicode (UCS-2) | 70 chars | 67 chars |
Any character outside the GSM-7 set (including Devanagari) switches the whole message to Unicode. Cost = segments × recipients × rate (default NPR 1.40 per segment). If a recipient is rejected upstream, its credits are automatically refunded.
Recipients
Message
Next: Delivery & webhooks · Errors