Saltar para o conteúdo
A integrar com assistente de IA? Copia a especificação oficial da KambaSMS em Markdown.
llms.txt
Navegar na documentação

Developers / Referência

Documentação

Referência completa da API KambaSMS, exemplos por linguagem e respostas esperadas.

Kamba Authenticator — Segundo fator SMS e recuperação: guia de integração →

Sandbox

Simula resultados previsíveis, não envia mensagens reais e não consome créditos SMS nem volume de email.

kamba_test_ · sem cobrança

Produção

Contacta os providers reais. SMS, OTP, Verify e Notify usam créditos; Kamba Email usa volume mensal próprio.

kamba_… · consumo real

// quick start

1.Gera a tua API key em/dashboard/keys
2.Usa o headerX-API-Key: SUA_KEY
3.Envia SMS ou usa o serviço OTPPOST /messages/send
Rastreio de suporte: todas as respostas incluem X-Request-Id. Guarda este valor quando ocorrer um erro e envia-o ao suporte; ele permite localizar o pedido sem partilhar a API key, o token ou o conteúdo da mensagem. Para investigar uma falha, guarda X-Request-Id e os campos reservation_id ou message_id devolvidos pela operação. Num replay idempotente, X-Original-Request-Id identifica o pedido original quando disponível. Podes enviar um UUID como identificador do pedido. Outros formatos são substituídos por um UUID gerado. Nunca envies credenciais, códigos, telefones ou conteúdo de mensagens ao suporte.

Falhas inesperadas devolvem uma mensagem genérica e INTERNAL_ERROR. JSON inválido usa INVALID_REQUEST (400), pedidos demasiado grandes REQUEST_TOO_LARGE (413), codificação não suportada UNSUPPORTED_ENCODING (415) e rotas inexistentes NOT_FOUND (404). Usa o estado HTTP e o code na integração; o texto do erro pode mudar. A expiração invalida a credencial; não apaga o histórico da operação nem devolve automaticamente o custo de um SMS. Uma resposta 202 de reconciliação exige revisão do resultado: não repitas o envio automaticamente.

Já tens uma chave? Personaliza os exemplos temporariamente

Opcional. A chave ficará visível nos exemplos de código. Fica apenas na memória desta página: sem guardar nem enviar. Limpa-a antes de partilhar o ecrã ou capturas.

Os exemplos usam valores ilustrativos. Para enviar, cria uma conta e uma chave API e aguarda a aprovação do Sender ID.

$ Gerar Chave
⏱️SMS:50/horaOTP:3/hora/númeroBulk:1000 dest.

Autenticação

Inclui o header X-API-Key: SUA_API_KEY em todos os pedidos autenticados. O endpoint /otp/verify também exige autenticação da mesma conta. Mantém a chave no teu servidor.

Permissões

Limita cada chave aos produtos necessários. Uma tentativa fora do scope responde 403 API_KEY_SCOPE_DENIED.

Expiração

Pode ser indefinida ou definida para 30, 90, 180 ou 365 dias. Uma chave expirada responde 401 API_KEY_EXPIRED.

Rotação

A chave anterior continua válida durante 24 horas para permitir atualizar a integração sem interrupção.

Base URLhttps://api.kambasms.ao
HeaderX-API-Key: SUA_API_KEY
Formatoapplication/json
Números suportadosAngola (+244)
Sender IDSEU_SENDER_ID

Ecossistema

Exemplos HTTP, referência Sandbox e integrações. Compatibilidade de pacotes em revisão.

Sandbox e Webhook Inspector

Usa a página Sandbox para gerar chaves kamba_test_, simular OTP/SMS e inspecionar eventos assinados. O Inspector não envia dados para URLs externas: apresenta o corpo, X-Kamba-Event, X-Kamba-Delivery e X-Kamba-Signature para validação local.

signature = HMAC_SHA256(signing_secret, raw_request_body)
header: X-Kamba-Signature: sha256=<hex>

OTP Service

API Service

