SMS Gateway API
REST API to send SMS and check delivery. Works with the Android SMS Gateway app—authentication, message flow, webhooks, errors, and scaling.
What is an SMS Gateway API?
An SMS gateway API is an HTTP interface that lets your application send and receive SMS without talking to the mobile network directly. You send a request (recipient + message); the gateway turns it into an actual SMS via a modem or phone and returns a message ID. You can then check delivery status (DLR) by ID. Some gateways also push delivery and incoming SMS to your server via webhooks.
Our SMS Gateway API is the HTTP layer in front of the Android SMS Gateway: you call our endpoints; the request is routed to your registered Android device(s), which send the SMS using the SIM. The same API works whether you run one device or many.
How this API works with Android SMS Gateway
You run the SMS Gateway app on one or more Android devices with a SIM. Each device registers with our backend. When you POST /messages, we queue a campaign and a phone picks it up on its next poll (about ten seconds). The device sends the SMS over the mobile network. Delivery reports are stored on the message and pushed as webhooks (message.delivered, message.failed).
No SDK required: any HTTP client works. You need an account and an API key from the dashboard. Interactive contract: docs.sms-gateway.app. For install paths, see Downloads.
Your app
HTTPS POST JSON with Bearer token
Control plane
Auth, queue, device pick, DLR store
Android + SIM
Radio send on your operator airtime
Authentication methods
Every request uses HTTP Bearer authentication. Create a key in the dashboard (https://app.sms-gateway.app) under Settings / API. Keys are shown once. There is no other authentication — no query ?key=, no email and password.
- Header:
Authorization: Bearer <key>on every request, including DLR lookups. - Optional write header:
Idempotency-Key(remembered 24 hours). Retries replay the original response instead of sending twice.
Do not expose the key in client-side code or public repos. Store it in environment variables or a secrets store and use it only from your backend.
Message sending flow
Send with POST https://app.sms-gateway.app/api/v1/messages. Required: to (array of E.164 numbers with +). Usually also text. Optional: type (sms or mms), deviceIds, scheduleAt, metadata, attachments (MMS). The call returns HTTP 202 and queues work — nothing has left the device yet. Store messages[].id for DLR.
https://app.sms-gateway.app/api/v1/messagesJSON body: to, text. Header: Authorization: Bearer. Full field list: API reference.
curl -X POST "https://app.sms-gateway.app/api/v1/messages" \
-H "Authorization: Bearer $SMS_GATEWAY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 3f1b0c8a-9d2e-4c77-9f5a-2b6d1e0f4a83" \
-d '{"to":["+14155552671"],"text":"Your verification code is 481920","type":"sms"}'Success is HTTP 202 with a MessageBatch: campaignId, accepted, messages[].id, status Pending. A 400 refusal writes nothing — retry after a top-up with a fresh Idempotency-Key.
{
"campaignId": 17,
"accepted": 1,
"scheduledAt": null,
"messages": [
{
"id": 41822,
"number": "+14155552671",
"text": "Your verification code is 481920",
"type": "sms",
"status": "Pending",
"campaignId": 17,
"deviceId": 3
}
]
}Checking delivery (DLR): GET https://app.sms-gateway.app/api/v1/messages/{id} with the same Bearer token. Status values include Pending, Queued, Scheduled, Sent, Delivered, Failed, Canceled, Received. Prefer webhooks in production. Overview: DLR documentation.
curl -X GET "https://app.sms-gateway.app/api/v1/messages/41822" \
-H "Authorization: Bearer $SMS_GATEWAY_API_KEY"Webhooks & callbacks
Instead of polling DLR, register an endpoint with POST /webhooks (or the dashboard). Events include message.delivered, message.failed, and message.received. Verify X-SmsGateway-Signature (v1= hex HMAC-SHA256 of {timestamp}.{body}) before trusting the body. Deduplicate on X-SmsGateway-Event-Id. Answer any 2xx; other statuses retry up to six times.
Payload catalogue and signing: API reference · Webhook guide.
Error handling & retries
On failure the API returns one envelope: error.type, error.code, error.message, and requestId. Branch on HTTP status first, then code — message is for humans and may be reworded. Send refusals (HTTP 400) include insufficient_credits, no_active_device, subscription_expired. Auth failures use type authentication_error. Rate limits are HTTP 429 / rate_limit_error.
{
"error": {
"type": "invalid_request",
"code": "insufficient_credits",
"message": "The account does not have enough credits for this send."
},
"requestId": "req_01K2F8QW3N4RXB7M"
}Retries: For transient errors (e.g. 5xx, timeouts), retry with exponential backoff. Do not retry 4xx indefinitely—fix the request. For rate limits (429), back off and retry after the suggested delay if present.
Rate limits & scaling
The API enforces per-account rate limits. Free accounts sit under lower ceilings than paid accounts; exact numbers live in the product for your tier and can change when capacity is managed—treat HTTP 429 as the signal to back off and retry. Throughput of actual SMS is also limited by your Android device(s) and carrier—often measured in hundreds to low thousands per day per device depending on OEM and operator policy. To scale, add more devices and pass deviceIds so a batch splits across them.
Confirm current plan limits in the app dashboard or on Pricing (devices + SMS volume)—not invented RPM marketing ranges. For sustained high-volume API traffic, contact support.
Security considerations
- Use HTTPS for all requests. Do not send the API key over plain HTTP.
- Store the API key in a secure store (env vars, secrets manager). Never in client-side code or public repos.
- If you expose a webhook URL, verify the request signature before processing to prevent spoofed callbacks.
- Validate and sanitize input (recipient numbers, message body) to avoid injection and abuse.
- Rotate the API key if it is compromised; generate a new one in the dashboard and update your config.
Setup & integration docs
Install the app, grab an API key, and wire samples into your backend.
Official API reference
Live OpenAPI: send, DLR, webhooks, errors
Setup guide
Device, SIM, permissions, first SMS
Tutorials
Install, ADB, OEM rate ceilings
PHP samples
HTTPS/JSON request examples
C# samples
.NET HTTPS/JSON examples
Webhooks
Inbound SMS and status callbacks
DLR docs
Delivery report tracking
Downloads
Android APK and tools
Developer FAQ
API keys, base URL, phone format, options, DLR, errors, and free-plan footers.
Explore more developer resources
Related pages for implementation, product, and operations.
PHP SMS Integration
PHP HTTPS/JSON samples for SMS Gateway REST integration
integrate SMS with PHP02C# SMS Integration
C# /.NET HTTPS/JSON samples for SMS Gateway REST integration
C# code examples03SMS Webhook Integration
Complete webhook guide for incoming SMS automation and auto-reply
webhook automationReady to start building?
Download SMS Gateway, connect a device, get your API key, and send a test SMS in minutes.
Any Android device · Devices + SMS volume pricing · Bring your own SIM
