πŸ“± SMS Gateway β€” API Documentation

Complete REST API reference for the SMS Gateway platform. Send SMS via any Android phone using a SIM card.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ External │────▢│ Laravel │────▢│ Flutter App │────▢│ SIM Card β”‚ β”‚ App / API β”‚ β”‚ API Server β”‚ β”‚ (Android) β”‚ β”‚ (SMS Send) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ POST /messages Queue + FCM Push Polls /device/jobs Sends SMS GET /messages/{id} Updates status Reports result Delivers to Webhook callback Webhook delivery recipient

Architecture

ComponentTechPurpose
API BackendLaravel 11 + MySQLREST API, auth, webhook delivery, job queue
Mobile AppFlutter (Android)Receives jobs via polling, sends SMS via SIM
Background ServiceKotlin Foreground ServicePolls API every 5 sec even when app is killed
AuthLaravel SanctumToken-based auth for dashboard + API keys
QueueDatabase driverAsync job processing (optional, device picks up directly)

Authentication

Two authentication methods are used:

1. Sanctum Token (Dashboard / Mobile App)

Used for user login, device management, message history, and API key management.

# After login, use the token:
Authorization: Bearer YOUR_SANCTUM_TOKEN

2. API Key (External Developers)

Used for sending messages, managing webhooks, and querying message status.

# API Key format: sk_live_xxxxxxxxxxxxxxxxxxxx
X-API-Key: sk_live_abc123def456ghi789
πŸ”‘ Getting an API Key:
1. Register/Login via POST /api/v1/auth/login
2. Create API key via POST /api/v1/api-keys
3. Use the key in X-API-Key header for all API calls

Base URL

# Local development
http://localhost:8000/api/v1

# Production (replace with your domain)
https://your-domain.com/api/v1

# With ngrok (for testing)
https://xxxx-xxx-xxx.ngrok-free.dev/api/v1

Rate Limiting

EndpointLimitWindow
POST /messages60 requestsPer minute per API key
All other endpoints120 requestsPer minute

Rate limit headers returned:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 55
Retry-After: 30  # seconds (only when rate limited)

Error Handling

HTTP CodeMeaningCommon Cause
400Bad RequestInvalid JSON or missing fields
401UnauthorizedMissing or invalid token/API key
403ForbiddenAPI key disabled / user suspended
404Not FoundResource doesn't exist
409ConflictDuplicate message to same number in 30s
422Validation ErrorInvalid phone format, missing message body
429Too Many RequestsRate limit exceeded
500Server ErrorUnexpected server error

Error response format:

{
    "success": false,
    "message": "Validation failed",
    "errors": {
        "to": ["The phone field must be a valid phone number."],
        "message": ["The message field is required."]
    }
}

πŸ” Authentication

POST /api/v1/auth/register Public

Register a new user account.

Request Body

FieldTypeRequiredDescription
namestringYesFull name (2-255 chars)
emailstringYesValid email address
passwordstringYesMin 8 characters
password_confirmationstringYesMust match password

Request

curl -X POST https://your-domain.com/api/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "name": "John Doe",
    "email": "john@example.com",
    "password": "secret123",
    "password_confirmation": "secret123"
  }'

Response 201

{
    "success": true,
    "message": "User registered successfully",
    "data": {
        "user": {
            "id": 1,
            "name": "John Doe",
            "email": "john@example.com",
            "is_admin": false,
            "created_at": "2026-08-27T10:00:00Z"
        },
        "token": "1|abc123def456..."
    }
}
POST /api/v1/auth/login Public

Login and get a Sanctum token.

Request Body

FieldTypeRequiredDescription
emailstringYesRegistered email
passwordstringYesPassword

Request

curl -X POST https://your-domain.com/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "john@example.com",
    "password": "secret123"
  }'

Response 200

{
    "success": true,
    "message": "Login successful",
    "data": {
        "user": {
            "id": 1,
            "name": "John Doe",
            "email": "john@example.com",
            "is_admin": false
        },
        "token": "2|xyz789abc123..."
    }
}
GET /api/v1/auth/me Sanctum

Get current authenticated user profile.

Request