Serviço gerido de autenticação por SMS. Rate limiting, expiração e validação incluídos.

POST/otp/send

Envia um código OTP de 6 dígitos por SMS. Autenticado via API Key. Debita 1 crédito.

Parâmetros

phonestringobrigatório

Número angolano no formato +244XXXXXXXXX

Rate limit: máximo 3 OTPs por hora por número. Código válido por 5 minutos.

bash
curl -X POST https://api.kambasms.ao/otp/send \
  -H "Content-Type: application/json" \
  -H "X-API-Key: SUA_API_KEY" \
  -H "Idempotency-Key: otp-sessao-123" \
  -d '{
    "phone": "+244912345678"
  }'

Resposta 200

response.json200 OK
{
  "success": true,
  "otp_id": "550e8400-e29b-41d4-a716-446655440000",
  "message": "OTP enviado com sucesso.",
  "expires_in": 300
}
POST/otp/verify

Valida um código OTP com autenticação da conta que o enviou.

Parâmetros

phonestringobrigatório

Mesmo número usado no envio

codestringobrigatório

Código de 6 dígitos recebido por SMS

otp_iduuidopcional

Identificador do OTP devolvido por /otp/send para isolar a validação

Autenticação obrigatória: usa a mesma conta e ambiente de /otp/send, no teu backend. Limite: 20 verificações/15min por conta e 5/min por conta + número; validade de 5min. Até cinco tentativas incorretas por pedido. Inclui otp_id para selecionar o pedido; sem ele, é usado o pedido mais recente do número. Para login com prova consumível, usa Authenticator. SDKs que omitem autenticação devem ser atualizados ou substituídos por pedidos HTTP autenticados.

bash
curl -X POST https://api.kambasms.ao/otp/verify \
  -H "X-API-Key: SUA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+244912345678",
    "code": "123456"
  }'

Sucesso 200

response.json200 OK
{
  "success": true,
  "message": "Código verificado com sucesso."
}

Erro 400

response.json400 Bad Request
{
  "error": "Código inválido ou expirado."
}

Mensagens

POST/messages/send

Envia um SMS para um número angolano.

Evita duplicados: envia o cabeçalho Idempotency-Key com uma chave única por operação. A mesma chave e o mesmo JSON devolvem a resposta guardada durante pelo menos 24 horas. Se o conteúdo mudar, a API responde 409. A proteção também funciona em OTP Send, Verify Start/Resend, Notify, Bulk e Agendamentos.

Parâmetros

tostringobrigatório

Número de destino no formato +244XXXXXXXXX

textstringobrigatório

Conteúdo da mensagem. Máximo 160 caracteres. Sem links ou URLs.

auto_gsm7booleanopcional

Remove automaticamente acentos não-GSM-7 para evitar cobrança Unicode extra

O Sender ID é definido automaticamente a partir da tua chave API.

bash
curl -X POST https://api.kambasms.ao/messages/send \
  -H "Content-Type: application/json" \
  -H "X-API-Key: SUA_API_KEY" \
  -H "Idempotency-Key: msg-pedido-123" \
  -d '{
    "to": "+244912345678",
    "text": "Ola! Mensagem de teste."
  }'

Resposta 201

response.json201 Created
{
  "success": true,
  "message_id": "SMxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "status": "queued",
  "to": "+244912345678",
  "sender_id": "SEU_SENDER_ID",
  "remaining_balance": 99,
  "segments": 1,
  "timestamp": "2025-01-01T12:00:00.000Z"
}
GET/messages

Lista o histórico de mensagens enviadas.

Retorna as últimas 100 mensagens ordenadas por data.

bash
curl https://api.kambasms.ao/messages \
  -H "X-API-Key: SUA_API_KEY"

Verificação

Kamba Verify

Fluxo completo de verificação em duas chamadas. A API gera, envia, limita, expira e confirma o código.

POST/verify/start

Inicia a verificação e envia o código. Debita 1 crédito por segmento SMS em produção.

phonestringobrigatório

Número no formato +244XXXXXXXXX

sender_idstringopcional

