
O que precisa
- Uma conta revendedora de SMS activa. Sem ela, a API responde
403com o códigosms_reseller_required. - Uma chave com a permissão
sms:writepara enviar, esms:readpara consultar. Veja Permissões.
O envio
Use POST /v1/sms/messages com o número e o texto:
curl
curl -X POST "https://api.mozout.co.mz/v1/sms/messages" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-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.co.mz/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: pt',
'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": "pt",
"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.co.mz/v1/sms/messages", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/messages", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"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());O número não precisa de indicativo, porque o sistema reconhece o país pelo primeiro algarismo: 841234567 vai para Moçambique e 923456789 para Angola. Com o indicativo também funciona, com ou sem o + e com espaços: +258 84 123 4567 e 258841234567 são o mesmo número. Se o número não for válido, a API responde 422 com validation_failed e o motivo invalid_number em details.reason.
Sem send_at, a mensagem sai logo e a resposta traz o estado real: sent se saiu, failed se falhou, ou queued se tiver de esperar a vez.
Envie o cabeçalho Idempotency-Key para uma repetição nunca enviar duas vezes. Veja Repetições.
O remetente
O campo sender é opcional. Se não o enviar, a mensagem sai com o remetente grátis, NETMSG, que todas as contas podem usar sem pedido.
Para usar outro nome, indique um remetente aprovado. A lista está em GET /v1/sms/senders, com o remetente grátis sempre em primeiro e o campo free a true.
Sandbox e Produção
- Com uma chave
sandbox_, ou enquanto a API está em preparação, a mensagem é simulada: não sai nada e não se gastam créditos. - Com uma chave
prod_, a mensagem é enviada e os créditos são descontados do saldo de SMS. O limite de gastos da chave, em moeda, não se aplica a estes créditos.
Veja Sandbox e Produção.
Envios agendados
Para a mensagem sair mais tarde, junte ao envio o campo send_at, com a data e a hora em ISO 8601 e o fuso horário, por exemplo 2026-11-20T09:30:00+02:00 (hora de Maputo). A data tem de ser no futuro e, no máximo, daqui a 365 dias. Caso contrário, a API responde 422, com o motivo invalid_send_at, send_at_in_past ou send_at_too_far em details.reason.
- A mensagem fica com o estado
schedulede com a hora marcada emscheduled_for. - Ao agendar, a API só confere se o saldo chega. Os créditos só são descontados quando a mensagem sair: até lá,
chargedficafalse, eGET /v1/sms/balancemostra emscheduled_creditso valor agendado que ainda não foi descontado. - Se, na hora marcada, o saldo não chegar, a mensagem não sai e fica
failed, comerrorainsufficient_credits.
Para desistir do envio, use POST /v1/sms/messages/{id}/cancel antes da hora marcada:
curl
curl -X POST "https://api.mozout.co.mz/v1/sms/messages/00000000-0000-4000-8000-000000000000/cancel" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Idempotency-Key: 9f1c2d3e-example"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/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: pt',
'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": "pt",
"Idempotency-Key": "9f1c2d3e-example",
}
r = requests.post("https://api.mozout.co.mz/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.co.mz/v1/sms/messages/00000000-0000-4000-8000-000000000000/cancel", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"Idempotency-Key": "9f1c2d3e-example",
},
});
console.log(response.status);
console.log(await response.text());Só se cancelam as mensagens da própria conta que ainda estejam scheduled. Se os créditos já tiverem sido descontados, voltam ao saldo, e credits_returned diz quantos. Se a mensagem já saiu, está a sair ou já foi cancelada, a API responde 409, com o motivo not_cancellable em details.reason. Com uma chave sandbox_, a API confere tudo e não muda nada.
Ver uma mensagem
Use GET /v1/sms/messages/{id} com o identificador devolvido no envio. A resposta traz o estado, a hora marcada (se a mensagem estiver agendada) e o campo charged, que diz se os créditos já foram descontados. As mensagens simuladas só se vêem com a chave que as criou.
O saldo
Use GET /v1/sms/balance. É o mesmo saldo em Sandbox e em Produção.
Ver as mensagens enviadas
GET /v1/sms/messages devolve as mensagens que a conta enviou, em páginas, com os filtros status, from, to e number. O número vem tapado. Os avisos da conta, os códigos de verificação e as mensagens simuladas não aparecem.
curl
curl "https://api.mozout.co.mz/v1/sms/messages" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/messages');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
],
]);
$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": "pt",
}
r = requests.get("https://api.mozout.co.mz/v1/sms/messages", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/messages", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Estatísticas
GET /v1/sms/stats dá os totais por estado, os créditos gastos e uma linha por cada dia com mensagens. Sem datas, conta os últimos 30 dias; no máximo 366.
Modelos
GET /v1/sms/templateslista os modelos da conta, eGET /v1/sms/templates/{id}mostra um.POST /v1/sms/templatescria,PATCH /v1/sms/templates/{id}altera eDELETE /v1/sms/templates/{id}apaga.
São os mesmos modelos da página de SMS do portal. Um modelo não envia nada: serve para guardar o texto. O texto aceita as variáveis {$client_name}, {$client_first_name}, {$client_last_name}, {$client_company_name}, {$remetente} e {$data}; outra variável responde 422.
Remetentes novos
POST /v1/sms/senders faz o pedido, com o nome, a entidade, o país, o número fiscal, a finalidade e um exemplo de mensagem. GET /v1/sms/senders/{sender} diz em que ponto está, pelo id ou pelo nome.
curl
curl -X POST "https://api.mozout.co.mz/v1/sms/senders" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"sender": "AMINHAMARCA", "entity": "My Company Ltd", "country": "MZ", "tax_id": "123456789", "purpose": "Order updates for our customers.", "sample": "Your order is ready."}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/senders');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{"sender": "AMINHAMARCA", "entity": "My Company Ltd", "country": "MZ", "tax_id": "123456789", "purpose": "Order updates for our customers.", "sample": "Your order is ready."}',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
'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": "pt",
"Idempotency-Key": "9f1c2d3e-example",
}
payload = {"sender": "AMINHAMARCA", "entity": "My Company Ltd", "country": "MZ", "tax_id": "123456789", "purpose": "Order updates for our customers.", "sample": "Your order is ready."}
r = requests.post("https://api.mozout.co.mz/v1/sms/senders", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/senders", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"Idempotency-Key": "9f1c2d3e-example",
"Content-Type": "application/json",
},
body: JSON.stringify({"sender": "AMINHAMARCA", "entity": "My Company Ltd", "country": "MZ", "tax_id": "123456789", "purpose": "Order updates for our customers.", "sample": "Your order is ready."}),
});
console.log(response.status);
console.log(await response.text());A nossa equipa analisa o pedido e trata do registo junto das operadoras; a aprovação depende delas. Se for recusado, note explica porquê e pode pedir de novo com os dados corrigidos. Para juntar documentos, faça o pedido no portal, em documents_url.
Números que não recebem
POST /v1/sms/opt-outs acrescenta um número à lista da conta: a partir daí, enviar para ele responde 422 com number_opted_out. GET /v1/sms/opt-outs mostra a lista. Para retirar um número, fale com o suporte.
Ajuda
Para outras dúvidas, veja a Base de Conhecimento.
Operações
38 operações nesta área. Clique numa operação para ver os parâmetros, os exemplos e as respostas, ou para a experimentar no Playground, sem sair da página.
GETListar as mensagens enviadas
/v1/sms/messages
https://api.mozout.co.mz/v1/sms/messagesPrecisa de sms:read. As mensagens que esta conta enviou, as mais recentes primeiro. Os avisos da conta e os códigos de verificação não aparecem, nem as mensagens simuladas com uma chave de Sandbox. O número vem tapado. Se uma mensagem falhar, error é delivery_failed. charged diz se os créditos já saíram do saldo.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
status | consulta | string: scheduled, queued, sending, sent, simulated, failed, cancelled | não | Só este estado. |
from | consulta | string (date) | não | Primeiro dia, AAAA-MM-DD. |
to | consulta | string (date) | não | Último dia, AAAA-MM-DD. |
number | consulta | string | não | Só este número, com ou sem indicativo. |
page | consulta | integer | não | O número da página. A primeira é a 1. |
per_page | consulta | integer | não | Resultados por página, de 1 a 100. Por omissão, 10. |
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Exemplos
curl
curl "https://api.mozout.co.mz/v1/sms/messages" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/messages');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
],
]);
$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": "pt",
}
r = requests.get("https://api.mozout.co.mz/v1/sms/messages", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/messages", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Listar as mensagens enviadas.
{
"data": [
{
"id": "128",
"status": "sent",
"simulated": false,
"to": "25884****567",
"sender": "NETMSG",
"text": "Your order is ready.",
"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
}
}| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}422
Alguns dados não são válidos.
{
"error": {
"code": "validation_failed",
"message": "Alguns dados não são válidos.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 422 | validation_failed | Alguns dados não são válidos. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
POSTEnviar um SMS
/v1/sms/messages
https://api.mozout.co.mz/v1/sms/messagesPrecisa de sms:write e de uma conta revendedora de SMS activa. Com uma chave de Sandbox, ou enquanto a API está em preparação, a mensagem é simulada: não sai nada e não se gastam créditos. Com uma chave de Produção, a mensagem entra na fila e os créditos saem do saldo de SMS (o limite de gastos da chave, em moeda, não se aplica a estes créditos). Envie Idempotency-Key para uma repetição nunca enviar duas vezes. Sem send_at a mensagem sai logo e a resposta traz o estado real: sent, failed, ou queued se tiver de esperar a vez. Com send_at fica scheduled: agora só se confere o saldo, e os créditos saem dele quando a mensagem sair (charged fica false até lá); se nessa hora o saldo não chegar, a mensagem não sai e fica failed, com error a insufficient_credits. Uma mensagem agendada pode ser cancelada com POST /v1/sms/messages/{id}/cancel.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
Idempotency-Key | cabeçalho | string | não | Um valor único qualquer, até 255 caracteres visíveis. Vale 24 horas por chave. Repetir o mesmo pedido devolve a resposta guardada; outro corpo, ou um primeiro pedido ainda em curso, devolve 409. |
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Corpo do pedido
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
number | string | sim | Com ou sem indicativo, e pode ter espaços: +258841234567, 258 84 123 4567 ou 84 123 4567. Os telemóveis de Moçambique e de Angola reconhecem-se sozinhos; qualquer outro sem indicativo segue o país da sua conta. |
text | string | sim | |
sender | string | não | Opcional. Um remetente aprovado; se faltar, o remetente grátis (veja GET /v1/sms/senders). |
send_at | string (date-time) | não | Opcional. Agenda a mensagem: data e hora em ISO 8601 com o fuso horário, como 2026-11-20T09:30:00+02:00. Tem de ser no futuro e, no máximo, daqui a 365 dias. Sem este campo, a mensagem sai logo. |
Exemplos
curl
curl -X POST "https://api.mozout.co.mz/v1/sms/messages" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-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.co.mz/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: pt',
'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": "pt",
"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.co.mz/v1/sms/messages", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/messages", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"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());Respostas
201
A mensagem: enviada, simulada, agendada ou à espera na fila.
{
"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": {}
}| Campo | Tipo | Descrição |
|---|---|---|
data.id | string | Um número nas mensagens que entraram na fila, um UUID nas simuladas. |
data.status | string: scheduled, queued, sending, sent, simulated, failed, cancelled | scheduled: à espera da hora em scheduled_for, e ainda se pode cancelar. queued: à espera da vez para sair. |
data.simulated | boolean | Verdadeiro quando o SMS é simulado e não sai nenhuma mensagem. |
data.to | string | O número, em parte tapado. |
data.credits | number | Quanto custa a mensagem, em créditos. Veja charged para saber se já saíram do saldo de SMS. Sempre 0 quando a API simula. |
data.would_cost | number | Só nas simuladas: quanto custaria o envio em Produção. |
data.error | string, null | delivery_failed quando não foi possível entregar; insufficient_credits quando uma mensagem agendada não tinha saldo suficiente na hora de sair. |
data.charged | boolean | Verdadeiro quando os créditos saíram do saldo de SMS. Uma mensagem agendada só se cobra quando sai; as falhadas, canceladas e simuladas devolvem os créditos. |
data.scheduled_for | string, null (date-time) | A hora escolhida em send_at, enquanto a mensagem está agendada ou depois de cancelada; nos outros casos, null. |
| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
X-API-Simulated | Presente e true quando esta escrita foi simulada: nada mudou e nada foi cobrado. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
Esta conta não tem revenda de SMS activa (sms_reseller_required), a chave não tem a permissão (insufficient_scope), ou a conta não pode usar a API (forbidden).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}409
A Idempotency-Key foi usada com outro pedido, ou o primeiro pedido ainda está em curso.
{
"error": {
"code": "idempotency_conflict",
"message": "Esta Idempotency-Key já foi usada com outro pedido, ou o primeiro pedido ainda está em curso.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "different_request"
}
}
}422
Alguns dados não são válidos.
{
"error": {
"code": "validation_failed",
"message": "Alguns dados não são válidos.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | sms_reseller_required, insufficient_scope, forbidden | Esta conta não tem revenda de SMS activa (sms_reseller_required), a chave não tem a permissão (insufficient_scope), ou a conta não pode usar a API (forbidden). |
| 409 | idempotency_conflict | A Idempotency-Key foi usada com outro pedido, ou o primeiro pedido ainda está em curso. |
| 422 | validation_failed | Alguns dados não são válidos. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
GETVer um SMS
/v1/sms/messages/{id}
https://api.mozout.co.mz/v1/sms/messages/{id}Precisa de sms:read. As mensagens simuladas só se vêem com a chave que as criou.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id devolvido ao enviar. |
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Exemplos
curl
curl "https://api.mozout.co.mz/v1/sms/messages/00000000-0000-4000-8000-000000000000" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/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: pt',
],
]);
$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": "pt",
}
r = requests.get("https://api.mozout.co.mz/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.co.mz/v1/sms/messages/00000000-0000-4000-8000-000000000000", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
A mensagem.
{
"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": {}
}| Campo | Tipo | Descrição |
|---|---|---|
data.id | string | Um número nas mensagens que entraram na fila, um UUID nas simuladas. |
data.status | string: scheduled, queued, sending, sent, simulated, failed, cancelled | scheduled: à espera da hora em scheduled_for, e ainda se pode cancelar. queued: à espera da vez para sair. |
data.simulated | boolean | Verdadeiro quando o SMS é simulado e não sai nenhuma mensagem. |
data.to | string | O número, em parte tapado. |
data.credits | number | Quanto custa a mensagem, em créditos. Veja charged para saber se já saíram do saldo de SMS. Sempre 0 quando a API simula. |
data.would_cost | number | Só nas simuladas: quanto custaria o envio em Produção. |
data.error | string, null | delivery_failed quando não foi possível entregar; insufficient_credits quando uma mensagem agendada não tinha saldo suficiente na hora de sair. |
data.charged | boolean | Verdadeiro quando os créditos saíram do saldo de SMS. Uma mensagem agendada só se cobra quando sai; as falhadas, canceladas e simuladas devolvem os créditos. |
data.scheduled_for | string, null (date-time) | A hora escolhida em send_at, enquanto a mensagem está agendada ou depois de cancelada; nos outros casos, null. |
| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
Esta conta não tem revenda de SMS activa (sms_reseller_required), a chave não tem a permissão (insufficient_scope), ou a conta não pode usar a API (forbidden).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}404
Não encontrado.
{
"error": {
"code": "not_found",
"message": "Não encontrado.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | sms_reseller_required, insufficient_scope, forbidden | Esta conta não tem revenda de SMS activa (sms_reseller_required), a chave não tem a permissão (insufficient_scope), ou a conta não pode usar a API (forbidden). |
| 404 | not_found | Não encontrado. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
GETVer o saldo de SMS
/v1/sms/balance
https://api.mozout.co.mz/v1/sms/balancePrecisa de sms:read. O saldo é o verdadeiro nos dois modos.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Exemplos
curl
curl "https://api.mozout.co.mz/v1/sms/balance" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/balance');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
],
]);
$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": "pt",
}
r = requests.get("https://api.mozout.co.mz/v1/sms/balance", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/balance", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Saldo e limite diário.
{
"data": {
"balance": 50,
"unit": "credits",
"daily_limit": 200,
"sent_today": 3,
"mode": "sandbox",
"scheduled_credits": 0.0
},
"meta": {}
}| Campo | Tipo | Descrição |
|---|---|---|
data.scheduled_credits | number | Créditos das mensagens agendadas que ainda não foram cobradas. Continuam em balance e saem quando cada mensagem sair. |
| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
Esta conta não tem revenda de SMS activa (sms_reseller_required), a chave não tem a permissão (insufficient_scope), ou a conta não pode usar a API (forbidden).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | sms_reseller_required, insufficient_scope, forbidden | Esta conta não tem revenda de SMS activa (sms_reseller_required), a chave não tem a permissão (insufficient_scope), ou a conta não pode usar a API (forbidden). |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
GETListar os remetentes de SMS
/v1/sms/senders
https://api.mozout.co.mz/v1/sms/sendersPrecisa de sms:read. O remetente grátis vem sempre em primeiro, com free: true.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Exemplos
curl
curl "https://api.mozout.co.mz/v1/sms/senders" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/senders');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
],
]);
$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": "pt",
}
r = requests.get("https://api.mozout.co.mz/v1/sms/senders", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/senders", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Os remetentes desta conta.
{
"data": [
{
"sender": "NETMSG",
"status": "approved",
"free": true
},
{
"sender": "MINHAEMPRESA",
"status": "pending",
"free": false
}
],
"meta": {}
}| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
Esta conta não tem revenda de SMS activa (sms_reseller_required), a chave não tem a permissão (insufficient_scope), ou a conta não pode usar a API (forbidden).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | sms_reseller_required, insufficient_scope, forbidden | Esta conta não tem revenda de SMS activa (sms_reseller_required), a chave não tem a permissão (insufficient_scope), ou a conta não pode usar a API (forbidden). |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
POSTPedir um remetente
/v1/sms/senders
https://api.mozout.co.mz/v1/sms/sendersPrecisa de sms:write. O nome tem até 11 caracteres, entre letras, números e espaços; cada conta tem até 30 remetentes, um pedido por nome e país. A taxa de registo paga-se como no portal: o pedido nasce como payment_pending e a resposta traz o payment_url, a página onde se paga. Depois de pago passa a documents_needed e os documentos da entidade enviam-se no portal da conta. Se a taxa já estava paga (pedido recusado antes do reembolso), passa logo a documents_needed e o payment_url vem nulo. Depois a equipa analisa e regista-o junto das operadoras; a aprovação depende delas. Limite de 20 alterações por minuto.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Idempotency-Key | cabeçalho | string | não | Identificador único deste pedido, para o repetir sem o duplicar. |
Corpo do pedido
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
sender | string | sim | |
entity | string | sim | |
country | string: MZ, AO, Mozambique, Angola, Moçambique | sim | Moçambique (MZ) ou Angola (AO), pelo código ou pelo nome. |
tax_id | string | sim | |
purpose | string | sim | |
sample | string | sim |
Exemplos
curl
curl -X POST "https://api.mozout.co.mz/v1/sms/senders" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"sender": "AMINHAMARCA", "entity": "My Company Ltd", "country": "MZ", "tax_id": "123456789", "purpose": "Order updates for our customers.", "sample": "Your order is ready."}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/senders');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{"sender": "AMINHAMARCA", "entity": "My Company Ltd", "country": "MZ", "tax_id": "123456789", "purpose": "Order updates for our customers.", "sample": "Your order is ready."}',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
'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": "pt",
"Idempotency-Key": "9f1c2d3e-example",
}
payload = {"sender": "AMINHAMARCA", "entity": "My Company Ltd", "country": "MZ", "tax_id": "123456789", "purpose": "Order updates for our customers.", "sample": "Your order is ready."}
r = requests.post("https://api.mozout.co.mz/v1/sms/senders", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/senders", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"Idempotency-Key": "9f1c2d3e-example",
"Content-Type": "application/json",
},
body: JSON.stringify({"sender": "AMINHAMARCA", "entity": "My Company Ltd", "country": "MZ", "tax_id": "123456789", "purpose": "Order updates for our customers.", "sample": "Your order is ready."}),
});
console.log(response.status);
console.log(await response.text());Respostas
201
Pedir um remetente.
{
"data": {
"id": 7,
"sender": "AMINHAMARCA",
"status": "payment_pending",
"free": false,
"entity": "My Company Ltd",
"country": "Moçambique",
"purpose": "Order updates for our customers.",
"sample": "Your order is ready.",
"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": false,
"payment_url": "https://my.example.com/onestep/checkout?v=3f9a1c2b7d4e5f60718293a4b5c6d7e8&language=english¤cy=1"
},
"meta": {}
}| Campo | Tipo | Descrição |
|---|---|---|
data.status | string | payment_pending (taxa por pagar), documents_needed, name_needed, pending, in_review, approved ou rejected. |
data.payment_url | string, null | A página onde se paga a taxa; nulo quando não há nada a pagar. |
| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}409
A operação não se pode fazer no estado actual. Veja 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
Alguns dados não são válidos.
{
"error": {
"code": "validation_failed",
"message": "Alguns dados não são válidos.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 409 | conflict | A operação não se pode fazer no estado actual. Veja details.reason. |
| 422 | validation_failed | Alguns dados não são válidos. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
GETVer as estatísticas de envio
/v1/sms/stats
https://api.mozout.co.mz/v1/sms/statsPrecisa de sms:read. Totais e uma linha por cada dia com mensagens. Sem datas, os últimos 30 dias; no máximo 366 dias. As mensagens falhadas, canceladas e simuladas não contam em credits_spent. Também não contam as mensagens agendadas que ainda não foram cobradas.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
from | consulta | string (date) | não | Primeiro dia, AAAA-MM-DD. |
to | consulta | string (date) | não | Último dia, AAAA-MM-DD. |
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Exemplos
curl
curl "https://api.mozout.co.mz/v1/sms/stats" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/stats');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
],
]);
$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": "pt",
}
r = requests.get("https://api.mozout.co.mz/v1/sms/stats", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/stats", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Ver as estatísticas de envio.
{
"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": {}
}| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}422
Alguns dados não são válidos.
{
"error": {
"code": "validation_failed",
"message": "Alguns dados não são válidos.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 422 | validation_failed | Alguns dados não são válidos. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
GETListar os modelos
/v1/sms/templates
https://api.mozout.co.mz/v1/sms/templatesPrecisa de sms:read. Os modelos desta conta, por nome.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
category | consulta | string: general, notice, promotion, billing, confirmation | não | Só esta categoria. |
language | consulta | string: pt, en | não | Só esta língua. |
page | consulta | integer | não | O número da página. A primeira é a 1. |
per_page | consulta | integer | não | Resultados por página, de 1 a 100. Por omissão, 10. |
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Exemplos
curl
curl "https://api.mozout.co.mz/v1/sms/templates" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/templates');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
],
]);
$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": "pt",
}
r = requests.get("https://api.mozout.co.mz/v1/sms/templates", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/templates", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Listar os modelos.
{
"data": [
{
"id": 41,
"name": "Invoice reminder",
"text": "Hi {$client_first_name}, your invoice is due today.",
"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
}
}| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}422
Alguns dados não são válidos.
{
"error": {
"code": "validation_failed",
"message": "Alguns dados não são válidos.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 422 | validation_failed | Alguns dados não são válidos. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
POSTCriar um modelo
/v1/sms/templates
https://api.mozout.co.mz/v1/sms/templatesPrecisa de sms:write. O nome não se pode repetir na conta. O texto aceita {$client_name}, {$client_first_name}, {$client_last_name}, {$client_company_name}, {$remetente} e {$data}. Limite de 20 alterações por minuto.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Idempotency-Key | cabeçalho | string | não | Identificador único deste pedido, para o repetir sem o duplicar. |
Corpo do pedido
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
name | string | sim | |
text | string | sim | |
category | string: general, notice, promotion, billing, confirmation | não | |
language | string: pt, en | não |
Exemplos
curl
curl -X POST "https://api.mozout.co.mz/v1/sms/templates" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"name": "Invoice reminder", "text": "Hi {$client_first_name}, your invoice is due today.", "category": "notice", "language": "pt"}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/templates');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{"name": "Invoice reminder", "text": "Hi {$client_first_name}, your invoice is due today.", "category": "notice", "language": "pt"}',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
'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": "pt",
"Idempotency-Key": "9f1c2d3e-example",
}
payload = {"name": "Invoice reminder", "text": "Hi {$client_first_name}, your invoice is due today.", "category": "notice", "language": "pt"}
r = requests.post("https://api.mozout.co.mz/v1/sms/templates", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/templates", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"Idempotency-Key": "9f1c2d3e-example",
"Content-Type": "application/json",
},
body: JSON.stringify({"name": "Invoice reminder", "text": "Hi {$client_first_name}, your invoice is due today.", "category": "notice", "language": "pt"}),
});
console.log(response.status);
console.log(await response.text());Respostas
201
Criar um modelo.
{
"data": {
"id": 41,
"name": "Invoice reminder",
"text": "Hi {$client_first_name}, your invoice is due today.",
"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": {}
}| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}409
A operação não se pode fazer no estado actual. Veja 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
Alguns dados não são válidos.
{
"error": {
"code": "validation_failed",
"message": "Alguns dados não são válidos.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 409 | conflict | A operação não se pode fazer no estado actual. Veja details.reason. |
| 422 | validation_failed | Alguns dados não são válidos. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
GETVer um modelo
/v1/sms/templates/{id}
https://api.mozout.co.mz/v1/sms/templates/{id}Precisa de sms:read. Um modelo desta conta.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id do modelo. |
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Exemplos
curl
curl "https://api.mozout.co.mz/v1/sms/templates/00000000-0000-4000-8000-000000000000" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/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: pt',
],
]);
$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": "pt",
}
r = requests.get("https://api.mozout.co.mz/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.co.mz/v1/sms/templates/00000000-0000-4000-8000-000000000000", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Ver um modelo.
{
"data": {
"id": 41,
"name": "Invoice reminder",
"text": "Hi {$client_first_name}, your invoice is due today.",
"category": "notice",
"language": "pt",
"created_at": "2026-11-05T09:30:00+02:00",
"updated_at": "2026-11-05T09:30:00+02:00"
},
"meta": {}
}| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}404
Não encontrado.
{
"error": {
"code": "not_found",
"message": "Não encontrado.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 404 | not_found | Não encontrado. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
PATCHAlterar um modelo
/v1/sms/templates/{id}
https://api.mozout.co.mz/v1/sms/templates/{id}Precisa de sms:write. Envie só os campos a alterar. Limite de 20 alterações por minuto.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id do modelo. |
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Corpo do pedido
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
name | string | não | |
text | string | não | |
category | string: general, notice, promotion, billing, confirmation | não | |
language | string: pt, en | não |
Exemplos
curl
curl -X PATCH "https://api.mozout.co.mz/v1/sms/templates/00000000-0000-4000-8000-000000000000" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Content-Type: application/json" \
-d '{"text": "Hi {$client_first_name}, your invoice is due tomorrow."}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/templates/00000000-0000-4000-8000-000000000000');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_POSTFIELDS => '{"text": "Hi {$client_first_name}, your invoice is due tomorrow."}',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
'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": "pt",
}
payload = {"text": "Hi {$client_first_name}, your invoice is due tomorrow."}
r = requests.patch("https://api.mozout.co.mz/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.co.mz/v1/sms/templates/00000000-0000-4000-8000-000000000000", {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"Content-Type": "application/json",
},
body: JSON.stringify({"text": "Hi {$client_first_name}, your invoice is due tomorrow."}),
});
console.log(response.status);
console.log(await response.text());Respostas
200
Alterar um modelo.
{
"data": {
"id": 41,
"name": "Invoice reminder",
"text": "Hi {$client_first_name}, your invoice is due today.",
"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": {}
}| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}404
Não encontrado.
{
"error": {
"code": "not_found",
"message": "Não encontrado.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}409
A operação não se pode fazer no estado actual. Veja 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
Alguns dados não são válidos.
{
"error": {
"code": "validation_failed",
"message": "Alguns dados não são válidos.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 404 | not_found | Não encontrado. |
| 409 | conflict | A operação não se pode fazer no estado actual. Veja details.reason. |
| 422 | validation_failed | Alguns dados não são válidos. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
DELETEApagar um modelo
/v1/sms/templates/{id}
https://api.mozout.co.mz/v1/sms/templates/{id}Precisa de sms:write. Os modelos padrão que forem apagados não voltam. Limite de 20 alterações por minuto.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id do modelo. |
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Exemplos
curl
curl -X DELETE "https://api.mozout.co.mz/v1/sms/templates/00000000-0000-4000-8000-000000000000" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/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: pt',
],
]);
$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": "pt",
}
r = requests.delete("https://api.mozout.co.mz/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.co.mz/v1/sms/templates/00000000-0000-4000-8000-000000000000", {
method: "DELETE",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Apagar um modelo.
{
"data": {
"id": 41,
"deleted": false,
"simulated": true
},
"meta": {}
}| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}404
Não encontrado.
{
"error": {
"code": "not_found",
"message": "Não encontrado.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 404 | not_found | Não encontrado. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
GETVer um pedido de remetente
/v1/sms/senders/{sender}
https://api.mozout.co.mz/v1/sms/senders/{sender}Precisa de sms:read. Pelo id ou pelo nome. note é a nota da nossa equipa. O remetente grátis responde sempre approved.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
sender | caminho | string | sim | O id do pedido ou o nome do remetente. |
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Exemplos
curl
curl "https://api.mozout.co.mz/v1/sms/senders/VALUE" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/senders/VALUE');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
],
]);
$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": "pt",
}
r = requests.get("https://api.mozout.co.mz/v1/sms/senders/VALUE", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/senders/VALUE", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Ver um pedido de remetente.
{
"data": {
"id": 7,
"sender": "AMINHAMARCA",
"status": "pending",
"free": false,
"entity": "My Company Ltd",
"country": "Mozambique",
"purpose": "Order updates for our customers.",
"sample": "Your order is ready.",
"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": {}
}| Campo | Tipo | Descrição |
|---|---|---|
data.status | string | payment_pending (taxa por pagar), documents_needed, name_needed, pending, in_review, approved ou rejected. |
| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}404
Não encontrado.
{
"error": {
"code": "not_found",
"message": "Não encontrado.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 404 | not_found | Não encontrado. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
GETListar os números que não recebem
/v1/sms/opt-outs
https://api.mozout.co.mz/v1/sms/opt-outsPrecisa de sms:read. Os números que esta conta bloqueou, tapados. Use number para confirmar um.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
number | consulta | string | não | Só este número, com ou sem indicativo. |
page | consulta | integer | não | O número da página. A primeira é a 1. |
per_page | consulta | integer | não | Resultados por página, de 1 a 100. Por omissão, 10. |
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Exemplos
curl
curl "https://api.mozout.co.mz/v1/sms/opt-outs" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/opt-outs');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
],
]);
$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": "pt",
}
r = requests.get("https://api.mozout.co.mz/v1/sms/opt-outs", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/opt-outs", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Listar os números que não recebem.
{
"data": [
{
"number": "25884****567",
"created_at": "2026-11-05T09:30:00+02:00"
}
],
"meta": {
"page": 1,
"per_page": 10,
"total": 1,
"total_pages": 1
}
}| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}422
Alguns dados não são válidos.
{
"error": {
"code": "validation_failed",
"message": "Alguns dados não são válidos.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 422 | validation_failed | Alguns dados não são válidos. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
POSTDeixar de enviar a um número
/v1/sms/opt-outs
https://api.mozout.co.mz/v1/sms/opt-outsPrecisa de sms:write. A partir daqui, enviar para este número responde 422 com number_opted_out. Para retirar um número da lista, fale com o suporte. Limite de 20 alterações por minuto.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Idempotency-Key | cabeçalho | string | não | Identificador único deste pedido, para o repetir sem o duplicar. |
Corpo do pedido
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
number | string | sim |
Exemplos
curl
curl -X POST "https://api.mozout.co.mz/v1/sms/opt-outs" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"number": "+258841234567"}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/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: pt',
'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": "pt",
"Idempotency-Key": "9f1c2d3e-example",
}
payload = {"number": "+258841234567"}
r = requests.post("https://api.mozout.co.mz/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.co.mz/v1/sms/opt-outs", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"Idempotency-Key": "9f1c2d3e-example",
"Content-Type": "application/json",
},
body: JSON.stringify({"number": "+258841234567"}),
});
console.log(response.status);
console.log(await response.text());Respostas
201
Deixar de enviar a um número.
{
"data": {
"number": "25884****567",
"created_at": "2026-11-05T09:30:00+02:00",
"already_listed": false,
"simulated": true
},
"meta": {}
}| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}422
Alguns dados não são válidos.
{
"error": {
"code": "validation_failed",
"message": "Alguns dados não são válidos.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 422 | validation_failed | Alguns dados não são válidos. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
POSTCancelar um SMS agendado
/v1/sms/messages/{id}/cancel
https://api.mozout.co.mz/v1/sms/messages/{id}/cancelPrecisa de sms:write. Só se cancelam mensagens desta conta que ainda estejam scheduled. Se os créditos já tiverem sido cobrados, voltam ao saldo, e credits_returned diz quantos; normalmente uma mensagem agendada só se cobra quando sai, e por isso muitas vezes não há nada a devolver. Uma mensagem que já saiu, que está a sair ou que já foi cancelada responde 409, com details.reason a not_cancellable. Com uma chave de Sandbox, ou enquanto a API está em preparação, confere tudo e não muda nada. Envie Idempotency-Key para uma repetição dar a mesma resposta.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id devolvido ao enviar. |
Idempotency-Key | cabeçalho | string | não | Um valor único qualquer, até 255 caracteres visíveis. Vale 24 horas por chave. Repetir o mesmo pedido devolve a resposta guardada; outro corpo, ou um primeiro pedido ainda em curso, devolve 409. |
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Exemplos
curl
curl -X POST "https://api.mozout.co.mz/v1/sms/messages/00000000-0000-4000-8000-000000000000/cancel" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Idempotency-Key: 9f1c2d3e-example"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/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: pt',
'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": "pt",
"Idempotency-Key": "9f1c2d3e-example",
}
r = requests.post("https://api.mozout.co.mz/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.co.mz/v1/sms/messages/00000000-0000-4000-8000-000000000000/cancel", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"Idempotency-Key": "9f1c2d3e-example",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Cancelar um SMS agendado.
{
"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": {}
}| Campo | Tipo | Descrição |
|---|---|---|
data.id | string | Um número nas mensagens que entraram na fila, um UUID nas simuladas. |
data.status | string: scheduled, queued, sending, sent, simulated, failed, cancelled | scheduled: à espera da hora em scheduled_for, e ainda se pode cancelar. queued: à espera da vez para sair. |
data.simulated | boolean | Verdadeiro quando o SMS é simulado e não sai nenhuma mensagem. |
data.to | string | O número, em parte tapado. |
data.credits | number | Quanto custa a mensagem, em créditos. Veja charged para saber se já saíram do saldo de SMS. Sempre 0 quando a API simula. |
data.would_cost | number | Só nas simuladas: quanto custaria o envio em Produção. |
data.error | string, null | delivery_failed quando não foi possível entregar; insufficient_credits quando uma mensagem agendada não tinha saldo suficiente na hora de sair. |
data.charged | boolean | Verdadeiro quando os créditos saíram do saldo de SMS. Uma mensagem agendada só se cobra quando sai; as falhadas, canceladas e simuladas devolvem os créditos. |
data.scheduled_for | string, null (date-time) | A hora escolhida em send_at, enquanto a mensagem está agendada ou depois de cancelada; nos outros casos, null. |
data.credits_returned | number | Créditos que voltaram ao saldo de SMS com este cancelamento. |
| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
X-API-Simulated | Presente e true quando esta escrita foi simulada: nada mudou e nada foi cobrado. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
Esta conta não tem revenda de SMS activa (sms_reseller_required), a chave não tem a permissão (insufficient_scope), ou a conta não pode usar a API (forbidden).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}404
Não encontrado.
{
"error": {
"code": "not_found",
"message": "Não encontrado.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}409
A operação não se pode fazer no estado actual. Veja 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
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | sms_reseller_required, insufficient_scope, forbidden | Esta conta não tem revenda de SMS activa (sms_reseller_required), a chave não tem a permissão (insufficient_scope), ou a conta não pode usar a API (forbidden). |
| 404 | not_found | Não encontrado. |
| 409 | conflict | A operação não se pode fazer no estado actual. Veja details.reason. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
GETListar os contactos
/v1/sms/contacts
https://api.mozout.co.mz/v1/sms/contactsPrecisa de sms:read. Os contactos de SMS desta conta, por nome, com os grupos.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
group | consulta | string | não | Só os contactos deste grupo (o número dele). |
search | consulta | string | não | Nome, empresa, e-mail ou parte do número. |
page | consulta | integer | não | O número da página. A primeira é a 1. |
per_page | consulta | integer | não | Resultados por página, de 1 a 100. Por omissão, 10. |
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Exemplos
curl
curl "https://api.mozout.co.mz/v1/sms/contacts" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/contacts');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
],
]);
$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": "pt",
}
r = requests.get("https://api.mozout.co.mz/v1/sms/contacts", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/contacts", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Listar os contactos.
{
"data": [
{
"id": 512,
"name": "Ana Silva",
"company": "Example Ltd",
"phone": "+258841234567",
"email": "[email protected]",
"notes": "Prefers mornings",
"groups": [
{
"id": 9,
"name": "Customers"
}
],
"created_at": "2026-11-11T09:30:00+02:00",
"updated_at": null
}
],
"meta": {
"page": 1,
"per_page": 10,
"total": 1,
"total_pages": 1
}
}| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}422
Alguns dados não são válidos.
{
"error": {
"code": "validation_failed",
"message": "Alguns dados não são válidos.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 422 | validation_failed | Alguns dados não são válidos. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
POSTCriar um contacto
/v1/sms/contacts
https://api.mozout.co.mz/v1/sms/contactsPrecisa de sms:write. O número não se pode repetir na conta. Até 20 000 contactos. Limite de 20 alterações por minuto.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Idempotency-Key | cabeçalho | string | não | Identificador único deste pedido, para o repetir sem o duplicar. |
Corpo do pedido
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
name | string | não | O nome do contacto. É preciso o nome ou a empresa. |
company | string | não | Opcional. |
phone | string | sim | Com ou sem indicativo; único na conta. |
email | string | não | Opcional. |
notes | string | não | Opcional. |
groups | array<integer> | não | Opcional. Números dos grupos de GET /v1/sms/groups; substitui os grupos actuais. |
Exemplos
curl
curl -X POST "https://api.mozout.co.mz/v1/sms/contacts" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"name": "Ana Silva", "company": "Example Ltd", "phone": "+258841234567", "email": "[email protected]", "groups": [9]}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/contacts');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{"name": "Ana Silva", "company": "Example Ltd", "phone": "+258841234567", "email": "[email protected]", "groups": [9]}',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
'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": "pt",
"Idempotency-Key": "9f1c2d3e-example",
}
payload = {"name": "Ana Silva", "company": "Example Ltd", "phone": "+258841234567", "email": "[email protected]", "groups": [9]}
r = requests.post("https://api.mozout.co.mz/v1/sms/contacts", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/contacts", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"Idempotency-Key": "9f1c2d3e-example",
"Content-Type": "application/json",
},
body: JSON.stringify({"name": "Ana Silva", "company": "Example Ltd", "phone": "+258841234567", "email": "[email protected]", "groups": [9]}),
});
console.log(response.status);
console.log(await response.text());Respostas
201
Criar um contacto.
{
"data": {
"id": 512,
"name": "Ana Silva",
"company": "Example Ltd",
"phone": "+258841234567",
"email": "[email protected]",
"notes": "Prefers mornings",
"groups": [
{
"id": 9,
"name": "Customers"
}
],
"created_at": "2026-11-11T09:30:00+02:00",
"updated_at": null,
"simulated": false
},
"meta": {}
}| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}409
A operação não se pode fazer no estado actual. Veja 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
Alguns dados não são válidos.
{
"error": {
"code": "validation_failed",
"message": "Alguns dados não são válidos.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 409 | conflict | A operação não se pode fazer no estado actual. Veja details.reason. |
| 422 | validation_failed | Alguns dados não são válidos. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
GETVer um contacto
/v1/sms/contacts/{id}
https://api.mozout.co.mz/v1/sms/contacts/{id}Precisa de sms:read.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id do contacto. |
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Exemplos
curl
curl "https://api.mozout.co.mz/v1/sms/contacts/00000000-0000-4000-8000-000000000000" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/contacts/00000000-0000-4000-8000-000000000000');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
],
]);
$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": "pt",
}
r = requests.get("https://api.mozout.co.mz/v1/sms/contacts/00000000-0000-4000-8000-000000000000", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/contacts/00000000-0000-4000-8000-000000000000", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Ver um contacto.
{
"data": {
"id": 512,
"name": "Ana Silva",
"company": "Example Ltd",
"phone": "+258841234567",
"email": "[email protected]",
"notes": "Prefers mornings",
"groups": [
{
"id": 9,
"name": "Customers"
}
],
"created_at": "2026-11-11T09:30:00+02:00",
"updated_at": null
},
"meta": {}
}| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}404
Não encontrado.
{
"error": {
"code": "not_found",
"message": "Não encontrado.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 404 | not_found | Não encontrado. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
PATCHAlterar um contacto
/v1/sms/contacts/{id}
https://api.mozout.co.mz/v1/sms/contacts/{id}Precisa de sms:write. Envie só os campos a mudar; groups substitui os grupos actuais. Limite de 20 alterações por minuto.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id do contacto. |
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Corpo do pedido
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
name | string | não | O nome do contacto. É preciso o nome ou a empresa. |
company | string | não | Opcional. |
phone | string | não | Com ou sem indicativo; único na conta. |
email | string | não | Opcional. |
notes | string | não | Opcional. |
groups | array<integer> | não | Opcional. Números dos grupos de GET /v1/sms/groups; substitui os grupos actuais. |
Exemplos
curl
curl -X PATCH "https://api.mozout.co.mz/v1/sms/contacts/00000000-0000-4000-8000-000000000000" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Content-Type: application/json" \
-d '{"notes": "Call after 10am", "groups": [9, 12]}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/contacts/00000000-0000-4000-8000-000000000000');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_POSTFIELDS => '{"notes": "Call after 10am", "groups": [9, 12]}',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
'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": "pt",
}
payload = {"notes": "Call after 10am", "groups": [9, 12]}
r = requests.patch("https://api.mozout.co.mz/v1/sms/contacts/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.co.mz/v1/sms/contacts/00000000-0000-4000-8000-000000000000", {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"Content-Type": "application/json",
},
body: JSON.stringify({"notes": "Call after 10am", "groups": [9, 12]}),
});
console.log(response.status);
console.log(await response.text());Respostas
200
Alterar um contacto.
{
"data": {
"id": 512,
"name": "Ana Silva",
"company": "Example Ltd",
"phone": "+258841234567",
"email": "[email protected]",
"notes": "Call after 10am",
"groups": [
{
"id": 9,
"name": "Customers"
}
],
"created_at": "2026-11-11T09:30:00+02:00",
"updated_at": null,
"simulated": false
},
"meta": {}
}| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}404
Não encontrado.
{
"error": {
"code": "not_found",
"message": "Não encontrado.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}409
A operação não se pode fazer no estado actual. Veja 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
Alguns dados não são válidos.
{
"error": {
"code": "validation_failed",
"message": "Alguns dados não são válidos.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 404 | not_found | Não encontrado. |
| 409 | conflict | A operação não se pode fazer no estado actual. Veja details.reason. |
| 422 | validation_failed | Alguns dados não são válidos. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
DELETEApagar um contacto
/v1/sms/contacts/{id}
https://api.mozout.co.mz/v1/sms/contacts/{id}Precisa de sms:write. As mensagens já enviadas continuam no histórico. Limite de 20 alterações por minuto.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id do contacto. |
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Exemplos
curl
curl -X DELETE "https://api.mozout.co.mz/v1/sms/contacts/00000000-0000-4000-8000-000000000000" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/contacts/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: pt',
],
]);
$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": "pt",
}
r = requests.delete("https://api.mozout.co.mz/v1/sms/contacts/00000000-0000-4000-8000-000000000000", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/contacts/00000000-0000-4000-8000-000000000000", {
method: "DELETE",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Apagar um contacto.
{
"data": {
"id": 512,
"deleted": true,
"simulated": false
},
"meta": {}
}| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}404
Não encontrado.
{
"error": {
"code": "not_found",
"message": "Não encontrado.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 404 | not_found | Não encontrado. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
GETListar os grupos de contactos
/v1/sms/groups
https://api.mozout.co.mz/v1/sms/groupsPrecisa de sms:read. Os grupos desta conta, por nome, com quantos contactos tem cada um.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
page | consulta | integer | não | O número da página. A primeira é a 1. |
per_page | consulta | integer | não | Resultados por página, de 1 a 100. Por omissão, 10. |
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Exemplos
curl
curl "https://api.mozout.co.mz/v1/sms/groups" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/groups');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
],
]);
$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": "pt",
}
r = requests.get("https://api.mozout.co.mz/v1/sms/groups", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/groups", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Listar os grupos de contactos.
{
"data": [
{
"id": 9,
"name": "Customers",
"contacts": 128,
"created_at": "2026-11-11T09:30:00+02:00"
}
],
"meta": {
"page": 1,
"per_page": 10,
"total": 1,
"total_pages": 1
}
}| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}422
Alguns dados não são válidos.
{
"error": {
"code": "validation_failed",
"message": "Alguns dados não são válidos.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 422 | validation_failed | Alguns dados não são válidos. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
POSTCriar um grupo de contactos
/v1/sms/groups
https://api.mozout.co.mz/v1/sms/groupsPrecisa de sms:write. O nome não se pode repetir na conta. Até 100 grupos. Limite de 20 alterações por minuto.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Idempotency-Key | cabeçalho | string | não | Identificador único deste pedido, para o repetir sem o duplicar. |
Corpo do pedido
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
name | string | sim | Único na conta. |
Exemplos
curl
curl -X POST "https://api.mozout.co.mz/v1/sms/groups" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"name": "Customers"}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/groups');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{"name": "Customers"}',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
'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": "pt",
"Idempotency-Key": "9f1c2d3e-example",
}
payload = {"name": "Customers"}
r = requests.post("https://api.mozout.co.mz/v1/sms/groups", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/groups", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"Idempotency-Key": "9f1c2d3e-example",
"Content-Type": "application/json",
},
body: JSON.stringify({"name": "Customers"}),
});
console.log(response.status);
console.log(await response.text());Respostas
201
Criar um grupo de contactos.
{
"data": {
"id": 9,
"name": "Customers",
"contacts": 0,
"created_at": "2026-11-11T09:30:00+02:00",
"simulated": false
},
"meta": {}
}| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}409
A operação não se pode fazer no estado actual. Veja 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
Alguns dados não são válidos.
{
"error": {
"code": "validation_failed",
"message": "Alguns dados não são válidos.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 409 | conflict | A operação não se pode fazer no estado actual. Veja details.reason. |
| 422 | validation_failed | Alguns dados não são válidos. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
GETVer um grupo de contactos
/v1/sms/groups/{id}
https://api.mozout.co.mz/v1/sms/groups/{id}Precisa de sms:read.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id do grupo. |
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Exemplos
curl
curl "https://api.mozout.co.mz/v1/sms/groups/00000000-0000-4000-8000-000000000000" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/groups/00000000-0000-4000-8000-000000000000');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
],
]);
$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": "pt",
}
r = requests.get("https://api.mozout.co.mz/v1/sms/groups/00000000-0000-4000-8000-000000000000", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/groups/00000000-0000-4000-8000-000000000000", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Ver um grupo de contactos.
{
"data": {
"id": 9,
"name": "Customers",
"contacts": 128,
"created_at": "2026-11-11T09:30:00+02:00"
},
"meta": {}
}| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}404
Não encontrado.
{
"error": {
"code": "not_found",
"message": "Não encontrado.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 404 | not_found | Não encontrado. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
PATCHMudar o nome de um grupo
/v1/sms/groups/{id}
https://api.mozout.co.mz/v1/sms/groups/{id}Precisa de sms:write. Limite de 20 alterações por minuto.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id do grupo. |
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Corpo do pedido
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
name | string | sim | Único na conta. |
Exemplos
curl
curl -X PATCH "https://api.mozout.co.mz/v1/sms/groups/00000000-0000-4000-8000-000000000000" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Content-Type: application/json" \
-d '{"name": "VIP customers"}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/groups/00000000-0000-4000-8000-000000000000');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_POSTFIELDS => '{"name": "VIP customers"}',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
'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": "pt",
}
payload = {"name": "VIP customers"}
r = requests.patch("https://api.mozout.co.mz/v1/sms/groups/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.co.mz/v1/sms/groups/00000000-0000-4000-8000-000000000000", {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"Content-Type": "application/json",
},
body: JSON.stringify({"name": "VIP customers"}),
});
console.log(response.status);
console.log(await response.text());Respostas
200
Mudar o nome de um grupo.
{
"data": {
"id": 9,
"name": "VIP customers",
"contacts": 128,
"created_at": "2026-11-11T09:30:00+02:00",
"simulated": false
},
"meta": {}
}| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}404
Não encontrado.
{
"error": {
"code": "not_found",
"message": "Não encontrado.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}409
A operação não se pode fazer no estado actual. Veja 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
Alguns dados não são válidos.
{
"error": {
"code": "validation_failed",
"message": "Alguns dados não são válidos.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 404 | not_found | Não encontrado. |
| 409 | conflict | A operação não se pode fazer no estado actual. Veja details.reason. |
| 422 | validation_failed | Alguns dados não são válidos. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
DELETEApagar um grupo de contactos
/v1/sms/groups/{id}
https://api.mozout.co.mz/v1/sms/groups/{id}Precisa de sms:write. Os contactos não são apagados: só saem do grupo. Limite de 20 alterações por minuto.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id do grupo. |
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Exemplos
curl
curl -X DELETE "https://api.mozout.co.mz/v1/sms/groups/00000000-0000-4000-8000-000000000000" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/groups/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: pt',
],
]);
$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": "pt",
}
r = requests.delete("https://api.mozout.co.mz/v1/sms/groups/00000000-0000-4000-8000-000000000000", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/groups/00000000-0000-4000-8000-000000000000", {
method: "DELETE",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Apagar um grupo de contactos.
{
"data": {
"id": 9,
"deleted": true,
"simulated": false
},
"meta": {}
}| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}404
Não encontrado.
{
"error": {
"code": "not_found",
"message": "Não encontrado.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 404 | not_found | Não encontrado. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
POSTEnviar um código de verificação
/v1/sms/otp
https://api.mozout.co.mz/v1/sms/otpPrecisa de sms:write. Geramos o código, enviamo-lo por SMS na hora e guardamos só o hash. Confira-o com POST /v1/sms/otp/{id}/verify. Um código novo para o mesmo número anula o anterior. Sem limites por omissão; pode definir um máximo por número e por hora em PUT /v1/sms/otp-settings. O SMS gasta créditos como os outros; com uma chave sandbox nada se envia nem se cobra e a resposta traz o code, para testar a conferência.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Idempotency-Key | cabeçalho | string | não | Um valor único qualquer, até 255 caracteres visíveis. Vale 24 horas por chave. Repetir o mesmo pedido devolve a resposta guardada; outro corpo, ou um primeiro pedido ainda em curso, devolve 409. |
Corpo do pedido
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
number | string | sim | Número de telemóvel de Moçambique ou Angola, com ou sem indicativo. |
sender | string | não | Opcional. Um Sender ID aprovado para o país do número; sem ele, o remetente grátis. |
length | integer | não | Algarismos do código. |
expires_in | integer | não | Minutos em que o código vale. |
max_attempts | integer | não | Tentativas erradas antes de o código falhar. |
text | string | não | Opcional. O seu texto, com {code} uma vez e, se quiser, {minutes}. O texto de omissão cabe num só SMS. |
Exemplos
curl
curl -X POST "https://api.mozout.co.mz/v1/sms/otp" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"number": "+258841234567", "sender": "MYBRAND", "length": 6, "expires_in": 5}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/otp');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{"number": "+258841234567", "sender": "MYBRAND", "length": 6, "expires_in": 5}',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
'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": "pt",
"Idempotency-Key": "9f1c2d3e-example",
}
payload = {"number": "+258841234567", "sender": "MYBRAND", "length": 6, "expires_in": 5}
r = requests.post("https://api.mozout.co.mz/v1/sms/otp", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/otp", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"Idempotency-Key": "9f1c2d3e-example",
"Content-Type": "application/json",
},
body: JSON.stringify({"number": "+258841234567", "sender": "MYBRAND", "length": 6, "expires_in": 5}),
});
console.log(response.status);
console.log(await response.text());Respostas
201
Enviar um código de verificação.
{
"data": {
"id": "otp_3f9a1c2b7d4e5f60718293a4b5c6d7e8",
"status": "pending",
"to": "+25884***4567",
"sender": "MYBRAND",
"attempts": 0,
"attempts_left": 5,
"max_attempts": 5,
"message_id": "18342",
"mode": "production",
"expires_at": "2026-11-12T10:35:00+02:00",
"verified_at": null,
"created_at": "2026-11-12T10:30:00+02:00",
"parts": 1,
"simulated": false
},
"meta": {}
}| Campo | Tipo | Descrição |
|---|---|---|
data.status | string: pending, verified, expired, failed, cancelled | pending (à espera do código), verified, expired, failed (sem tentativas) ou cancelled (saiu um código mais novo, ou cancelado). |
data.code | string | Só com uma chave sandbox. |
| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}409
A operação não se pode fazer no estado actual. Veja 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
Alguns dados não são válidos.
{
"error": {
"code": "validation_failed",
"message": "Alguns dados não são válidos.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 409 | conflict | A operação não se pode fazer no estado actual. Veja details.reason. |
| 422 | validation_failed | Alguns dados não são válidos. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
GETVer um código de verificação
/v1/sms/otp/{id}
https://api.mozout.co.mz/v1/sms/otp/{id}Precisa de sms:read. O estado, nunca o código.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id devolvido quando o código foi enviado (otp_...). |
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Exemplos
curl
curl "https://api.mozout.co.mz/v1/sms/otp/00000000-0000-4000-8000-000000000000" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/otp/00000000-0000-4000-8000-000000000000');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
],
]);
$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": "pt",
}
r = requests.get("https://api.mozout.co.mz/v1/sms/otp/00000000-0000-4000-8000-000000000000", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/otp/00000000-0000-4000-8000-000000000000", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Ver um código de verificação.
{
"data": {
"id": "otp_3f9a1c2b7d4e5f60718293a4b5c6d7e8",
"status": "pending",
"to": "+25884***4567",
"sender": "MYBRAND",
"attempts": 0,
"attempts_left": 5,
"max_attempts": 5,
"message_id": "18342",
"mode": "production",
"expires_at": "2026-11-12T10:35:00+02:00",
"verified_at": null,
"created_at": "2026-11-12T10:30:00+02:00"
},
"meta": {}
}| Campo | Tipo | Descrição |
|---|---|---|
data.status | string: pending, verified, expired, failed, cancelled | pending (à espera do código), verified, expired, failed (sem tentativas) ou cancelled (saiu um código mais novo, ou cancelado). |
| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}404
Não encontrado.
{
"error": {
"code": "not_found",
"message": "Não encontrado.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 404 | not_found | Não encontrado. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
POSTConferir um código
/v1/sms/otp/{id}/verify
https://api.mozout.co.mz/v1/sms/otp/{id}/verifyPrecisa de sms:write. Compara em tempo constante o código que o utilizador escreveu. valid diz se bateu; cada código errado gasta uma tentativa e, sem tentativas, o estado passa a failed. Os espaços não contam. Um código já conferido, expirado ou falhado responde sempre valid: false.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id devolvido quando o código foi enviado (otp_...). |
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Idempotency-Key | cabeçalho | string | não | Identificador único deste pedido, para o repetir sem o duplicar. |
Corpo do pedido
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
code | string | sim | O código que o utilizador escreveu. |
Exemplos
curl
curl -X POST "https://api.mozout.co.mz/v1/sms/otp/00000000-0000-4000-8000-000000000000/verify" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"code": "482913"}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/otp/00000000-0000-4000-8000-000000000000/verify');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{"code": "482913"}',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
'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": "pt",
"Idempotency-Key": "9f1c2d3e-example",
}
payload = {"code": "482913"}
r = requests.post("https://api.mozout.co.mz/v1/sms/otp/00000000-0000-4000-8000-000000000000/verify", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/otp/00000000-0000-4000-8000-000000000000/verify", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"Idempotency-Key": "9f1c2d3e-example",
"Content-Type": "application/json",
},
body: JSON.stringify({"code": "482913"}),
});
console.log(response.status);
console.log(await response.text());Respostas
200
Conferir um código.
{
"data": {
"id": "otp_3f9a1c2b7d4e5f60718293a4b5c6d7e8",
"status": "verified",
"to": "+25884***4567",
"sender": "MYBRAND",
"attempts": 1,
"attempts_left": 4,
"max_attempts": 5,
"message_id": "18342",
"mode": "production",
"expires_at": "2026-11-12T10:35:00+02:00",
"verified_at": "2026-11-12T10:31:10+02:00",
"created_at": "2026-11-12T10:30:00+02:00",
"valid": true
},
"meta": {}
}| Campo | Tipo | Descrição |
|---|---|---|
data.status | string: pending, verified, expired, failed, cancelled | pending (à espera do código), verified, expired, failed (sem tentativas) ou cancelled (saiu um código mais novo, ou cancelado). |
| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}409
A operação não se pode fazer no estado actual. Veja 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
Alguns dados não são válidos.
{
"error": {
"code": "validation_failed",
"message": "Alguns dados não são válidos.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 409 | conflict | A operação não se pode fazer no estado actual. Veja details.reason. |
| 422 | validation_failed | Alguns dados não são válidos. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
POSTCancelar um código de verificação
/v1/sms/otp/{id}/cancel
https://api.mozout.co.mz/v1/sms/otp/{id}/cancelPrecisa de sms:write. Um código pendente deixa de valer. O SMS já enviado não é devolvido.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id devolvido quando o código foi enviado (otp_...). |
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Idempotency-Key | cabeçalho | string | não | Identificador único deste pedido, para o repetir sem o duplicar. |
Exemplos
curl
curl -X POST "https://api.mozout.co.mz/v1/sms/otp/00000000-0000-4000-8000-000000000000/cancel" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Idempotency-Key: 9f1c2d3e-example"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/otp/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: pt',
'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": "pt",
"Idempotency-Key": "9f1c2d3e-example",
}
r = requests.post("https://api.mozout.co.mz/v1/sms/otp/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.co.mz/v1/sms/otp/00000000-0000-4000-8000-000000000000/cancel", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"Idempotency-Key": "9f1c2d3e-example",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Cancelar um código de verificação.
{
"data": {
"id": "otp_3f9a1c2b7d4e5f60718293a4b5c6d7e8",
"status": "cancelled",
"to": "+25884***4567",
"sender": "MYBRAND",
"attempts": 0,
"attempts_left": 5,
"max_attempts": 5,
"message_id": "18342",
"mode": "production",
"expires_at": "2026-11-12T10:35:00+02:00",
"verified_at": null,
"created_at": "2026-11-12T10:30:00+02:00"
},
"meta": {}
}| Campo | Tipo | Descrição |
|---|---|---|
data.status | string: pending, verified, expired, failed, cancelled | pending (à espera do código), verified, expired, failed (sem tentativas) ou cancelled (saiu um código mais novo, ou cancelado). |
| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}409
A operação não se pode fazer no estado actual. Veja 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
Alguns dados não são válidos.
{
"error": {
"code": "validation_failed",
"message": "Alguns dados não são válidos.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 409 | conflict | A operação não se pode fazer no estado actual. Veja details.reason. |
| 422 | validation_failed | Alguns dados não são válidos. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
POSTEnviar mensagens em lote
/v1/sms/messages/batch
https://api.mozout.co.mz/v1/sms/messages/batchPrecisa de sms:write. Sem limite de mensagens (só conta o tamanho do pedido, 1 MB), cada uma com o seu número e, se quiser, o seu texto; sender, text e send_at valem para todas. Cada mensagem segue as regras de POST /v1/sms/messages e results diz o que aconteceu a cada uma (error usa as mesmas razões). As mensagens entram na fila (sai a cada minuto); até 20 saem logo. Sem créditos ou no limite do dia, as restantes são recusadas. Com uma chave sandbox nada se envia nem se cobra.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Idempotency-Key | cabeçalho | string | não | Um valor único qualquer, até 255 caracteres visíveis. Vale 24 horas por chave. Repetir o mesmo pedido devolve a resposta guardada; outro corpo, ou um primeiro pedido ainda em curso, devolve 409. |
Corpo do pedido
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
sender | string | não | |
text | string | não | Texto das mensagens que não tragam o seu. |
send_at | string | não | Opcional, ISO 8601 com fuso. |
messages | array<object> | sim |
Exemplos
curl
curl -X POST "https://api.mozout.co.mz/v1/sms/messages/batch" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"sender": "MYBRAND", "text": "Your order is ready for pickup.", "messages": [{"number": "+258841234567"}, {"number": "+244923456789", "text": "Your order is ready in Luanda."}, {"number": "12"}]}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/messages/batch');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{"sender": "MYBRAND", "text": "Your order is ready for pickup.", "messages": [{"number": "+258841234567"}, {"number": "+244923456789", "text": "Your order is ready in Luanda."}, {"number": "12"}]}',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
'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": "pt",
"Idempotency-Key": "9f1c2d3e-example",
}
payload = {"sender": "MYBRAND", "text": "Your order is ready for pickup.", "messages": [{"number": "+258841234567"}, {"number": "+244923456789", "text": "Your order is ready in Luanda."}, {"number": "12"}]}
r = requests.post("https://api.mozout.co.mz/v1/sms/messages/batch", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/messages/batch", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"Idempotency-Key": "9f1c2d3e-example",
"Content-Type": "application/json",
},
body: JSON.stringify({"sender": "MYBRAND", "text": "Your order is ready for pickup.", "messages": [{"number": "+258841234567"}, {"number": "+244923456789", "text": "Your order is ready in Luanda."}, {"number": "12"}]}),
});
console.log(response.status);
console.log(await response.text());Respostas
201
Enviar mensagens em lote.
{
"data": {
"total": 3,
"accepted": 2,
"rejected": 1,
"credits": 2.0,
"scheduled_for": null,
"simulated": false,
"results": [
{
"index": 0,
"id": "18401",
"status": "queued",
"to": "25884****567",
"parts": 1
},
{
"index": 1,
"id": "18402",
"status": "queued",
"to": "24492****789",
"parts": 1
},
{
"index": 2,
"id": null,
"status": "rejected",
"error": "invalid_number"
}
]
},
"meta": {}
}| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}409
A operação não se pode fazer no estado actual. Veja 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
Alguns dados não são válidos.
{
"error": {
"code": "validation_failed",
"message": "Alguns dados não são válidos.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 409 | conflict | A operação não se pode fazer no estado actual. Veja details.reason. |
| 422 | validation_failed | Alguns dados não são válidos. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
POSTReenviar um código de verificação
/v1/sms/otp/{id}/resend
https://api.mozout.co.mz/v1/sms/otp/{id}/resendPrecisa de sms:write. Envia um código NOVO no mesmo pedido (o id mantém-se) e a validade volta a contar; as tentativas erradas já gastas continuam gastas. Sem limite de reenvios por omissão; a espera entre reenvios e o limite por número e por hora só valem se os definir em PUT /v1/sms/otp-settings. Só para códigos pending ou expired. Com uma chave sandbox a resposta traz o code.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id devolvido quando o código foi enviado (otp_...). |
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Idempotency-Key | cabeçalho | string | não | Identificador único deste pedido, para o repetir sem o duplicar. |
Exemplos
curl
curl -X POST "https://api.mozout.co.mz/v1/sms/otp/00000000-0000-4000-8000-000000000000/resend" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Idempotency-Key: 9f1c2d3e-example"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/otp/00000000-0000-4000-8000-000000000000/resend');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
'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": "pt",
"Idempotency-Key": "9f1c2d3e-example",
}
r = requests.post("https://api.mozout.co.mz/v1/sms/otp/00000000-0000-4000-8000-000000000000/resend", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/otp/00000000-0000-4000-8000-000000000000/resend", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"Idempotency-Key": "9f1c2d3e-example",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Reenviar um código de verificação.
{
"data": {
"id": "otp_3f9a1c2b7d4e5f60718293a4b5c6d7e8",
"status": "pending",
"to": "25884****567",
"sender": "MYBRAND",
"attempts": 1,
"attempts_left": 4,
"max_attempts": 5,
"message_id": "18410",
"mode": "production",
"resends": 1,
"expires_at": "2026-11-12T10:41:00+02:00",
"verified_at": null,
"created_at": "2026-11-12T10:30:00+02:00",
"simulated": false
},
"meta": {}
}| Campo | Tipo | Descrição |
|---|---|---|
data.status | string: pending, verified, expired, failed, cancelled | pending (à espera do código), verified, expired, failed (sem tentativas) ou cancelled (saiu um código mais novo, ou cancelado). |
data.code | string | Só com uma chave sandbox. |
| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}409
A operação não se pode fazer no estado actual. Veja 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
Alguns dados não são válidos.
{
"error": {
"code": "validation_failed",
"message": "Alguns dados não são válidos.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 409 | conflict | A operação não se pode fazer no estado actual. Veja details.reason. |
| 422 | validation_failed | Alguns dados não são válidos. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
GETVer o webhook de entregas
/v1/sms/webhook
https://api.mozout.co.mz/v1/sms/webhookPrecisa de sms:read. O endereço, os eventos e a última entrega; nunca o segredo. Fazemos POST de um JSON {"event": "sms.sent" | "sms.failed", "created_at", "data": {...}} (data com os campos de GET /v1/sms/messages/{id}) para o seu endereço HTTPS na porta 443, só para mensagens criadas depois de o webhook ser gravado. Confira o cabeçalho X-Webhook-Signature: t=<hora unix>,v1=<hex>: v1 é o HMAC-SHA256 de t + "." + corpo cru com o seu segredo; recuse horas antigas. Responda com qualquer 2xx em 5 segundos; senão tentamos de novo após 1 min, 5 min, 30 min, 2 h e 6 h. Endereços internos ou privados são recusados.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Exemplos
curl
curl "https://api.mozout.co.mz/v1/sms/webhook" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/webhook');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
],
]);
$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": "pt",
}
r = requests.get("https://api.mozout.co.mz/v1/sms/webhook", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/webhook", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Ver o webhook de entregas.
{
"data": {
"url": "https://example.com/webhooks/sms",
"events": [
"sms.sent",
"sms.failed"
],
"created_at": "2026-11-12T10:30:00+02:00",
"updated_at": "2026-11-12T10:30:00+02:00",
"last_delivery_at": null,
"last_status_code": null,
"last_error": null
},
"meta": {}
}| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}404
Não encontrado.
{
"error": {
"code": "not_found",
"message": "Não encontrado.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 404 | not_found | Não encontrado. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
PUTGravar o webhook de entregas
/v1/sms/webhook
https://api.mozout.co.mz/v1/sms/webhookPrecisa de sms:write. Cria ou muda o endereço. O secret só aparece quando o webhook nasce ou com rotate_secret: true: guarde-o. Fazemos POST de um JSON {"event": "sms.sent" | "sms.failed", "created_at", "data": {...}} (data com os campos de GET /v1/sms/messages/{id}) para o seu endereço HTTPS na porta 443, só para mensagens criadas depois de o webhook ser gravado. Confira o cabeçalho X-Webhook-Signature: t=<hora unix>,v1=<hex>: v1 é o HMAC-SHA256 de t + "." + corpo cru com o seu segredo; recuse horas antigas. Responda com qualquer 2xx em 5 segundos; senão tentamos de novo após 1 min, 5 min, 30 min, 2 h e 6 h. Endereços internos ou privados são recusados.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Corpo do pedido
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
url | string | sim | Endereço HTTPS, porta 443. |
events | array<string: sms.sent, sms.failed> | não | Por omissão: os dois. |
rotate_secret | boolean | não | Criar um segredo novo. |
Exemplos
curl
curl -X PUT "https://api.mozout.co.mz/v1/sms/webhook" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/webhooks/sms", "events": ["sms.sent", "sms.failed"]}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/webhook');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_POSTFIELDS => '{"url": "https://example.com/webhooks/sms", "events": ["sms.sent", "sms.failed"]}',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
'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": "pt",
}
payload = {"url": "https://example.com/webhooks/sms", "events": ["sms.sent", "sms.failed"]}
r = requests.put("https://api.mozout.co.mz/v1/sms/webhook", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/webhook", {
method: "PUT",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"Content-Type": "application/json",
},
body: JSON.stringify({"url": "https://example.com/webhooks/sms", "events": ["sms.sent", "sms.failed"]}),
});
console.log(response.status);
console.log(await response.text());Respostas
200
Gravar o webhook de entregas.
{
"data": {
"url": "https://example.com/webhooks/sms",
"events": [
"sms.sent",
"sms.failed"
],
"created_at": "2026-11-12T10:30:00+02:00",
"updated_at": "2026-11-12T10:30:00+02:00",
"last_delivery_at": null,
"last_status_code": null,
"last_error": null,
"secret": "whsec_8c1f0e2d4b6a7c9e1f3a5b7d9e0c2a4b6d8f0a1c3e5b7d9f",
"simulated": false
},
"meta": {}
}| Campo | Tipo | Descrição |
|---|---|---|
data.secret | string | Só quando nasce ou é trocado. |
| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}404
Não encontrado.
{
"error": {
"code": "not_found",
"message": "Não encontrado.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}409
A operação não se pode fazer no estado actual. Veja 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
Alguns dados não são válidos.
{
"error": {
"code": "validation_failed",
"message": "Alguns dados não são válidos.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 404 | not_found | Não encontrado. |
| 409 | conflict | A operação não se pode fazer no estado actual. Veja details.reason. |
| 422 | validation_failed | Alguns dados não são válidos. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
DELETEApagar o webhook de entregas
/v1/sms/webhook
https://api.mozout.co.mz/v1/sms/webhookPrecisa de sms:write. As entregas por fazer são canceladas.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Exemplos
curl
curl -X DELETE "https://api.mozout.co.mz/v1/sms/webhook" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/webhook');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
],
]);
$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": "pt",
}
r = requests.delete("https://api.mozout.co.mz/v1/sms/webhook", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/webhook", {
method: "DELETE",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Apagar o webhook de entregas.
{
"data": {
"deleted": true,
"simulated": false
},
"meta": {}
}| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}404
Não encontrado.
{
"error": {
"code": "not_found",
"message": "Não encontrado.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 404 | not_found | Não encontrado. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
POSTTestar o webhook de entregas
/v1/sms/webhook/test
https://api.mozout.co.mz/v1/sms/webhook/testPrecisa de sms:write. Envia já um evento webhook.test assinado para o endereço gravado e devolve o que o seu servidor respondeu.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Idempotency-Key | cabeçalho | string | não | Identificador único deste pedido, para o repetir sem o duplicar. |
Exemplos
curl
curl -X POST "https://api.mozout.co.mz/v1/sms/webhook/test" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Idempotency-Key: 9f1c2d3e-example"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/webhook/test');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
'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": "pt",
"Idempotency-Key": "9f1c2d3e-example",
}
r = requests.post("https://api.mozout.co.mz/v1/sms/webhook/test", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/webhook/test", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"Idempotency-Key": "9f1c2d3e-example",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Testar o webhook de entregas.
{
"data": {
"delivered": true,
"status_code": 200,
"error": null
},
"meta": {}
}| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}409
A operação não se pode fazer no estado actual. Veja 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
Alguns dados não são válidos.
{
"error": {
"code": "validation_failed",
"message": "Alguns dados não são válidos.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 409 | conflict | A operação não se pode fazer no estado actual. Veja details.reason. |
| 422 | validation_failed | Alguns dados não são válidos. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
GETVer as regras dos códigos
/v1/sms/otp-settings
https://api.mozout.co.mz/v1/sms/otp-settingsPrecisa de sms:read. Por omissão não há limites (0).
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Exemplos
curl
curl "https://api.mozout.co.mz/v1/sms/otp-settings" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/otp-settings');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
],
]);
$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": "pt",
}
r = requests.get("https://api.mozout.co.mz/v1/sms/otp-settings", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/otp-settings", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Ver as regras dos códigos.
{
"data": {
"resend_wait_seconds": 0,
"max_codes_per_number_per_hour": 0
},
"meta": {}
}| Campo | Tipo | Descrição |
|---|---|---|
data.resend_wait_seconds | integer | Segundos entre reenvios do mesmo código. 0 = sem limite (omissão). |
data.max_codes_per_number_per_hour | integer | Códigos (novos e reenviados) por número e por hora. 0 = sem limite (omissão). |
| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}404
Não encontrado.
{
"error": {
"code": "not_found",
"message": "Não encontrado.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 404 | not_found | Não encontrado. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
PUTDefinir as regras dos códigos
/v1/sms/otp-settings
https://api.mozout.co.mz/v1/sms/otp-settingsPrecisa de sms:write. Envie só o que quer mudar; 0 tira o limite. As mesmas regras mudam-se no portal da conta, na página das chaves da API.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: sms:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
X-API-Mode | cabeçalho | string: sandbox, production | não | Opcional. Se não coincidir com o modo da chave, o pedido é recusado com invalid_request e a razão mode_mismatch. Serve para garantir que um programa nunca corre com a chave errada. |
Corpo do pedido
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
resend_wait_seconds | integer | não | Segundos entre reenvios do mesmo código. 0 = sem limite (omissão). |
max_codes_per_number_per_hour | integer | não | Códigos (novos e reenviados) por número e por hora. 0 = sem limite (omissão). |
Exemplos
curl
curl -X PUT "https://api.mozout.co.mz/v1/sms/otp-settings" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Content-Type: application/json" \
-d '{"resend_wait_seconds": 30, "max_codes_per_number_per_hour": 5}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/sms/otp-settings');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_POSTFIELDS => '{"resend_wait_seconds": 30, "max_codes_per_number_per_hour": 5}',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('RLX_API_KEY'),
'Accept-Language: pt',
'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": "pt",
}
payload = {"resend_wait_seconds": 30, "max_codes_per_number_per_hour": 5}
r = requests.put("https://api.mozout.co.mz/v1/sms/otp-settings", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/sms/otp-settings", {
method: "PUT",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"Content-Type": "application/json",
},
body: JSON.stringify({"resend_wait_seconds": 30, "max_codes_per_number_per_hour": 5}),
});
console.log(response.status);
console.log(await response.text());Respostas
200
Definir as regras dos códigos.
{
"data": {
"resend_wait_seconds": 30,
"max_codes_per_number_per_hour": 5,
"simulated": false
},
"meta": {}
}| Campo | Tipo | Descrição |
|---|---|---|
data.resend_wait_seconds | integer | Segundos entre reenvios do mesmo código. 0 = sem limite (omissão). |
data.max_codes_per_number_per_hour | integer | Códigos (novos e reenviados) por número e por hora. 0 = sem limite (omissão). |
| Cabeçalho | Descrição |
|---|---|
X-Correlation-ID | Identificador deste pedido. Indique-o ao suporte se comunicar um problema. |
X-RateLimit-Limit | Pedidos permitidos por minuto. |
X-RateLimit-Remaining | Pedidos que restam no minuto actual. |
X-RateLimit-Reset | Quando acaba o minuto, em segundos Unix. |
X-API-Mode | O modo da chave que fez o pedido: sandbox ou production. |
401
A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta.
{
"error": {
"code": "unauthorized",
"message": "Chave da API em falta ou inválida.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}403
A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed).
{
"error": {
"code": "insufficient_scope",
"message": "Esta chave não tem a permissão necessária.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"required": "dns:read"
}
}
}404
Não encontrado.
{
"error": {
"code": "not_found",
"message": "Não encontrado.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}409
A operação não se pode fazer no estado actual. Veja 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
Alguns dados não são válidos.
{
"error": {
"code": "validation_failed",
"message": "Alguns dados não são válidos.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}429
Demasiados pedidos. Espere o tempo indicado em Retry-After.
{
"error": {
"code": "rate_limited",
"message": "Demasiados pedidos. Tente de novo daqui a pouco.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"retry_after": 42
}
}
}| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a esperar antes de tentar de novo. |
500
Ocorreu um erro interno. Indique o correlation_id ao suporte.
{
"error": {
"code": "internal_error",
"message": "Ocorreu um erro interno. Indique o correlation_id ao suporte.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}503
A API está desligada.
{
"error": {
"code": "disabled",
"message": "A API está desligada de momento.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}Erros
| Estado | Código | Significado |
|---|---|---|
| 401 | unauthorized | A chave está em falta, não é válida, foi revogada ou passou da validade, ou quem a criou já não tem acesso à conta. |
| 403 | forbidden, insufficient_scope, ip_not_allowed | A conta não pode usar a API (forbidden), a chave não tem a permissão necessária (insufficient_scope), ou o endereço IP não está na lista da chave (ip_not_allowed). |
| 404 | not_found | Não encontrado. |
| 409 | conflict | A operação não se pode fazer no estado actual. Veja details.reason. |
| 422 | validation_failed | Alguns dados não são válidos. |
| 429 | rate_limited | Demasiados pedidos. Espere o tempo indicado em Retry-After. |
| 500 | internal_error | Ocorreu um erro interno. Indique o correlation_id ao suporte. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
Nenhuma operação encontrada.