curl -X GET https://your-domain.com/api/v1/auth/me \
  -H "Authorization: Bearer YOUR_TOKEN"

Response 200

{
    "id": 1,
    "name": "John Doe",
    "email": "john@example.com",
    "is_admin": false,
    "created_at": "2026-08-27T10:00:00Z"
}
POST /api/v1/auth/logout Sanctum

Revoke the current token and create an audit log.

Request

curl -X POST https://your-domain.com/api/v1/auth/logout \
  -H "Authorization: Bearer YOUR_TOKEN"

Response 200

{
    "success": true,
    "message": "Logged out successfully"
}

πŸ”‘ API Keys

GET /api/v1/api-keys Sanctum

List all API keys for the authenticated user.

Request

curl -X GET https://your-domain.com/api/v1/api-keys \
  -H "Authorization: Bearer YOUR_TOKEN"

Response 200

{
    "success": true,
    "data": [
        {
            "id": 1,
            "name": "Production Key",
            "key_prefix": "sk_live_abc12...",
            "is_active": true,
            "last_used_at": "2026-08-27T10:30:00Z",
            "created_at": "2026-08-27T10:00:00Z"
        }
    ]
}
POST /api/v1/api-keys Sanctum

Create a new API key. The full key is shown only once.

Request Body

FieldTypeRequiredDescription
namestringYesA label for this key (e.g., "Production")

Request

curl -X POST https://your-domain.com/api/v1/api-keys \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Production Key"
  }'

Response 201

{
    "success": true,
    "message": "API key created successfully",
    "data": {
        "id": 1,
        "name": "Production Key",
        "key": "sk_live_abc123def456ghi789jkl012mno345",
        "key_prefix": "sk_live_abc12...",
        "created_at": "2026-08-27T10:00:00Z"
    }
}
⚠️ Save the full API key now! It will only be shown once. After that, only the prefix is visible.
DELETE /api/v1/api-keys/{id} Sanctum

Permanently delete an API key.

Request

curl -X DELETE https://your-domain.com/api/v1/api-keys/1 \
  -H "Authorization: Bearer YOUR_TOKEN"

Response 200

{
    "success": true,
    "message": "API key deleted"
}

πŸ“± Devices

GET /api/v1/devices Sanctum

List all registered devices for the authenticated user.

Request

curl -X GET https://your-domain.com/api/v1/devices \
  -H "Authorization: Bearer YOUR_TOKEN"

Response 200

{
    "success": true,
    "data": [
        {
            "id": 1,
            "device_id": "android-abc123",
            "device_name": "My Phone",
            "phone_number": "+919917408207",
            "country_code": "IN",
            "platform": "android",
            "android_version": "14",
            "app_version": "1.0.0",
            "status": "online",
            "last_heartbeat_at": "2026-08-27T10:30:00Z",
            "created_at": "2026-08-27T10:00:00Z"
        }
    ]
}
POST /api/v1/devices/register Sanctum

Register a new Android device to send SMS. Called by the Flutter app.

Request Body

FieldTypeRequiredDescription
device_idstringYesUnique device identifier (UUID)
device_namestringNoUser-friendly name
phone_numberstringNoSIM phone number
country_codestringNoe.g., "IN"
platformstringNo"android"
android_versionstringNoe.g., "14"
app_versionstringNoe.g., "1.0.0"

Request

curl -X POST https://your-domain.com/api/v1/devices/register \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "device_id": "android-abc123",
    "device_name": "My Phone",
    "phone_number": "+919917408207",
    "country_code": "IN",
    "platform": "android",
    "android_version": "14",
    "app_version": "1.0.0"
  }'

Response 201

{
    "success": true,
    "message": "Device registered successfully",
    "data": {
        "device_id": 1,
        "device_name": "My Phone",
        "phone_number": "+919917408207",
        "country_code": "IN",
        "platform": "android",
        "status": "online",
        "created_at": "2026-08-27T10:00:00Z"
    }
}
POST /api/v1/devices/{id}/heartbeat Sanctum

Keep the device "online" by sending periodic heartbeats (every 15 sec).

Request

curl -X POST https://your-domain.com/api/v1/devices/1/heartbeat \
  -H "Authorization: Bearer YOUR_TOKEN"

