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

  1. 01 Create an account at sms.twozero.io
  2. 02 Complete KYC verification for full access
  3. 03 Generate an API key from your dashboard
  4. 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.

HTTP header (recommended)
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:

Production
https://sms.twozero.io/api/v1

Rate limits

Requests are rate-limited per API key to ensure fair usage.

Endpoint Limit
Send SMS100 / minute
Send Bulk SMS10 / minute
Status / History / Balance300 / minute
POST

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
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

200 OK
{
  "status": "success",
  "message": "SMS sent successfully",
  "data": {
    "message_id": "msg_abc123def456",
    "to": "9841234567",
    "credits_used": 1,
    "status": "sent"
  }
}

Error · 400

400 Bad Request
{
  "status": "error",
  "message": "Insufficient credits",
  "data": null
}
POST

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
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

200 OK
{
  "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"}
    ]
  }
}
GET

Message status

Check the delivery status of a sent message.

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

Example request

cURL
curl -X GET "https://sms.twozero.io/api/v1/sms/status/msg_abc123def456" \
  -H "X-API-Key: sk_your_api_key_here"

Success · 200

200 OK
{
  "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"
  }
}
GET

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
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"
GET

Check balance

Return your current credit balance and KYC status.

GET /api/v1/account/balance

Example request

cURL
curl -X GET "https://sms.twozero.io/api/v1/account/balance" \
  -H "X-API-Key: sk_your_api_key_here"

Success · 200

200 OK
{
  "status": "success",
  "data": {
    "credits": 5000,
    "kyc_status": "approved",
    "kyc_verified": true
  }
}

PHP

send-sms.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

send-sms.js
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

send_sms.py
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.