Usa o Sender ID associado à chave quando omitido

bash
curl -X POST https://api.kambasms.ao/verify/start \
  -H "X-API-Key: SUA_API_KEY" -H "Content-Type: application/json" \
  -d '{"phone":"+244912345678"}'
POST/verify/check

Confirma o código introduzido pelo utilizador.

verification_iduuidobrigatório

Identificador devolvido por /verify/start

codestringobrigatório

Código de 6 dígitos

bash
curl -X POST https://api.kambasms.ao/verify/check \
  -H "X-API-Key: SUA_API_KEY" -H "Content-Type: application/json" \
  -d '{"verification_id":"UUID","code":"123456"}'

Verify exige a mesma conta e ambiente. O reenvio exige remetente aprovado/ativo, intervalo de 60 segundos e permite duas tentativas. Reservar o reenvio invalida o código live anterior; durante envio ou reconciliação, confirmações/reenvios devolvem 409. Um resultado 202 incerto exige reconciliação antes de outro envio. O histórico oculta o código. Uma sessão já verificada pode voltar a devolver sucesso; usa Authenticator para provas de login consumíveis.Gestão: POST /verify/resend, GET /verify, GET /verify/stats?days=30, GET /verify/events e GET /verify/:id.

Dados

Kamba Lookup

Valida e normaliza números angolanos. A operadora indicada corresponde à atribuição provável do prefixo, sem consulta em tempo real nem identificação do titular.

POST/lookup

Consulta individual sem consumir créditos.

phonestringobrigatório

Número nacional ou internacional

bash
curl -X POST https://api.kambasms.ao/lookup \
  -H "X-API-Key: SUA_API_KEY" -H "Content-Type: application/json" \
  -d '{"phone":"+244923000000"}'
POST/lookup/bulk

Analisa até 500 números e assinala inválidos e duplicados.

phonesarrayobrigatório

Lista com até 500 números

bash
curl -X POST https://api.kambasms.ao/lookup/bulk \
  -H "X-API-Key: SUA_API_KEY" -H "Content-Type: application/json" \
  -d '{"phones":["+244923000000","+244953000000"]}'

Mensagens transacionais

Kamba Email

Envia emails transacionais pela API com domínio próprio, histórico, supressões automáticas e volume mensal separado dos créditos SMS.

POST/email/send

Envia um email em produção. Exige domínio verificado e volume mensal disponível.

domain_iduuidobrigatório

Domínio verificado na conta

from_localstringobrigatório

Parte antes de @, por exemplo notificacoes

from_namestringopcional

Nome apresentado ao destinatário

tostringobrigatório

Um destinatário por pedido

subjectstringobrigatório

Assunto até 200 caracteres

htmlstringopcional

Conteúdo HTML; usa html ou text

textstringopcional

Conteúdo em texto simples; usa html ou text

bash
curl -X POST https://api.kambasms.ao/email/send \
  -H "X-API-Key: SUA_API_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: pedido-123-email" \
  -d '{"domain_id":"UUID_DO_DOMINIO","from_local":"notificacoes","from_name":"Minha Loja","to":"cliente@exemplo.ao","subject":"Pedido confirmado","html":"<h1>Pedido confirmado</h1>"}'
POST/email/sandbox/send

Simula estados previsíveis sem contactar o fornecedor e sem consumir volume.

tostringobrigatório

Usa delivered, bounced, complained, opened, clicked ou failed antes de @kambasms.test

subjectstringobrigatório

Assunto do teste

bash
curl -X POST https://api.kambasms.ao/email/sandbox/send \
  -H "X-API-Key: SUA_API_KEY" -H "Content-Type: application/json" \
  -d '{"to":"delivered@kambasms.test","subject":"Teste Kamba Email"}'
POST/email/templates

Cria um template reutilizável com variáveis no formato {{nome}}.

keystringobrigatório

Chave única, por exemplo pedido_confirmado

namestringobrigatório

Nome visível no dashboard

subjectstringobrigatório

Assunto, com variáveis opcionais

