Skip to content

Send an instant SMS

sending_type: "immediate" (the default) queues the SMS for immediate carrier dispatch. The body shape is the same whether you’re sending to one number or a thousand — only the size of the to array changes.

Terminal window
curl $BASE_URL/api/v1/lisoloo/sms-api/send \
-X POST \
-H "app-key: $LISOLOO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": ["+243998857000"],
"message": "Your OTP is 482194. Valid for 5 minutes.",
"sender_id": "MYAPP"
}'

to is always an array. Pass up to 1 000 numbers in a single call. Each number is billed independently against your unit_price.

Terminal window
curl $BASE_URL/api/v1/lisoloo/sms-api/send \
-X POST \
-H "app-key: $LISOLOO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": [
"+243998857000",
"+243998857001",
"+243998857002"
],
"message": "Class is cancelled today. See you next week.",
"sender_id": "SCHOOL"
}'

The response includes total_recipients and total_messages:

{
"status_code": 201,
"success": true,
"data": {
"message_id": "507f1f77bcf86cd799439011",
"total_recipients": 3,
"total_messages": 3,
"total_cost": 0.06,
"currency": "USD",
"status": "pending"
}
}

For larger campaigns split into batches of ≤1 000, spaced ≥1 second apart to stay under the 60/min rate limit on POST /send. A simple chunked sender:

def chunks(seq, size):
for i in range(0, len(seq), size):
yield seq[i:i + size]
for batch in chunks(all_recipients, 1000):
requests.post(SEND_URL, headers=HEADERS, json={
"to": batch, "message": MESSAGE, "sender_id": SENDER,
}).raise_for_status()
time.sleep(1.1)

Each batch returns its own message_id. Track them all if you need cross-batch reporting.

If you want this specific batch’s delivery receipts to go to a different endpoint than the merchant-wide webhook, set callback_url on the request:

{
"to": ["+243998857000"],
"message": "Your delivery is on the way.",
"sender_id": "SHOP",
"callback_url": "https://my-shop.example.com/lisoloo/webhook"
}

The callback_url is per-message; it does not override the merchant-wide webhook (both fire if both are set). See Webhooks overview.

sender_id is the alphanumeric origin string the carrier displays on the recipient’s handset. Constraints:

  • 3–11 characters (carrier-imposed; longer values are truncated by the network).
  • A–Z, 0–9. No spaces, no punctuation.
  • Pre-registered with your Bloonio account. Unregistered IDs may be rewritten by the carrier to a generic shortcode.

If omitted, the gateway uses your merchant default (set in the dashboard).