
What you need
- An active SMS reseller account. Without it, the API answers
403with the codesms_reseller_required. - A key with the
sms:writepermission to send, andsms:readto look things up. See Permissions.
Sending
Use POST /v1/sms/messages with the number and the text:
curl
curl -X POST "https://api.mozout.com/v1/sms/messages" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: en" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"number": "+258841234567", "text": "Your order is ready.", "send_at": "2026-11-20T09:30:00+02:00"}'PHP
<?php
$ch = curl_init('https://api.mozout.com/v1/sms/messages');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{"number": "+258841234567", "text": "Your order is ready.", "send_at": "2026-11-20T09:30:00+02:00"}',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: en',
'Idempotency-Key: 9f1c2d3e-example',
'Content-Type: application/json',
],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status, PHP_EOL, $body, PHP_EOL;Python
import os
import requests
headers = {
"Authorization": "Bearer " + os.environ["RLX_API_KEY"],
"Accept-Language": "en",
"Idempotency-Key": "9f1c2d3e-example",
}
payload = {"number": "+258841234567", "text": "Your order is ready.", "send_at": "2026-11-20T09:30:00+02:00"}
r = requests.post("https://api.mozout.com/v1/sms/messages", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.com/v1/sms/messages", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "en",
"Idempotency-Key": "9f1c2d3e-example",
"Content-Type": "application/json",
},
body: JSON.stringify({"number": "+258841234567", "text": "Your order is ready.", "send_at": "2026-11-20T09:30:00+02:00"}),
});
console.log(response.status);
console.log(await response.text());The number does not need the country code: the system can tell the country from the first digit, so 841234567 goes to Mozambique and 923456789 to Angola. It also works with the country code, with or without the + and with spaces: +258 84 123 4567 and 258841234567 are the same number. If the number is not valid, the API responds with 422, the code validation_failed and the reason invalid_number in details.reason.
Without send_at, the message goes out right away and the answer brings its real status: sent if it went out, failed if it failed, or queued if it has to wait its turn.
Send the Idempotency-Key header so a retry never sends twice. See Retries.
The sender
The sender field is optional. If you do not send it, the message goes out with the free sender, NETMSG, which every account can use without asking.
To use another name, give an approved sender. The list is at GET /v1/sms/senders, with the free sender always first and the free field set to true.
Sandbox and Production
- With a
sandbox_key, or while the API is in preparation, the message is simulated: nothing is sent and no credits are used. - With a
prod_key, the message is sent and credits are taken from the SMS balance. The spending limit of the key, in currency, does not apply to these credits.
Scheduled messages
To send the message later, add the send_at field, with the date and time in ISO 8601 and the time zone, for example 2026-11-20T09:30:00+02:00 (Maputo time). The date must be in the future and at most 365 days from now. Otherwise, the API responds with 422 and the reason invalid_send_at, send_at_in_past or send_at_too_far in details.reason.
- The message gets the status
scheduled, with the chosen time inscheduled_for. - When you schedule, the API only checks that the balance is enough. The credits are only taken when the message goes out: until then,
chargedstaysfalse, andGET /v1/sms/balanceshows inscheduled_creditsthe scheduled amount that has not been taken yet. - If the balance is not enough at the chosen time, the message is not sent and ends up
failed, witherrorset toinsufficient_credits.
To cancel the message, use POST /v1/sms/messages/{id}/cancel before the chosen time:
curl
curl -X POST "https://api.mozout.com/v1/sms/messages/00000000-0000-4000-8000-000000000000/cancel" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: en" \
-H "Idempotency-Key: 9f1c2d3e-example"PHP
<?php
$ch = curl_init('https://api.mozout.com/v1/sms/messages/00000000-0000-4000-8000-000000000000/cancel');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: en',
'Idempotency-Key: 9f1c2d3e-example',
],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status, PHP_EOL, $body, PHP_EOL;Python
import os
import requests
headers = {
"Authorization": "Bearer " + os.environ["RLX_API_KEY"],
"Accept-Language": "en",
"Idempotency-Key": "9f1c2d3e-example",
}
r = requests.post("https://api.mozout.com/v1/sms/messages/00000000-0000-4000-8000-000000000000/cancel", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.com/v1/sms/messages/00000000-0000-4000-8000-000000000000/cancel", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "en",
"Idempotency-Key": "9f1c2d3e-example",
},
});
console.log(response.status);
console.log(await response.text());Only messages from your own account that are still scheduled can be cancelled. If the credits were already taken, they go back to the balance, and credits_returned says how many. If the message already went out, is going out or was already cancelled, the API responds with 409 and the reason not_cancellable in details.reason. With a sandbox_ key, the API checks everything and changes nothing.
See a message
Use GET /v1/sms/messages/{id} with the identifier returned when sending. The response includes the status, the chosen time if the message is scheduled, and the charged field, which says whether the credits have already been taken. Simulated messages can only be seen with the key that created them.
See the balance
Use GET /v1/sms/balance. The balance is real in both modes.
See sent messages
GET /v1/sms/messages returns the messages the account sent, in pages, with the status, from, to and number filters. The number comes masked. Account notices, verification codes and simulated messages are not listed.
curl
curl "https://api.mozout.com/v1/sms/messages" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: en"PHP
<?php
$ch = curl_init('https://api.mozout.com/v1/sms/messages');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: en',
],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status, PHP_EOL, $body, PHP_EOL;Python
import os
import requests
headers = {
"Authorization": "Bearer " + os.environ["RLX_API_KEY"],
"Accept-Language": "en",
}
r = requests.get("https://api.mozout.com/v1/sms/messages", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.com/v1/sms/messages", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "en",
},
});
console.log(response.status);
console.log(await response.text());Statistics
GET /v1/sms/stats gives the totals by status, the credits spent and one line per day with messages. Without dates, it counts the last 30 days; at most 366.
Templates
GET /v1/sms/templateslists the templates of the account, andGET /v1/sms/templates/{id}shows one.POST /v1/sms/templatescreates,PATCH /v1/sms/templates/{id}changes andDELETE /v1/sms/templates/{id}deletes.
They are the same templates as on the SMS page of the portal. A template sends nothing: it only keeps the text. The text accepts the variables {$client_name}, {$client_first_name}, {$client_last_name}, {$client_company_name}, {$remetente} and {$data}; any other variable answers 422.
New senders
POST /v1/sms/senders makes the request, with the name, the entity, the country, the tax number, the purpose and a sample message. GET /v1/sms/senders/{sender} says where it stands, by id or by name.
curl
curl -X POST "https://api.mozout.com/v1/sms/senders" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: en" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"sender": "AMINHAMARCA", "entity": "A Minha Empresa, Lda", "country": "Moçambique", "tax_id": "123456789", "purpose": "Avisos de encomenda aos nossos clientes.", "sample": "A sua encomenda está pronta."}'PHP
<?php
$ch = curl_init('https://api.mozout.com/v1/sms/senders');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{"sender": "AMINHAMARCA", "entity": "A Minha Empresa, Lda", "country": "Moçambique", "tax_id": "123456789", "purpose": "Avisos de encomenda aos nossos clientes.", "sample": "A sua encomenda está pronta."}',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: en',
'Idempotency-Key: 9f1c2d3e-example',
'Content-Type: application/json',
],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status, PHP_EOL, $body, PHP_EOL;Python
import os
import requests
headers = {
"Authorization": "Bearer " + os.environ["RLX_API_KEY"],
"Accept-Language": "en",
"Idempotency-Key": "9f1c2d3e-example",
}
payload = {"sender": "AMINHAMARCA", "entity": "A Minha Empresa, Lda", "country": "Moçambique", "tax_id": "123456789", "purpose": "Avisos de encomenda aos nossos clientes.", "sample": "A sua encomenda está pronta."}
r = requests.post("https://api.mozout.com/v1/sms/senders", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.com/v1/sms/senders", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "en",
"Idempotency-Key": "9f1c2d3e-example",
"Content-Type": "application/json",
},
body: JSON.stringify({"sender": "AMINHAMARCA", "entity": "A Minha Empresa, Lda", "country": "Moçambique", "tax_id": "123456789", "purpose": "Avisos de encomenda aos nossos clientes.", "sample": "A sua encomenda está pronta."}),
});
console.log(response.status);
console.log(await response.text());Our team reviews the request and handles the registration with the operators; approval depends on them. If it is rejected, note explains why and you can request it again with the data corrected. To add documents, make the request in the portal, at documents_url.
Numbers that do not receive
POST /v1/sms/opt-outs adds a number to the list of the account: from then on, sending to it answers 422 with number_opted_out. GET /v1/sms/opt-outs shows the list. To take a number off, ask support.
Help
For other questions, see the Knowledge Base.
Operations
16 operations in this area. Click an operation to see its parameters, examples and responses, or to try it in the Playground, without leaving the page.
GETList sent messages
/v1/sms/messages
https://api.mozout.com/v1/sms/messagesNeeds sms:read. The messages this account sent, newest first. Account notices and verification codes are not listed, and messages simulated with a Sandbox key are not either. The number comes masked. If a message fails, error is delivery_failed. charged says whether the credits already left the balance.
Authentication
Needs a valid key in the Authorization: Bearer header. Required permission: sms:read.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
status | query | string: scheduled, queued, sending, sent, simulated, failed, cancelled | no | Only this status. |
from | query | string (date) | no | First day, YYYY-MM-DD. |
to | query | string (date) | no | Last day, YYYY-MM-DD. |
number | query | string | no | Only this number, with or without the country code. |
page | query | integer | no | The page number. The first is 1. |
per_page | query | integer | no | Results per page, from 1 to 100. The default is 10. |
X-API-Mode | header | string: sandbox, production | no | Optional. If it does not match the mode of the key, the request is refused with invalid_request and reason mode_mismatch. Use it to make sure a program never runs with the wrong key. |
Examples
curl
curl "https://api.mozout.com/v1/sms/messages" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: en"PHP
<?php
$ch = curl_init('https://api.mozout.com/v1/sms/messages');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: en',
],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status, PHP_EOL, $body, PHP_EOL;Python
import os
import requests
headers = {
"Authorization": "Bearer " + os.environ["RLX_API_KEY"],
"Accept-Language": "en",
}
r = requests.get("https://api.mozout.com/v1/sms/messages", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.com/v1/sms/messages", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "en",
},
});
console.log(response.status);
console.log(await response.text());Responses
200
List sent messages.
{
"data": [
{
"id": "128",
"status": "sent",
"simulated": false,
"to": "25884****567",
"sender": "NETMSG",
"text": "A sua encomenda está pronta.",
"parts": 1,
"encoding": "GSM",
"credits": 1.0,
"campaign_id": null,
"error": null,
"scheduled_for": "2026-11-05T09:30:00+02:00",
"created_at": "2026-11-05T09:30:00+02:00",
"sent_at": "2026-11-05T09:30:04+02:00",
"charged": true
}
],
"meta": {
"page": 1,
"per_page": 10,
"total": 1,
"total_pages": 1
}
}| Header | Description |
|---|---|
X-Correlation-ID | Identifier of this request. Give it to support when you report a problem. |
X-RateLimit-Limit | Requests allowed per minute. |
X-RateLimit-Remaining | Requests left in the current minute. |
X-RateLimit-Reset | When the minute ends, as a Unix timestamp in seconds. |
X-API-Mode | The mode of the key that made the request: sandbox or production. |
401
The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account.
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
The account cannot use the API (forbidden), the key lacks the permission (insufficient_scope), or the IP address is not on the list of the key (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "This key does not have the required permission.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}422
Some of the data is not valid.
{
"error": {
"code": "validation_failed",
"message": "Some of the data is not valid.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Too many requests. Wait for the time in Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Please try again shortly.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Header | Description |
|---|---|
Retry-After | Seconds to wait before trying again. |
500
An internal error occurred. Give the correlation_id to support.
{
"error": {
"code": "internal_error",
"message": "An internal error occurred. Please give the correlation_id to support.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
The API is turned off.
{
"error": {
"code": "disabled",
"message": "The API is currently turned off.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | unauthorized | The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | The account cannot use the API (forbidden), the key lacks the permission (insufficient_scope), or the IP address is not on the list of the key (ip_not_allowed). |
| 422 | validation_failed | Some of the data is not valid. |
| 429 | rate_limited | Too many requests. Wait for the time in Retry-After. |
| 500 | internal_error | An internal error occurred. Give the correlation_id to support. |
| 503 | disabled | The API is turned off. |
The error format is explained in Errors.
POSTSend an SMS
/v1/sms/messages
https://api.mozout.com/v1/sms/messagesNeeds sms:write and an active SMS reseller account. With a Sandbox key, or while the API is in preparation, the message is simulated: nothing is sent and no credits are used. With a Production key the message enters the queue and credits are taken from the SMS balance (the key spending limit, in currency, does not apply to these credits). Send Idempotency-Key so a retry never sends twice. Without send_at the message goes out right away and the answer brings its real status: sent, failed, or queued if it has to wait its turn. With send_at it stays scheduled: the balance is only checked now and the credits leave it when the message goes out (charged is false until then); if the balance is short at that time, the message is not sent and ends up failed with error set to insufficient_credits. A scheduled message can be cancelled with POST /v1/sms/messages/{id}/cancel.
Authentication
Needs a valid key in the Authorization: Bearer header. Required permission: sms:write.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
Idempotency-Key | header | string | no | Any unique value, up to 255 visible characters. Valid for 24 hours per key. Repeating the same request returns the saved answer; a different body, or a first request still in progress, returns 409. |
X-API-Mode | header | string: sandbox, production | no | Optional. If it does not match the mode of the key, the request is refused with invalid_request and reason mode_mismatch. Use it to make sure a program never runs with the wrong key. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
number | string | yes | With or without the country code, spaces allowed: +258841234567, 258 84 123 4567 or 84 123 4567. Mozambican and Angolan mobile numbers are recognised on their own; any other number without a code uses the country of your account. |
text | string | yes | |
sender | string | no | Optional. An approved sender; if omitted, the free sender (see GET /v1/sms/senders). |
send_at | string (date-time) | no | Optional. Schedules the message: ISO 8601 date and time with the time zone, such as 2026-11-20T09:30:00+02:00. It must be in the future and at most 365 days from now. Without it, the message goes out right away. |
Examples
curl
curl -X POST "https://api.mozout.com/v1/sms/messages" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: en" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"number": "+258841234567", "text": "Your order is ready.", "send_at": "2026-11-20T09:30:00+02:00"}'PHP
<?php
$ch = curl_init('https://api.mozout.com/v1/sms/messages');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{"number": "+258841234567", "text": "Your order is ready.", "send_at": "2026-11-20T09:30:00+02:00"}',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: en',
'Idempotency-Key: 9f1c2d3e-example',
'Content-Type: application/json',
],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status, PHP_EOL, $body, PHP_EOL;Python
import os
import requests
headers = {
"Authorization": "Bearer " + os.environ["RLX_API_KEY"],
"Accept-Language": "en",
"Idempotency-Key": "9f1c2d3e-example",
}
payload = {"number": "+258841234567", "text": "Your order is ready.", "send_at": "2026-11-20T09:30:00+02:00"}
r = requests.post("https://api.mozout.com/v1/sms/messages", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.com/v1/sms/messages", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "en",
"Idempotency-Key": "9f1c2d3e-example",
"Content-Type": "application/json",
},
body: JSON.stringify({"number": "+258841234567", "text": "Your order is ready.", "send_at": "2026-11-20T09:30:00+02:00"}),
});
console.log(response.status);
console.log(await response.text());Responses
201
The message: sent, simulated, scheduled or waiting in the queue.
{
"data": {
"id": "412",
"status": "scheduled",
"simulated": false,
"to": "25884****567",
"sender": "NETMSG",
"parts": 1,
"encoding": "GSM",
"credits": 1.0,
"charged": false,
"mode": "production",
"error": null,
"scheduled_for": "2026-11-20T09:30:00+02:00",
"created_at": "2026-11-10T12:00:00+02:00",
"sent_at": null
},
"meta": {}
}| Field | Type | Description |
|---|---|---|
data.id | string | A number for messages in the queue, a UUID for simulated ones. |
data.status | string: scheduled, queued, sending, sent, simulated, failed, cancelled | scheduled: waiting for the time in scheduled_for, and it can still be cancelled. queued: waiting its turn to go out. |
data.simulated | boolean | True when no real SMS goes out. |
data.to | string | The number, partly hidden. |
data.credits | number | What the message costs in credits. See charged to know whether they already left the SMS balance. Always 0 when simulated by the API. |
data.would_cost | number | Only on simulated messages: what a real send would cost. |
data.error | string, null | delivery_failed when it could not be delivered; insufficient_credits when a scheduled message did not have enough balance when it was due to go out. |
data.charged | boolean | True when the credits have left the SMS balance. A scheduled message is only charged when it goes out; failed, cancelled and simulated messages give the credits back. |
data.scheduled_for | string, null (date-time) | The time chosen in send_at, while the message is scheduled or after it was cancelled; otherwise null. |
| Header | Description |
|---|---|
X-Correlation-ID | Identifier of this request. Give it to support when you report a problem. |
X-RateLimit-Limit | Requests allowed per minute. |
X-RateLimit-Remaining | Requests left in the current minute. |
X-RateLimit-Reset | When the minute ends, as a Unix timestamp in seconds. |
X-API-Mode | The mode of the key that made the request: sandbox or production. |
X-API-Simulated | Present and true when this write was simulated: nothing changed and nothing was charged. |
401
The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account.
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
This account does not have an active SMS reseller plan (sms_reseller_required), the key lacks the permission (insufficient_scope), or the account cannot use the API (forbidden).
{
"error": {
"code": "insufficient_scope",
"message": "This key does not have the required permission.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}409
The Idempotency-Key was used with a different request, or the first request is still in progress.
{
"error": {
"code": "idempotency_conflict",
"message": "This Idempotency-Key was already used with a different request, or the first request is still in progress.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "different_request"
}
}
}422
Some of the data is not valid.
{
"error": {
"code": "validation_failed",
"message": "Some of the data is not valid.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Too many requests. Wait for the time in Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Please try again shortly.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Header | Description |
|---|---|
Retry-After | Seconds to wait before trying again. |
500
An internal error occurred. Give the correlation_id to support.
{
"error": {
"code": "internal_error",
"message": "An internal error occurred. Please give the correlation_id to support.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
The API is turned off.
{
"error": {
"code": "disabled",
"message": "The API is currently turned off.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | unauthorized | The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account. |
| 403 | sms_reseller_required, insufficient_scope, forbidden | This account does not have an active SMS reseller plan (sms_reseller_required), the key lacks the permission (insufficient_scope), or the account cannot use the API (forbidden). |
| 409 | idempotency_conflict | The Idempotency-Key was used with a different request, or the first request is still in progress. |
| 422 | validation_failed | Some of the data is not valid. |
| 429 | rate_limited | Too many requests. Wait for the time in Retry-After. |
| 500 | internal_error | An internal error occurred. Give the correlation_id to support. |
| 503 | disabled | The API is turned off. |
The error format is explained in Errors.
GETSee one SMS
/v1/sms/messages/{id}
https://api.mozout.com/v1/sms/messages/{id}Needs sms:read. Simulated messages can only be seen with the key that created them.
Authentication
Needs a valid key in the Authorization: Bearer header. Required permission: sms:read.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | The id returned when sending. |
X-API-Mode | header | string: sandbox, production | no | Optional. If it does not match the mode of the key, the request is refused with invalid_request and reason mode_mismatch. Use it to make sure a program never runs with the wrong key. |
Examples
curl
curl "https://api.mozout.com/v1/sms/messages/00000000-0000-4000-8000-000000000000" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: en"PHP
<?php
$ch = curl_init('https://api.mozout.com/v1/sms/messages/00000000-0000-4000-8000-000000000000');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: en',
],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status, PHP_EOL, $body, PHP_EOL;Python
import os
import requests
headers = {
"Authorization": "Bearer " + os.environ["RLX_API_KEY"],
"Accept-Language": "en",
}
r = requests.get("https://api.mozout.com/v1/sms/messages/00000000-0000-4000-8000-000000000000", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.com/v1/sms/messages/00000000-0000-4000-8000-000000000000", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "en",
},
});
console.log(response.status);
console.log(await response.text());Responses
200
The message.
{
"data": {
"id": "7f0c9d2e-3a51-4c7e-9b1a-2d4f6a8b0c11",
"status": "simulated",
"simulated": true,
"to": "25884****567",
"sender": "NETMSG",
"parts": 1,
"encoding": "GSM",
"would_cost": 1,
"mode": "sandbox",
"credits": 0,
"created_at": "2026-11-04T10:00:00+02:00",
"error": null,
"sent_at": null,
"charged": false,
"scheduled_for": null
},
"meta": {}
}| Field | Type | Description |
|---|---|---|
data.id | string | A number for messages in the queue, a UUID for simulated ones. |
data.status | string: scheduled, queued, sending, sent, simulated, failed, cancelled | scheduled: waiting for the time in scheduled_for, and it can still be cancelled. queued: waiting its turn to go out. |
data.simulated | boolean | True when no real SMS goes out. |
data.to | string | The number, partly hidden. |
data.credits | number | What the message costs in credits. See charged to know whether they already left the SMS balance. Always 0 when simulated by the API. |
data.would_cost | number | Only on simulated messages: what a real send would cost. |
data.error | string, null | delivery_failed when it could not be delivered; insufficient_credits when a scheduled message did not have enough balance when it was due to go out. |
data.charged | boolean | True when the credits have left the SMS balance. A scheduled message is only charged when it goes out; failed, cancelled and simulated messages give the credits back. |
data.scheduled_for | string, null (date-time) | The time chosen in send_at, while the message is scheduled or after it was cancelled; otherwise null. |
| Header | Description |
|---|---|
X-Correlation-ID | Identifier of this request. Give it to support when you report a problem. |
X-RateLimit-Limit | Requests allowed per minute. |
X-RateLimit-Remaining | Requests left in the current minute. |
X-RateLimit-Reset | When the minute ends, as a Unix timestamp in seconds. |
X-API-Mode | The mode of the key that made the request: sandbox or production. |
401
The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account.
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
This account does not have an active SMS reseller plan (sms_reseller_required), the key lacks the permission (insufficient_scope), or the account cannot use the API (forbidden).
{
"error": {
"code": "insufficient_scope",
"message": "This key does not have the required permission.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}404
Not found.
{
"error": {
"code": "not_found",
"message": "Not found.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Too many requests. Wait for the time in Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Please try again shortly.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Header | Description |
|---|---|
Retry-After | Seconds to wait before trying again. |
500
An internal error occurred. Give the correlation_id to support.
{
"error": {
"code": "internal_error",
"message": "An internal error occurred. Please give the correlation_id to support.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
The API is turned off.
{
"error": {
"code": "disabled",
"message": "The API is currently turned off.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | unauthorized | The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account. |
| 403 | sms_reseller_required, insufficient_scope, forbidden | This account does not have an active SMS reseller plan (sms_reseller_required), the key lacks the permission (insufficient_scope), or the account cannot use the API (forbidden). |
| 404 | not_found | Not found. |
| 429 | rate_limited | Too many requests. Wait for the time in Retry-After. |
| 500 | internal_error | An internal error occurred. Give the correlation_id to support. |
| 503 | disabled | The API is turned off. |
The error format is explained in Errors.
GETSee the SMS balance
/v1/sms/balance
https://api.mozout.com/v1/sms/balanceNeeds sms:read. The balance is real in both modes.
Authentication
Needs a valid key in the Authorization: Bearer header. Required permission: sms:read.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
X-API-Mode | header | string: sandbox, production | no | Optional. If it does not match the mode of the key, the request is refused with invalid_request and reason mode_mismatch. Use it to make sure a program never runs with the wrong key. |
Examples
curl
curl "https://api.mozout.com/v1/sms/balance" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: en"PHP
<?php
$ch = curl_init('https://api.mozout.com/v1/sms/balance');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: en',
],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status, PHP_EOL, $body, PHP_EOL;Python
import os
import requests
headers = {
"Authorization": "Bearer " + os.environ["RLX_API_KEY"],
"Accept-Language": "en",
}
r = requests.get("https://api.mozout.com/v1/sms/balance", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.com/v1/sms/balance", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "en",
},
});
console.log(response.status);
console.log(await response.text());Responses
200
Balance and daily limit.
{
"data": {
"balance": 50,
"unit": "credits",
"daily_limit": 200,
"sent_today": 3,
"mode": "sandbox",
"scheduled_credits": 0.0
},
"meta": {}
}| Field | Type | Description |
|---|---|---|
data.scheduled_credits | number | Credits of scheduled messages that were not charged yet. They are still in balance and leave it when each message goes out. |
| Header | Description |
|---|---|
X-Correlation-ID | Identifier of this request. Give it to support when you report a problem. |
X-RateLimit-Limit | Requests allowed per minute. |
X-RateLimit-Remaining | Requests left in the current minute. |
X-RateLimit-Reset | When the minute ends, as a Unix timestamp in seconds. |
X-API-Mode | The mode of the key that made the request: sandbox or production. |
401
The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account.
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
This account does not have an active SMS reseller plan (sms_reseller_required), the key lacks the permission (insufficient_scope), or the account cannot use the API (forbidden).
{
"error": {
"code": "insufficient_scope",
"message": "This key does not have the required permission.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}429
Too many requests. Wait for the time in Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Please try again shortly.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Header | Description |
|---|---|
Retry-After | Seconds to wait before trying again. |
500
An internal error occurred. Give the correlation_id to support.
{
"error": {
"code": "internal_error",
"message": "An internal error occurred. Please give the correlation_id to support.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
The API is turned off.
{
"error": {
"code": "disabled",
"message": "The API is currently turned off.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | unauthorized | The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account. |
| 403 | sms_reseller_required, insufficient_scope, forbidden | This account does not have an active SMS reseller plan (sms_reseller_required), the key lacks the permission (insufficient_scope), or the account cannot use the API (forbidden). |
| 429 | rate_limited | Too many requests. Wait for the time in Retry-After. |
| 500 | internal_error | An internal error occurred. Give the correlation_id to support. |
| 503 | disabled | The API is turned off. |
The error format is explained in Errors.
GETList the SMS senders
/v1/sms/senders
https://api.mozout.com/v1/sms/sendersNeeds sms:read. The free sender always comes first, with free: true.
Authentication
Needs a valid key in the Authorization: Bearer header. Required permission: sms:read.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
X-API-Mode | header | string: sandbox, production | no | Optional. If it does not match the mode of the key, the request is refused with invalid_request and reason mode_mismatch. Use it to make sure a program never runs with the wrong key. |
Examples
curl
curl "https://api.mozout.com/v1/sms/senders" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: en"PHP
<?php
$ch = curl_init('https://api.mozout.com/v1/sms/senders');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: en',
],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status, PHP_EOL, $body, PHP_EOL;Python
import os
import requests
headers = {
"Authorization": "Bearer " + os.environ["RLX_API_KEY"],
"Accept-Language": "en",
}
r = requests.get("https://api.mozout.com/v1/sms/senders", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.com/v1/sms/senders", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "en",
},
});
console.log(response.status);
console.log(await response.text());Responses
200
The senders of this account.
{
"data": [
{
"sender": "NETMSG",
"status": "approved",
"free": true
},
{
"sender": "MINHAEMPRESA",
"status": "pending",
"free": false
}
],
"meta": {}
}| Header | Description |
|---|---|
X-Correlation-ID | Identifier of this request. Give it to support when you report a problem. |
X-RateLimit-Limit | Requests allowed per minute. |
X-RateLimit-Remaining | Requests left in the current minute. |
X-RateLimit-Reset | When the minute ends, as a Unix timestamp in seconds. |
X-API-Mode | The mode of the key that made the request: sandbox or production. |
401
The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account.
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
This account does not have an active SMS reseller plan (sms_reseller_required), the key lacks the permission (insufficient_scope), or the account cannot use the API (forbidden).
{
"error": {
"code": "insufficient_scope",
"message": "This key does not have the required permission.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}429
Too many requests. Wait for the time in Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Please try again shortly.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Header | Description |
|---|---|
Retry-After | Seconds to wait before trying again. |
500
An internal error occurred. Give the correlation_id to support.
{
"error": {
"code": "internal_error",
"message": "An internal error occurred. Please give the correlation_id to support.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
The API is turned off.
{
"error": {
"code": "disabled",
"message": "The API is currently turned off.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | unauthorized | The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account. |
| 403 | sms_reseller_required, insufficient_scope, forbidden | This account does not have an active SMS reseller plan (sms_reseller_required), the key lacks the permission (insufficient_scope), or the account cannot use the API (forbidden). |
| 429 | rate_limited | Too many requests. Wait for the time in Retry-After. |
| 500 | internal_error | An internal error occurred. Give the correlation_id to support. |
| 503 | disabled | The API is turned off. |
The error format is explained in Errors.
POSTRequest a sender
/v1/sms/senders
https://api.mozout.com/v1/sms/sendersNeeds sms:write. Up to 11 letters, numbers and spaces, at most 30 in the account. The team reviews the request and registers it with the operators; approval depends on them. After a rejection, send it again with the data corrected. Documents are sent in the account portal, when the request is made there. Limited to 20 changes per minute.
Authentication
Needs a valid key in the Authorization: Bearer header. Required permission: sms:write.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
X-API-Mode | header | string: sandbox, production | no | Optional. If it does not match the mode of the key, the request is refused with invalid_request and reason mode_mismatch. Use it to make sure a program never runs with the wrong key. |
Idempotency-Key | header | string | no | A unique identifier for this request, so it can be repeated without duplicating it. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
sender | string | yes | |
entity | string | yes | |
country | string | yes | |
tax_id | string | yes | |
purpose | string | yes | |
sample | string | yes |
Examples
curl
curl -X POST "https://api.mozout.com/v1/sms/senders" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: en" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"sender": "AMINHAMARCA", "entity": "A Minha Empresa, Lda", "country": "Moçambique", "tax_id": "123456789", "purpose": "Avisos de encomenda aos nossos clientes.", "sample": "A sua encomenda está pronta."}'PHP
<?php
$ch = curl_init('https://api.mozout.com/v1/sms/senders');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{"sender": "AMINHAMARCA", "entity": "A Minha Empresa, Lda", "country": "Moçambique", "tax_id": "123456789", "purpose": "Avisos de encomenda aos nossos clientes.", "sample": "A sua encomenda está pronta."}',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: en',
'Idempotency-Key: 9f1c2d3e-example',
'Content-Type: application/json',
],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status, PHP_EOL, $body, PHP_EOL;Python
import os
import requests
headers = {
"Authorization": "Bearer " + os.environ["RLX_API_KEY"],
"Accept-Language": "en",
"Idempotency-Key": "9f1c2d3e-example",
}
payload = {"sender": "AMINHAMARCA", "entity": "A Minha Empresa, Lda", "country": "Moçambique", "tax_id": "123456789", "purpose": "Avisos de encomenda aos nossos clientes.", "sample": "A sua encomenda está pronta."}
r = requests.post("https://api.mozout.com/v1/sms/senders", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.com/v1/sms/senders", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "en",
"Idempotency-Key": "9f1c2d3e-example",
"Content-Type": "application/json",
},
body: JSON.stringify({"sender": "AMINHAMARCA", "entity": "A Minha Empresa, Lda", "country": "Moçambique", "tax_id": "123456789", "purpose": "Avisos de encomenda aos nossos clientes.", "sample": "A sua encomenda está pronta."}),
});
console.log(response.status);
console.log(await response.text());Responses
201
Request a sender.
{
"data": {
"id": 7,
"sender": "AMINHAMARCA",
"status": "pending",
"free": false,
"entity": "A Minha Empresa, Lda",
"country": "Moçambique",
"purpose": "Avisos de encomenda aos nossos clientes.",
"sample": "A sua encomenda está pronta.",
"note": null,
"documents": 0,
"documents_url": "https://my.example.com/sms-center.php?view=senders&language=portuguese¤cy=5",
"created_at": "2026-11-05T09:30:00+02:00",
"updated_at": "2026-11-05T09:30:00+02:00",
"simulated": true
},
"meta": {}
}| Header | Description |
|---|---|
X-Correlation-ID | Identifier of this request. Give it to support when you report a problem. |
X-RateLimit-Limit | Requests allowed per minute. |
X-RateLimit-Remaining | Requests left in the current minute. |
X-RateLimit-Reset | When the minute ends, as a Unix timestamp in seconds. |
X-API-Mode | The mode of the key that made the request: sandbox or production. |
401
The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account.
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
The account cannot use the API (forbidden), the key lacks the permission (insufficient_scope), or the IP address is not on the list of the key (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "This key does not have the required permission.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}409
The operation cannot be done in the current state. See details.reason.
{
"error": {
"code": "conflict",
"message": "This operation only works on an active domain.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "domain_not_active"
}
}
}422
Some of the data is not valid.
{
"error": {
"code": "validation_failed",
"message": "Some of the data is not valid.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Too many requests. Wait for the time in Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Please try again shortly.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Header | Description |
|---|---|
Retry-After | Seconds to wait before trying again. |
500
An internal error occurred. Give the correlation_id to support.
{
"error": {
"code": "internal_error",
"message": "An internal error occurred. Please give the correlation_id to support.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
The API is turned off.
{
"error": {
"code": "disabled",
"message": "The API is currently turned off.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | unauthorized | The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | The account cannot use the API (forbidden), the key lacks the permission (insufficient_scope), or the IP address is not on the list of the key (ip_not_allowed). |
| 409 | conflict | The operation cannot be done in the current state. See details.reason. |
| 422 | validation_failed | Some of the data is not valid. |
| 429 | rate_limited | Too many requests. Wait for the time in Retry-After. |
| 500 | internal_error | An internal error occurred. Give the correlation_id to support. |
| 503 | disabled | The API is turned off. |
The error format is explained in Errors.
GETSee sending statistics
/v1/sms/stats
https://api.mozout.com/v1/sms/statsNeeds sms:read. Totals and one line per day with messages. Without dates, the last 30 days; at most 366 days. Failed, cancelled and simulated messages do not count in credits_spent. Scheduled messages that were not charged yet do not count either.
Authentication
Needs a valid key in the Authorization: Bearer header. Required permission: sms:read.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
from | query | string (date) | no | First day, YYYY-MM-DD. |
to | query | string (date) | no | Last day, YYYY-MM-DD. |
X-API-Mode | header | string: sandbox, production | no | Optional. If it does not match the mode of the key, the request is refused with invalid_request and reason mode_mismatch. Use it to make sure a program never runs with the wrong key. |
Examples
curl
curl "https://api.mozout.com/v1/sms/stats" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: en"PHP
<?php
$ch = curl_init('https://api.mozout.com/v1/sms/stats');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: en',
],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status, PHP_EOL, $body, PHP_EOL;Python
import os
import requests
headers = {
"Authorization": "Bearer " + os.environ["RLX_API_KEY"],
"Accept-Language": "en",
}
r = requests.get("https://api.mozout.com/v1/sms/stats", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.com/v1/sms/stats", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "en",
},
});
console.log(response.status);
console.log(await response.text());Responses
200
See sending statistics.
{
"data": {
"from": "2026-10-07",
"to": "2026-11-05",
"messages": 12,
"parts": 14,
"credits_spent": 13.0,
"by_status": {
"scheduled": 0,
"queued": 0,
"sending": 0,
"sent": 11,
"simulated": 0,
"failed": 1,
"cancelled": 0
},
"by_day": [
{
"date": "2026-11-05",
"messages": 12,
"sent": 11,
"failed": 1,
"credits": 13.0
}
]
},
"meta": {}
}| Header | Description |
|---|---|
X-Correlation-ID | Identifier of this request. Give it to support when you report a problem. |
X-RateLimit-Limit | Requests allowed per minute. |
X-RateLimit-Remaining | Requests left in the current minute. |
X-RateLimit-Reset | When the minute ends, as a Unix timestamp in seconds. |
X-API-Mode | The mode of the key that made the request: sandbox or production. |
401
The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account.
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
The account cannot use the API (forbidden), the key lacks the permission (insufficient_scope), or the IP address is not on the list of the key (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "This key does not have the required permission.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}422
Some of the data is not valid.
{
"error": {
"code": "validation_failed",
"message": "Some of the data is not valid.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Too many requests. Wait for the time in Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Please try again shortly.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Header | Description |
|---|---|
Retry-After | Seconds to wait before trying again. |
500
An internal error occurred. Give the correlation_id to support.
{
"error": {
"code": "internal_error",
"message": "An internal error occurred. Please give the correlation_id to support.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
The API is turned off.
{
"error": {
"code": "disabled",
"message": "The API is currently turned off.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | unauthorized | The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | The account cannot use the API (forbidden), the key lacks the permission (insufficient_scope), or the IP address is not on the list of the key (ip_not_allowed). |
| 422 | validation_failed | Some of the data is not valid. |
| 429 | rate_limited | Too many requests. Wait for the time in Retry-After. |
| 500 | internal_error | An internal error occurred. Give the correlation_id to support. |
| 503 | disabled | The API is turned off. |
The error format is explained in Errors.
GETList templates
/v1/sms/templates
https://api.mozout.com/v1/sms/templatesNeeds sms:read. The templates of this account, by name.
Authentication
Needs a valid key in the Authorization: Bearer header. Required permission: sms:read.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
category | query | string: general, notice, promotion, billing, confirmation | no | Only this category. |
language | query | string: pt, en | no | Only this language. |
page | query | integer | no | The page number. The first is 1. |
per_page | query | integer | no | Results per page, from 1 to 100. The default is 10. |
X-API-Mode | header | string: sandbox, production | no | Optional. If it does not match the mode of the key, the request is refused with invalid_request and reason mode_mismatch. Use it to make sure a program never runs with the wrong key. |
Examples
curl
curl "https://api.mozout.com/v1/sms/templates" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: en"PHP
<?php
$ch = curl_init('https://api.mozout.com/v1/sms/templates');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: en',
],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status, PHP_EOL, $body, PHP_EOL;Python
import os
import requests
headers = {
"Authorization": "Bearer " + os.environ["RLX_API_KEY"],
"Accept-Language": "en",
}
r = requests.get("https://api.mozout.com/v1/sms/templates", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.com/v1/sms/templates", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "en",
},
});
console.log(response.status);
console.log(await response.text());Responses
200
List templates.
{
"data": [
{
"id": 41,
"name": "Aviso de factura",
"text": "Olá {$client_first_name}, a sua factura vence hoje.",
"category": "notice",
"language": "pt",
"created_at": "2026-11-05T09:30:00+02:00",
"updated_at": "2026-11-05T09:30:00+02:00"
}
],
"meta": {
"page": 1,
"per_page": 10,
"total": 1,
"total_pages": 1
}
}| Header | Description |
|---|---|
X-Correlation-ID | Identifier of this request. Give it to support when you report a problem. |
X-RateLimit-Limit | Requests allowed per minute. |
X-RateLimit-Remaining | Requests left in the current minute. |
X-RateLimit-Reset | When the minute ends, as a Unix timestamp in seconds. |
X-API-Mode | The mode of the key that made the request: sandbox or production. |
401
The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account.
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
The account cannot use the API (forbidden), the key lacks the permission (insufficient_scope), or the IP address is not on the list of the key (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "This key does not have the required permission.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}422
Some of the data is not valid.
{
"error": {
"code": "validation_failed",
"message": "Some of the data is not valid.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Too many requests. Wait for the time in Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Please try again shortly.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Header | Description |
|---|---|
Retry-After | Seconds to wait before trying again. |
500
An internal error occurred. Give the correlation_id to support.
{
"error": {
"code": "internal_error",
"message": "An internal error occurred. Please give the correlation_id to support.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
The API is turned off.
{
"error": {
"code": "disabled",
"message": "The API is currently turned off.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | unauthorized | The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | The account cannot use the API (forbidden), the key lacks the permission (insufficient_scope), or the IP address is not on the list of the key (ip_not_allowed). |
| 422 | validation_failed | Some of the data is not valid. |
| 429 | rate_limited | Too many requests. Wait for the time in Retry-After. |
| 500 | internal_error | An internal error occurred. Give the correlation_id to support. |
| 503 | disabled | The API is turned off. |
The error format is explained in Errors.
POSTCreate a template
/v1/sms/templates
https://api.mozout.com/v1/sms/templatesNeeds sms:write. The name must be unique in the account. The text accepts {$client_name}, {$client_first_name}, {$client_last_name}, {$client_company_name}, {$remetente} and {$data}. Limited to 20 changes per minute.
Authentication
Needs a valid key in the Authorization: Bearer header. Required permission: sms:write.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
X-API-Mode | header | string: sandbox, production | no | Optional. If it does not match the mode of the key, the request is refused with invalid_request and reason mode_mismatch. Use it to make sure a program never runs with the wrong key. |
Idempotency-Key | header | string | no | A unique identifier for this request, so it can be repeated without duplicating it. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | |
text | string | yes | |
category | string: general, notice, promotion, billing, confirmation | no | |
language | string: pt, en | no |
Examples
curl
curl -X POST "https://api.mozout.com/v1/sms/templates" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: en" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"name": "Aviso de factura", "text": "Olá {$client_first_name}, a sua factura vence hoje.", "category": "notice", "language": "pt"}'PHP
<?php
$ch = curl_init('https://api.mozout.com/v1/sms/templates');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{"name": "Aviso de factura", "text": "Olá {$client_first_name}, a sua factura vence hoje.", "category": "notice", "language": "pt"}',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: en',
'Idempotency-Key: 9f1c2d3e-example',
'Content-Type: application/json',
],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status, PHP_EOL, $body, PHP_EOL;Python
import os
import requests
headers = {
"Authorization": "Bearer " + os.environ["RLX_API_KEY"],
"Accept-Language": "en",
"Idempotency-Key": "9f1c2d3e-example",
}
payload = {"name": "Aviso de factura", "text": "Olá {$client_first_name}, a sua factura vence hoje.", "category": "notice", "language": "pt"}
r = requests.post("https://api.mozout.com/v1/sms/templates", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.com/v1/sms/templates", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "en",
"Idempotency-Key": "9f1c2d3e-example",
"Content-Type": "application/json",
},
body: JSON.stringify({"name": "Aviso de factura", "text": "Olá {$client_first_name}, a sua factura vence hoje.", "category": "notice", "language": "pt"}),
});
console.log(response.status);
console.log(await response.text());Responses
201
Create a template.
{
"data": {
"id": 41,
"name": "Aviso de factura",
"text": "Olá {$client_first_name}, a sua factura vence hoje.",
"category": "notice",
"language": "pt",
"created_at": "2026-11-05T09:30:00+02:00",
"updated_at": "2026-11-05T09:30:00+02:00",
"simulated": true
},
"meta": {}
}| Header | Description |
|---|---|
X-Correlation-ID | Identifier of this request. Give it to support when you report a problem. |
X-RateLimit-Limit | Requests allowed per minute. |
X-RateLimit-Remaining | Requests left in the current minute. |
X-RateLimit-Reset | When the minute ends, as a Unix timestamp in seconds. |
X-API-Mode | The mode of the key that made the request: sandbox or production. |
401
The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account.
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
The account cannot use the API (forbidden), the key lacks the permission (insufficient_scope), or the IP address is not on the list of the key (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "This key does not have the required permission.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}409
The operation cannot be done in the current state. See details.reason.
{
"error": {
"code": "conflict",
"message": "This operation only works on an active domain.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "domain_not_active"
}
}
}422
Some of the data is not valid.
{
"error": {
"code": "validation_failed",
"message": "Some of the data is not valid.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Too many requests. Wait for the time in Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Please try again shortly.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Header | Description |
|---|---|
Retry-After | Seconds to wait before trying again. |
500
An internal error occurred. Give the correlation_id to support.
{
"error": {
"code": "internal_error",
"message": "An internal error occurred. Please give the correlation_id to support.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
The API is turned off.
{
"error": {
"code": "disabled",
"message": "The API is currently turned off.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | unauthorized | The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | The account cannot use the API (forbidden), the key lacks the permission (insufficient_scope), or the IP address is not on the list of the key (ip_not_allowed). |
| 409 | conflict | The operation cannot be done in the current state. See details.reason. |
| 422 | validation_failed | Some of the data is not valid. |
| 429 | rate_limited | Too many requests. Wait for the time in Retry-After. |
| 500 | internal_error | An internal error occurred. Give the correlation_id to support. |
| 503 | disabled | The API is turned off. |
The error format is explained in Errors.
GETSee a template
/v1/sms/templates/{id}
https://api.mozout.com/v1/sms/templates/{id}Needs sms:read. A template of this account.
Authentication
Needs a valid key in the Authorization: Bearer header. Required permission: sms:read.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | The id of the template. |
X-API-Mode | header | string: sandbox, production | no | Optional. If it does not match the mode of the key, the request is refused with invalid_request and reason mode_mismatch. Use it to make sure a program never runs with the wrong key. |
Examples
curl
curl "https://api.mozout.com/v1/sms/templates/00000000-0000-4000-8000-000000000000" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: en"PHP
<?php
$ch = curl_init('https://api.mozout.com/v1/sms/templates/00000000-0000-4000-8000-000000000000');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: en',
],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status, PHP_EOL, $body, PHP_EOL;Python
import os
import requests
headers = {
"Authorization": "Bearer " + os.environ["RLX_API_KEY"],
"Accept-Language": "en",
}
r = requests.get("https://api.mozout.com/v1/sms/templates/00000000-0000-4000-8000-000000000000", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.com/v1/sms/templates/00000000-0000-4000-8000-000000000000", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "en",
},
});
console.log(response.status);
console.log(await response.text());Responses
200
See a template.
{
"data": {
"id": 41,
"name": "Aviso de factura",
"text": "Olá {$client_first_name}, a sua factura vence hoje.",
"category": "notice",
"language": "pt",
"created_at": "2026-11-05T09:30:00+02:00",
"updated_at": "2026-11-05T09:30:00+02:00"
},
"meta": {}
}| Header | Description |
|---|---|
X-Correlation-ID | Identifier of this request. Give it to support when you report a problem. |
X-RateLimit-Limit | Requests allowed per minute. |
X-RateLimit-Remaining | Requests left in the current minute. |
X-RateLimit-Reset | When the minute ends, as a Unix timestamp in seconds. |
X-API-Mode | The mode of the key that made the request: sandbox or production. |
401
The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account.
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
The account cannot use the API (forbidden), the key lacks the permission (insufficient_scope), or the IP address is not on the list of the key (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "This key does not have the required permission.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}404
Not found.
{
"error": {
"code": "not_found",
"message": "Not found.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Too many requests. Wait for the time in Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Please try again shortly.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Header | Description |
|---|---|
Retry-After | Seconds to wait before trying again. |
500
An internal error occurred. Give the correlation_id to support.
{
"error": {
"code": "internal_error",
"message": "An internal error occurred. Please give the correlation_id to support.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
The API is turned off.
{
"error": {
"code": "disabled",
"message": "The API is currently turned off.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | unauthorized | The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | The account cannot use the API (forbidden), the key lacks the permission (insufficient_scope), or the IP address is not on the list of the key (ip_not_allowed). |
| 404 | not_found | Not found. |
| 429 | rate_limited | Too many requests. Wait for the time in Retry-After. |
| 500 | internal_error | An internal error occurred. Give the correlation_id to support. |
| 503 | disabled | The API is turned off. |
The error format is explained in Errors.
PATCHChange a template
/v1/sms/templates/{id}
https://api.mozout.com/v1/sms/templates/{id}Needs sms:write. Send only the fields to change. Limited to 20 changes per minute.
Authentication
Needs a valid key in the Authorization: Bearer header. Required permission: sms:write.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | The id of the template. |
X-API-Mode | header | string: sandbox, production | no | Optional. If it does not match the mode of the key, the request is refused with invalid_request and reason mode_mismatch. Use it to make sure a program never runs with the wrong key. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | no | |
text | string | no | |
category | string: general, notice, promotion, billing, confirmation | no | |
language | string: pt, en | no |
Examples
curl
curl -X PATCH "https://api.mozout.com/v1/sms/templates/00000000-0000-4000-8000-000000000000" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: en" \
-H "Content-Type: application/json" \
-d '{"text": "Olá {$client_first_name}, a sua factura vence amanhã."}'PHP
<?php
$ch = curl_init('https://api.mozout.com/v1/sms/templates/00000000-0000-4000-8000-000000000000');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_POSTFIELDS => '{"text": "Olá {$client_first_name}, a sua factura vence amanhã."}',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: en',
'Content-Type: application/json',
],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status, PHP_EOL, $body, PHP_EOL;Python
import os
import requests
headers = {
"Authorization": "Bearer " + os.environ["RLX_API_KEY"],
"Accept-Language": "en",
}
payload = {"text": "Olá {$client_first_name}, a sua factura vence amanhã."}
r = requests.patch("https://api.mozout.com/v1/sms/templates/00000000-0000-4000-8000-000000000000", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.com/v1/sms/templates/00000000-0000-4000-8000-000000000000", {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "en",
"Content-Type": "application/json",
},
body: JSON.stringify({"text": "Olá {$client_first_name}, a sua factura vence amanhã."}),
});
console.log(response.status);
console.log(await response.text());Responses
200
Change a template.
{
"data": {
"id": 41,
"name": "Aviso de factura",
"text": "Olá {$client_first_name}, a sua factura vence hoje.",
"category": "notice",
"language": "pt",
"created_at": "2026-11-05T09:30:00+02:00",
"updated_at": "2026-11-05T09:30:00+02:00",
"simulated": true
},
"meta": {}
}| Header | Description |
|---|---|
X-Correlation-ID | Identifier of this request. Give it to support when you report a problem. |
X-RateLimit-Limit | Requests allowed per minute. |
X-RateLimit-Remaining | Requests left in the current minute. |
X-RateLimit-Reset | When the minute ends, as a Unix timestamp in seconds. |
X-API-Mode | The mode of the key that made the request: sandbox or production. |
401
The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account.
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
The account cannot use the API (forbidden), the key lacks the permission (insufficient_scope), or the IP address is not on the list of the key (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "This key does not have the required permission.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}404
Not found.
{
"error": {
"code": "not_found",
"message": "Not found.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}409
The operation cannot be done in the current state. See details.reason.
{
"error": {
"code": "conflict",
"message": "This operation only works on an active domain.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "domain_not_active"
}
}
}422
Some of the data is not valid.
{
"error": {
"code": "validation_failed",
"message": "Some of the data is not valid.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Too many requests. Wait for the time in Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Please try again shortly.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Header | Description |
|---|---|
Retry-After | Seconds to wait before trying again. |
500
An internal error occurred. Give the correlation_id to support.
{
"error": {
"code": "internal_error",
"message": "An internal error occurred. Please give the correlation_id to support.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
The API is turned off.
{
"error": {
"code": "disabled",
"message": "The API is currently turned off.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | unauthorized | The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | The account cannot use the API (forbidden), the key lacks the permission (insufficient_scope), or the IP address is not on the list of the key (ip_not_allowed). |
| 404 | not_found | Not found. |
| 409 | conflict | The operation cannot be done in the current state. See details.reason. |
| 422 | validation_failed | Some of the data is not valid. |
| 429 | rate_limited | Too many requests. Wait for the time in Retry-After. |
| 500 | internal_error | An internal error occurred. Give the correlation_id to support. |
| 503 | disabled | The API is turned off. |
The error format is explained in Errors.
DELETEDelete a template
/v1/sms/templates/{id}
https://api.mozout.com/v1/sms/templates/{id}Needs sms:write. Standard templates that are deleted do not come back. Limited to 20 changes per minute.
Authentication
Needs a valid key in the Authorization: Bearer header. Required permission: sms:write.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | The id of the template. |
X-API-Mode | header | string: sandbox, production | no | Optional. If it does not match the mode of the key, the request is refused with invalid_request and reason mode_mismatch. Use it to make sure a program never runs with the wrong key. |
Examples
curl
curl -X DELETE "https://api.mozout.com/v1/sms/templates/00000000-0000-4000-8000-000000000000" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: en"PHP
<?php
$ch = curl_init('https://api.mozout.com/v1/sms/templates/00000000-0000-4000-8000-000000000000');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: en',
],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status, PHP_EOL, $body, PHP_EOL;Python
import os
import requests
headers = {
"Authorization": "Bearer " + os.environ["RLX_API_KEY"],
"Accept-Language": "en",
}
r = requests.delete("https://api.mozout.com/v1/sms/templates/00000000-0000-4000-8000-000000000000", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.com/v1/sms/templates/00000000-0000-4000-8000-000000000000", {
method: "DELETE",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "en",
},
});
console.log(response.status);
console.log(await response.text());Responses
200
Delete a template.
{
"data": {
"id": 41,
"deleted": false,
"simulated": true
},
"meta": {}
}| Header | Description |
|---|---|
X-Correlation-ID | Identifier of this request. Give it to support when you report a problem. |
X-RateLimit-Limit | Requests allowed per minute. |
X-RateLimit-Remaining | Requests left in the current minute. |
X-RateLimit-Reset | When the minute ends, as a Unix timestamp in seconds. |
X-API-Mode | The mode of the key that made the request: sandbox or production. |
401
The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account.
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
The account cannot use the API (forbidden), the key lacks the permission (insufficient_scope), or the IP address is not on the list of the key (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "This key does not have the required permission.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}404
Not found.
{
"error": {
"code": "not_found",
"message": "Not found.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Too many requests. Wait for the time in Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Please try again shortly.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Header | Description |
|---|---|
Retry-After | Seconds to wait before trying again. |
500
An internal error occurred. Give the correlation_id to support.
{
"error": {
"code": "internal_error",
"message": "An internal error occurred. Please give the correlation_id to support.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
The API is turned off.
{
"error": {
"code": "disabled",
"message": "The API is currently turned off.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | unauthorized | The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | The account cannot use the API (forbidden), the key lacks the permission (insufficient_scope), or the IP address is not on the list of the key (ip_not_allowed). |
| 404 | not_found | Not found. |
| 429 | rate_limited | Too many requests. Wait for the time in Retry-After. |
| 500 | internal_error | An internal error occurred. Give the correlation_id to support. |
| 503 | disabled | The API is turned off. |
The error format is explained in Errors.
GETSee a sender request
/v1/sms/senders/{sender}
https://api.mozout.com/v1/sms/senders/{sender}Needs sms:read. By id or by name. note is the note from our team. The free sender always answers as approved.
Authentication
Needs a valid key in the Authorization: Bearer header. Required permission: sms:read.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
sender | path | string | yes | The id of the request or the name of the sender. |
X-API-Mode | header | string: sandbox, production | no | Optional. If it does not match the mode of the key, the request is refused with invalid_request and reason mode_mismatch. Use it to make sure a program never runs with the wrong key. |
Examples
curl
curl "https://api.mozout.com/v1/sms/senders/VALUE" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: en"PHP
<?php
$ch = curl_init('https://api.mozout.com/v1/sms/senders/VALUE');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: en',
],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status, PHP_EOL, $body, PHP_EOL;Python
import os
import requests
headers = {
"Authorization": "Bearer " + os.environ["RLX_API_KEY"],
"Accept-Language": "en",
}
r = requests.get("https://api.mozout.com/v1/sms/senders/VALUE", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.com/v1/sms/senders/VALUE", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "en",
},
});
console.log(response.status);
console.log(await response.text());Responses
200
See a sender request.
{
"data": {
"id": 7,
"sender": "AMINHAMARCA",
"status": "pending",
"free": false,
"entity": "A Minha Empresa, Lda",
"country": "Moçambique",
"purpose": "Avisos de encomenda aos nossos clientes.",
"sample": "A sua encomenda está pronta.",
"note": null,
"documents": 0,
"documents_url": "https://my.example.com/sms-center.php?view=senders&language=portuguese¤cy=5",
"created_at": "2026-11-05T09:30:00+02:00",
"updated_at": "2026-11-05T09:30:00+02:00"
},
"meta": {}
}| Header | Description |
|---|---|
X-Correlation-ID | Identifier of this request. Give it to support when you report a problem. |
X-RateLimit-Limit | Requests allowed per minute. |
X-RateLimit-Remaining | Requests left in the current minute. |
X-RateLimit-Reset | When the minute ends, as a Unix timestamp in seconds. |
X-API-Mode | The mode of the key that made the request: sandbox or production. |
401
The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account.
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
The account cannot use the API (forbidden), the key lacks the permission (insufficient_scope), or the IP address is not on the list of the key (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "This key does not have the required permission.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}404
Not found.
{
"error": {
"code": "not_found",
"message": "Not found.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Too many requests. Wait for the time in Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Please try again shortly.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Header | Description |
|---|---|
Retry-After | Seconds to wait before trying again. |
500
An internal error occurred. Give the correlation_id to support.
{
"error": {
"code": "internal_error",
"message": "An internal error occurred. Please give the correlation_id to support.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
The API is turned off.
{
"error": {
"code": "disabled",
"message": "The API is currently turned off.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | unauthorized | The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | The account cannot use the API (forbidden), the key lacks the permission (insufficient_scope), or the IP address is not on the list of the key (ip_not_allowed). |
| 404 | not_found | Not found. |
| 429 | rate_limited | Too many requests. Wait for the time in Retry-After. |
| 500 | internal_error | An internal error occurred. Give the correlation_id to support. |
| 503 | disabled | The API is turned off. |
The error format is explained in Errors.
GETList numbers that do not receive
/v1/sms/opt-outs
https://api.mozout.com/v1/sms/opt-outsNeeds sms:read. The numbers this account blocked, masked. Use number to check one.
Authentication
Needs a valid key in the Authorization: Bearer header. Required permission: sms:read.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
number | query | string | no | Only this number, with or without the country code. |
page | query | integer | no | The page number. The first is 1. |
per_page | query | integer | no | Results per page, from 1 to 100. The default is 10. |
X-API-Mode | header | string: sandbox, production | no | Optional. If it does not match the mode of the key, the request is refused with invalid_request and reason mode_mismatch. Use it to make sure a program never runs with the wrong key. |
Examples
curl
curl "https://api.mozout.com/v1/sms/opt-outs" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: en"PHP
<?php
$ch = curl_init('https://api.mozout.com/v1/sms/opt-outs');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: en',
],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status, PHP_EOL, $body, PHP_EOL;Python
import os
import requests
headers = {
"Authorization": "Bearer " + os.environ["RLX_API_KEY"],
"Accept-Language": "en",
}
r = requests.get("https://api.mozout.com/v1/sms/opt-outs", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.com/v1/sms/opt-outs", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "en",
},
});
console.log(response.status);
console.log(await response.text());Responses
200
List numbers that do not receive.
{
"data": [
{
"number": "25884****567",
"created_at": "2026-11-05T09:30:00+02:00"
}
],
"meta": {
"page": 1,
"per_page": 10,
"total": 1,
"total_pages": 1
}
}| Header | Description |
|---|---|
X-Correlation-ID | Identifier of this request. Give it to support when you report a problem. |
X-RateLimit-Limit | Requests allowed per minute. |
X-RateLimit-Remaining | Requests left in the current minute. |
X-RateLimit-Reset | When the minute ends, as a Unix timestamp in seconds. |
X-API-Mode | The mode of the key that made the request: sandbox or production. |
401
The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account.
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
The account cannot use the API (forbidden), the key lacks the permission (insufficient_scope), or the IP address is not on the list of the key (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "This key does not have the required permission.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}422
Some of the data is not valid.
{
"error": {
"code": "validation_failed",
"message": "Some of the data is not valid.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Too many requests. Wait for the time in Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Please try again shortly.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Header | Description |
|---|---|
Retry-After | Seconds to wait before trying again. |
500
An internal error occurred. Give the correlation_id to support.
{
"error": {
"code": "internal_error",
"message": "An internal error occurred. Please give the correlation_id to support.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
The API is turned off.
{
"error": {
"code": "disabled",
"message": "The API is currently turned off.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | unauthorized | The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | The account cannot use the API (forbidden), the key lacks the permission (insufficient_scope), or the IP address is not on the list of the key (ip_not_allowed). |
| 422 | validation_failed | Some of the data is not valid. |
| 429 | rate_limited | Too many requests. Wait for the time in Retry-After. |
| 500 | internal_error | An internal error occurred. Give the correlation_id to support. |
| 503 | disabled | The API is turned off. |
The error format is explained in Errors.
POSTStop sending to a number
/v1/sms/opt-outs
https://api.mozout.com/v1/sms/opt-outsNeeds sms:write. From now on, sending to this number answers 422 with number_opted_out. To take a number off the list, ask support. Limited to 20 changes per minute.
Authentication
Needs a valid key in the Authorization: Bearer header. Required permission: sms:write.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
X-API-Mode | header | string: sandbox, production | no | Optional. If it does not match the mode of the key, the request is refused with invalid_request and reason mode_mismatch. Use it to make sure a program never runs with the wrong key. |
Idempotency-Key | header | string | no | A unique identifier for this request, so it can be repeated without duplicating it. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
number | string | yes |
Examples
curl
curl -X POST "https://api.mozout.com/v1/sms/opt-outs" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: en" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"number": "+258841234567"}'PHP
<?php
$ch = curl_init('https://api.mozout.com/v1/sms/opt-outs');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{"number": "+258841234567"}',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: en',
'Idempotency-Key: 9f1c2d3e-example',
'Content-Type: application/json',
],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status, PHP_EOL, $body, PHP_EOL;Python
import os
import requests
headers = {
"Authorization": "Bearer " + os.environ["RLX_API_KEY"],
"Accept-Language": "en",
"Idempotency-Key": "9f1c2d3e-example",
}
payload = {"number": "+258841234567"}
r = requests.post("https://api.mozout.com/v1/sms/opt-outs", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.com/v1/sms/opt-outs", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "en",
"Idempotency-Key": "9f1c2d3e-example",
"Content-Type": "application/json",
},
body: JSON.stringify({"number": "+258841234567"}),
});
console.log(response.status);
console.log(await response.text());Responses
201
Stop sending to a number.
{
"data": {
"number": "25884****567",
"created_at": "2026-11-05T09:30:00+02:00",
"already_listed": false,
"simulated": true
},
"meta": {}
}| Header | Description |
|---|---|
X-Correlation-ID | Identifier of this request. Give it to support when you report a problem. |
X-RateLimit-Limit | Requests allowed per minute. |
X-RateLimit-Remaining | Requests left in the current minute. |
X-RateLimit-Reset | When the minute ends, as a Unix timestamp in seconds. |
X-API-Mode | The mode of the key that made the request: sandbox or production. |
401
The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account.
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
The account cannot use the API (forbidden), the key lacks the permission (insufficient_scope), or the IP address is not on the list of the key (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "This key does not have the required permission.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}422
Some of the data is not valid.
{
"error": {
"code": "validation_failed",
"message": "Some of the data is not valid.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Too many requests. Wait for the time in Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Please try again shortly.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Header | Description |
|---|---|
Retry-After | Seconds to wait before trying again. |
500
An internal error occurred. Give the correlation_id to support.
{
"error": {
"code": "internal_error",
"message": "An internal error occurred. Please give the correlation_id to support.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
The API is turned off.
{
"error": {
"code": "disabled",
"message": "The API is currently turned off.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | unauthorized | The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | The account cannot use the API (forbidden), the key lacks the permission (insufficient_scope), or the IP address is not on the list of the key (ip_not_allowed). |
| 422 | validation_failed | Some of the data is not valid. |
| 429 | rate_limited | Too many requests. Wait for the time in Retry-After. |
| 500 | internal_error | An internal error occurred. Give the correlation_id to support. |
| 503 | disabled | The API is turned off. |
The error format is explained in Errors.
POSTCancel a scheduled SMS
/v1/sms/messages/{id}/cancel
https://api.mozout.com/v1/sms/messages/{id}/cancelNeeds sms:write. Only messages of this account that are still scheduled can be cancelled. If the credits were already charged they go back to the balance, and credits_returned says how many; a scheduled message is usually only charged when it goes out, so there is often nothing to return. A message that already went out, is going out, or was already cancelled returns 409 with details.reason set to not_cancellable. With a Sandbox key, or while the API is in preparation, it checks everything and changes nothing. Send Idempotency-Key so a retry gives the same answer.
Authentication
Needs a valid key in the Authorization: Bearer header. Required permission: sms:write.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | The id returned when sending. |
Idempotency-Key | header | string | no | Any unique value, up to 255 visible characters. Valid for 24 hours per key. Repeating the same request returns the saved answer; a different body, or a first request still in progress, returns 409. |
X-API-Mode | header | string: sandbox, production | no | Optional. If it does not match the mode of the key, the request is refused with invalid_request and reason mode_mismatch. Use it to make sure a program never runs with the wrong key. |
Examples
curl
curl -X POST "https://api.mozout.com/v1/sms/messages/00000000-0000-4000-8000-000000000000/cancel" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: en" \
-H "Idempotency-Key: 9f1c2d3e-example"PHP
<?php
$ch = curl_init('https://api.mozout.com/v1/sms/messages/00000000-0000-4000-8000-000000000000/cancel');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: en',
'Idempotency-Key: 9f1c2d3e-example',
],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status, PHP_EOL, $body, PHP_EOL;Python
import os
import requests
headers = {
"Authorization": "Bearer " + os.environ["RLX_API_KEY"],
"Accept-Language": "en",
"Idempotency-Key": "9f1c2d3e-example",
}
r = requests.post("https://api.mozout.com/v1/sms/messages/00000000-0000-4000-8000-000000000000/cancel", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.com/v1/sms/messages/00000000-0000-4000-8000-000000000000/cancel", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "en",
"Idempotency-Key": "9f1c2d3e-example",
},
});
console.log(response.status);
console.log(await response.text());Responses
200
Cancel a scheduled SMS.
{
"data": {
"id": "412",
"status": "cancelled",
"simulated": false,
"to": "25884****567",
"sender": "NETMSG",
"parts": 1,
"encoding": "GSM",
"credits": 1.0,
"charged": false,
"mode": "production",
"error": null,
"scheduled_for": "2026-11-20T09:30:00+02:00",
"created_at": "2026-11-10T12:00:00+02:00",
"sent_at": null,
"credits_returned": 0.0
},
"meta": {}
}| Field | Type | Description |
|---|---|---|
data.id | string | A number for messages in the queue, a UUID for simulated ones. |
data.status | string: scheduled, queued, sending, sent, simulated, failed, cancelled | scheduled: waiting for the time in scheduled_for, and it can still be cancelled. queued: waiting its turn to go out. |
data.simulated | boolean | True when no real SMS goes out. |
data.to | string | The number, partly hidden. |
data.credits | number | What the message costs in credits. See charged to know whether they already left the SMS balance. Always 0 when simulated by the API. |
data.would_cost | number | Only on simulated messages: what a real send would cost. |
data.error | string, null | delivery_failed when it could not be delivered; insufficient_credits when a scheduled message did not have enough balance when it was due to go out. |
data.charged | boolean | True when the credits have left the SMS balance. A scheduled message is only charged when it goes out; failed, cancelled and simulated messages give the credits back. |
data.scheduled_for | string, null (date-time) | The time chosen in send_at, while the message is scheduled or after it was cancelled; otherwise null. |
data.credits_returned | number | Credits that went back to the SMS balance with this cancellation. |
| Header | Description |
|---|---|
X-Correlation-ID | Identifier of this request. Give it to support when you report a problem. |
X-RateLimit-Limit | Requests allowed per minute. |
X-RateLimit-Remaining | Requests left in the current minute. |
X-RateLimit-Reset | When the minute ends, as a Unix timestamp in seconds. |
X-API-Mode | The mode of the key that made the request: sandbox or production. |
X-API-Simulated | Present and true when this write was simulated: nothing changed and nothing was charged. |
401
The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account.
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
This account does not have an active SMS reseller plan (sms_reseller_required), the key lacks the permission (insufficient_scope), or the account cannot use the API (forbidden).
{
"error": {
"code": "insufficient_scope",
"message": "This key does not have the required permission.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}404
Not found.
{
"error": {
"code": "not_found",
"message": "Not found.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}409
The operation cannot be done in the current state. See details.reason.
{
"error": {
"code": "conflict",
"message": "This operation only works on an active domain.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "domain_not_active"
}
}
}429
Too many requests. Wait for the time in Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Please try again shortly.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Header | Description |
|---|---|
Retry-After | Seconds to wait before trying again. |
500
An internal error occurred. Give the correlation_id to support.
{
"error": {
"code": "internal_error",
"message": "An internal error occurred. Please give the correlation_id to support.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
The API is turned off.
{
"error": {
"code": "disabled",
"message": "The API is currently turned off.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | unauthorized | The key is missing, invalid, revoked or expired, or the user who created it no longer has access to the account. |
| 403 | sms_reseller_required, insufficient_scope, forbidden | This account does not have an active SMS reseller plan (sms_reseller_required), the key lacks the permission (insufficient_scope), or the account cannot use the API (forbidden). |
| 404 | not_found | Not found. |
| 409 | conflict | The operation cannot be done in the current state. See details.reason. |
| 429 | rate_limited | Too many requests. Wait for the time in Retry-After. |
| 500 | internal_error | An internal error occurred. Give the correlation_id to support. |
| 503 | disabled | The API is turned off. |
The error format is explained in Errors.
No operation found.