htmlstringopcional

HTML do email

textstringopcional

Alternativa em texto simples

bash
curl -X POST https://api.kambasms.ao/email/templates \
  -H "X-API-Key: SUA_API_KEY" -H "Content-Type: application/json" \
  -d '{"key":"pedido_confirmado","name":"Pedido confirmado","subject":"Pedido {{pedido}} confirmado","text":"Olá {{nome}}, o pedido {{pedido}} foi confirmado."}'
POST/email/bulk

Coloca até 500 destinatários numa fila processada em segundo plano. Cada destinatário enviado consome uma unidade do volume mensal.

domain_iduuidobrigatório

Domínio verificado

template_iduuidobrigatório

Template ativo

recipientsarrayobrigatório

Objetos com email e variables

bash
curl -X POST https://api.kambasms.ao/email/bulk \
  -H "X-API-Key: SUA_API_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: campanha-setembro-01" \
  -d '{"name":"Confirmações","domain_id":"UUID_DO_DOMINIO","template_id":"UUID_DO_TEMPLATE","from_local":"notificacoes","recipients":[{"email":"ana@exemplo.ao","variables":{"nome":"Ana","pedido":"123"}}]}'

Gestão: domínios por GET /email/overview, POST /email/domains e POST /email/domains/:id/verify; templates por PATCH/DELETE /email/templates/:id e POST /email/templates/:id/render; bulk por GET /email/bulk/:id e POST /email/bulk/:id/cancel. Usa Idempotency-Key nos envios para repetir pedidos em segurança. Bounces e complaints entram automaticamente nas supressões.

Mensagens

Kamba Notify

Modelos transacionais com variáveis. Nesta fase, o canal disponível é SMS.

POST/notify/templates

Cria um modelo reutilizável.

keystringobrigatório

Identificador único, por exemplo pedido_confirmado

namestringobrigatório

Nome visível no dashboard

bodystringobrigatório

Mensagem com variáveis como {{nome}}

bash
curl -X POST https://api.kambasms.ao/notify/templates \
  -H "X-API-Key: SUA_API_KEY" -H "Content-Type: application/json" \
  -d '{"key":"pedido_confirmado","name":"Pedido confirmado","body":"Olá {{nome}}, o pedido {{pedido}} foi confirmado."}'
POST/notify/send

Renderiza o modelo e envia por SMS. Debita 1 crédito por segmento SMS em produção.

template_keystringobrigatório

Chave do modelo ativo

tostringobrigatório

Destino +244XXXXXXXXX

variablesobjectobrigatório

Valores para todas as variáveis do modelo

bash
curl -X POST https://api.kambasms.ao/notify/send \
  -H "X-API-Key: SUA_API_KEY" -H "Content-Type: application/json" \
  -d '{"template_key":"pedido_confirmado","to":"+244912345678","variables":{"nome":"Ana","pedido":"1234"}}'

Gestão: GET /notify/templates, DELETE /notify/templates/:id, POST /notify/render e GET /notify/deliveries.

Orquestração

Kamba Automations

Liga eventos de SMS, Verify, Links e Chat a um endpoint Webhook ou modelo Kamba Notify. Regras nascem pausadas e podem ser simuladas sem consumir créditos.

POST/automations

Cria uma regra pausada.

namestringobrigatório

Nome interno

trigger_eventstringobrigatório

Evento que inicia a regra

action_typestringobrigatório

webhook ou notify

action_configobjectobrigatório

endpoint_id ou template_key e to

bash
curl -X POST https://api.kambasms.ao/automations \
  -H "X-API-Key: SUA_API_KEY" -H "Content-Type: application/json" \
  -d '{"name":"Verify concluído","trigger_event":"verify.completed","action_type":"webhook","action_config":{"endpoint_id":"UUID_DO_ENDPOINT"}}'
Ações Notify: cada execução real consome 1 crédito por segmento SMS. A ativação exige confirm_paid_action: true. Cada regra aceita até 50 execuções por hora.