Response 200

{
    "success": true,
    "data": {
        "status": "online",
        "last_heartbeat_at": "2026-08-27T10:30:00Z",
        "device_name": "My Phone",
        "phone_number": "+919917408207"
    }
}
DELETE /api/v1/devices/{id} Sanctum

Unregister a device from the gateway.

Request

curl -X DELETE https://your-domain.com/api/v1/devices/1 \
  -H "Authorization: Bearer YOUR_TOKEN"

Response 200

{
    "success": true,
    "message": "Device deleted"
}

πŸ’¬ Messages

Message Lifecycle:
queued β†’ Device picks up β†’ processing β†’ SMS sent β†’ sent β†’ delivered
Or on failure: processing β†’ failed
POST /api/v1/messages API Key

Send an SMS message. The message is queued and a connected device will pick it up.

Request Body

FieldTypeRequiredDescription
tostringYesRecipient phone with country code (e.g., "+919917408207")
messagestringYesSMS text (max 1600 chars)
device_idintegerNoTarget a specific device (auto-selected if omitted)
sim_slotintegerNoSIM slot (0 or 1, default 0)

Request

curl -X POST https://your-domain.com/api/v1/messages \
  -H "X-API-Key: sk_live_abc123def456" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+919917408207",
    "message": "Hello from SMS Gateway!"
  }'

Response 201

{
    "success": true,
    "message": "SMS accepted",
    "data": {
        "id": "msg_5",
        "status": "queued"
    }
}
GET /api/v1/messages API Key

List all messages sent via this API key. Paginated.

Query Parameters

ParamTypeDescription
statusstringFilter: queued, processing, sent, delivered, failed, cancelled
per_pageintegerResults per page (default 15, max 100)

Request

curl -X GET "https://your-domain.com/api/v1/messages?status=sent&per_page=10" \
  -H "X-API-Key: sk_live_abc123def456"

Response 200

{
    "data": [
        {
            "id": "msg_5",
            "to": "+919917408207",
            "message": "Hello from SMS Gateway!",
            "status": "sent",
            "sent_at": "2026-08-27T10:30:15Z",
            "delivered_at": "2026-08-27T10:30:18Z"
        }
    ],
    "links": {
        "first": "?page=1",
        "last": "?page=3",
        "next": "?page=2"
    }
}
GET /api/v1/messages/{id} API Key

Get detailed status of a specific message.

Request

curl -X GET https://your-domain.com/api/v1/messages/msg_5 \
  -H "X-API-Key: sk_live_abc123def456"

Response 200

{
    "id": "msg_5",
    "to": "+919917408207",
    "message": "Hello from SMS Gateway!",
    "status": "sent",
    "device_id": 1,
    "sent_at": "2026-08-27T10:30:15Z",
    "delivered_at": "2026-08-27T10:30:18Z",
    "created_at": "2026-08-27T10:30:10Z"
}
POST /api/v1/messages/{id}/cancel API Key

Cancel a queued message before it's sent.

Request

curl -X POST https://your-domain.com/api/v1/messages/msg_5/cancel \
  -H "X-API-Key: sk_live_abc123def456"

Response 200

{
    "success": true,
    "message": "Message cancelled"
}
GET /api/v1/message-history Sanctum

Get message history for the dashboard/mobile app with filtering.

Query Parameters

ParamTypeDescription
statusstringFilter by status
searchstringSearch by phone number
fromdateStart date (YYYY-MM-DD)
todateEnd date (YYYY-MM-DD)
per_pageintegerResults per page (default 20)

Request

curl -X GET "https://your-domain.com/api/v1/message-history?status=sent&search=9917&from=2026-08-01" \
  -H "Authorization: Bearer YOUR_TOKEN"

Response 200

{
    "success": true,
    "data": {
        "data": [...],
        "links": {...},
        "meta": { "total": 42 }
    }
}
GET /api/v1/message-history/{id} Sanctum

Get detailed message info with delivery timeline and attempt history.

Request

curl -X GET https://your-domain.com/api/v1/message-history/msg_5 \
  -H "Authorization: Bearer YOUR_TOKEN"

Response 200

