Referência para developers
API StrongX
Envie SMS, Email e WhatsApp para os seus clientes em Angola com uma única API REST. OTPs, confirmações de pedido, alertas e campanhas em massa.
Cada pedido de envio é aceite de imediato com o estado queued e processado de forma assíncrona. Quando o estado muda (sent, delivered, failed), a StrongX notifica o seu backend com um webhook assinado.
messageId devolvido e acompanhe o resultado pelos webhooks ou pelo painel.Começar
Base URL
Produção e sandbox usam o mesmo host. É a chave API que decide o ambiente: uma chave strx_… envia de verdade; uma chave strx_test_… simula o envio.
https://api.strongx.it.ao/v1Começar
Autenticação
Todas as chamadas exigem HTTPS e uma chave API no cabeçalho Authorization com o esquema Bearer. Associe a chave a uma aplicação aprovada para enviar com o nome e os remetentes dessa aplicação.
Authorization: Bearer strx_YOUR_API_KEYTestes
Sandbox
Com uma chave sandbox (strx_test_…) nada é cobrado e nenhuma mensagem sai para a operadora. Apenas os destinatários de teste abaixo são aceites; cada um simula um resultado. Webhooks, validações e formato das respostas são iguais aos de produção: o envio responde sempre 202 queued e o resultado do cenário chega depois, por webhook ou em GET /v1/messages/{id}.
| Cenário | Destinatário | Notas |
|---|---|---|
| Entregue | +244900000000delivered@sandbox.strongx.ao | Passa por sent e delivered; dispara message.delivered. |
| Falha | +244900000001bounce@sandbox.strongx.ao | Rejeitada pelo provider simulado; dispara message.failed. |
| Só enviado | +244900000002sent@sandbox.strongx.ao | Fica em sent, sem confirmação de entrega. |
Chaves sandbox funcionam mesmo antes de a aplicação ser aprovada, mas só nos endpoints de envio. Outros endpoints respondem 403 sandbox_not_supported. Qualquer outro destinatário responde 422 sandbox_recipient_not_allowed.
# Use a SANDBOX key (strx_test_…). Nothing is charged or sent.
curl -X POST https://api.strongx.it.ao/v1/sms/send \
-H "Authorization: Bearer strx_test_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "to": "+244900000000", "message": "Hello sandbox" }'
# +244900000000 → delivered
# +244900000001 → failed
# +244900000002 → sent (no delivery receipt)Mensagens
Enviar SMS
Envia um SMS para um número. Use message para texto livre ou templateId + variables.
Corpo do pedido
| Campo | Tipo | Descrição |
|---|---|---|
toobrigatório | string | Número do destinatário, ex.: +244923456789. |
messageopcional | string | Texto da mensagem (máx. 1600). |
applicationIdopcional | uuid | Aplicação que envia. Por omissão, a aplicação associada à chave. |
templateIdopcional | uuid | Template a usar em vez do texto livre. |
variablesopcional | object | Valores para as variáveis do template, ex.: { "name": "Ana" }. |
curl -X POST https://api.strongx.it.ao/v1/sms/send \
-H "Authorization: Bearer strx_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+244923456789",
"message": "Hello from StrongX!",
"applicationId": "YOUR_APP_ID"
}'{
"success": true,
"data": {
"messageId": "7d1c2f9e-5b1a-4c6e-9a43-0f8f2b6d1e21",
"status": "queued"
}
}Experimentar no sandbox
Mensagens
SMS em massa
Envia o mesmo SMS para até 500 números, com {{name}} personalizado por destinatário. O custo é debitado de uma só vez.
Corpo do pedido
| Campo | Tipo | Descrição |
|---|---|---|
recipientsobrigatório | array | Lista de { phone, name? } (1–500). |
messageopcional | string | Texto da mensagem; aceita {{name}}. |
applicationIdopcional | uuid | Aplicação que envia. Por omissão, a aplicação associada à chave. |
templateIdopcional | uuid | Template a usar em vez do texto livre. |
curl -X POST https://api.strongx.it.ao/v1/sms/send-bulk \
-H "Authorization: Bearer strx_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"recipients": [
{ "phone": "+244923456789", "name": "João" },
{ "phone": "+244912345678", "name": "Maria" }
],
"message": "Hello from StrongX!",
"applicationId": "YOUR_APP_ID"
}'{
"success": true,
"data": {
"enqueued": 2,
"totalCost": 10.0,
"messages": [
{ "messageId": "…", "phone": "244923456789", "status": "queued" },
{ "messageId": "…", "phone": "244912345678", "status": "queued" }
]
}
}Experimentar no sandbox
Mensagens
Enviar Email
Envia um email. O HTML é sanitizado antes do envio.
Corpo do pedido
| Campo | Tipo | Descrição |
|---|---|---|
toobrigatório | string | Email do destinatário. |
subjectopcional | string | Assunto (máx. 500). Obrigatório sem template. |
htmlBodyopcional | string | Corpo HTML. Obrigatório sem template. |
textBodyopcional | string | Versão em texto simples. |
senderIdopcional | uuid | Remetente verificado da aplicação (domínio próprio). Sem ele, usa o remetente da plataforma. |
applicationIdopcional | uuid | Aplicação que envia. Por omissão, a aplicação associada à chave. |
templateIdopcional | uuid | Template a usar em vez do texto livre. |
variablesopcional | object | Valores para as variáveis do template, ex.: { "name": "Ana" }. |
attachmentsopcional | array | Lista de { url, filename, contentType }. |
curl -X POST https://api.strongx.it.ao/v1/email/send \
-H "Authorization: Bearer strx_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "user@example.com",
"subject": "Hello from StrongX!",
"htmlBody": "<h1>Hello!</h1><p>This is a test email.</p>",
"textBody": "Hello! This is a test email.",
"applicationId": "YOUR_APP_ID"
}'{
"success": true,
"data": {
"messageId": "7d1c2f9e-5b1a-4c6e-9a43-0f8f2b6d1e21",
"status": "queued"
}
}Experimentar no sandbox
Mensagens
Email em massa
Envia o mesmo email para até 500 destinatários.
Corpo do pedido
| Campo | Tipo | Descrição |
|---|---|---|
recipientsobrigatório | string[] | Lista de emails (1–500). |
subjectopcional | string | Assunto (máx. 500). Obrigatório sem template. |
htmlBodyopcional | string | Corpo HTML. Obrigatório sem template. |
textBodyopcional | string | Versão em texto simples. |
senderIdopcional | uuid | Remetente verificado da aplicação (domínio próprio). Sem ele, usa o remetente da plataforma. |
applicationIdopcional | uuid | Aplicação que envia. Por omissão, a aplicação associada à chave. |
templateIdopcional | uuid | Template a usar em vez do texto livre. |
attachmentsopcional | array | Lista de { url, filename, contentType }. |
curl -X POST https://api.strongx.it.ao/v1/email/send-bulk \
-H "Authorization: Bearer strx_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"recipients": ["user1@example.com", "user2@example.com"],
"subject": "Hello from StrongX!",
"htmlBody": "<h1>Hello!</h1><p>This is a bulk email.</p>",
"applicationId": "YOUR_APP_ID"
}'{
"success": true,
"data": {
"sent": 2,
"failed": 0,
"messages": [
{ "messageId": "…", "email": "ana@example.com", "status": "queued" },
{ "messageId": "…", "email": "rui@example.com", "status": "queued" }
]
}
}Experimentar no sandbox
Mensagens
Enviar WhatsApp
Envia uma mensagem WhatsApp. Fora da janela de 24h use um template aprovado (templateId).
Corpo do pedido
| Campo | Tipo | Descrição |
|---|---|---|
toobrigatório | string | Número com indicativo, ex.: +244923456789. |
messageopcional | string | Texto (máx. 4096). Obrigatório sem template. |
applicationIdopcional | uuid | Aplicação que envia. Por omissão, a aplicação associada à chave. |
templateIdopcional | uuid | Template a usar em vez do texto livre. |
variablesopcional | object | Valores para as variáveis do template, ex.: { "name": "Ana" }. |
attachmentsopcional | array | Lista de { url, filename, contentType }. |
curl -X POST https://api.strongx.it.ao/v1/whatsapp/send \
-H "Authorization: Bearer strx_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+244923456789",
"message": "Hello from StrongX via WhatsApp!",
"applicationId": "YOUR_APP_ID"
}'{
"success": true,
"data": {
"messageId": "7d1c2f9e-5b1a-4c6e-9a43-0f8f2b6d1e21",
"status": "queued"
}
}Experimentar no sandbox
Mensagens
Campanhas
Uma campanha junta contactos, um segmento e um template, e envia para todos de uma vez pelo mesmo caminho do envio em massa. Os passos abaixo mostram o fluxo completo.
403 sandbox_not_supported.1. Criar um contacto
curl -X POST https://api.strongx.it.ao/v1/contacts \
-H "Authorization: Bearer strx_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "João Silva",
"phone": "+244923456789",
"email": "joao@example.com"
}'
# Response: {"success": true, "data": {"id": "...", ...}}2. Criar um segmento
curl -X POST https://api.strongx.it.ao/v1/segments \
-H "Authorization: Bearer strx_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Clientes VIP",
"description": "Clientes com maior volume de compras"
}'
# Response: {"success": true, "data": {"id": "...", ...}}3. Adicionar contactos ao segmento
curl -X POST https://api.strongx.it.ao/v1/segments/YOUR_SEGMENT_ID/contacts \
-H "Authorization: Bearer strx_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contact_ids": ["YOUR_CONTACT_ID"]
}'
# Note: this endpoint takes "contact_ids" in snake_case (an exception
# to the camelCase convention used by the rest of the API).4. Criar um template
curl -X POST https://api.strongx.it.ao/v1/templates \
-H "Authorization: Bearer strx_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"channel": "sms",
"name": "Promoção de aniversário",
"body": "Olá {{name}}, tens um desconto especial à tua espera!",
"variables": ["name"]
}'
# Response: {"success": true, "data": {"id": "...", ...}}5. Criar a campanha
curl -X POST https://api.strongx.it.ao/v1/campaigns \
-H "Authorization: Bearer strx_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Campanha de aniversário",
"channel": "sms",
"segmentId": "YOUR_SEGMENT_ID",
"templateId": "YOUR_TEMPLATE_ID"
}'
# Response: {"success": true, "data": {"id": "...", "status": "draft", ...}}6. Disparar a campanha
curl -X POST https://api.strongx.it.ao/v1/campaigns/YOUR_CAMPAIGN_ID/send \
-H "Authorization: Bearer strx_YOUR_API_KEY"
# Queues the send for every contact in the segment through the same bulk
# path as /send-bulk (credits, rate limits and provider resolution behave
# the same way).Webhooks
Eventos de estado
Registe um URL de webhook na aplicação (painel → Aplicações → Webhooks). A cada mudança de estado, a StrongX faz POST ao seu URL com o corpo { "event", "data" }. Responda com 2xx; outros códigos são repetidos mais tarde.
| Evento | Descrição |
|---|---|
message.sent | A operadora/provider aceitou a mensagem. |
message.delivered | Entrega confirmada ao destinatário. |
message.failed | A mensagem falhou; o custo é devolvido se nenhum provider a aceitou. |
{
"event": "message.delivered",
"data": {
"message_id": "7d1c2f9e-5b1a-4c6e-9a43-0f8f2b6d1e21",
"channel": "sms",
"status": "delivered",
"to": "244923456789",
"provider_name": "telco_sms",
"error_message": null,
"sandbox": false
}
}Webhooks
Verificar assinatura
Cada webhook é assinado com o segredo da subscrição. Use X-StrongX-Signature-V2: calcule o HMAC-SHA256 de timestamp + "." + corpo bruto e compare com v1. Rejeite pedidos com t demasiado antigo para evitar replays.
v1 = HexEncode( HMAC-SHA256( secret, t + "." + rawBody ) )X-StrongX-Signature (sha256=<hex>, HMAC do corpo bruto) continua a ser enviado para compatibilidade.
import crypto from 'node:crypto';
// rawBody: the request body exactly as received (Buffer)
function verifyStrongX(rawBody, header, secret, toleranceSec = 300) {
const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')));
const timestamp = Number(parts.t);
if (!timestamp || Math.abs(Date.now() / 1000 - timestamp) > toleranceSec) return false;
const expected = crypto
.createHmac('sha256', secret)
.update(`${parts.t}.`)
.update(rawBody)
.digest('hex');
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1 ?? ''));
}
// verifyStrongX(req.rawBody, req.get('X-StrongX-Signature-V2'), process.env.STRONGX_WEBHOOK_SECRET)Referência
Consultar mensagem
Devolve uma mensagem de qualquer canal com o estado atual. Use para acompanhar o resultado depois do envio, quando não usa webhooks. Funciona com chaves sandbox (só para mensagens sandbox).
{
"success": true,
"data": {
"id": "7d1c2f9e-5b1a-4c6e-9a43-0f8f2b6d1e21",
"channel": "sms",
"to": "244900000001",
"status": "failed",
"errorMessage": "Sandbox: simulated provider rejection",
"cost": 0.0,
"isSandbox": true,
"createdAt": "2026-10-08T10:00:00+00:00",
"updatedAt": "2026-10-08T10:00:01+00:00"
}
}Referência
Estados da mensagem
| Estado | Significado |
|---|---|
| queued | Aceite pela StrongX e à espera de envio. |
| sent | Entregue à operadora/provider. |
| delivered | Entrega confirmada. |
| failed | Não foi possível enviar. Veja errorMessage. |
Referência
Erros
Erros devolvem um código HTTP e um corpo JSON com error (código estável) e message (texto legível).
| Código | Significado |
|---|---|
| 401 | Chave em falta, inválida ou aplicação não aprovada. |
| 402 | Saldo insuficiente na carteira ou na reserva da aplicação. |
| 403 | Sem permissão (por exemplo, chave sandbox fora dos endpoints de envio). |
| 404 | Recurso não encontrado. |
| 422 | Pedido inválido (campos em falta, destinatário sandbox não permitido…). |
| 429 | Limite de pedidos excedido; tente novamente em instantes. |
{
"error": "sandbox_recipient_not_allowed",
"message": "Sandbox keys only accept test recipients: …"
}Referência
Limites
- SMS: até 10 pedidos por segundo por conta.
- Envios em massa: até 500 destinatários por pedido.
- SMS: até 1600 caracteres; WhatsApp: até 4096 caracteres.
