API Documentation

Integrate SMS Localhost into your application with our REST API.

Authentication

All API requests require an API key passed via the X-API-KEY header.

curl -H "X-API-KEY: your_api_key_here" \ https://sms.localhost.co.zw/api/v1/sms/history/
import requests headers = {"X-API-KEY": "your_api_key_here"} response = requests.get( "https://sms.localhost.co.zw/api/v1/sms/history/", headers=headers ) print(response.json())
const response = await fetch( "https://sms.localhost.co.zw/api/v1/sms/history/", { headers: { "X-API-KEY": "your_api_key_here" } } ); const data = await response.json(); console.log(data);
$ch = curl_init("https://sms.localhost.co.zw/api/v1/sms/history/"); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "X-API-KEY: your_api_key_here" ]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); $data = json_decode($response, true);
HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://sms.localhost.co.zw/api/v1/sms/history/")) .header("X-API-KEY", "your_api_key_here") .build(); HttpResponse<String> response = client.send( request, HttpResponse.BodyHandlers.ofString() ); System.out.println(response.body());

Generate API keys from your API Keys page in the dashboard.

Auth

GET POST /api/v1/auth/keys/

List active API keys or create a new one.

POST body: name

DELETE /api/v1/auth/keys/{key_id}/

Revoke an API key.

SMS

POST /api/v1/sms/send/

Send an SMS message.

Body: to (phone number), sender (approved Sender ID), message

curl -X POST https://sms.localhost.co.zw/api/v1/sms/send/ \ -H "X-API-KEY: your_api_key" \ -H "Content-Type: application/json" \ -d '{"to": "0771234567", "sender": "MyBrand", "message": "Hello!"}'
import requests response = requests.post( "https://sms.localhost.co.zw/api/v1/sms/send/", headers={ "X-API-KEY": "your_api_key", "Content-Type": "application/json", }, json={ "to": "0771234567", "sender": "MyBrand", "message": "Hello!" } ) print(response.json()) # {"message_id": "...", "channel": "sms", "status": "sent", ...}
const response = await fetch( "https://sms.localhost.co.zw/api/v1/sms/send/", { method: "POST", headers: { "X-API-KEY": "your_api_key", "Content-Type": "application/json", }, body: JSON.stringify({ to: "0771234567", sender: "MyBrand", message: "Hello!", }), } ); const data = await response.json(); console.log(data); // {message_id: "...", channel: "sms", status: "sent", ...}
$ch = curl_init("https://sms.localhost.co.zw/api/v1/sms/send/"); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ "X-API-KEY: your_api_key", "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode([ "to" => "0771234567", "sender" => "MyBrand", "message" => "Hello!", ]), CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); $data = json_decode($response, true); print_r($data);
String json = """ {"to":"0771234567","sender":"MyBrand","message":"Hello!"} """; HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://sms.localhost.co.zw/api/v1/sms/send/")) .header("X-API-KEY", "your_api_key") .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString(json)) .build(); HttpResponse<String> response = client.send( request, HttpResponse.BodyHandlers.ofString() ); System.out.println(response.body());

Success response:

{ "message_id": "a1b2c3d4-...", "channel": "sms", "status": "sent", "to": "0771234567", "sender": "MyBrand", "sms_credits": 142 }
GET /api/v1/sms/history/

Retrieve the last 100 sent messages.

Optional query: ?channel=sms

curl https://sms.localhost.co.zw/api/v1/sms/history/ \ -H "X-API-KEY: your_api_key"
import requests response = requests.get( "https://sms.localhost.co.zw/api/v1/sms/history/", headers={"X-API-KEY": "your_api_key"} ) messages = response.json()["messages"] for msg in messages: print(f"{msg['recipient']}: {msg['status']}")
const response = await fetch( "https://sms.localhost.co.zw/api/v1/sms/history/", { headers: { "X-API-KEY": "your_api_key" } } ); const { messages } = await response.json(); messages.forEach(msg => console.log(`${msg.recipient}: ${msg.status}`) );
$ch = curl_init("https://sms.localhost.co.zw/api/v1/sms/history/"); curl_setopt($ch, CURLOPT_HTTPHEADER, ["X-API-KEY: your_api_key"]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $data = json_decode(curl_exec($ch), true); foreach ($data["messages"] as $msg) { echo $msg["recipient"] . ": " . $msg["status"] . "\n"; }
GET POST /api/v1/sms/senders/

List your Sender IDs or request a new one.

POST body: sender_name (3-11 alphanumeric characters)

GET /api/v1/sms/testers/

List your verified tester numbers.

Contacts

GET POST /api/v1/contacts/

List contacts or create a new one.

POST body: phone, first_name, last_name (optional), email (optional)

# Create a contact curl -X POST https://sms.localhost.co.zw/api/v1/contacts/ \ -H "X-API-KEY: your_api_key" \ -H "Content-Type: application/json" \ -d '{"phone": "0771234567", "first_name": "John", "last_name": "Doe"}'
import requests # Create a contact response = requests.post( "https://sms.localhost.co.zw/api/v1/contacts/", headers={ "X-API-KEY": "your_api_key", "Content-Type": "application/json", }, json={ "phone": "0771234567", "first_name": "John", "last_name": "Doe", } ) print(response.json())
// Create a contact const response = await fetch( "https://sms.localhost.co.zw/api/v1/contacts/", { method: "POST", headers: { "X-API-KEY": "your_api_key", "Content-Type": "application/json", }, body: JSON.stringify({ phone: "0771234567", first_name: "John", last_name: "Doe", }), } ); console.log(await response.json());
// Create a contact $ch = curl_init("https://sms.localhost.co.zw/api/v1/contacts/"); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ "X-API-KEY: your_api_key", "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode([ "phone" => "0771234567", "first_name" => "John", "last_name" => "Doe", ]), CURLOPT_RETURNTRANSFER => true, ]); $data = json_decode(curl_exec($ch), true);
GET PUT DELETE /api/v1/contacts/{contact_id}/

Retrieve, update, or delete a single contact.

GET POST /api/v1/contacts/groups/

List contact groups or create a new one.

Campaigns

GET POST /api/v1/campaigns/

List campaigns or create a new one.

POST body: name, message, sender_name, group_id

curl -X POST https://sms.localhost.co.zw/api/v1/campaigns/ \ -H "X-API-KEY: your_api_key" \ -H "Content-Type: application/json" \ -d '{ "name": "March Promo", "message": "Hi {name}, enjoy 20% off this week!", "sender_name": "MyBrand", "group_id": "your_group_uuid" }'
import requests response = requests.post( "https://sms.localhost.co.zw/api/v1/campaigns/", headers={ "X-API-KEY": "your_api_key", "Content-Type": "application/json", }, json={ "name": "March Promo", "message": "Hi {name}, enjoy 20% off this week!", "sender_name": "MyBrand", "group_id": "your_group_uuid", } ) campaign = response.json() print(f"Campaign created: {campaign['id']}")
const response = await fetch( "https://sms.localhost.co.zw/api/v1/campaigns/", { method: "POST", headers: { "X-API-KEY": "your_api_key", "Content-Type": "application/json", }, body: JSON.stringify({ name: "March Promo", message: "Hi {name}, enjoy 20% off this week!", sender_name: "MyBrand", group_id: "your_group_uuid", }), } ); const campaign = await response.json(); console.log(`Campaign created: ${campaign.id}`);
POST /api/v1/campaigns/{campaign_id}/send/

Launch a campaign for sending.

POST /api/v1/campaigns/{campaign_id}/pause/

Pause a running campaign.

POST /api/v1/campaigns/{campaign_id}/cancel/

Cancel a campaign.

Billing

GET /api/v1/billing/balance/

Get your current SMS credit balance.

curl https://sms.localhost.co.zw/api/v1/billing/balance/ \ -H "X-API-KEY: your_api_key"
import requests response = requests.get( "https://sms.localhost.co.zw/api/v1/billing/balance/", headers={"X-API-KEY": "your_api_key"} ) data = response.json() print(f"Credits remaining: {data['sms_credits']}")
const response = await fetch( "https://sms.localhost.co.zw/api/v1/billing/balance/", { headers: { "X-API-KEY": "your_api_key" } } ); const data = await response.json(); console.log(`Credits remaining: ${data.sms_credits}`);
$ch = curl_init("https://sms.localhost.co.zw/api/v1/billing/balance/"); curl_setopt($ch, CURLOPT_HTTPHEADER, ["X-API-KEY: your_api_key"]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $data = json_decode(curl_exec($ch), true); echo "Credits remaining: " . $data["sms_credits"];
GET /api/v1/billing/transactions/

View your transaction history.

Rate Limits

Endpoint Limit
/api/v1/sms/send/ 60 requests per minute (per user)

Error Responses

All errors return a JSON object with an error key.

{"error": "Insufficient SMS credits."}
Status Meaning
400 Bad request — check your request body
401 Unauthorized — invalid or missing API key
402 Insufficient SMS credits
403 Sender not approved or insufficient permissions
404 Resource not found
409 Conflict — resource already exists
429 Rate limit exceeded — slow down