REST API Reference

Everything you need to integrate SMSFoundry into your application.

Authentication

All API requests require an X-API-Key header with your tenant API key.

X-API-Key: sf_live_your_key_here

Generate API keys from your dashboard under API Keys.

Base URL

https://smsfoundry.com/api/v1/

Rate Limiting

Requests are limited per API key per minute. Response headers show your current usage:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-RateLimit-Reset: 1709884800

Exceeding the limit returns 429 Too Many Requests with a Retry-After header.

Idempotency

Send endpoints accept an optional X-Idempotency-Key header. If you retry a request with the same key within 24 hours, you'll receive the original response without creating a duplicate message.

X-Idempotency-Key: my-unique-request-id-123

POST /api/v1/send

Send a single SMS message.

Request

{
  "to": "+919999999999",
  "message": "Your OTP is 482910. Valid for 5 minutes."
}

Response (201)

{
  "success": true,
  "data": {
    "message_id": "msg_a1b2c3d4e5f6",
    "status": "queued",
    "recipient": "+919999999999"
  },
  "meta": {
    "request_id": "req_f6e5d4c3b2a1",
    "timestamp": "2026-03-08T12:00:00Z"
  }
}

POST /api/v1/send-bulk

Send the same message to multiple recipients.

Request

{
  "to": ["+919999999901", "+919999999902", "+919999999903"],
  "message": "Flash sale! 50% off all routes this weekend."
}

Response (201)

{
  "success": true,
  "data": {
    "message_id": "msg_b2c3d4e5f6a1",
    "status": "queued",
    "recipient_count": 3
  }
}

POST /api/v1/send-template

Send using a saved template with variable substitution.

Request

{
  "to": "+919999999999",
  "template_id": 1,
  "variables": {
    "name": "Lohit",
    "booking_id": "BK-20260308",
    "route": "Hyderabad → Bangalore"
  }
}

Response (201)

{
  "success": true,
  "data": {
    "message_id": "msg_c3d4e5f6a1b2",
    "status": "queued",
    "recipient": "+919999999999",
    "template_used": "Booking Confirmation"
  }
}

GET /api/v1/status?id=msg_abc123

Check delivery status of a message.

Response (200)

{
  "success": true,
  "data": {
    "message_id": "msg_abc123",
    "type": "api",
    "recipient": "+919999999999",
    "status": "delivered",
    "timestamps": {
      "queued": "2026-03-08T12:00:00",
      "sent": "2026-03-08T12:00:03",
      "delivered": "2026-03-08T12:00:08"
    }
  }
}

GET /api/v1/templates

List all active templates for your account.

GET /api/v1/devices

List all registered devices and their current status.

Error Codes

400 — Validation error (bad input, missing fields)
401 — Invalid or missing API key
403 — Account suspended or abuse detected
404 — Resource not found
405 — Method not allowed
429 — Rate limit or quota exceeded
500 — Server error

All errors return JSON: { "success": false, "error": { "code": "...", "message": "..." } }

Code Examples

PHP

$ch = curl_init('https://smsfoundry.com/api/v1/send');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'X-API-Key: sf_live_your_key_here',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'to' => '+919999999999',
        'message' => 'Hello from SMSFoundry!',
    ]),
    CURLOPT_RETURNTRANSFER => true,
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);

Python

import requests

response = requests.post(
    'https://smsfoundry.com/api/v1/send',
    json={'to': '+919999999999', 'message': 'Hello from SMSFoundry!'},
    headers={'X-API-Key': 'sf_live_your_key_here'}
)
print(response.json())

Node.js

const response = await fetch('https://smsfoundry.com/api/v1/send', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': 'sf_live_your_key_here',
  },
  body: JSON.stringify({
    to: '+919999999999',
    message: 'Hello from SMSFoundry!',
  }),
});
const data = await response.json();
console.log(data);