Send SMS from your own software and receive replies and delivery receipts back, using a simple JSON API over HTTPS.
In short: POST a JSON message to https://api.everymessage.com/v1/submit with HTTP Basic authentication. Replies and delivery receipts arrive at your webhook as they happen, or you can collect them with a GET request.
Getting started
- Get your API keys. Contact us and we will issue an
api_keyandsecret_keyfor your account. - Send a message. Call Send SMS. Each request can carry many messages, each with many recipients.
- Handle replies. Choose a webhook or polling for inbound SMS.
- Track delivery. Ask for delivery receipts on the messages you need to confirm.
Send SMS
One message or thousands, scheduling, expiry and Unicode.
POST /v1/submit →Receive SMS
Replies to your numbers, pushed to you or collected by API.
Webhook or GET /v1/inbound_messages →Delivery receipts
Know which messages reached the handset.
Webhook or GET /v1/delivery_receipts →Send RCS
Branded rich cards, carousels and buttons, with automatic SMS fallback.
POST /v1/rcs/messages →Send WhatsApp
Approved templates, plus text and media replies inside the 24-hour window.
POST /v1/whatsapp/messages →Workflow API
Email, voice calls and multi-step journeys such as SMS, then email, then a call.
POST /rest/v1/records/submit →Authentication
Every request uses HTTP Basic authentication over HTTPS: your api_key is the username and your secret_key is the password.
Authorization: Basic base64(api_key:secret_key)
If your tooling cannot set headers, you can pass api_key and secret_key as query parameters instead. The header is preferred, because query strings can end up in logs.
Keep your keys on your server. Never put them in a web page or mobile app.
Responses
Every call returns the same JSON envelope. The result is in body.
Always check responseStatusReason. The API returns HTTP 200 even when a request is refused. On success the field is left out; otherwise it holds one of the reasons below.
{
"apiName": "everymessage Web API",
"apiVersion": "1.0.2",
"apiTime": "11 October 2026 10:30:00",
"apiState": "RUNNING",
"responseStatusCode": 200,
"processingTime": 42,
"body": {}
}
| Field | Type | Description |
|---|---|---|
apiName | string | Always everymessage Web API. |
apiVersion | string | API version. |
apiTime | string | Server time (UTC) the response was produced. |
apiState | string | RUNNING when the service is healthy. |
responseStatusCode | integer | Always 200. |
responseStatusReason | string | Left out on success. If present, the request was refused: see status reasons. |
processingTime | integer | Time taken on our side, in milliseconds. |
body | object / array | The result. Its shape depends on the endpoint. |
Status reasons
| responseStatusReason | Meaning |
|---|---|
UNAUTHORIZED | The keys are wrong, or the account is blocked. |
INSUFFICIENT_DATA | A required field is missing or the JSON could not be read. |
INSUFFICIENT_CREDITS | A prepay account does not have enough credit for the request. |
USER_DAILY_CREDIT_LIMIT_REACHED | The user’s daily sending limit has been reached. |
COMPANY_DAILY_CREDIT_LIMIT_REACHED | The company’s daily sending limit has been reached. |
BLOCKED | The request was blocked. |
NO_CURRENT_ENTRIES | A collect call found nothing new. This is not an error. |
PROCESSING_FAILURE | Something went wrong on our side. It is safe to retry after a short wait. |
Fixed IP addresses
Webhooks to your systems come from 13.134.161.74. Add it to your firewall allow-list if you restrict inbound traffic. If your own firewall restricts outbound traffic to the API, ask us for the fixed addresses of api.everymessage.com.
Both directions run from UK and EU data centres.
