SMS API documentation

Send SMS from your website, app or software with one HTTP request. Masking and non-masking, English and Bangla, single or bulk — with delivery status and balance checks.

Base URL
https://app.buysms.bd/api/v1
Auth
X-API-KEY header (or api_key parameter)
Format
JSON in, JSON out (UTF-8)
Numbers
01XXXXXXXXX, 8801XXXXXXXXX or +8801XXXXXXXXX
Time zone
Asia/Dhaka (UTC+6)
Currency
BDT (৳)

Quick start

1. Open an account and sign in to the panel at https://app.buysms.bd.

2. Go to Developer API and copy your API key. Keep it secret: anyone with the key can send SMS from your balance.

3. Send your first SMS:

cURL
curl -X POST "https://app.buysms.bd/api/v1/sms/send" \
  -H "X-API-KEY: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"to":"01711000000,01811000000","message":"Your OTP is 4821"}'
Response
{
  "success": true,
  "batch_id": "5f0c2a1e-7b1d-4c55-9a7e-2d1f0c9b8a10",
  "queued": 2,
  "parts": 2,
  "cost": 0.70,
  "balance": 199.30,
  "invalid_numbers": [],
  "messages": [
    { "id": "b1e2c3d4-0000-4000-8000-000000000001", "to": "8801711000000" },
    { "id": "c9d0e1f2-0000-4000-8000-000000000002", "to": "8801811000000" }
  ]
}

Authentication

Every request needs your API key. Send it in the X-API-KEY header (recommended), or as the api_key parameter in the query string, form fields or JSON body.

A wrong or missing key, or an inactive account, returns HTTP 401 with code invalid_api_key. You can regenerate the key in the panel at any time; the old key stops working immediately.

Header
X-API-KEY: YOUR_API_KEY

Send SMS

POST/api/v1/sms/send
GET/api/v1/sms/send?api_key=…&to=…&message=…

Send the same message to one or many numbers. The body can be JSON, form fields (application/x-www-form-urlencoded) or, for simple integrations, a GET query string.

ParameterRequiredDescription
to✔Mobile number. For several numbers, separate them with commas (also accepted: semicolon, space, new line). Up to 50,000 per request.
message✔SMS text in English or Bangla, up to 1,000 characters.
sender_id—Masking sender ID (brand name) assigned to your account. Leave empty or omit for non-masking.
api_key—Your API key, if you don't send the X-API-KEY header.
cURL (JSON)
curl -X POST "https://app.buysms.bd/api/v1/sms/send" \
  -H "X-API-KEY: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"to":"01711000000,01811000000","message":"Your OTP is 4821"}'
Response
{
  "success": true,
  "batch_id": "5f0c2a1e-7b1d-4c55-9a7e-2d1f0c9b8a10",
  "queued": 2,
  "parts": 2,
  "cost": 0.70,
  "balance": 199.30,
  "invalid_numbers": [],
  "messages": [
    { "id": "b1e2c3d4-0000-4000-8000-000000000001", "to": "8801711000000" },
    { "id": "c9d0e1f2-0000-4000-8000-000000000002", "to": "8801811000000" }
  ]
}
  • The request is charged immediately and every SMS goes into the delivery queue.
  • Invalid numbers are skipped and listed in invalid_numbers; the rest are sent.
  • Save each messages[].id to check its delivery status later.

Bulk SMS (a different message per number)

POST/api/v1/sms/bulk

Send personalised messages — a bill, an OTP, a name — to many numbers in one request (up to 50,000 items). The whole request is charged at once. JSON body only.

ParameterRequiredDescription
messages✔Array of { "to": "01XXXXXXXXX", "message": "text" } objects.
sender_id—Masking sender ID for every message in the request. Empty = non-masking.
api_key—Your API key, if you don't send the X-API-KEY header.
cURL
curl -X POST "https://app.buysms.bd/api/v1/sms/bulk" \
  -H "X-API-KEY: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sender_id": "",
    "messages": [
      { "to": "01711000000", "message": "Dear Rahim, your bill is 1,200 Tk." },
      { "to": "01811000000", "message": "প্রিয় করিম, আপনার বিল ৮৫০ টাকা।" }
    ]
  }'
Response
{
  "success": true,
  "batch_id": "5f0c2a1e-7b1d-4c55-9a7e-2d1f0c9b8a10",
  "queued": 2,
  "parts": 2,
  "cost": 0.70,
  "balance": 199.30,
  "invalid_numbers": [],
  "messages": [
    { "id": "b1e2c3d4-0000-4000-8000-000000000001", "to": "8801711000000" },
    { "id": "c9d0e1f2-0000-4000-8000-000000000002", "to": "8801811000000" }
  ]
}

Delivery status

GET/api/v1/sms/status/{id}

Check one message by the id returned when you sent it.

cURL
curl "https://app.buysms.bd/api/v1/sms/status/b1e2c3d4-0000-4000-8000-000000000001" \
  -H "X-API-KEY: YOUR_API_KEY"
Response
{
  "success": true,
  "id": "b1e2c3d4-0000-4000-8000-000000000001",
  "to": "8801711000000",
  "status": "sent",
  "parts": 1,
  "cost": 0.35,
  "error": null,
  "queued_at": "28 Sep 2026, 03:15 PM",
  "finished_at": "28 Sep 2026, 03:15 PM"
}
  • status is one of: queued (waiting), sending, sent (accepted by the operator), failed.
  • A failed SMS is refunded to your balance automatically; error says why.
  • Times are Bangladesh time. Message logs are kept for 3 months; older ids return 404 not_found.

Balance

GET/api/v1/balance

Your current balance, your per-SMS rates and the masking sender IDs you may use.

cURL
curl "https://app.buysms.bd/api/v1/balance" -H "X-API-KEY: YOUR_API_KEY"
Response
{
  "success": true,
  "balance": 199.30,
  "currency": "BDT",
  "rate_non_masking": 0.35,
  "rate_masking": 0.60,
  "masking_sender_ids": ["YourBrand"]
}

Errors

Errors return success: false, a machine-readable code and a human-readable error. Nothing is charged when a request fails.

Response
{
  "success": false,
  "code": "insufficient_balance",
  "error": "Insufficient balance. Needed ৳12.50, available ৳3.00.",
  "invalid_numbers": null
}
HTTPcodeMeaning
401invalid_api_keyKey missing or wrong, or the account is inactive.
402insufficient_balanceNot enough balance for the whole request. Nothing was queued.
400missing_to / missing_message / missing_messagesA required parameter is empty.
400invalid_jsonThe request body is not valid JSON.
400rejectedNo valid numbers, message too long, masking ID not assigned to you, too many recipients, etc. See error.
404not_foundUnknown message id, or its log was already deleted.

SMS length, masking and good practice

  • English (GSM) text: 160 characters in one SMS; longer messages are split into parts of 153.
  • Bangla or other Unicode text: 70 characters in one SMS; longer messages are split into parts of 67.
  • You are charged per part: cost = parts × your rate.
  • Numbers are Bangladeshi mobiles (013–019). 01XXXXXXXXX, 8801XXXXXXXXX and +8801XXXXXXXXX are all accepted and stored as 8801XXXXXXXXX.
  • Masking = your brand name as the sender (sender_id). Non-masking = a number as the sender (leave sender_id empty). Masking names are approved and assigned in the panel.
  • Keep your API key on your server. Never put it in a mobile app, a web page or a public repository.
  • Retry only on network errors or HTTP 5xx; a 4xx answer will fail again with the same input.

Machine-readable versions

For AI assistants, bots and code generators: