Integrate SMS into your application in minutes. Create an account to get your API token.
The Blast SMS REST API lets you send SMS, check delivery and manage contacts from your own application. All requests and responses use JSON over HTTPS.
Create an API token under Developers in your dashboard and send it in the Authorization header on every request. Keep it secret; regenerate it if it leaks.
| Header | Required | Value |
|---|---|---|
| Authorization | Yes | Bearer YOUR_API_TOKEN |
| Accept | Yes | application/json |
| Content-Type | POST | application/json |
Rate limit: 120 requests per minute per token.
Successful calls return "status": "success" with a data object. Errors return "status": "error" and a human-readable message.
{ "status": "error", "message": "Insufficient SMS balance: 400 units needed, 120 available." }
| HTTP | Meaning |
|---|---|
| 200 | OK |
| 201 | Created / queued |
| 401 | Missing or invalid API token |
| 402 | Insufficient SMS balance |
| 403 | Account suspended |
| 404 | Resource not found |
| 422 | Validation failed (see errors) |
| 429 | Too many requests |
Message statuses: queued → sent → delivered, or failed / cancelled. Messages the network rejects at submission are refunded automatically.
Send one message to one or many numbers (up to 10,000 per request). Numbers can be local (07…, 01…) or international (2547…).
| Parameter | Required | Type | Description |
|---|---|---|---|
| sender_id | No | string | An active sender ID on your account. Omit to use your default sender ID. |
| phone | Yes | string|array | Comma-separated numbers or a JSON array |
| message | Yes | string | Message text (max 1600 characters) |
| schedule_time | No | datetime | Send later, e.g. 2026-12-24 09:00 (your account timezone) |
| client_reference | No | string | Your own ID, returned in status and webhooks |
curl -X POST https://www.blastsms.site/api/v1/sms/send \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json" -H "Content-Type: application/json" \
-d '{"sender_id":"BLASTSMS","phone":"0712345678,0798765432","message":"Hello from Blast SMS!"}'
{
"status": "success",
"message": "Message queued for delivery",
"data": {
"campaign_id": "k2j4h5g6f7d8s",
"status": "queued",
"recipients": 2,
"units": 2,
"cost": 0.70,
"balance": 998,
"invalid": [],
"blacklisted": 0,
"messages": [ { "uid": "a1b2c3…", "to": "254712345678", "status": "queued", "parts": 1 } ]
}
}
Send a personalised campaign to one or more contact groups. Use tags {first_name} {last_name} {name} {phone}.
{ "name": "December promo", "sender_id": "BLASTSMS", "group_ids": ["6065ecdc9184a"],
"message": "Hi {first_name}, enjoy 20% off this week!", "schedule_time": "2026-12-20 10:00" }
{ "message": "Hello 👋", "phone": "0712345678,0722000000" }
→ { "status": "success", "data": { "encoding": "unicode", "length": 8, "parts": 1, "recipients": 2, "units": 2, "rate": 0.35, "cost": 0.7, "balance": 1000, "sufficient": true } }
{ "status": "success", "data": { "uid": "a1b2c3…", "to": "254712345678", "from": "BLASTSMS", "status": "delivered",
"parts": 1, "units": 1, "cost": 0.35, "sent_at": "2026-10-22T10:00:02+03:00", "delivered_at": "2026-10-22T10:00:05+03:00" } }
Filters: status, phone, campaign_id, from_date, to_date, per_page (max 200), page. Responses include a meta pagination object.
Cancelling a scheduled or queued campaign refunds every unsent message.
For systems that can only call a URL, pass the token as api_key:
{ "status": "success", "data": { "sms_balance": 1250, "rate": 0.35, "currency": "KES", "estimated_value": 437.5 } }
Sender IDs you can send with right now.
Ledger of top-ups, charges and refunds in SMS units.
POST /contact-groups { "name": "VIP customers" }
→ { "status": "success", "data": { "uid": "6065ecdc9184a", "name": "VIP customers", "status": "active", "contacts": 0 } }
| Parameter | Required | Description |
|---|---|---|
| phone | Yes | Phone number of the contact |
| first_name | No | First name |
| last_name | No | Last name |
| No | Email address |
Set a webhook URL under Developers. Whenever a message status changes we POST JSON to it. Verify the X-Signature header: HMAC-SHA256 of the raw body, keyed with the SHA-256 hash of your API token. Failed deliveries are retried up to 5 times.
{ "event": "sms.status", "uid": "a1b2c3…", "to": "254712345678", "from": "BLASTSMS", "status": "delivered",
"parts": 1, "cost": 0.35, "client_reference": "order-1042", "delivered_at": "2026-10-22T10:00:05+03:00" }
<?php
$ch = curl_init('https://www.blastsms.site/api/v1/sms/send');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_TOKEN',
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'sender_id' => 'BLASTSMS',
'phone' => '0712345678',
'message' => 'Hello World! This is a test message.',
]),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);
import requests
r = requests.post(
"https://www.blastsms.site/api/v1/sms/send",
headers={"Authorization": "Bearer YOUR_API_TOKEN", "Accept": "application/json"},
json={"sender_id": "BLASTSMS", "phone": "0712345678", "message": "Hello World!"},
timeout=30,
)
print(r.json())
const res = await fetch('https://www.blastsms.site/api/v1/sms/send', {
method: 'POST',
headers: {
Authorization: 'Bearer YOUR_API_TOKEN',
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({ sender_id: 'BLASTSMS', phone: '0712345678', message: 'Hello World!' }),
});
console.log(await res.json());
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://www.blastsms.site/api/v1/sms/send"))
.header("Authorization", "Bearer YOUR_API_TOKEN")
.header("Accept", "application/json")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(
"{\"sender_id\":\"BLASTSMS\",\"phone\":\"0712345678\",\"message\":\"Hello World!\"}"))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());