{
    "id": "msg_5",
    "to": "+919917408207",
    "message": "Hello from SMS Gateway!",
    "status": "delivered",
    "device_id": 1,
    "device_name": "My Phone",
    "sim_slot": 0,
    "sent_at": "2026-08-27T10:30:15Z",
    "delivered_at": "2026-08-27T10:30:18Z",
    "attempts": [
        {
            "id": 1,
            "status": "sent",
            "attempted_at": "2026-08-27T10:30:15Z",
            "device_id": 1
        }
    ]
}
POST /api/v1/message-history/{id}/retry Sanctum

Re-queue a failed message for retry.

Request

curl -X POST https://your-domain.com/api/v1/message-history/msg_5/retry \
  -H "Authorization: Bearer YOUR_TOKEN"

Response 200

{
    "success": true,
    "message": "Message re-queued for retry"
}

βš™οΈ Device Internal APIs

These endpoints are called by the Flutter app / Kotlin foreground service to poll for jobs and report results.

Authentication: These require both X-API-Key and X-Device-ID headers.
GET /api/v1/device/jobs API Key + Device ID

Poll for pending SMS jobs. Atomically claims messages (sets status to "processing").

Headers

HeaderValue
X-API-KeyYour API key
X-Device-IDYour device ID

Request

curl -X GET https://your-domain.com/api/v1/device/jobs \
  -H "X-API-Key: sk_live_abc123def456" \
  -H "X-Device-ID: 1"

Response 200

{
    "success": true,
    "jobs": [
        {
            "id": "msg_5",
            "to": "+919917408207",
            "message": "Hello from SMS Gateway!",
            "sim_slot": 0
        }
    ]
}

Response 200 (no jobs)

{
    "success": true,
    "jobs": []
}
POST /api/v1/device/messages/{id}/result API Key + Device ID

Report the SMS send result back to the server. Updates message status synchronously.

Request Body

FieldTypeRequiredDescription
statusstringYes"sent" or "failed"
errorstringNoError message if failed
error_codestringNoTelephony error code

Request (Success)

curl -X POST https://your-domain.com/api/v1/device/messages/5/result \
  -H "X-API-Key: sk_live_abc123def456" \
  -H "X-Device-ID: 1" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "sent"
  }'

Request (Failure)

curl -X POST https://your-domain.com/api/v1/device/messages/5/result \
  -H "X-API-Key: sk_live_abc123def456" \
  -H "X-Device-ID: 1" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "failed",
    "error": "SMS permission not granted",
    "error_code": "PERMISSION_DENIED"
  }'

Response 200

{
    "success": true,
    "message": "Result recorded",
    "data": {
        "id": "msg_5",
        "status": "sent",
        "sent_at": "2026-08-27T10:30:15Z"
    }
}
POST /api/v1/device/messages/{id}/delivery API Key + Device ID

Report SMS delivery confirmation (when carrier confirms delivery).

Request

curl -X POST https://your-domain.com/api/v1/device/messages/5/delivery \
  -H "X-API-Key: sk_live_abc123def456" \
  -H "X-Device-ID: 1" \
  -H "Content-Type: application/json" \
  -d '{}'

Response 200

{
    "success": true,
    "message": "Delivery confirmed",
    "data": {
        "id": "msg_5",
        "status": "delivered",
        "delivered_at": "2026-08-27T10:30:18Z"
    }
}
POST /api/v1/device/received-messages API Key + Device ID

Report an incoming SMS received by the device. Triggers webhook for message.received.

Request Body

FieldTypeRequiredDescription
fromstringYesSender phone number
bodystringYesSMS text content
received_atdatetimeNoISO 8601 timestamp

Request

curl -X POST https://your-domain.com/api/v1/device/received-messages \
  -H "X-API-Key: sk_live_abc123def456" \
  -H "X-Device-ID: 1" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "+919876543210",
    "body": "Your OTP is 1234",
    "received_at": "2026-08-27T10:35:00Z"
  }'

Response 201

{
    "success": true,
    "message": "Received message saved",
    "data": {
        "id": 1,
        "from": "+919876543210",
        "body": "Your OTP is 1234",
        "received_at": "2026-08-27T10:35:00Z"
    }
}
GET /api/v1/received-messages Sanctum