Gestão: GET /automations, PATCH/DELETE /automations/:id, POST /automations/:id/simulate e GET /automation-runs.

Developers / Eventos

Webhooks de produção

Entrega eventos para URLs HTTPS públicas com certificado TLS válido. Endereços privados, locais e reservados são bloqueados, incluindo IPv6; todos os resultados DNS devem ser públicos. Não seguimos redirecionamentos. Responde com HTTP 2xx em até 8 segundos e processa o evento de forma assíncrona. Cada pedido inclui identificador, tipo, data e dados sem conteúdo sensível. Há até seis tentativas automáticas, incluindo a primeira. O consumidor deve deduplicar o id do evento; recuperação após falha pode repetir uma entrega. Retry manual recusa entregas em curso ou já entregues. A ordem de entrega não é garantida: deduplica pelo id do evento e consulta o estado da mensagem quando necessário.

POST/webhook-endpoints

Cria um endpoint. O segredo whsec_ é devolvido apenas nesta resposta.

namestringobrigatório

Nome interno do endpoint

urlstringobrigatório

URL HTTPS pública

eventsstring[]opcional

Tipos desejados; omite para receber todos

bash
curl -X POST https://api.kambasms.ao/webhook-endpoints \
  -H "X-API-Key: SUA_API_KEY" -H "Content-Type: application/json" \
  -d '{"name":"Produção","url":"https://api.exemplo.ao/webhooks/kambasms","events":["verify.completed","message.status"]}'
Assinatura: HMAC SHA-256 de timestamp.raw_body. Lê x-kambasms-timestamp e compara x-kambasms-signature em tempo constante. Rejeita pedidos com mais de cinco minutos.
Eventos: message.status, verify.started, verify.completed, verify.failed, link.clicked, chat.conversation.created, chat.message.created, notify.sent e email.sent/delivered/bounced/complained/opened/clicked/failed.

Gestão: GET /webhook-endpoints, PATCH/DELETE /webhook-endpoints/:id, POST /webhook-endpoints/:id/test, GET /webhook-deliveries e POST /webhook-deliveries/:id/retry.

Atendimento

KambaChat

O dashboard gere o widget e a caixa de entrada. O browser do visitante usa um token temporário próprio e nunca recebe a chave API da conta.

POST/chat/widgets

Cria ou devolve o primeiro widget da conta.

namestringopcional

Nome apresentado no cabeçalho do widget

bash
curl -X POST https://api.kambasms.ao/chat/widgets \
  -H "X-API-Key: SUA_API_KEY" -H "Content-Type: application/json" \
  -d '{"name":"Atendimento"}'

Conta autenticada: GET/PATCH /chat/widgets, GET /chat/conversations, GET/POST /chat/conversations/:id/messages e PATCH /chat/conversations/:id.

Estados: open, in_progress, closed. responsible_name é uma identificação interna e não concede acesso. GET/POST /chat/conversations/:id/notes guarda notas privadas (50 por conversa, 90 dias); as notas nunca são devolvidas ao visitante. GET /chat/conversations/:id/contact-history devolve até 20 conversas do mesmo contacto no mesmo widget.

Instalação pública: GET /chat/widget.js?key=.... Os endpoints /chat/public são utilizados internamente pelo widget.

Créditos

GET/credits/balance

Retorna o saldo atual de SMS disponíveis.

bash
curl https://api.kambasms.ao/credits/balance \
  -H "X-API-Key: SUA_API_KEY"

Resposta 200

response.json200 OK
{ "balance": 99 }

Agendamentos

POST/messages/schedule

Agenda um SMS para envio futuro. Requer primeira recarga SMS aprovada, saldo e Sender ID aprovado.

Parâmetros

tostringobrigatório

Número +244XXXXXXXXX

textstringobrigatório

Mensagem (máx 160 chars, sem URLs)

sender_idstringobrigatório

3–11 caracteres alfanuméricos

scheduled_atstringobrigatório

ISO 8601. Deve ser no futuro.

auto_gsm7booleanopcional

