API Reference · v1
Documentation
The SMS Nepal API by Twozero lets you send messages, check delivery status and manage your account programmatically over HTTPS. Every response is JSON. Every send returns a receipt.
KYC verification required
Until your KYC is approved you can only send test messages to your own registered number. Complete verification from your dashboard to unlock full sending.
Quick start
- 01 Create an account at sms.twozero.io
- 02 Complete KYC verification for full access
- 03 Generate an API key from your dashboard
- 04 Send your first message with the API
Authentication
All requests are authenticated with an API key generated from your client dashboard. Keys are prefixed with
sk_ followed by a 60-character string.
X-API-Key: sk_your_api_key_here
You may also pass the key as an api_key query parameter, but the header is preferred for security.
Base URL
All endpoints are relative to the production base URL:
https://sms.twozero.io/api/v1
Rate limits
Requests are rate-limited per API key to ensure fair usage.
| Endpoint | Limit |
|---|---|
| Send SMS | 100 / minute |
| Send Bulk SMS | 10 / minute |
| Status / History / Balance | 300 / minute |
Send SMS
Send a single message to one recipient.
POST /api/v1/sms/send
Parameters
|
to
string ·
required
|
Nepal phone number (+977XXXXXXXXXX, 977XXXXXXXXXX, or 10 digits). |
|
message
string ·
required
|
Message content, up to 1600 characters. |
|
sender_id
string ·
optional
|
Sender ID, up to 11 characters. Defaults to your account setting. |
Example request
curl -X POST "https://sms.twozero.io/api/v1/sms/send" \
-H "X-API-Key: sk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"to": "9841234567",
"message": "Hello! This is a test message.",
"sender_id": "TZLABS"
}'
Success · 200
{
"status": "success",
"message": "SMS sent successfully",
"data": {
"message_id": "msg_abc123def456",
"to": "9841234567",
"credits_used": 1,
"status": "sent"
}
}
Error · 400
{
"status": "error",
"message": "Insufficient credits",
"data": null
}
Send bulk SMS
Send the same message to many recipients in one request.
POST /api/v1/sms/send-bulk
Parameters
|
recipients
array ·
required
|
Array of Nepal phone numbers, up to 1000 per request. |
|
message
string ·
required
|
Message content, up to 1600 characters. |
|
sender_id
string ·
optional
|
Sender ID, up to 11 characters. |
Example request
curl -X POST "https://sms.twozero.io/api/v1/sms/send-bulk" \
-H "X-API-Key: sk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"recipients": ["9841234567", "9851234567", "9861234567"],
"message": "Special offer! Get 20% off today.",
"sender_id": "TZLABS"
}'
Success · 200
{
"status": "success",
"message": "Bulk SMS processed: 3 sent, 0 failed",
"data": {
"total": 3,
"success": 3,
"failed": 0,
"credits_used": 3,
"results": [
{"success": true, "message_id": "msg_abc123", "recipient": "9841234567"},
{"success": true, "message_id": "msg_def456", "recipient": "9851234567"},
{"success": true, "message_id": "msg_ghi789", "recipient": "9861234567"}
]
}
}
Message status
Check the delivery status of a sent message.
GET /api/v1/sms/status/{message_id}
Example request
curl -X GET "https://sms.twozero.io/api/v1/sms/status/msg_abc123def456" \
-H "X-API-Key: sk_your_api_key_here"
Success · 200
{
"status": "success",
"data": {
"message_id": "msg_abc123def456",
"recipient": "9841234567",
"sender_id": "TZLABS",
"status": "delivered",
"credits_used": 1,
"sent_at": "2026-01-15T10:30:00+05:45",
"delivered_at": "2026-01-15T10:30:05+05:45",
"created_at": "2026-01-15T10:29:58+05:45"
}
}
Message history
Retrieve past messages with pagination and filtering.
GET /api/v1/sms/history
Query parameters
page (default 1) ·
per_page (default 50, max 100) ·
status ·
from_date ·
to_date
Example request
curl -X GET "https://sms.twozero.io/api/v1/sms/history?page=1&per_page=20&status=sent" \
-H "X-API-Key: sk_your_api_key_here"
Check balance
Return your current credit balance and KYC status.
GET /api/v1/account/balance
Example request
curl -X GET "https://sms.twozero.io/api/v1/account/balance" \
-H "X-API-Key: sk_your_api_key_here"
Success · 200
{
"status": "success",
"data": {
"credits": 5000,
"kyc_status": "approved",
"kyc_verified": true
}
}
PHP
<?php
$apiKey = 'sk_your_api_key_here';
$baseUrl = 'https://sms.twozero.io/api/v1';
function sendSms($to, $message, $senderId = null) {
global $apiKey, $baseUrl;
$data = ['to' => $to, 'message' => $message];
if ($senderId) $data['sender_id'] = $senderId;
$ch = curl_init($baseUrl . '/sms/send');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'X-API-Key: ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($data),
]);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
$result = sendSms('9841234567', 'Hello from Twozero!', 'TZLABS');
print_r($result);
JavaScript
const API_KEY = 'sk_your_api_key_here';
const BASE_URL = 'https://sms.twozero.io/api/v1';
async function sendSms(to, message, senderId = null) {
const data = { to, message };
if (senderId) data.sender_id = senderId;
const response = await fetch(`${BASE_URL}/sms/send`, {
method: 'POST',
headers: {
'X-API-Key': API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});
return await response.json();
}
const result = await sendSms('9841234567', 'Hello from Twozero!', 'TZLABS');
console.log(result);
Python
import requests
API_KEY = 'sk_your_api_key_here'
BASE_URL = 'https://sms.twozero.io/api/v1'
headers = {
'X-API-Key': API_KEY,
'Content-Type': 'application/json',
}
def send_sms(to: str, message: str, sender_id: str = None) -> dict:
data = {'to': to, 'message': message}
if sender_id:
data['sender_id'] = sender_id
response = requests.post(f'{BASE_URL}/sms/send', headers=headers, json=data)
return response.json()
result = send_sms('9841234567', 'Hello from Twozero!', 'TZLABS')
print(result)
Error codes
| Code | Meaning | Description |
|---|---|---|
| 200 | OK | Request successful |
| 400 | Bad Request | Invalid request, e.g. insufficient credits |
| 401 | Unauthorized | Missing or invalid API key |
| 403 | Forbidden | Account inactive or IP not whitelisted |
| 404 | Not Found | Resource not found |
| 422 | Validation Error | Request data failed validation |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Server Error | Internal server error |
Message status codes
- pending
- Message queued and waiting to be sent
- sent
- Message handed off to the gateway
- delivered
- Message delivered to the recipient
- failed
- Message delivery failed
- rejected
- Message rejected by the gateway
Need a hand?
Stuck on an integration or have a question about the API? Our team is happy to help.