List all incoming SMS received by your devices.

Request

curl -X GET https://your-domain.com/api/v1/received-messages \
  -H "Authorization: Bearer YOUR_TOKEN"

Response 200

{
    "success": true,
    "data": [
        {
            "id": 1,
            "from": "+919876543210",
            "body": "Your OTP is 1234",
            "device_id": 1,
            "received_at": "2026-08-27T10:35:00Z"
        }
    ]
}

πŸ”” Webhooks

Webhooks send HTTP POST requests to your URL when message events occur.

GET /api/v1/webhooks API Key

List all configured webhooks.

Request

curl -X GET https://your-domain.com/api/v1/webhooks \
  -H "X-API-Key: sk_live_abc123def456"

Response 200

{
    "success": true,
    "data": [
        {
            "id": 1,
            "url": "https://your-app.com/webhook",
            "events": ["message.sent", "message.delivered"],
            "is_active": true,
            "created_at": "2026-08-27T10:00:00Z"
        }
    ]
}
POST /api/v1/webhooks API Key

Register a new webhook endpoint.

Request Body

FieldTypeRequiredDescription
urlstringYesHTTPS URL to receive webhooks
eventsarrayYesEvent types to subscribe to

Request

curl -X POST https://your-domain.com/api/v1/webhooks \
  -H "X-API-Key: sk_live_abc123def456" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhook",
    "events": ["message.sent", "message.delivered", "message.failed"]
  }'

Response 201

{
    "success": true,
    "message": "Webhook created",
    "data": {
        "id": 1,
        "url": "https://your-app.com/webhook",
        "events": ["message.sent", "message.delivered", "message.failed"],
        "is_active": true,
        "secret": "whsec_abc123...",
        "created_at": "2026-08-27T10:00:00Z"
    }
}
PUT /api/v1/webhooks/{id} API Key

Update a webhook URL, events, or active status.

Request

curl -X PUT https://your-domain.com/api/v1/webhooks/1 \
  -H "X-API-Key: sk_live_abc123def456" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://new-url.com/webhook",
    "events": ["message.sent", "message.received"],
    "is_active": true
  }'

Response 200

{
    "success": true,
    "message": "Webhook updated"
}
DELETE /api/v1/webhooks/{id} API Key

Delete a webhook.

Request

curl -X DELETE https://your-domain.com/api/v1/webhooks/1 \
  -H "X-API-Key: sk_live_abc123def456"

Response 200

{
    "success": true,
    "message": "Webhook deleted"
}
POST /api/v1/webhooks/{id}/test API Key

Send a test payload to verify your webhook is working.

Request

curl -X POST https://your-domain.com/api/v1/webhooks/1/test \
  -H "X-API-Key: sk_live_abc123def456"

Response 200

{
    "success": true,
    "message": "Test webhook sent",
    "data": {
        "status_code": 200,
        "response": "OK"
    }
}
POST /api/v1/webhook-receiver Public (Test)

Built-in test webhook receiver. Configure this as your webhook URL for testing.

curl -X POST https://your-domain.com/api/v1/webhook-receiver \
  -H "Content-Type: application/json" \
  -d '{
    "event": "message.sent",
    "data": { "id": "msg_5" }
  }'

πŸ›‘οΈ Admin

Admin endpoints require is_admin: true user and Sanctum token.

GET /api/v1/admin/dashboard Admin

Get system-wide statistics.

Request

curl -X GET https://your-domain.com/api/v1/admin/dashboard \
  -H "Authorization: Bearer ADMIN_TOKEN"

Response 200

{
    "users": { "total": 15, "active": 12 },
    "devices": { "total": 8, "online": 5 },
    "messages": {
        "total": 1247,
        "sent": 1180,
        "delivered": 1150,
        "failed": 30,
        "queued": 12
    }
}
GET /api/v1/admin/users Admin

List all users. Also: GET /admin/users/{id}, PATCH /admin/users/{id}/suspend, PATCH /admin/users/{id}/activate

GET /api/v1/admin/devices Admin

List all devices across all users. Also: GET /admin/devices/{id}, PATCH /admin/devices/{id}/disable