Remove automaticamente acentos não-GSM-7 para evitar cobrança Unicode extra

bash
curl -X POST https://api.kambasms.ao/messages/schedule \
  -H "Content-Type: application/json" \
  -H "X-API-Key: SUA_API_KEY" \
  -H "Idempotency-Key: agendamento-consulta-123" \
  -d '{
    "to": "+244912345678",
    "text": "Lembrete: consulta amanha as 10h.",
    "sender_id": "SEU_SENDER_ID",
    "scheduled_at": "2025-06-01T09:00:00.000Z"
  }'

Resposta 201

response.json201 Created
{
  "success": true,
  "scheduled": {
    "id": "uuid",
    "sms_to": "+244912345678",
    "scheduled_at": "2025-06-01T09:00:00.000Z",
    "status": "pending"
  }
}

Envio em Massa

POST/messages/bulk

Envio para múltiplos destinatários. Máx 1000. Processado em background.

Opt-out obrigatório para campanhas

Inclui forma de cancelamento: Responda PARAR para cancelar.

Parâmetros

namestringobrigatório

Nome da campanha

sender_idstringobrigatório

3–11 caracteres alfanuméricos

textstringobrigatório

Mensagem (máx 160 chars, sem URLs)

recipientsarrayobrigatório

Array de números +244. Máx 1000.

auto_gsm7booleanopcional

Remove automaticamente acentos não-GSM-7 para evitar cobrança Unicode extra

bash
curl -X POST https://api.kambasms.ao/messages/bulk \
  -H "Content-Type: application/json" \
  -H "X-API-Key: SUA_API_KEY" \
  -H "Idempotency-Key: campanha-consultas-01" \
  -d '{
    "name": "Confirmacoes de consultas",
    "sender_id": "SEU_SENDER_ID",
    "text": "A sua consulta foi confirmada. Consulte os detalhes na sua conta.",
    "recipients": ["+244912345678", "+244923456789"]
  }'

Resposta 201

response.json201 Created
{
  "success": true,
  "job_id": "uuid",
  "total": 2
}

Receitas de Integração

Liga a KambaSMS aos teus provedores de identidade, frameworks de backend e lojas virtuais em minutos com snippets prontos a usar.

Keycloak / Authelia (SSO & 2FA)

Dispara códigos OTP de segundo fator ou alertas de segurança para números +244 no login ou recuperação.

OIDC / Webhook

Configura o teu Keycloak SMS SPI ou webhook de notificação do Authelia para fazer POST na KambaSMS com o número de destino e o código de segurança:

bash
curl -X POST https://api.kambasms.ao/messages/send \
  -H "X-API-Key: ${KAMBASMS_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+244923000000",
    "sender_id": "MINHAMARCA",
    "text": "Código de segurança: 849201. Válido por 5 minutos."
  }'

Laravel (Notification Channel / Service)

Envio de SMS transacional ou OTP usando o cliente HTTP nativo e o sistema de filas do Laravel.

PHP / Laravel 10+

Define a tua KAMBASMS_API_KEY no .env e envia mensagens diretamente nas tuas notificações ou serviços:

php
use Illuminate\Support\Facades\Http;

// Envio rápido de SMS ou OTP transacional
$response = Http::withHeaders([
    'X-API-Key' => config('services.kambasms.key'),
    'Content-Type' => 'application/json',
])->post('https://api.kambasms.ao/messages/send', [
    'to' => $user->phone, // Formato: +2449XXXXXXXX
    'sender_id' => 'MINHAMARCA',
    'text' => "Olá {$user->name}, a tua encomenda foi despachada com sucesso.",
    'auto_gsm7' => true,
]);

if ($response->successful()) {
    $messageId = $response->json('message_id');
}

WordPress & WooCommerce

Notifica clientes automaticamente quando o estado da encomenda é alterado ou processado.

WooCommerce 8+

Adiciona este hook ao functions.php do teu tema ou num plugin personalizado para avisar compradores em Angola:

