
O que precisa
- O Email Center activo na sua conta. Activa-se no portal, na página E-mail transaccional. Sem ele, a API responde
403comforbiddene o motivoemail_account_requiredemdetails.reason. - Uma chave com a permissão
email_center:writepara enviar e alterar, eemail_center:readpara consultar. Veja Permissões. As permissõesemail:readeemail:writesão outras: servem para as caixas de correio da hospedagem. - Um domínio remetente verificado. Só se envia de endereços desse domínio ou de um subdomínio dele.
O domínio remetente
Junte o domínio com POST /v1/email/domains:
curl
curl -X POST "https://api.mozout.co.mz/v1/email/domains" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"domain": "example.com"}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/domains');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{"domain": "example.com"}',
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 = {"domain": "example.com"}
r = requests.post("https://api.mozout.co.mz/v1/email/domains", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/domains", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"Idempotency-Key": "9f1c2d3e-example",
"Content-Type": "application/json",
},
body: JSON.stringify({"domain": "example.com"}),
});
console.log(response.status);
console.log(await response.text());A resposta traz em dns_records os registos a pôr no DNS do domínio:
- três registos
CNAMEde DKIM, que assinam os seus e-mails (obrigatórios); - um
TXTde SPF, que autoriza o nosso envio (recomendado); - um
TXTde DMARC, a política do domínio (recomendado).
Depois de os pôr, chame POST /v1/email/domains/{domain}/verify. O DNS pode levar algumas horas a propagar. Quando os registos DKIM estiverem no ar, o domínio passa a verified. O campo found de cada registo diz se ele já foi encontrado.
Se quiser que o endereço de retorno também seja seu, defina um subdomínio com PUT /v1/email/domains/{domain}/mail-from, por exemplo bounce. Aparecem então mais um MX e um TXT para pôr no DNS.
O envio
Use POST /v1/email/messages com o remetente, os destinatários, o assunto e o conteúdo em html, em text ou nos dois:
curl
curl -X POST "https://api.mozout.co.mz/v1/email/messages" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"from": "Example Ltd <[email protected]>", "to": ["[email protected]"], "reply_to": "[email protected]", "template_id": 7, "variables": {"name": "Ana", "order": "1234"}}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/messages');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{"from": "Example Ltd <[email protected]>", "to": ["[email protected]"], "reply_to": "[email protected]", "template_id": 7, "variables": {"name": "Ana", "order": "1234"}}',
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 = {"from": "Example Ltd <[email protected]>", "to": ["[email protected]"], "reply_to": "[email protected]", "template_id": 7, "variables": {"name": "Ana", "order": "1234"}}
r = requests.post("https://api.mozout.co.mz/v1/email/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/email/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({"from": "Example Ltd <[email protected]>", "to": ["[email protected]"], "reply_to": "[email protected]", "template_id": 7, "variables": {"name": "Ana", "order": "1234"}}),
});
console.log(response.status);
console.log(await response.text());to,ccebccaceitam um endereço, uma lista separada por vírgulas ou um array. No máximo 50 destinatários por e-mail.- Cada destinatário conta como um e-mail e gasta um crédito.
- Sem
send_at, o e-mail sai logo e a resposta traz o estado real. - Os anexos vão em
attachments, em base64, até 5 MB no total. Os executáveis são recusados.
Envie o cabeçalho Idempotency-Key para que uma repetição nunca envie o e-mail duas vezes. Veja Repetições.
Modelos e variáveis
Crie modelos com POST /v1/email/templates, com o assunto e o HTML ou o texto. Escreva as variáveis como {{name}}.
No envio, indique o template_id e os valores em variables. O assunto, o html e o text que não enviar vêm do modelo. No HTML, os valores entram escapados, por isso um nome com < ou & aparece como texto.
Envios agendados e em lote
Para o e-mail sair mais tarde, junte send_at em ISO 8601 com o fuso horário, por exemplo 2026-11-20T09:30:00+02:00, até 30 dias à frente. Os créditos só são descontados quando o e-mail sair. Para desistir, use POST /v1/email/messages/{id}/cancel antes da hora.
Para muitos e-mails de uma vez, use POST /v1/email/messages/batch. Não há limite de mensagens, só de tamanho do pedido (8 MB). Os campos fora de messages valem para todas, e cada mensagem tem o seu to e as suas variables. Em results vem o que aconteceu a cada uma.
Estados e eventos
GET /v1/email/messages/{id} mostra o estado e os eventos de cada destinatário:
sent: saiu para os servidores de destino;delivered: o servidor do destinatário aceitou;bounced: devolvido. Se a devolução for permanente, o endereço entra na lista de bloqueados;complained: o destinatário marcou como spam, e o endereço entra na lista de bloqueados;failed: não saiu, e os créditos voltam ao saldo.
O conteúdo dos e-mails guarda-se durante 30 dias. Depois, html e text vêm a null e fica só o registo.
Bloqueados
Os endereços da lista de bloqueados nunca recebem os seus e-mails: são retirados antes de o e-mail sair, não são cobrados e vêm em suppressed na resposta. Se não sobrar nenhum destinatário, a API responde 422 com o motivo all_recipients_suppressed.
Veja a lista com GET /v1/email/suppressions, junte endereços com POST /v1/email/suppressions e tire-os com DELETE /v1/email/suppressions/{email}, com o endereço codificado no caminho (ana%40example.org).
Avisos por webhook
Grave um endereço HTTPS com PUT /v1/email/webhook e escolha os eventos: email.sent, email.delivered, email.bounced, email.complained e email.failed. Este webhook é diferente do webhook do SMS.
Cada aviso é assinado como os do SMS, no cabeçalho X-Webhook-Signature. Veja o webhook do SMS para conferir a assinatura.
Sandbox e Produção
- Com uma chave
sandbox_, nada se envia nem se cobra. O e-mail ficasimulated, com os eventos simulados. As outras alterações (domínios, modelos, bloqueados) só se simulam. - Para ensaiar devoluções e queixas, envie para
[email protected]ou[email protected]. - Enquanto o Email Center estiver em modo de teste, também as chaves
prod_simulam:GET /v1/email/balancediz-lhe isso emtest_mode.
Veja Sandbox e Produção.
SMTP Relay
No portal, na página SMTP, crie utilizadores e senhas para enviar a partir do seu programa ou servidor, nas portas 587 (STARTTLS) e 465 (TLS). A senha só se mostra uma vez. O servidor SMTP ainda está a ser ligado: até lá, use a API.
E-mail marketing
Além do e-mail transaccional, o Email Center envia campanhas para os seus contactos: os do SMS Center que têm e-mail e os contactos só de e-mail. Cada destinatário gasta um crédito, como os outros e-mails.
- Junte contactos com
POST /v1/email/contacts, com os grupos emgroups. Os grupos são os mesmos dos contactos do SMS: veja-os emGET /v1/email/groups. - Crie a campanha com
POST /v1/email/campaigns, com os blocos emblocks(header,text,image,button,dividerefooter) ou com um modelo pronto emtemplate. Se quiser, peça antes uma proposta à IA comPOST /v1/email/campaigns/generate. - Escolha o público em
target: grupos, quem abriu ou clicou antes, e a data de entrada. - Confira o resultado de
GET /v1/email/campaigns/{id}/spam-checke mande um teste comPOST /v1/email/campaigns/{id}/test. - Envie já com
POST /v1/email/campaigns/{id}/sendou agende comPOST /v1/email/campaigns/{id}/schedule.
curl
curl -X POST "https://api.mozout.co.mz/v1/email/campaigns" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"name": "November news", "template": "comercio", "from": "[email protected]", "from_name": "Example Ltd", "target": {"groups": [3]}}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/campaigns');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{"name": "November news", "template": "comercio", "from": "[email protected]", "from_name": "Example Ltd", "target": {"groups": [3]}}',
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": "November news", "template": "comercio", "from": "[email protected]", "from_name": "Example Ltd", "target": {"groups": [3]}}
r = requests.post("https://api.mozout.co.mz/v1/email/campaigns", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/campaigns", {
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": "November news", "template": "comercio", "from": "[email protected]", "from_name": "Example Ltd", "target": {"groups": [3]}}),
});
console.log(response.status);
console.log(await response.text());Nos textos pode usar {{first_name}}, {{name}}, {{company}} e {{email}} de cada contacto.
Subscrição e cancelamento
Todos os e-mails de campanha levam, no fim, a morada e uma ligação para cancelar a subscrição, e o cabeçalho List-Unsubscribe, para os programas de e-mail mostrarem o botão de cancelar. Quem cancela deixa de receber as suas campanhas, tal como quem está na lista de bloqueados. Veja e mude o estado com PUT /v1/email/contacts/{email}/subscription.
Estatísticas
GET /v1/email/campaigns/{id}/stats dá as entregas, as aberturas, os cliques, os cancelamentos e as devoluções. GET /v1/email/campaigns/{id}/recipients mostra o que cada contacto fez. Em modo de teste os números são de exemplo e vêm com simulated a true.
Operações
43 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 os e-mails
/v1/email/messages
https://api.mozout.co.mz/v1/email/messagesPrecisa de email_center:read. Os mais recentes primeiro, sem o conteúdo (veja GET /v1/email/messages/{id}).
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
status | consulta | string | não | Um de: queued, scheduled, sending, sent, delivered, bounced, complained, failed, simulated, cancelled. |
from | consulta | string | não | Desde este dia, AAAA-MM-DD. |
to | consulta | string | não | Até este dia, AAAA-MM-DD. |
recipient | consulta | string | não | Só os e-mails para este endereço (to, cc ou bcc). |
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/email/messages" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/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/email/messages", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/messages", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Listar os e-mails.
{
"data": [
{
"id": "5120",
"status": "delivered",
"simulated": false,
"from": "[email protected]",
"to": [
"[email protected]"
],
"cc": [],
"bcc": [],
"reply_to": [
"[email protected]"
],
"subject": "Your order 1234 is ready",
"recipients": 1,
"credits": 1.0,
"charged": true,
"source": "api",
"template_id": 7,
"attachments": [],
"error": null,
"scheduled_for": null,
"created_at": "2026-11-12T10:30:00+02:00",
"sent_at": "2026-11-12T10:30:01+02:00",
"from_name": "Example Ltd"
}
],
"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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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 e-mail
/v1/email/messages
https://api.mozout.co.mz/v1/email/messagesPrecisa de email_center:write. Cada destinatário (to, cc e bcc, até 50) é um e-mail e um crédito. Os endereços da lista de bloqueados saem e vêm em suppressed; se não sobrar nenhum, a API responde 422 all_recipients_suppressed. Sem send_at o e-mail sai logo e a resposta traz o estado real. Com uma chave sandbox, ou com o Email Center em modo de teste, nada se envia nem se cobra: o e-mail fica simulated e os eventos da simulação ficam registados ([email protected] simula uma devolução, [email protected] uma queixa). Envie Idempotency-Key para uma repetição nunca enviar duas vezes.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center: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 |
|---|---|---|---|
from | string | sim | Remetente num domínio verificado (ou subdomínio dele): [email protected] ou Empresa <[email protected]>. |
from_name | string | não | Nome a mostrar, opcional. |
to | any | sim | Um endereço, uma lista separada por vírgulas ou um array. |
cc | any | não | |
bcc | any | não | |
reply_to | any | não | Até 5 endereços. |
subject | string | não | Até 998 caracteres. Pode usar {{variáveis}}. |
html | string | não | Corpo em HTML. Os valores das {{variáveis}} entram escapados. |
text | string | não | Corpo em texto simples. |
template_id | integer | não | Um modelo desta conta; o assunto, o html e o text vazios vêm dele. |
variables | object | não | Os valores das marcas {{nome}}, num objecto. |
attachments | array<object> | não | Ficheiros em base64; 5 MB no total por omissão, executáveis recusados. |
send_at | string | não | Opcional, ISO 8601 com fuso, até 30 dias por omissão. |
Exemplos
curl
curl -X POST "https://api.mozout.co.mz/v1/email/messages" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"from": "Example Ltd <[email protected]>", "to": ["[email protected]"], "reply_to": "[email protected]", "template_id": 7, "variables": {"name": "Ana", "order": "1234"}}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/messages');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{"from": "Example Ltd <[email protected]>", "to": ["[email protected]"], "reply_to": "[email protected]", "template_id": 7, "variables": {"name": "Ana", "order": "1234"}}',
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 = {"from": "Example Ltd <[email protected]>", "to": ["[email protected]"], "reply_to": "[email protected]", "template_id": 7, "variables": {"name": "Ana", "order": "1234"}}
r = requests.post("https://api.mozout.co.mz/v1/email/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/email/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({"from": "Example Ltd <[email protected]>", "to": ["[email protected]"], "reply_to": "[email protected]", "template_id": 7, "variables": {"name": "Ana", "order": "1234"}}),
});
console.log(response.status);
console.log(await response.text());Respostas
201
Enviar um e-mail.
{
"data": {
"id": "5120",
"status": "sent",
"simulated": false,
"from": "[email protected]",
"to": [
"[email protected]"
],
"cc": [],
"bcc": [],
"reply_to": [
"[email protected]"
],
"subject": "Your order 1234 is ready",
"recipients": 1,
"credits": 1.0,
"charged": true,
"source": "api",
"template_id": 7,
"attachments": [],
"error": null,
"scheduled_for": null,
"created_at": "2026-11-12T10:30:00+02:00",
"sent_at": "2026-11-12T10:30:01+02:00",
"from_name": "Example Ltd",
"suppressed": []
},
"meta": {}
}| Campo | Tipo | Descrição |
|---|---|---|
data.recipients | integer | Destinatários depois da lista de bloqueados; cada um é um crédito. |
data.source | string | portal, api ou smtp. |
| 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. |
400
O pedido não é válido, por exemplo o corpo não é JSON ou a ligação não é HTTPS.
{
"error": {
"code": "invalid_request",
"message": "O pedido não é válido.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 |
|---|---|---|
| 400 | invalid_request | O pedido não é válido, por exemplo o corpo não é JSON ou a ligação não é HTTPS. |
| 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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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 e-mails em lote
/v1/email/messages/batch
https://api.mozout.co.mz/v1/email/messages/batchPrecisa de email_center:write. Sem limite de mensagens, só do tamanho do pedido (8 MB). Os campos fora de messages (from, subject, html, text, template_id, reply_to, send_at) valem para todas; cada mensagem pode mudá-los e tem o seu to e as suas variables. Cada uma segue as regras de POST /v1/email/messages e results diz o que lhe aconteceu (error usa as mesmas razões). Até 20 saem logo; as outras entram na fila (a cada minuto). Sem créditos ou no limite do dia, as restantes são recusadas.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center: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 |
|---|---|---|---|
from | string | não | Remetente num domínio verificado (ou subdomínio dele): [email protected] ou Empresa <[email protected]>. |
from_name | string | não | Nome a mostrar, opcional. |
to | any | não | Um endereço, uma lista separada por vírgulas ou um array. |
cc | any | não | |
bcc | any | não | |
reply_to | any | não | Até 5 endereços. |
subject | string | não | Até 998 caracteres. Pode usar {{variáveis}}. |
html | string | não | Corpo em HTML. Os valores das {{variáveis}} entram escapados. |
text | string | não | Corpo em texto simples. |
template_id | integer | não | Um modelo desta conta; o assunto, o html e o text vazios vêm dele. |
variables | object | não | Os valores das marcas {{nome}}, num objecto. |
attachments | array<object> | não | Ficheiros em base64; 5 MB no total por omissão, executáveis recusados. |
send_at | string | não | Opcional, ISO 8601 com fuso, até 30 dias por omissão. |
messages | array<object> | sim |
Exemplos
curl
curl -X POST "https://api.mozout.co.mz/v1/email/messages/batch" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"from": "Example Ltd <[email protected]>", "subject": "Hello {{name}}", "text": "Hi {{name}}, your invoice is ready.", "messages": [{"to": "[email protected]", "variables": {"name": "Ana"}}, {"to": "[email protected]", "variables": {"name": "Rui"}}, {"to": "not-an-email"}]}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/messages/batch');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{"from": "Example Ltd <[email protected]>", "subject": "Hello {{name}}", "text": "Hi {{name}}, your invoice is ready.", "messages": [{"to": "[email protected]", "variables": {"name": "Ana"}}, {"to": "[email protected]", "variables": {"name": "Rui"}}, {"to": "not-an-email"}]}',
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 = {"from": "Example Ltd <[email protected]>", "subject": "Hello {{name}}", "text": "Hi {{name}}, your invoice is ready.", "messages": [{"to": "[email protected]", "variables": {"name": "Ana"}}, {"to": "[email protected]", "variables": {"name": "Rui"}}, {"to": "not-an-email"}]}
r = requests.post("https://api.mozout.co.mz/v1/email/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/email/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({"from": "Example Ltd <[email protected]>", "subject": "Hello {{name}}", "text": "Hi {{name}}, your invoice is ready.", "messages": [{"to": "[email protected]", "variables": {"name": "Ana"}}, {"to": "[email protected]", "variables": {"name": "Rui"}}, {"to": "not-an-email"}]}),
});
console.log(response.status);
console.log(await response.text());Respostas
201
Enviar e-mails em lote.
{
"data": {
"total": 3,
"accepted": 2,
"rejected": 1,
"credits": 2.0,
"simulated": false,
"results": [
{
"index": 0,
"id": "5121",
"status": "sent",
"recipients": 1,
"suppressed": []
},
{
"index": 1,
"id": "5122",
"status": "sent",
"recipients": 1,
"suppressed": []
},
{
"index": 2,
"id": null,
"status": "rejected",
"error": "invalid_recipient",
"field": "to"
}
]
},
"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. |
400
O pedido não é válido, por exemplo o corpo não é JSON ou a ligação não é HTTPS.
{
"error": {
"code": "invalid_request",
"message": "O pedido não é válido.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 |
|---|---|---|
| 400 | invalid_request | O pedido não é válido, por exemplo o corpo não é JSON ou a ligação não é HTTPS. |
| 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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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 e-mail
/v1/email/messages/{id}
https://api.mozout.co.mz/v1/email/messages/{id}Precisa de email_center:read. Com os eventos de cada destinatário e o conteúdo (guardado 30 dias por omissão; depois html e text vêm a null).
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id devolvido no envio. |
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/email/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/email/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/email/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/email/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
Ver um e-mail.
{
"data": {
"id": "5120",
"status": "delivered",
"simulated": false,
"from": "[email protected]",
"to": [
"[email protected]"
],
"cc": [],
"bcc": [],
"reply_to": [
"[email protected]"
],
"subject": "Your order 1234 is ready",
"recipients": 1,
"credits": 1.0,
"charged": true,
"source": "api",
"template_id": 7,
"attachments": [],
"error": null,
"scheduled_for": null,
"created_at": "2026-11-12T10:30:00+02:00",
"sent_at": "2026-11-12T10:30:01+02:00",
"from_name": "Example Ltd",
"html": "<p>Hello Ana, your order 1234 is ready.</p>",
"text": "Hello Ana, your order 1234 is ready.",
"events": [
{
"type": "sent",
"recipient": null,
"detail": null,
"simulated": false,
"created_at": "2026-11-12T10:30:01+02:00"
},
{
"type": "delivered",
"recipient": "[email protected]",
"detail": null,
"simulated": false,
"created_at": "2026-11-12T10:30:03+02:00"
}
]
},
"meta": {}
}| Campo | Tipo | Descrição |
|---|---|---|
data.recipients | integer | Destinatários depois da lista de bloqueados; cada um é um crédito. |
data.source | string | portal, api ou smtp. |
| 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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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.
POSTCancelar um e-mail agendado
/v1/email/messages/{id}/cancel
https://api.mozout.co.mz/v1/email/messages/{id}/cancelPrecisa de email_center:write. Só e-mails scheduled que ainda não saíram; os créditos já descontados voltam (credits_returned). Senão 409 not_cancellable.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id devolvido no envio. |
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/email/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/email/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/email/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/email/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 e-mail agendado.
{
"data": {
"id": "5120",
"status": "cancelled",
"simulated": false,
"from": "[email protected]",
"to": [
"[email protected]"
],
"cc": [],
"bcc": [],
"reply_to": [
"[email protected]"
],
"subject": "Your order 1234 is ready",
"recipients": 1,
"credits": 1.0,
"charged": true,
"source": "api",
"template_id": 7,
"attachments": [],
"error": null,
"scheduled_for": "2026-11-20T09:30:00+02:00",
"created_at": "2026-11-12T10:30:00+02:00",
"sent_at": null,
"from_name": "Example Ltd",
"credits_returned": 0.0
},
"meta": {}
}| Campo | Tipo | Descrição |
|---|---|---|
data.recipients | integer | Destinatários depois da lista de bloqueados; cada um é um crédito. |
data.source | string | portal, api ou smtp. |
| 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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | forbidden, insufficient_scope | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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.
GETVer o saldo de e-mail
/v1/email/balance
https://api.mozout.co.mz/v1/email/balancePrecisa de email_center:read. Um crédito é um e-mail para um destinatário. test_mode é true enquanto o Email Center não envia a sério.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center: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/email/balance" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/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/email/balance", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/balance", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Ver o saldo de e-mail.
{
"data": {
"balance": 9850.0,
"unit": "emails",
"scheduled_credits": 0.0,
"daily_limit": 500,
"sent_today": 42,
"mode": "production",
"test_mode": 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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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 e-mail
/v1/email/stats
https://api.mozout.co.mz/v1/email/statsPrecisa de email_center:read. Por estado e por dia. Entregues, devolvidos e queixas contam destinatários; as taxas são sobre os destinatários. Por omissão, os últimos 30 dias; no máximo 366.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
from | consulta | string | não | AAAA-MM-DD. |
to | consulta | string | não | 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/email/stats" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/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/email/stats", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/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 e-mail.
{
"data": {
"from": "2026-10-14",
"to": "2026-11-12",
"messages": 320,
"recipients": 340,
"credits_spent": 338.0,
"by_status": {
"delivered": 300,
"bounced": 4,
"complained": 0,
"sent": 14,
"failed": 2
},
"events": {
"delivered": 330,
"bounced": 4,
"complained": 0
},
"delivery_rate": 97.06,
"bounce_rate": 1.18,
"complaint_rate": 0.0,
"by_day": [
{
"date": "2026-11-12",
"messages": 12,
"recipients": 12,
"delivered": 12,
"bounced": 0,
"complained": 0,
"credits": 12.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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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 domínios remetentes
/v1/email/domains
https://api.mozout.co.mz/v1/email/domainsPrecisa de email_center:read. Por ordem alfabética.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center: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/email/domains" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/domains');
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/email/domains", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/domains", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Listar os domínios remetentes.
{
"data": [
{
"id": 12,
"domain": "example.com",
"status": "verified",
"mail_from": null,
"verified_at": "2026-11-12T10:00:00+02:00",
"last_checked_at": "2026-11-12T10:00:00+02:00",
"created_at": "2026-11-12T09:40: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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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.
POSTJuntar um domínio remetente
/v1/email/domains
https://api.mozout.co.mz/v1/email/domainsPrecisa de email_center:write. Ponha no DNS do domínio os registos de dns_records: três CNAME de DKIM (obrigatórios), SPF e DMARC (recomendados) e, com MAIL FROM, um MX e um TXT. Depois chame verify; o DNS pode levar algumas horas. Só os domínios verificados enviam, de qualquer endereço do domínio ou de um subdomínio. Os domínios de caixas grátis (gmail.com e outros) são recusados. Com uma chave sandbox nada se guarda.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center: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 |
|---|---|---|---|
domain | string | sim |
Exemplos
curl
curl -X POST "https://api.mozout.co.mz/v1/email/domains" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"domain": "example.com"}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/domains');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{"domain": "example.com"}',
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 = {"domain": "example.com"}
r = requests.post("https://api.mozout.co.mz/v1/email/domains", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/domains", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"Idempotency-Key": "9f1c2d3e-example",
"Content-Type": "application/json",
},
body: JSON.stringify({"domain": "example.com"}),
});
console.log(response.status);
console.log(await response.text());Respostas
201
Juntar um domínio remetente.
{
"data": {
"id": 12,
"domain": "example.com",
"status": "pending",
"mail_from": null,
"verified_at": null,
"last_checked_at": null,
"created_at": "2026-11-12T09:40:00+02:00",
"dns_records": [
{
"type": "CNAME",
"name": "k3jd8s0a1b2c3d4e5f6a7b8c9d0e1f2a._domainkey.example.com",
"value": "k3jd8s0a1b2c3d4e5f6a7b8c9d0e1f2a.dkim.example-brand.com",
"priority": null,
"purpose": "dkim",
"required": true,
"found": null
},
{
"type": "TXT",
"name": "example.com",
"value": "v=spf1 include:_spf.example-brand.com ~all",
"priority": null,
"purpose": "spf",
"required": false,
"found": null
},
{
"type": "TXT",
"name": "_dmarc.example.com",
"value": "v=DMARC1; p=none; adkim=r; aspf=r",
"priority": null,
"purpose": "dmarc",
"required": false,
"found": null
}
],
"test_mode_accepted": false,
"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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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 domínio remetente
/v1/email/domains/{domain}
https://api.mozout.co.mz/v1/email/domains/{domain}Precisa de email_center:read. Com os registos DNS a pôr e se cada um foi encontrado na última verificação.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
domain | caminho | string | sim | O nome do domínio (example.com) ou o seu id. |
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/email/domains/VALUE" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/domains/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/email/domains/VALUE", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/domains/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 domínio remetente.
{
"data": {
"id": 12,
"domain": "example.com",
"status": "verified",
"mail_from": null,
"verified_at": "2026-11-12T10:00:00+02:00",
"last_checked_at": "2026-11-12T10:00:00+02:00",
"created_at": "2026-11-12T09:40:00+02:00",
"dns_records": [
{
"type": "CNAME",
"name": "k3jd8s0a1b2c3d4e5f6a7b8c9d0e1f2a._domainkey.example.com",
"value": "k3jd8s0a1b2c3d4e5f6a7b8c9d0e1f2a.dkim.example-brand.com",
"priority": null,
"purpose": "dkim",
"required": true,
"found": true
},
{
"type": "TXT",
"name": "example.com",
"value": "v=spf1 include:_spf.example-brand.com ~all",
"priority": null,
"purpose": "spf",
"required": false,
"found": true
},
{
"type": "TXT",
"name": "_dmarc.example.com",
"value": "v=DMARC1; p=none; adkim=r; aspf=r",
"priority": null,
"purpose": "dmarc",
"required": false,
"found": false
}
],
"test_mode_accepted": false,
"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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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.
DELETEApagar um domínio remetente
/v1/email/domains/{domain}
https://api.mozout.co.mz/v1/email/domains/{domain}Precisa de email_center:write. O domínio deixa de poder enviar. Os e-mails já enviados ficam no registo.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
domain | caminho | string | sim | O nome do domínio (example.com) ou o seu id. |
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/email/domains/VALUE" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/domains/VALUE');
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/email/domains/VALUE", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/domains/VALUE", {
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 domínio remetente.
{
"data": {
"id": 12,
"domain": "example.com",
"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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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.
POSTVerificar um domínio remetente
/v1/email/domains/{domain}/verify
https://api.mozout.co.mz/v1/email/domains/{domain}/verifyPrecisa de email_center:write. Confere já os registos DKIM e devolve o estado novo. Com uma chave sandbox o resultado não se guarda.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
domain | caminho | string | sim | O nome do domínio (example.com) ou o seu id. |
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/email/domains/VALUE/verify" \
-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/email/domains/VALUE/verify');
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/email/domains/VALUE/verify", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/domains/VALUE/verify", {
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
Verificar um domínio remetente.
{
"data": {
"id": 12,
"domain": "example.com",
"status": "verified",
"mail_from": null,
"verified_at": "2026-11-12T10:00:00+02:00",
"last_checked_at": "2026-11-12T10:00:00+02:00",
"created_at": "2026-11-12T09:40:00+02:00",
"dns_records": [
{
"type": "CNAME",
"name": "k3jd8s0a1b2c3d4e5f6a7b8c9d0e1f2a._domainkey.example.com",
"value": "k3jd8s0a1b2c3d4e5f6a7b8c9d0e1f2a.dkim.example-brand.com",
"priority": null,
"purpose": "dkim",
"required": true,
"found": true
},
{
"type": "TXT",
"name": "example.com",
"value": "v=spf1 include:_spf.example-brand.com ~all",
"priority": null,
"purpose": "spf",
"required": false,
"found": true
},
{
"type": "TXT",
"name": "_dmarc.example.com",
"value": "v=DMARC1; p=none; adkim=r; aspf=r",
"priority": null,
"purpose": "dmarc",
"required": false,
"found": false
}
],
"test_mode_accepted": false,
"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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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 o subdomínio do MAIL FROM
/v1/email/domains/{domain}/mail-from
https://api.mozout.co.mz/v1/email/domains/{domain}/mail-fromPrecisa de email_center:write. Opcional: um subdomínio seu para o endereço de retorno (por exemplo bounce), para o SPF alinhar com o seu domínio no DMARC. Vazio volta ao nosso. Ponha o MX e o TXT que aparecem em dns_records.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
domain | caminho | string | sim | O nome do domínio (example.com) ou o seu id. |
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 |
|---|---|---|---|
subdomain | string, null | sim |
Exemplos
curl
curl -X PUT "https://api.mozout.co.mz/v1/email/domains/VALUE/mail-from" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Content-Type: application/json" \
-d '{"subdomain": "bounce"}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/domains/VALUE/mail-from');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_POSTFIELDS => '{"subdomain": "bounce"}',
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 = {"subdomain": "bounce"}
r = requests.put("https://api.mozout.co.mz/v1/email/domains/VALUE/mail-from", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/domains/VALUE/mail-from", {
method: "PUT",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"Content-Type": "application/json",
},
body: JSON.stringify({"subdomain": "bounce"}),
});
console.log(response.status);
console.log(await response.text());Respostas
200
Definir o subdomínio do MAIL FROM.
{
"data": {
"id": 12,
"domain": "example.com",
"status": "verified",
"mail_from": "bounce.example.com",
"verified_at": "2026-11-12T10:00:00+02:00",
"last_checked_at": "2026-11-12T10:00:00+02:00",
"created_at": "2026-11-12T09:40:00+02:00",
"dns_records": [
{
"type": "CNAME",
"name": "k3jd8s0a1b2c3d4e5f6a7b8c9d0e1f2a._domainkey.example.com",
"value": "k3jd8s0a1b2c3d4e5f6a7b8c9d0e1f2a.dkim.example-brand.com",
"priority": null,
"purpose": "dkim",
"required": true,
"found": true
},
{
"type": "TXT",
"name": "example.com",
"value": "v=spf1 include:_spf.example-brand.com ~all",
"priority": null,
"purpose": "spf",
"required": false,
"found": true
},
{
"type": "TXT",
"name": "_dmarc.example.com",
"value": "v=DMARC1; p=none; adkim=r; aspf=r",
"priority": null,
"purpose": "dmarc",
"required": false,
"found": false
}
],
"test_mode_accepted": false,
"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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}404
Não encontrado.
{
"error": {
"code": "not_found",
"message": "Não encontrado.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 404 | not_found | Não encontrado. |
| 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 de e-mail
/v1/email/templates
https://api.mozout.co.mz/v1/email/templatesPrecisa de email_center:read. Por nome.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center: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/email/templates" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/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/email/templates", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/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 de e-mail.
{
"data": [
{
"id": 7,
"name": "Order ready",
"subject": "Your order {{order}} is ready",
"html": "<p>Hello {{name}}, your order {{order}} is ready.</p>",
"text": "Hello {{name}}, your order {{order}} is ready.",
"variables": [
"order",
"name"
],
"created_at": "2026-11-12T09:00:00+02:00",
"updated_at": "2026-11-12T09:00: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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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 de e-mail
/v1/email/templates
https://api.mozout.co.mz/v1/email/templatesPrecisa de email_center:write. Assunto e html ou text, com marcas {{nome}} preenchidas pelas variables do envio.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center: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 |
|---|---|---|---|
name | string | sim | Até 100 caracteres, único na conta. |
subject | string | sim | |
html | string | não | |
text | string | não |
Exemplos
curl
curl -X POST "https://api.mozout.co.mz/v1/email/templates" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"name": "Order ready", "subject": "Your order {{order}} is ready", "html": "<p>Hello {{name}}, your order {{order}} is ready.</p>", "text": "Hello {{name}}, your order {{order}} is ready."}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/templates');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{"name": "Order ready", "subject": "Your order {{order}} is ready", "html": "<p>Hello {{name}}, your order {{order}} is ready.</p>", "text": "Hello {{name}}, your order {{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 = {"name": "Order ready", "subject": "Your order {{order}} is ready", "html": "<p>Hello {{name}}, your order {{order}} is ready.</p>", "text": "Hello {{name}}, your order {{order}} is ready."}
r = requests.post("https://api.mozout.co.mz/v1/email/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/email/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": "Order ready", "subject": "Your order {{order}} is ready", "html": "<p>Hello {{name}}, your order {{order}} is ready.</p>", "text": "Hello {{name}}, your order {{order}} is ready."}),
});
console.log(response.status);
console.log(await response.text());Respostas
201
Criar um modelo de e-mail.
{
"data": {
"id": 7,
"name": "Order ready",
"subject": "Your order {{order}} is ready",
"html": "<p>Hello {{name}}, your order {{order}} is ready.</p>",
"text": "Hello {{name}}, your order {{order}} is ready.",
"variables": [
"order",
"name"
],
"created_at": "2026-11-12T09:00:00+02:00",
"updated_at": "2026-11-12T09:00: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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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 de e-mail
/v1/email/templates/{id}
https://api.mozout.co.mz/v1/email/templates/{id}Precisa de email_center:read. Com as variáveis que usa.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id do modelo (o mesmo template_id do envio). |
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/email/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/email/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/email/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/email/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 de e-mail.
{
"data": {
"id": 7,
"name": "Order ready",
"subject": "Your order {{order}} is ready",
"html": "<p>Hello {{name}}, your order {{order}} is ready.</p>",
"text": "Hello {{name}}, your order {{order}} is ready.",
"variables": [
"order",
"name"
],
"created_at": "2026-11-12T09:00:00+02:00",
"updated_at": "2026-11-12T09:00: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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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 de e-mail
/v1/email/templates/{id}
https://api.mozout.co.mz/v1/email/templates/{id}Precisa de email_center:write. Só mudam os campos enviados.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id do modelo (o mesmo template_id do envio). |
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 | Até 100 caracteres, único na conta. |
subject | string | não | |
html | string | não | |
text | string | não |
Exemplos
curl
curl -X PATCH "https://api.mozout.co.mz/v1/email/templates/00000000-0000-4000-8000-000000000000" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Content-Type: application/json" \
-d '{"subject": "Order {{order}}: ready for pickup"}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/templates/00000000-0000-4000-8000-000000000000');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_POSTFIELDS => '{"subject": "Order {{order}}: ready for pickup"}',
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 = {"subject": "Order {{order}}: ready for pickup"}
r = requests.patch("https://api.mozout.co.mz/v1/email/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/email/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({"subject": "Order {{order}}: ready for pickup"}),
});
console.log(response.status);
console.log(await response.text());Respostas
200
Alterar um modelo de e-mail.
{
"data": {
"id": 7,
"name": "Order ready",
"subject": "Your order {{order}} is ready",
"html": "<p>Hello {{name}}, your order {{order}} is ready.</p>",
"text": "Hello {{name}}, your order {{order}} is ready.",
"variables": [
"order",
"name"
],
"created_at": "2026-11-12T09:00:00+02:00",
"updated_at": "2026-11-12T09:00: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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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 de e-mail
/v1/email/templates/{id}
https://api.mozout.co.mz/v1/email/templates/{id}Precisa de email_center:write. Os e-mails já enviados não mudam.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id do modelo (o mesmo template_id do envio). |
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/email/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/email/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/email/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/email/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 de e-mail.
{
"data": {
"id": 7,
"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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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 endereços bloqueados
/v1/email/suppressions
https://api.mozout.co.mz/v1/email/suppressionsPrecisa de email_center:read. Endereços que nunca recebem e-mails desta conta: as devoluções permanentes e as queixas entram sozinhas; pode juntar outros.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
reason | consulta | string | não | bounce, complaint ou manual. |
email | consulta | string | não | Um endereç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/email/suppressions" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/suppressions');
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/email/suppressions", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/suppressions", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Listar os endereços bloqueados.
{
"data": [
{
"email": "[email protected]",
"reason": "manual",
"note": "Asked to stop",
"created_at": "2026-11-12T10:00: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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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.
POSTBloquear um endereço
/v1/email/suppressions
https://api.mozout.co.mz/v1/email/suppressionsPrecisa de email_center:write. Os envios para ele saem antes de enviar e nunca se cobram.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center: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 |
|---|---|---|---|
email | string | sim | |
note | string | não |
Exemplos
curl
curl -X POST "https://api.mozout.co.mz/v1/email/suppressions" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]", "note": "Asked to stop"}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/suppressions');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{"email": "[email protected]", "note": "Asked to stop"}',
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 = {"email": "[email protected]", "note": "Asked to stop"}
r = requests.post("https://api.mozout.co.mz/v1/email/suppressions", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/suppressions", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"Idempotency-Key": "9f1c2d3e-example",
"Content-Type": "application/json",
},
body: JSON.stringify({"email": "[email protected]", "note": "Asked to stop"}),
});
console.log(response.status);
console.log(await response.text());Respostas
201
Bloquear um endereço.
{
"data": {
"email": "[email protected]",
"reason": "manual",
"note": "Asked to stop",
"created_at": "2026-11-12T10:00:00+02:00",
"already_listed": false,
"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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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.
DELETEDesbloquear um endereço
/v1/email/suppressions/{email}
https://api.mozout.co.mz/v1/email/suppressions/{email}Precisa de email_center:write. O endereço vai no caminho, codificado (ana%40example.org).
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
email | caminho | string | sim | O endereço, codificado. |
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/email/suppressions/VALUE" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/suppressions/VALUE');
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/email/suppressions/VALUE", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/suppressions/VALUE", {
method: "DELETE",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Desbloquear um endereço.
{
"data": {
"email": "[email protected]",
"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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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 webhook de e-mail
/v1/email/webhook
https://api.mozout.co.mz/v1/email/webhookPrecisa de email_center:read. O endereço, os eventos e a última entrega; nunca o segredo. Fazemos POST de {"event": "email.delivered", "created_at", "data": {"id", "event_id", "recipient", "detail", "from", "subject", "simulated"}} para o seu endereço HTTPS na porta 443, uma chamada por evento e destinatário, só para eventos depois de o webhook ser gravado. Confira X-Webhook-Signature: t=<hora unix>,v1=<hex>: v1 é o HMAC-SHA256 de t + "." + corpo cru com o seu segredo. Responda 2xx em 5 segundos; senão tentamos de novo após 1 min, 5 min, 30 min, 2 h e 6 h. Este webhook é separado do do SMS.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center: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/email/webhook" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/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/email/webhook", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/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 e-mail.
{
"data": {
"url": "https://example.com/webhooks/email",
"events": [
"email.delivered",
"email.bounced",
"email.complained"
],
"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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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 e-mail
/v1/email/webhook
https://api.mozout.co.mz/v1/email/webhookPrecisa de email_center:write. O secret só aparece quando o webhook nasce ou com rotate_secret: true. Fazemos POST de {"event": "email.delivered", "created_at", "data": {"id", "event_id", "recipient", "detail", "from", "subject", "simulated"}} para o seu endereço HTTPS na porta 443, uma chamada por evento e destinatário, só para eventos depois de o webhook ser gravado. Confira X-Webhook-Signature: t=<hora unix>,v1=<hex>: v1 é o HMAC-SHA256 de t + "." + corpo cru com o seu segredo. Responda 2xx em 5 segundos; senão tentamos de novo após 1 min, 5 min, 30 min, 2 h e 6 h. Este webhook é separado do do SMS.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center: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 | |
events | array<string: email.sent, email.delivered, email.bounced, email.complained, email.failed> | não | |
rotate_secret | boolean | não |
Exemplos
curl
curl -X PUT "https://api.mozout.co.mz/v1/email/webhook" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/webhooks/email", "events": ["email.delivered", "email.bounced", "email.complained"]}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/webhook');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_POSTFIELDS => '{"url": "https://example.com/webhooks/email", "events": ["email.delivered", "email.bounced", "email.complained"]}',
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/email", "events": ["email.delivered", "email.bounced", "email.complained"]}
r = requests.put("https://api.mozout.co.mz/v1/email/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/email/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/email", "events": ["email.delivered", "email.bounced", "email.complained"]}),
});
console.log(response.status);
console.log(await response.text());Respostas
200
Gravar o webhook de e-mail.
{
"data": {
"url": "https://example.com/webhooks/email",
"events": [
"email.delivered",
"email.bounced",
"email.complained"
],
"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": {}
}| 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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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 e-mail
/v1/email/webhook
https://api.mozout.co.mz/v1/email/webhookPrecisa de email_center: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: email_center: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/email/webhook" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/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/email/webhook", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/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 e-mail.
{
"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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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 e-mail
/v1/email/webhook/test
https://api.mozout.co.mz/v1/email/webhook/testPrecisa de email_center: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: email_center: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/email/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/email/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/email/webhook/test", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/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 e-mail.
{
"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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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 as campanhas
/v1/email/campaigns
https://api.mozout.co.mz/v1/email/campaignsPrecisa de email_center:read. As mais recentes primeiro, sem os blocos.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
status | consulta | string | não | draft, scheduled, sending, sent, cancelled ou automation. |
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/email/campaigns" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/campaigns');
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/email/campaigns", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/campaigns", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Listar as campanhas.
{
"data": [
{
"id": 41,
"name": "November news",
"type": "campaign",
"status": "draft",
"subject": "New arrivals for you",
"preheader": "Special prices until the end of the month",
"from": "[email protected]",
"from_name": "Example Ltd",
"reply_to": null,
"recipients": 0,
"credits": 0.0,
"simulated": false,
"scheduled_for": null,
"sent_at": null,
"created_at": "2026-11-12T10:00:00+02:00",
"updated_at": "2026-11-12T10:05:00+02:00",
"blocks": null,
"target": 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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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 uma campanha
/v1/email/campaigns
https://api.mozout.co.mz/v1/email/campaignsPrecisa de email_center:write. Cria um rascunho. Envie blocks, ou template para um modelo pronto. Variáveis: {{first_name}}, {{name}}, {{company}}, {{email}}. Com uma chave sandbox nada se guarda.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center: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 |
|---|---|---|---|
name | string | não | |
subject | string | não | |
preheader | string | não | Texto que aparece a seguir ao assunto na caixa de entrada. |
from | string | não | Um endereço de um domínio verificado. |
from_name | string | não | |
reply_to | string | não | |
blocks | array<object> | não | |
template | string | não | Em vez de blocks: um modelo pronto por sector (restauracao, comercio, servicos, educacao, saude, eventos, imobiliario, tecnologia). |
target | object | não | |
target.groups | array<integer> | não | Ids dos grupos; vazio quer dizer todos os contactos. |
target.opened | string, null | não | yes ou no: já abriu alguma campanha. |
target.clicked | string, null | não | yes ou no. |
target.joined_from | string, null | não | AAAA-MM-DD. |
target.joined_to | string, null | não | AAAA-MM-DD. |
Exemplos
curl
curl -X POST "https://api.mozout.co.mz/v1/email/campaigns" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"name": "November news", "template": "comercio", "from": "[email protected]", "from_name": "Example Ltd", "target": {"groups": [3]}}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/campaigns');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{"name": "November news", "template": "comercio", "from": "[email protected]", "from_name": "Example Ltd", "target": {"groups": [3]}}',
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": "November news", "template": "comercio", "from": "[email protected]", "from_name": "Example Ltd", "target": {"groups": [3]}}
r = requests.post("https://api.mozout.co.mz/v1/email/campaigns", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/campaigns", {
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": "November news", "template": "comercio", "from": "[email protected]", "from_name": "Example Ltd", "target": {"groups": [3]}}),
});
console.log(response.status);
console.log(await response.text());Respostas
201
Criar uma campanha.
{
"data": {
"id": 41,
"name": "November news",
"type": "campaign",
"status": "draft",
"subject": "New arrivals for you",
"preheader": "Special prices until the end of the month",
"from": "[email protected]",
"from_name": "Example Ltd",
"reply_to": null,
"recipients": 0,
"credits": 0.0,
"simulated": false,
"scheduled_for": null,
"sent_at": null,
"created_at": "2026-11-12T10:00:00+02:00",
"updated_at": "2026-11-12T10:05:00+02:00",
"blocks": [
{
"type": "header",
"title": "New arrivals for you",
"logo": "",
"color": "#af2835"
},
{
"type": "text",
"text": "Hi {{first_name}},\n\nNew products have arrived, with **special prices** until the end of the month."
},
{
"type": "button",
"text": "See what is new",
"url": "https://example.com",
"color": "#af2835"
},
{
"type": "divider"
},
{
"type": "footer",
"text": "You are receiving this email because you subscribed to our news."
}
],
"target": {
"groups": [
3
],
"opened": null,
"clicked": null,
"joined_from": null,
"joined_to": null
}
},
"meta": {}
}| Campo | Tipo | Descrição |
|---|---|---|
data.target.groups | array<integer> | Ids dos grupos; vazio quer dizer todos os contactos. |
data.target.opened | string, null | yes ou no: já abriu alguma campanha. |
data.target.clicked | string, null | yes ou no. |
data.target.joined_from | string, null | AAAA-MM-DD. |
data.target.joined_to | string, null | AAAA-MM-DD. |
| 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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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.
POSTGerar uma campanha com IA
/v1/email/campaigns/generate
https://api.mozout.co.mz/v1/email/campaigns/generatePrecisa de email_center:write. Descreva o que quer enviar; a resposta traz o assunto, a pré-visualização e os blocos, que depois pode mandar para POST /v1/email/campaigns. Nada se guarda. 503 ai_unavailable se a IA estiver desligada; conta para o limite diário da IA.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center: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 |
|---|---|---|---|
description | string | sim | 10 a 1500 caracteres. |
sector | string | não |
Exemplos
curl
curl -X POST "https://api.mozout.co.mz/v1/email/campaigns/generate" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"description": "20% off all plans until Friday, for existing customers.", "sector": "tecnologia"}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/campaigns/generate');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{"description": "20% off all plans until Friday, for existing customers.", "sector": "tecnologia"}',
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 = {"description": "20% off all plans until Friday, for existing customers.", "sector": "tecnologia"}
r = requests.post("https://api.mozout.co.mz/v1/email/campaigns/generate", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/campaigns/generate", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"Idempotency-Key": "9f1c2d3e-example",
"Content-Type": "application/json",
},
body: JSON.stringify({"description": "20% off all plans until Friday, for existing customers.", "sector": "tecnologia"}),
});
console.log(response.status);
console.log(await response.text());Respostas
200
Gerar uma campanha com IA.
{
"data": {
"subject": "Our November offers",
"preheader": "20% off until Friday",
"blocks": [
{
"type": "header",
"title": "New arrivals for you",
"logo": "",
"color": "#af2835"
},
{
"type": "text",
"text": "Hi {{first_name}},\n\nNew products have arrived, with **special prices** until the end of the month."
},
{
"type": "button",
"text": "See what is new",
"url": "https://example.com",
"color": "#af2835"
},
{
"type": "divider"
},
{
"type": "footer",
"text": "You are receiving this email because you subscribed to our news."
}
]
},
"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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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": {}
}
}502
O serviço por trás da API não respondeu como esperado.
{
"error": {
"code": "upstream_error",
"message": "The service did not respond as expected. Please try again later.",
"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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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. |
| 502 | upstream_error | O serviço por trás da API não respondeu como esperado. |
| 503 | disabled | A API está desligada. |
O formato dos erros está explicado em Erros.
GETVer uma campanha
/v1/email/campaigns/{id}
https://api.mozout.co.mz/v1/email/campaigns/{id}Precisa de email_center:read. Com os blocos e o público.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id da campanha. |
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/email/campaigns/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/email/campaigns/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/email/campaigns/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/email/campaigns/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 uma campanha.
{
"data": {
"id": 41,
"name": "November news",
"type": "campaign",
"status": "draft",
"subject": "New arrivals for you",
"preheader": "Special prices until the end of the month",
"from": "[email protected]",
"from_name": "Example Ltd",
"reply_to": null,
"recipients": 0,
"credits": 0.0,
"simulated": false,
"scheduled_for": null,
"sent_at": null,
"created_at": "2026-11-12T10:00:00+02:00",
"updated_at": "2026-11-12T10:05:00+02:00",
"blocks": [
{
"type": "header",
"title": "New arrivals for you",
"logo": "",
"color": "#af2835"
},
{
"type": "text",
"text": "Hi {{first_name}},\n\nNew products have arrived, with **special prices** until the end of the month."
},
{
"type": "button",
"text": "See what is new",
"url": "https://example.com",
"color": "#af2835"
},
{
"type": "divider"
},
{
"type": "footer",
"text": "You are receiving this email because you subscribed to our news."
}
],
"target": {
"groups": [
3
],
"opened": null,
"clicked": null,
"joined_from": null,
"joined_to": null
}
},
"meta": {}
}| Campo | Tipo | Descrição |
|---|---|---|
data.target.groups | array<integer> | Ids dos grupos; vazio quer dizer todos os contactos. |
data.target.opened | string, null | yes ou no: já abriu alguma campanha. |
data.target.clicked | string, null | yes ou no. |
data.target.joined_from | string, null | AAAA-MM-DD. |
data.target.joined_to | string, null | AAAA-MM-DD. |
| 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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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 uma campanha
/v1/email/campaigns/{id}
https://api.mozout.co.mz/v1/email/campaigns/{id}Precisa de email_center:write. Só rascunhos e e-mails de automação; só mudam os campos enviados.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id da campanha. |
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 | |
subject | string | não | |
preheader | string | não | Texto que aparece a seguir ao assunto na caixa de entrada. |
from | string | não | Um endereço de um domínio verificado. |
from_name | string | não | |
reply_to | string | não | |
blocks | array<object> | não | |
template | string | não | Em vez de blocks: um modelo pronto por sector (restauracao, comercio, servicos, educacao, saude, eventos, imobiliario, tecnologia). |
target | object | não | |
target.groups | array<integer> | não | Ids dos grupos; vazio quer dizer todos os contactos. |
target.opened | string, null | não | yes ou no: já abriu alguma campanha. |
target.clicked | string, null | não | yes ou no. |
target.joined_from | string, null | não | AAAA-MM-DD. |
target.joined_to | string, null | não | AAAA-MM-DD. |
Exemplos
curl
curl -X PATCH "https://api.mozout.co.mz/v1/email/campaigns/00000000-0000-4000-8000-000000000000" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Content-Type: application/json" \
-d '{"subject": "Last days of our offers"}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/campaigns/00000000-0000-4000-8000-000000000000');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_POSTFIELDS => '{"subject": "Last days of our offers"}',
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 = {"subject": "Last days of our offers"}
r = requests.patch("https://api.mozout.co.mz/v1/email/campaigns/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/email/campaigns/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({"subject": "Last days of our offers"}),
});
console.log(response.status);
console.log(await response.text());Respostas
200
Alterar uma campanha.
{
"data": {
"id": 41,
"name": "November news",
"type": "campaign",
"status": "draft",
"subject": "New arrivals for you",
"preheader": "Special prices until the end of the month",
"from": "[email protected]",
"from_name": "Example Ltd",
"reply_to": null,
"recipients": 0,
"credits": 0.0,
"simulated": false,
"scheduled_for": null,
"sent_at": null,
"created_at": "2026-11-12T10:00:00+02:00",
"updated_at": "2026-11-12T10:05:00+02:00",
"blocks": [
{
"type": "header",
"title": "New arrivals for you",
"logo": "",
"color": "#af2835"
},
{
"type": "text",
"text": "Hi {{first_name}},\n\nNew products have arrived, with **special prices** until the end of the month."
},
{
"type": "button",
"text": "See what is new",
"url": "https://example.com",
"color": "#af2835"
},
{
"type": "divider"
},
{
"type": "footer",
"text": "You are receiving this email because you subscribed to our news."
}
],
"target": {
"groups": [
3
],
"opened": null,
"clicked": null,
"joined_from": null,
"joined_to": null
}
},
"meta": {}
}| Campo | Tipo | Descrição |
|---|---|---|
data.target.groups | array<integer> | Ids dos grupos; vazio quer dizer todos os contactos. |
data.target.opened | string, null | yes ou no: já abriu alguma campanha. |
data.target.clicked | string, null | yes ou no. |
data.target.joined_from | string, null | AAAA-MM-DD. |
data.target.joined_to | string, null | AAAA-MM-DD. |
| 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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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 uma campanha
/v1/email/campaigns/{id}
https://api.mozout.co.mz/v1/email/campaigns/{id}Precisa de email_center:write. Só rascunhos e e-mails de automação.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id da campanha. |
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/email/campaigns/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/email/campaigns/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/email/campaigns/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/email/campaigns/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 uma campanha.
{
"data": {
"id": 41,
"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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | forbidden, insufficient_scope | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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.
GETVerificar a campanha contra spam
/v1/email/campaigns/{id}/spam-check
https://api.mozout.co.mz/v1/email/campaigns/{id}/spam-checkPrecisa de email_center:read. Regras simples (assunto em maiúsculas, palavras de spam, pouco texto, só imagens, ligações encurtadas, remetente não verificado). A partir de blocks_sending_at pontos a campanha não se envia.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id da campanha. |
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/email/campaigns/00000000-0000-4000-8000-000000000000/spam-check" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/campaigns/00000000-0000-4000-8000-000000000000/spam-check');
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/email/campaigns/00000000-0000-4000-8000-000000000000/spam-check", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/campaigns/00000000-0000-4000-8000-000000000000/spam-check", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Verificar a campanha contra spam.
{
"data": {
"score": 1,
"max": 10,
"blocks_sending_at": 8,
"warnings": [
{
"code": "preheader_missing"
}
]
},
"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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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 a campanha já
/v1/email/campaigns/{id}/send
https://api.mozout.co.mz/v1/email/campaigns/{id}/sendPrecisa de email_center:write. Só recebem os contactos subscritos com e-mail e fora da lista de bloqueados; cada um é um crédito (sai já e volta para os que não saírem). Cada e-mail leva a ligação de cancelar a subscrição e o cabeçalho List-Unsubscribe, mais um pixel e ligações com redireccionamento assinado para as estatísticas. Uma campanha que chegue ao limite do verificador de spam é recusada (422 spam_score_too_high). Com uma chave sandbox, ou com o Email Center em modo de teste, nada se envia nem se cobra e os números são simulados (simulated: true).
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id da campanha. |
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/email/campaigns/00000000-0000-4000-8000-000000000000/send" \
-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/email/campaigns/00000000-0000-4000-8000-000000000000/send');
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/email/campaigns/00000000-0000-4000-8000-000000000000/send", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/campaigns/00000000-0000-4000-8000-000000000000/send", {
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
Enviar a campanha já.
{
"data": {
"id": 41,
"name": "November news",
"type": "campaign",
"status": "sending",
"subject": "New arrivals for you",
"preheader": "Special prices until the end of the month",
"from": "[email protected]",
"from_name": "Example Ltd",
"reply_to": null,
"recipients": 1200,
"credits": 1200.0,
"simulated": false,
"scheduled_for": null,
"sent_at": null,
"created_at": "2026-11-12T10:00:00+02:00",
"updated_at": "2026-11-12T10:05:00+02:00",
"blocks": null,
"target": null,
"stats": {
"recipients": 1200,
"sent": 0,
"delivered": 0,
"bounced": 12,
"opened": 0,
"clicked": 0,
"unsubscribed": 4,
"open_rate": 43.77,
"click_rate": 11.03,
"unsubscribe_rate": 0.34,
"bounce_rate": 1.0,
"by_status": {
"enviado": 1200
},
"top_links": [
{
"url": "https://example.com",
"clicks": 131
}
],
"simulated": false
}
},
"meta": {}
}| Campo | Tipo | Descrição |
|---|---|---|
data.target.groups | array<integer> | Ids dos grupos; vazio quer dizer todos os contactos. |
data.target.opened | string, null | yes ou no: já abriu alguma campanha. |
data.target.clicked | string, null | yes ou no. |
data.target.joined_from | string, null | AAAA-MM-DD. |
data.target.joined_to | string, null | AAAA-MM-DD. |
| 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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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.
POSTAgendar a campanha
/v1/email/campaigns/{id}/schedule
https://api.mozout.co.mz/v1/email/campaigns/{id}/schedulePrecisa de email_center:write. send_at em ISO 8601 com o fuso, até 30 dias. Só recebem os contactos subscritos com e-mail e fora da lista de bloqueados; cada um é um crédito (sai já e volta para os que não saírem). Cada e-mail leva a ligação de cancelar a subscrição e o cabeçalho List-Unsubscribe, mais um pixel e ligações com redireccionamento assinado para as estatísticas. Uma campanha que chegue ao limite do verificador de spam é recusada (422 spam_score_too_high). Com uma chave sandbox, ou com o Email Center em modo de teste, nada se envia nem se cobra e os números são simulados (simulated: true).
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id da campanha. |
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 |
|---|---|---|---|
send_at | string | sim |
Exemplos
curl
curl -X POST "https://api.mozout.co.mz/v1/email/campaigns/00000000-0000-4000-8000-000000000000/schedule" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"send_at": "2026-11-20T09:00:00+02:00"}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/campaigns/00000000-0000-4000-8000-000000000000/schedule');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{"send_at": "2026-11-20T09:00: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 = {"send_at": "2026-11-20T09:00:00+02:00"}
r = requests.post("https://api.mozout.co.mz/v1/email/campaigns/00000000-0000-4000-8000-000000000000/schedule", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/campaigns/00000000-0000-4000-8000-000000000000/schedule", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"Idempotency-Key": "9f1c2d3e-example",
"Content-Type": "application/json",
},
body: JSON.stringify({"send_at": "2026-11-20T09:00:00+02:00"}),
});
console.log(response.status);
console.log(await response.text());Respostas
200
Agendar a campanha.
{
"data": {
"id": 41,
"name": "November news",
"type": "campaign",
"status": "scheduled",
"subject": "New arrivals for you",
"preheader": "Special prices until the end of the month",
"from": "[email protected]",
"from_name": "Example Ltd",
"reply_to": null,
"recipients": 1200,
"credits": 1200.0,
"simulated": false,
"scheduled_for": "2026-11-20T09:00:00+02:00",
"sent_at": null,
"created_at": "2026-11-12T10:00:00+02:00",
"updated_at": "2026-11-12T10:05:00+02:00",
"blocks": null,
"target": null,
"stats": {
"recipients": 1200,
"sent": 0,
"delivered": 0,
"bounced": 12,
"opened": 0,
"clicked": 0,
"unsubscribed": 4,
"open_rate": 43.77,
"click_rate": 11.03,
"unsubscribe_rate": 0.34,
"bounce_rate": 1.0,
"by_status": {
"enviado": 1200
},
"top_links": [
{
"url": "https://example.com",
"clicks": 131
}
],
"simulated": false
}
},
"meta": {}
}| Campo | Tipo | Descrição |
|---|---|---|
data.target.groups | array<integer> | Ids dos grupos; vazio quer dizer todos os contactos. |
data.target.opened | string, null | yes ou no: já abriu alguma campanha. |
data.target.clicked | string, null | yes ou no. |
data.target.joined_from | string, null | AAAA-MM-DD. |
data.target.joined_to | string, null | AAAA-MM-DD. |
| 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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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.
POSTCancelar a campanha
/v1/email/campaigns/{id}/cancel
https://api.mozout.co.mz/v1/email/campaigns/{id}/cancelPrecisa de email_center:write. Agendada ou ainda a enviar: o que não saiu já não sai, e os créditos voltam (credits_returned).
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id da campanha. |
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/email/campaigns/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/email/campaigns/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/email/campaigns/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/email/campaigns/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 a campanha.
{
"data": {
"id": 41,
"name": "November news",
"type": "campaign",
"status": "cancelled",
"subject": "New arrivals for you",
"preheader": "Special prices until the end of the month",
"from": "[email protected]",
"from_name": "Example Ltd",
"reply_to": null,
"recipients": 0,
"credits": 0.0,
"simulated": false,
"scheduled_for": null,
"sent_at": null,
"created_at": "2026-11-12T10:00:00+02:00",
"updated_at": "2026-11-12T10:05:00+02:00",
"blocks": null,
"target": null,
"credits_returned": 1200.0
},
"meta": {}
}| Campo | Tipo | Descrição |
|---|---|---|
data.target.groups | array<integer> | Ids dos grupos; vazio quer dizer todos os contactos. |
data.target.opened | string, null | yes ou no: já abriu alguma campanha. |
data.target.clicked | string, null | yes ou no. |
data.target.joined_from | string, null | AAAA-MM-DD. |
data.target.joined_to | string, null | AAAA-MM-DD. |
| 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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | forbidden, insufficient_scope | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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.
GETVer as estatísticas da campanha
/v1/email/campaigns/{id}/stats
https://api.mozout.co.mz/v1/email/campaigns/{id}/statsPrecisa de email_center:read. Entregues, aberturas (pixel), cliques (ligações assinadas), cancelamentos e devoluções; taxas sobre os entregues. simulated marca os números de exemplo do modo de teste.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id da campanha. |
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/email/campaigns/00000000-0000-4000-8000-000000000000/stats" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/campaigns/00000000-0000-4000-8000-000000000000/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/email/campaigns/00000000-0000-4000-8000-000000000000/stats", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/campaigns/00000000-0000-4000-8000-000000000000/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 da campanha.
{
"data": {
"recipients": 1200,
"sent": 1200,
"delivered": 1188,
"bounced": 12,
"opened": 520,
"clicked": 131,
"unsubscribed": 4,
"open_rate": 43.77,
"click_rate": 11.03,
"unsubscribe_rate": 0.34,
"bounce_rate": 1.0,
"by_status": {
"enviado": 1200
},
"top_links": [
{
"url": "https://example.com",
"clicks": 131
}
],
"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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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 destinatários da campanha
/v1/email/campaigns/{id}/recipients
https://api.mozout.co.mz/v1/email/campaigns/{id}/recipientsPrecisa de email_center:read. O que cada contacto fez: abriu, clicou, cancelou ou devolveu.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id da campanha. |
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/email/campaigns/00000000-0000-4000-8000-000000000000/recipients" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/campaigns/00000000-0000-4000-8000-000000000000/recipients');
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/email/campaigns/00000000-0000-4000-8000-000000000000/recipients", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/campaigns/00000000-0000-4000-8000-000000000000/recipients", {
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
},
});
console.log(response.status);
console.log(await response.text());Respostas
200
Listar os destinatários da campanha.
{
"data": [
{
"email": "[email protected]",
"status": "sent",
"simulated": false,
"sent_at": "2026-11-12T10:30:00+02:00",
"opened_at": "2026-11-12T11:02:00+02:00",
"opens": 2,
"clicked_at": null,
"clicks": 0,
"unsubscribed_at": null,
"bounced_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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}404
Não encontrado.
{
"error": {
"code": "not_found",
"message": "Não encontrado.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 404 | not_found | Não encontrado. |
| 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 teste da campanha
/v1/email/campaigns/{id}/test
https://api.mozout.co.mz/v1/email/campaigns/{id}/testPrecisa de email_center:write. Um e-mail para um endereço, com variáveis de exemplo e «[Teste]» no assunto; custa um crédito, como qualquer e-mail.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | O id da campanha. |
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 |
|---|---|---|---|
to | string | sim |
Exemplos
curl
curl -X POST "https://api.mozout.co.mz/v1/email/campaigns/00000000-0000-4000-8000-000000000000/test" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"to": "[email protected]"}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/campaigns/00000000-0000-4000-8000-000000000000/test');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{"to": "[email protected]"}',
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 = {"to": "[email protected]"}
r = requests.post("https://api.mozout.co.mz/v1/email/campaigns/00000000-0000-4000-8000-000000000000/test", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/campaigns/00000000-0000-4000-8000-000000000000/test", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"Idempotency-Key": "9f1c2d3e-example",
"Content-Type": "application/json",
},
body: JSON.stringify({"to": "[email protected]"}),
});
console.log(response.status);
console.log(await response.text());Respostas
201
Enviar um teste da campanha.
{
"data": {
"id": "5130",
"status": "sent"
},
"meta": {}
}| Campo | Tipo | Descrição |
|---|---|---|
data.recipients | integer | Destinatários depois da lista de bloqueados; cada um é um crédito. |
data.source | string | portal, api ou smtp. |
| 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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}404
Não encontrado.
{
"error": {
"code": "not_found",
"message": "Não encontrado.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 404 | not_found | Não encontrado. |
| 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 contactos de e-mail
/v1/email/contacts
https://api.mozout.co.mz/v1/email/contactsPrecisa de email_center:read. Os contactos do SMS com e-mail e os contactos só de e-mail, sem endereços repetidos, com o estado da subscrição.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
group | consulta | string | não | Id do grupo. |
subscription | consulta | string | não | subscribed, unsubscribed ou suppressed. |
opened | consulta | string | não | yes ou no. |
clicked | consulta | string | não | yes ou no. |
joined_from | consulta | string | não | AAAA-MM-DD. |
joined_to | consulta | string | não | AAAA-MM-DD. |
q | consulta | string | não | Procura. |
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/email/contacts" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/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/email/contacts", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/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 de e-mail.
{
"data": [
{
"email": "[email protected]",
"name": "Ana",
"company": "Example Ltd",
"source": "email_contact",
"subscription": "subscribed",
"created_at": "2026-11-12T09:00: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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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.
POSTJuntar um contacto de e-mail
/v1/email/contacts
https://api.mozout.co.mz/v1/email/contactsPrecisa de email_center:write. Se o endereço já for de um contacto do SMS, usa-se esse contacto e junta-se aos grupos. Confirma que a pessoa aceitou receber os seus e-mails.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center: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 |
|---|---|---|---|
email | string | sim | |
name | string | não | |
company | string | não | |
groups | array<integer> | não | |
subscription | string | não | subscribed (por omissão) ou unsubscribed. |
Exemplos
curl
curl -X POST "https://api.mozout.co.mz/v1/email/contacts" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Idempotency-Key: 9f1c2d3e-example" \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]", "name": "Ana", "groups": [3]}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/contacts');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{"email": "[email protected]", "name": "Ana", "groups": [3]}',
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 = {"email": "[email protected]", "name": "Ana", "groups": [3]}
r = requests.post("https://api.mozout.co.mz/v1/email/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/email/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({"email": "[email protected]", "name": "Ana", "groups": [3]}),
});
console.log(response.status);
console.log(await response.text());Respostas
201
Juntar um contacto de e-mail.
{
"data": {
"email": "[email protected]",
"name": "Ana",
"company": "Example Ltd",
"source": "email_contact",
"subscription": "subscribed",
"created_at": "2026-11-12T09:00:00+02:00",
"created": 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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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 de e-mail
/v1/email/contacts/{email}
https://api.mozout.co.mz/v1/email/contacts/{email}Precisa de email_center:read. Com as últimas campanhas que recebeu e o que fez.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center:read.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
email | caminho | string | sim | O endereço, codificado. |
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/email/contacts/VALUE" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/contacts/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/email/contacts/VALUE", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/contacts/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 contacto de e-mail.
{
"data": {
"email": "[email protected]",
"name": "Ana",
"company": "Example Ltd",
"source": "email_contact",
"subscription": "subscribed",
"created_at": "2026-11-12T09:00:00+02:00",
"campaigns": [
{
"campaign_id": 41,
"sent_at": "2026-11-12T10:30:00+02:00",
"opened": true,
"clicked": false,
"unsubscribed": false,
"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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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.
PUTMudar a subscrição
/v1/email/contacts/{email}/subscription
https://api.mozout.co.mz/v1/email/contacts/{email}/subscriptionPrecisa de email_center:write. subscribed ou unsubscribed. Quem cancelou pela ligação só deve voltar a ser subscrito com o seu consentimento.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center:write.
Parâmetros
| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
email | caminho | string | sim | O endereço, codificado. |
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 |
|---|---|---|---|
status | string | sim |
Exemplos
curl
curl -X PUT "https://api.mozout.co.mz/v1/email/contacts/VALUE/subscription" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt" \
-H "Content-Type: application/json" \
-d '{"status": "unsubscribed"}'PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/contacts/VALUE/subscription');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_POSTFIELDS => '{"status": "unsubscribed"}',
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 = {"status": "unsubscribed"}
r = requests.put("https://api.mozout.co.mz/v1/email/contacts/VALUE/subscription", headers=headers, json=payload, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/contacts/VALUE/subscription", {
method: "PUT",
headers: {
Authorization: `Bearer ${process.env.RLX_API_KEY}`,
"Accept-Language": "pt",
"Content-Type": "application/json",
},
body: JSON.stringify({"status": "unsubscribed"}),
});
console.log(response.status);
console.log(await response.text());Respostas
200
Mudar a subscrição.
{
"data": {
"email": "[email protected]",
"subscription": "unsubscribed",
"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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}404
Não encontrado.
{
"error": {
"code": "not_found",
"message": "Não encontrado.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 404 | not_found | Não encontrado. |
| 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 grupos de contactos
/v1/email/groups
https://api.mozout.co.mz/v1/email/groupsPrecisa de email_center:read. Os mesmos grupos dos contactos do SMS, com quantos têm e-mail.
Autenticação
Precisa de uma chave válida no cabeçalho Authorization: Bearer. Permissão necessária: email_center: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/email/groups" \
-H "Authorization: Bearer $RLX_API_KEY" \
-H "Accept-Language: pt"PHP
<?php
$ch = curl_init('https://api.mozout.co.mz/v1/email/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/email/groups", headers=headers, timeout=30)
print(r.status_code)
print(r.text)JavaScript
const response = await fetch("https://api.mozout.co.mz/v1/email/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": 3,
"name": "Customers",
"contacts": 1200
}
],
"meta": {
"total": 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 tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope).
{
"error": {
"code": "forbidden",
"message": "This account does not have Email Center active. Turn it on in the portal.",
"correlation_id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"details": {
"reason": "email_account_required"
}
}
}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 | A conta não tem o Email Center activo (forbidden, details.reason = email_account_required), ou a chave não tem a permissão (insufficient_scope). |
| 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.