- 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 -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"}'
{
"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.
X-API-KEY: YOUR_API_KEY
Send SMS
/api/v1/sms/send/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.
| Parameter | Required | Description |
|---|---|---|
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 -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"}'
https://app.buysms.bd/api/v1/sms/send?api_key=YOUR_API_KEY&to=01711000000&message=Hello%20from%20BuySMS
curl -X POST "https://app.buysms.bd/api/v1/sms/send" \
-d "api_key=YOUR_API_KEY" \
-d "to=01711000000" \
--data-urlencode "message=আপনার অর্ডার পাঠানো হয়েছে"
<?php
$ch = curl_init("https://app.buysms.bd/api/v1/sms/send");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["X-API-KEY: YOUR_API_KEY", "Content-Type: application/json"],
CURLOPT_POSTFIELDS => json_encode([
"to" => "01711000000",
"message" => "আপনার অর্ডার পাঠানো হয়েছে",
"sender_id" => "YourBrand", // masking; leave "" for non-masking
]),
]);
$result = json_decode(curl_exec($ch), true);
echo $result["success"] ? "Queued: " . $result["batch_id"] : $result["error"];
import requests
r = requests.post("https://app.buysms.bd/api/v1/sms/send",
headers={"X-API-KEY": "YOUR_API_KEY"},
json={"to": "01711000000", "message": "Your OTP is 4821"})
data = r.json()
print(data["messages"][0]["id"] if data["success"] else data["error"])
const res = await fetch("https://app.buysms.bd/api/v1/sms/send", {
method: "POST",
headers: { "X-API-KEY": "YOUR_API_KEY", "Content-Type": "application/json" },
body: JSON.stringify({ to: "01711000000", message: "Your OTP is 4821" })
});
console.log(await res.json());
using System.Net.Http.Json;
using var http = new HttpClient();
http.DefaultRequestHeaders.Add("X-API-KEY", "YOUR_API_KEY");
var res = await http.PostAsJsonAsync("https://app.buysms.bd/api/v1/sms/send",
new { to = "01711000000", message = "Your OTP is 4821" });
Console.WriteLine(await res.Content.ReadAsStringAsync());
{
"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)
/api/v1/sms/bulkSend 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.
| Parameter | Required | Description |
|---|---|---|
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 -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": "প্রিয় করিম, আপনার বিল ৮৫০ টাকা।" }
]
}'
import requests
rows = [("01711000000", "Rahim", 1200), ("01811000000", "Karim", 850)]
r = requests.post("https://app.buysms.bd/api/v1/sms/bulk",
headers={"X-API-KEY": "YOUR_API_KEY"},
json={"messages": [{"to": n, "message": f"Dear {name}, your bill is {amt} Tk."} for n, name, amt in rows]})
print(r.json())
{
"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
/api/v1/sms/status/{id}Check one message by the id returned when you sent it.
curl "https://app.buysms.bd/api/v1/sms/status/b1e2c3d4-0000-4000-8000-000000000001" \
-H "X-API-KEY: YOUR_API_KEY"
{
"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
/api/v1/balanceYour current balance, your per-SMS rates and the masking sender IDs you may use.
curl "https://app.buysms.bd/api/v1/balance" -H "X-API-KEY: YOUR_API_KEY"
{
"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.
{
"success": false,
"code": "insufficient_balance",
"error": "Insufficient balance. Needed ৳12.50, available ৳3.00.",
"invalid_numbers": null
}
| HTTP | code | Meaning |
|---|---|---|
| 401 | invalid_api_key | Key missing or wrong, or the account is inactive. |
| 402 | insufficient_balance | Not enough balance for the whole request. Nothing was queued. |
| 400 | missing_to / missing_message / missing_messages | A required parameter is empty. |
| 400 | invalid_json | The request body is not valid JSON. |
| 400 | rejected | No valid numbers, message too long, masking ID not assigned to you, too many recipients, etc. See error. |
| 404 | not_found | Unknown 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:
- https://buysms.bd/en/api.md — Markdown
- https://buysms.bd/openapi.json — OpenAPI 3.0
- https://buysms.bd/llms.txt — llms.txt