php
add_action('woocommerce_order_status_processing', function($order_id) {
    $order = wc_get_order($order_id);
    $phone = $order->get_billing_phone();

    // Normaliza para +244 se necessário
    if (!str_starts_with($phone, '+244')) {
        $phone = '+244' . ltrim($phone, '0');
    }

    wp_remote_post('https://api.kambasms.ao/messages/send', [
        'headers' => [
            'X-API-Key' => getenv('KAMBASMS_API_KEY'),
            'Content-Type' => 'application/json',
        ],
        'body' => wp_json_encode([
            'to' => $phone,
            'sender_id' => 'MINHALOJA',
            'text' => "Encomenda #{$order_id} confirmada. Estamos a preparar o envio.",
            'auto_gsm7' => true,
        ]),
        'timeout' => 10,
    ]);
});

Node.js / TypeScript (Next.js, Express, NestJS)

Função assíncrona moderna usando fetch nativo com tratamento de erros e otimização GSM-7.

Node 18+ / TS

Snippet universal com suporte a X-API-Key e remoção automática de acentos:

javascript
export async function sendKambaSms(to: string, text: string, senderId = 'MINHAMARCA') {
  const response = await fetch('https://api.kambasms.ao/messages/send', {
    method: 'POST',
    headers: {
      'X-API-Key': process.env.KAMBASMS_API_KEY!,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      to,
      text,
      sender_id: senderId,
      auto_gsm7: true,
    }),
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(error.error || 'Falha ao enviar SMS');
  }

  return response.json();
}

Boas Práticas e Limitações

📏

Limite de 160 caracteres e Segmentos (GSM-7 vs Unicode)

Cada SMS suporta até 160 caracteres em GSM-7 (1 crédito). Acentos fora da tabela GSM-7 (como á, í, ó, ú, ã, õ, ê, ç) mudam a codificação para Unicode (70 caracteres por segmento, 67 se concatenado). Envia auto_gsm7: true no payload para remover acentos automaticamente e manter 160 caracteres por segmento.

🚫

Links e URLs não são permitidos

Mensagens com links (https://, www., domínios) são bloqueadas automaticamente pelas operadoras angolanas como spam.

⏱️

Limites de envio

SMS (/messages/send)50/hora por conta
OTP (/otp/send)3/hora por número
OTP verify (/otp/verify)20 tentativas/15min
Bulk (/messages/bulk)1000 destinatários/campanha
Pedidos globais por IP100/15 minutos

Códigos de erro

400

VALIDATION_ERROR

Pedido inválido

Parâmetros inválidos ou em falta. Revê corpo, formato e conteúdo.

Consumo

Não

Repetir

Depois de corrigir

401

UNAUTHORIZED

Não autenticado

API Key inválida, revogada ou em falta. Confirma a chave e o header.

Consumo

Não

Repetir

Sim

402

INSUFFICIENT_BALANCE

Saldo insuficiente

A conta não tem créditos SMS suficientes. Recarrega SMS e OTP.

Consumo

Não

Repetir

Depois da recarga

402

EMAIL_QUOTA_EXHAUSTED

Volume de email esgotado

O ciclo do Kamba Email não tem volume disponível. Ativa outro pacote de email.

Consumo

Não

Repetir

Depois da recarga

404

NOT_FOUND

Não encontrado

O recurso não existe ou não pertence à conta. Confirma o identificador.

Consumo

Não

Repetir

Não

409

EMAIL_SUPPRESSED

Destinatário suprimido

Bounce permanente ou reclamação bloqueou o endereço. Não forces um novo envio.

Consumo

Não

Repetir

Não

429

RATE_LIMITED

Limite atingido

A proteção de frequência recusou temporariamente o pedido. Respeita Retry-After quando existir.

Consumo

Não

Repetir

Após o intervalo

500

INTERNAL_ERROR

Erro interno

A plataforma não concluiu a operação. Guarda X-Request-Id e contacta o suporte.

Consumo

Confirmar histórico

Repetir

Com idempotência

Aprender com vídeosGuias da plataforma e dos produtos