Developer Center

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.

Concept

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.

Architecture

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.

  1. Your app

    HTTPS POST JSON with Bearer token

  2. Control plane

    Auth, queue, device pick, DLR store

  3. Android + SIM

    Radio send on your operator airtime

Credentials

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.

Endpoints

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.

Send SMS endpointPOST
https://app.sms-gateway.app/api/v1/messages

JSON body: to, text. Header: Authorization: Bearer. Full field list: API reference.

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

Success response (excerpt)
{
  "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.

DLR
curl -X GET "https://app.sms-gateway.app/api/v1/messages/41822" \
  -H "Authorization: Bearer $SMS_GATEWAY_API_KEY"
Callbacks

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.

Resilience

Error handling & retries

On failure the API returns one envelope: error.type, error.code, error.message, and requestId. Branch on HTTP status first, then codemessage 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 response example
{
  "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.

Capacity

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.

Hardening

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

Developer FAQ

API keys, base URL, phone format, options, DLR, errors, and free-plan footers.

Get started

Ready 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