GET /api/v1/admin/messages Admin

List all messages across all users. Also: GET /admin/messages/{id}

πŸ“‹ Webhook Events & Payloads

EventDescription
message.sentDevice reported SMS sent successfully
message.deliveredCarrier confirmed SMS delivery
message.failedSMS send failed
message.receivedDevice received an incoming SMS

Webhook Payload

{
    "event": "message.sent",
    "timestamp": "2026-08-27T10:30:15Z",
    "data": {
        "id": "msg_5",
        "to": "+919917408207",
        "message": "Hello from SMS Gateway!",
        "status": "sent",
        "device_id": 1,
        "sent_at": "2026-08-27T10:30:15Z"
    }
}

Webhook Headers

HeaderValue
X-SMS-EventEvent type (e.g., "message.sent")
X-SMS-SignatureHMAC-SHA256 signature (verify with webhook secret)
Content-Typeapplication/json

πŸ“¦ Data Models

Message

FieldTypeDescription
idstringmsg_1, msg_2, ...
tostringRecipient phone number
messagestringSMS text content
statusenumqueued / processing / sent / delivered / failed / cancelled
device_idintegerID of the device that sent it
sim_slotintegerSIM slot used (0 or 1)
failure_reasonstringError message if failed
failure_codestringTelephony error code
sent_atdatetimeWhen SMS was sent
delivered_atdatetimeWhen delivery was confirmed
created_atdatetimeWhen message was queued

Device

FieldTypeDescription
idintegerAuto-increment ID
device_idstringUnique device UUID
device_namestringUser-friendly name
phone_numberstringSIM phone number
statusenumonline / offline / disabled
last_heartbeat_atdatetimeLast heartbeat timestamp

API Key

FieldTypeDescription
idintegerAuto-increment ID
namestringLabel
key_prefixstringFirst 16 chars of key
key_hashstringSHA-256 hash (key never stored in plain)
is_activebooleanEnabled/disabled
last_used_atdatetimeLast API call timestamp

πŸš€ Quick Start Examples

Step 1: Register & Login

# Register
curl -X POST http://localhost:8000/api/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{"name":"John","email":"john@test.com","password":"secret123","password_confirmation":"secret123"}'

# Login
curl -X POST http://localhost:8000/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"john@test.com","password":"secret123"}'

Step 2: Create API Key

curl -X POST http://localhost:8000/api/v1/api-keys \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"My App"}'

Step 3: Send SMS

curl -X POST http://localhost:8000/api/v1/messages \
  -H "X-API-Key: sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"to":"+919917408207","message":"Hello!"}'

Step 4: Check Status

curl -X GET http://localhost:8000/api/v1/messages/msg_1 \
  -H "X-API-Key: sk_live_..."

Python Example

import requests

BASE = "http://localhost:8000/api/v1"

# Login
r = requests.post(f"{BASE}/auth/login", json={
    "email": "john@test.com",
    "password": "secret123"
})
token = r.json()["data"]["token"]

# Send SMS
r = requests.post(f"{BASE}/messages",
    headers={"X-API-Key": "sk_live_..."},
    json={"to": "+919917408207", "message": "Hello!"}
)
print(r.json())  # {success: true, data: {id: "msg_1", status: "queued"}}

JavaScript / Node.js Example

const response = await fetch("http://localhost:8000/api/v1/messages", {
    method: "POST",
    headers: {
        "Content-Type": "application/json",
        "X-API-Key": "sk_live_..."
    },
    body: JSON.stringify({
        to: "+919917408207",
        message: "Hello from Node.js!"
    })
});
const data = await response.json();
console.log(data);  // {success: true, data: {id: "msg_1", status: "queued"}}

PHP Example

<?php
$ch = curl_init("http://localhost:8000/api/v1/messages");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        "Content-Type: application/json",
        "X-API-Key: sk_live_...",
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "to" => "+919917408207",
        "message" => "Hello from PHP!",
    ]),
    CURLOPT_RETURNTRANSFER => true,
]);
$result = json_decode(curl_exec($ch), true);
print_r($result);


SMS Gateway API v1.0 • Built with Laravel 11 + Flutter • Last updated: August 2026