smskit

Documentação

API de SMS para o Brasil.

Uma API HTTP em https://api.smskit.dev, SDKs para TypeScript e Python e um servidor MCP para agentes. Números brasileiros (+55), preços em reais por segmento, respostas em JSON e erros com códigos estáveis.

Três passos até o primeiro envio

  1. Crie uma chave no console

    Em Configurações → Chaves de API, gere uma chave sk_test_ para ensaiar ou sk_live_ para produção. A chave aparece uma única vez; guarde-a como segredo.

    terminal
    export SMSKIT_KEY="sk_test_…"
    
  2. Troque a chave por um token Bearer

    Envie a chave no header X-API-Key para POST /v1/auth/token. O token vale 48 horas e é a única credencial usada nas demais rotas. Os SDKs fazem esta troca sozinhos, guardam o token em memória e renovam quando ele vence.

    cURL
    curl -X POST https://api.smskit.dev/v1/auth/token \
      -H "X-API-Key: $SMSKIT_KEY"
    
  3. Envie o SMS

    POST /v1/sms aceita um ou vários destinatários e responde 202 com o envio na fila. O resultado por destinatário chega por webhook ou em GET /v1/sms/{id}.

    cURL
    curl -X POST https://api.smskit.dev/v1/sms \
      -H "Authorization: Bearer $SMSKIT_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "to": "+5511999990123",
        "text": "Sua mesa está pronta. Até já."
      }'
    

Autenticação em dois passos

A chave de API nunca trafega em cada requisição. Ela é trocada uma vez por um token Bearer em POST /v1/auth/token; só o token vai no header Authorization das demais rotas.

  • Validade. Cada token expira em 48 horas (expires_in em segundos, expires_at em ISO 8601). Ao receber 401 token_expired, gere outro.
  • Revogação. Revogar a chave no console invalida todos os tokens emitidos a partir dela na hora.
  • Ambiente. O token herda o modo da chave: sk_live_ gera tokens live; sk_test_ gera tokens test.
  • Limites. Até 20 chaves por workspace. Use uma chave por integração para revogar sem afetar as outras.
200 · TokenResponse
{
  "access_token": "smt_…",
  "expires_at": "2026-09-13T14:03:00Z",
  "expires_in": 172800,
  "mode": "live",
  "workspace_id": "ws_3h7k9d",
  "token_type": "bearer"
}
Usando o token
curl https://api.smskit.dev/v1/account \
  -H "Authorization: Bearer $SMSKIT_TOKEN"

Modo de teste

Chaves sk_test_ percorrem exatamente os mesmos endpoints, com as mesmas respostas. A diferença está no que acontece depois:

  • Nada é cobrado e nenhuma mensagem sai para a operadora.
  • A entrega é simulada: números terminados em 0000 falham; todos os outros são entregues.
  • Os objetos retornam "test": true, e os webhooks disparam normalmente, também com "test": true no envelope.
  • Modelos, saldo e webhooks são os do seu workspace; só o envio é simulado.
202 · envio em modo de teste
{
  "id": "sms_7f3k2m",
  "object": "sms",
  "status": "queued",
  "test": true,
  "recipients": 1,
  "segments": 1,
  "credits": 1
}

Referência da API

Gerada a partir do OpenAPI 3.1.0 da versão 1.0.0. Base: https://api.smskit.dev. Todas as rotas, exceto POST /v1/auth/token, exigem Authorization: Bearer <token>. Ids nos exemplos como sms_7f3k2m são ilustrativos.

Auth

POST/v1/auth/token

Trocar a chave de API por um token Bearer de 48h

Envie a chave em X-API-Key (ou no corpo como api_key). O token retornado vale 48 horas e é o único credencial usado nas demais rotas; a chave nunca trafega em cada requisição. Chaves sk_test_ geram tokens de modo de teste: mesmas rotas, respostas idênticas, nada é cobrado nem enviado.

Parâmetros
NomeOndeTipo
x-api-keyheaderstring
Corpo · TokenRequest (opcional)
CampoTipoDescrição
api_keystring | null
Respostas
StatusDescrição
200Objeto TokenResponseaccess_token, expires_at, expires_in, mode, token_type, workspace_id
401Credencial ausente, inválida ou expirada
422validation_error
429rate_limited — respeite Retry-After
cURL
curl -X POST https://api.smskit.dev/v1/auth/token \
  -H "X-API-Key: $SMSKIT_KEY"
200 · resposta
{
  "access_token": "smt_…",
  "expires_at": "2026-09-13T14:03:00Z",
  "expires_in": 172800,
  "mode": "live",
  "workspace_id": "ws_3h7k9d",
  "token_type": "bearer"
}

SMS

POST/v1/sms

Enviar SMS

Aceita um ou vários destinatários (to), com text livre ou template + variables. Todo envio passa por análise de risco (spam, golpe, phishing, links): risco baixo entra na fila (queued); risco médio ou alto fica em revisão manual (review) com os créditos reservados até a decisão. Envios em produção exigem o cadastro do titular concluído no console (identity_required). Responde 202; a entrega chega por webhook ou por GET /v1/sms/{id}. Envie Idempotency-Key para repetir com segurança.

Parâmetros
NomeOndeTipo
idempotency-keyheaderstring
Corpo · SendRequest
CampoTipoDescrição
fromstring | nullaté 40 caracteres
kindauthentication | utility | nullWhich delivery route a message takes.valores: authentication, utility
metadataobject<string> | null
scheduled_atdate-time | null
templatestring | nullaté 100 caracteres
textstring | nullaté 1000 caracteres
toobrigatóriostring | string[]
variablesobject<string> | null
Respostas
StatusDescrição
202Objeto SmsOutcompleted_at, created_at, credits, from, id, kind, messages, metadata, object, recipients, scheduled_at, segments, status, template, test, text
401Credencial ausente, inválida ou expirada
402insufficient_balance
403template_not_approved ou identity_required
409conflict (Idempotency-Key reutilizada com outro corpo)
422validation_error
429rate_limited — respeite Retry-After
cURL
curl -X POST https://api.smskit.dev/v1/sms \
  -H "Authorization: Bearer $SMSKIT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+5511999990123",
    "text": "Sua mesa está pronta. Até já."
  }'
202 · resposta
{
  "id": "sms_7f3k2m",
  "object": "sms",
  "text": "Sua mesa está pronta. Até já.",
  "template": "order-confirmed",
  "status": "queued",
  "created_at": "2026-09-11T14:03:00Z",
  "credits": 1,
  "kind": "utility",
  "recipients": 1,
  "segments": 1,
  "test": false,
  "completed_at": null,
  "from": null,
  "messages": [
    {
      "id": "msg_2b9x4c",
      "object": "message",
      "to": "+5511999990123",
      "status": "queued",
      "updated_at": "2026-09-11T14:03:05Z",
      "error": null
    }
  ],
  "metadata": {
    "order_id": "1042"
  },
  "scheduled_at": null
}

GET/v1/sms

Listar envios

Parâmetros
NomeOndeTipo
limitqueryintegerpadrão: 20
starting_afterquerystring
Respostas
StatusDescrição
200Objeto SmsListdata, has_more, next_cursor, object
401Credencial ausente, inválida ou expirada
422validation_error
429rate_limited — respeite Retry-After
cURL
curl https://api.smskit.dev/v1/sms?limit=20 \
  -H "Authorization: Bearer $SMSKIT_TOKEN"
200 · resposta
{
  "object": "list",
  "data": [
    {
      "id": "sms_7f3k2m",
      "object": "sms",
      "text": "Sua mesa está pronta. Até já.",
      "template": "order-confirmed",
      "status": "queued",
      "created_at": "2026-09-11T14:03:00Z",
      "credits": 1,
      "kind": "utility",
      "recipients": 1,
      "segments": 1,
      "test": false,
      "completed_at": null,
      "from": null,
      "messages": [
        {
          "id": "msg_2b9x4c",
          "object": "message",
          "to": "+5511999990123",
          "status": "queued",
          "updated_at": "2026-09-11T14:03:05Z",
          "error": null
        }
      ],
      "metadata": {
        "order_id": "1042"
      },
      "scheduled_at": null
    }
  ],
  "has_more": false,
  "next_cursor": null
}

GET/v1/sms/{sms_id}

Consultar um envio e seus destinatários

Parâmetros
NomeOndeTipo
sms_idobrigatóriopathstring
Respostas
StatusDescrição
200Objeto SmsOutcompleted_at, created_at, credits, from, id, kind, messages, metadata, object, recipients, scheduled_at, segments, status, template, test, text
401Credencial ausente, inválida ou expirada
404not_found
422validation_error
429rate_limited — respeite Retry-After
cURL
curl https://api.smskit.dev/v1/sms/sms_7f3k2m \
  -H "Authorization: Bearer $SMSKIT_TOKEN"
200 · resposta
{
  "id": "sms_7f3k2m",
  "object": "sms",
  "text": "Sua mesa está pronta. Até já.",
  "template": "order-confirmed",
  "status": "queued",
  "created_at": "2026-09-11T14:03:00Z",
  "credits": 1,
  "kind": "utility",
  "recipients": 1,
  "segments": 1,
  "test": false,
  "completed_at": null,
  "from": null,
  "messages": [
    {
      "id": "msg_2b9x4c",
      "object": "message",
      "to": "+5511999990123",
      "status": "queued",
      "updated_at": "2026-09-11T14:03:05Z",
      "error": null
    }
  ],
  "metadata": {
    "order_id": "1042"
  },
  "scheduled_at": null
}

Conta

GET/v1/account

Conta, saldo e preços

Respostas
StatusDescrição
200Objeto AccountOutbalance, id, mode, name, object, pricing
401Credencial ausente, inválida ou expirada
422validation_error
429rate_limited — respeite Retry-After
cURL
curl https://api.smskit.dev/v1/account \
  -H "Authorization: Bearer $SMSKIT_TOKEN"
200 · resposta
{
  "id": "ws_3h7k9d",
  "object": "account",
  "balance": {
    "credits": 1250
  },
  "mode": "live",
  "name": "Studio",
  "pricing": {
    "currency": "BRL",
    "creditsPerSegment": 1
  }
}

Modelos

GET/v1/templates

Modelos do workspace e sua aprovação

Respostas
StatusDescrição
200Objeto TemplateListdata, object
401Credencial ausente, inválida ou expirada
422validation_error
429rate_limited — respeite Retry-After
cURL
curl https://api.smskit.dev/v1/templates \
  -H "Authorization: Bearer $SMSKIT_TOKEN"
200 · resposta
{
  "object": "list",
  "data": [
    {
      "id": "order-confirmed",
      "object": "template",
      "variables": {
        "empresa": "Studio",
        "pedido": "1042"
      },
      "approved": true,
      "body": "{{empresa}}: seu pedido {{pedido}} foi confirmado. Acompanhe: {{link}}",
      "category": "transactional",
      "kind": "utility",
      "name": "Studio"
    }
  ]
}

Webhooks

POST/v1/webhooks

Criar webhook

O secret é exibido apenas nesta resposta. Use-o para verificar X-SMSKit-Signature.

Corpo · WebhookIn
CampoTipoDescrição
descriptionstringaté 200 caracteres
eventsobrigatórioWebhookEventType[]valores: message.sent, message.delivered, message.failed, sms.completed, webhook.test
urlobrigatóriostringaté 500 caracteres
Respostas
StatusDescrição
201Objeto WebhookOutactive, created_at, description, events, id, object, secret, url
401Credencial ausente, inválida ou expirada
422validation_error
429rate_limited — respeite Retry-After
cURL
curl -X POST https://api.smskit.dev/v1/webhooks \
  -H "Authorization: Bearer $SMSKIT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/webhooks/smskit",
    "events": [
      "message.delivered",
      "sms.completed"
    ]
  }'
201 · resposta
{
  "id": "wh_4d8q1z",
  "object": "webhook",
  "url": "https://example.com/webhooks/smskit",
  "events": [
    "message.delivered",
    "sms.completed"
  ],
  "active": true,
  "created_at": "2026-09-11T14:03:00Z",
  "description": "Entregas em produção",
  "secret": "whsec_6k2p9v4d1z8m"
}

GET/v1/webhooks

Listar webhooks

Respostas
StatusDescrição
200Objeto WebhookListdata, object
401Credencial ausente, inválida ou expirada
422validation_error
429rate_limited — respeite Retry-After
cURL
curl https://api.smskit.dev/v1/webhooks \
  -H "Authorization: Bearer $SMSKIT_TOKEN"
200 · resposta
{
  "object": "list",
  "data": [
    {
      "id": "wh_4d8q1z",
      "object": "webhook",
      "url": "https://example.com/webhooks/smskit",
      "events": [
        "message.delivered",
        "sms.completed"
      ],
      "active": true,
      "created_at": "2026-09-11T14:03:00Z",
      "description": "Entregas em produção",
      "secret": "whsec_6k2p9v4d1z8m"
    }
  ]
}

DELETE/v1/webhooks/{webhook_id}

Remover webhook

Parâmetros
NomeOndeTipo
webhook_idobrigatóriopathstring
Respostas
StatusDescrição
204Sucesso
401Credencial ausente, inválida ou expirada
404not_found
422validation_error
429rate_limited — respeite Retry-After
cURL
curl -X DELETE https://api.smskit.dev/v1/webhooks/wh_4d8q1z \
  -H "Authorization: Bearer $SMSKIT_TOKEN"

GET/v1/webhooks/{webhook_id}/deliveries

Entregas recentes de um webhook

Parâmetros
NomeOndeTipo
webhook_idobrigatóriopathstring
Respostas
StatusDescrição
200Objeto WebhookDeliveryListdata, object
401Credencial ausente, inválida ou expirada
422validation_error
429rate_limited — respeite Retry-After
cURL
curl https://api.smskit.dev/v1/webhooks/wh_4d8q1z/deliveries \
  -H "Authorization: Bearer $SMSKIT_TOKEN"
200 · resposta
{
  "object": "list",
  "data": [
    {
      "id": "whd_9k2p7r",
      "object": "webhook_delivery",
      "status": "pending",
      "attempts": 1,
      "created_at": "2026-09-11T14:03:00Z",
      "event_id": "evt_8n3v5t",
      "event_type": "message.delivered",
      "delivered_at": "2026-09-11T14:03:05Z",
      "last_error": null,
      "last_status_code": 200,
      "next_attempt_at": null,
      "test": false
    }
  ]
}

POST/v1/webhooks/{webhook_id}/test

Disparar um evento webhook.test

Parâmetros
NomeOndeTipo
webhook_idobrigatóriopathstring
Respostas
StatusDescrição
202Sucesso
401Credencial ausente, inválida ou expirada
422validation_error
429rate_limited — respeite Retry-After
cURL
curl -X POST https://api.smskit.dev/v1/webhooks/wh_4d8q1z/test \
  -H "Authorization: Bearer $SMSKIT_TOKEN"

Referência

GET/v1/errors

Códigos de erro estáveis (v1)

Respostas
StatusDescrição
200Sucesso
cURL
curl https://api.smskit.dev/v1/errors \
  -H "Authorization: Bearer $SMSKIT_TOKEN"

GET/v1/events

Tipos de evento de webhook (v1)

Respostas
StatusDescrição
200Sucesso
cURL
curl https://api.smskit.dev/v1/events \
  -H "Authorization: Bearer $SMSKIT_TOKEN"

Webhooks assinados

Cadastre uma URL HTTPS em POST /v1/webhooks com os eventos que quer receber. A resposta traz o secret (whsec_) uma única vez. Cada entrega é um POST com JSON e dois headers:

  • X-SMSKit-Signature: t=<unix>,v1=<hex> — HMAC-SHA256 com o secret sobre a string "<t>.<corpo bruto>".
  • X-SMSKit-Event-Id — id do evento, útil para descartar duplicatas.

Verificação

Recalcule o HMAC sobre os bytes exatos que chegaram, compare em tempo constante e rejeite carimbos com mais de 5 minutos de diferença. JSON re-serializado muda espaços e ordem de chaves e invalida a assinatura.

Node
import { createHmac, timingSafeEqual } from "node:crypto";

// Verifique sobre o corpo BRUTO da requisição, nunca sobre JSON re-serializado.
export function verify(secret: string, header: string, rawBody: Buffer) {
  const parts = Object.fromEntries(
    header.split(",").map((part) => part.trim().split("=", 2)),
  );
  const age = Math.abs(Math.floor(Date.now() / 1000) - Number(parts.t));
  if (!parts.t || !parts.v1 || Number.isNaN(age) || age > 300) return false;
  const expected = createHmac("sha256", secret)
    .update(`${parts.t}.`)
    .update(rawBody)
    .digest();
  const received = Buffer.from(parts.v1, "hex");
  return expected.length === received.length && timingSafeEqual(expected, received);
}

// Express: mantenha o corpo bruto no handler do webhook.
app.post("/webhooks/smskit", express.raw({ type: "application/json" }), (req, res) => {
  const header = req.header("X-SMSKit-Signature") ?? "";
  if (!verify(process.env.SMSKIT_WEBHOOK_SECRET!, header, req.body)) {
    return res.status(400).end();
  }
  const event = JSON.parse(req.body.toString("utf8"));
  // event.type, event.data …
  res.status(204).end();
});

Com os SDKs, a verificação é uma chamada:

verifySignature(secret, header, rawBody)
import { verifySignature } from "smskit";

// Assíncrono: usa Web Crypto, funciona em Node, Bun, Deno e edge runtimes.
const ok = await verifySignature(
  process.env.SMSKIT_WEBHOOK_SECRET!,
  request.headers.get("X-SMSKit-Signature"),
  rawBody, // string ou Uint8Array com o corpo bruto
);
if (!ok) return new Response(null, { status: 400 });

Envelope

Todo evento tem o mesmo envelope. data é o objeto do evento: a mensagem de um destinatário em message.*, o resumo do envio em sms.completed.

message.delivered
{
  "id": "evt_8n3v5t",
  "object": "event",
  "type": "message.delivered",
  "api_version": "v1",
  "created_at": "2026-09-11T14:03:05Z",
  "test": false,
  "data": {
    "id": "msg_2b9x4c",
    "sms_id": "sms_7f3k2m",
    "to": "+5511999990123",
    "status": "delivered",
    "error": null,
    "kind": "utility",
    "updated_at": "2026-09-11T14:03:05Z",
    "metadata": { "order_id": "1042" }
  }
}
Tipos de evento
EventoQuando dispara
message.sentA operadora aceitou a mensagem para um destinatário.
message.deliveredA operadora confirmou a entrega no aparelho.
message.failedA entrega falhou para um destinatário.
sms.completedTodos os destinatários de um envio têm resultado final.
webhook.testEvento de verificação disparado pelo console ou pela API.

Tentativas

Qualquer resposta 2xx conta como entregue. Sem isso, o evento é reenviado até 6 vezes com espera crescente: 1 min, 5 min, 30 min, 2 h, 12 h. Responda rápido e processe depois; GET /v1/webhooks/{id}/deliveries mostra as tentativas recentes e POST /v1/webhooks/{id}/test dispara um webhook.test para validar a integração.

Erros estáveis

Toda falha responde com o mesmo envelope e um code do enum versionado em GET /v1/errors. Trate pelo código, não pela mensagem: a mensagem é para humanos e pode mudar. details aparece só em validation_error; request_id identifica a requisição no suporte.

402 · envelope
{
  "error": {
    "code": "insufficient_balance",
    "message": "O saldo não cobre este envio.",
    "status": 402,
    "request_id": "req_8f3k2m"
  }
}
422 · com details
{
  "error": {
    "code": "validation_error",
    "message": "Um ou mais campos são inválidos.",
    "status": 422,
    "details": [
      {
        "field": "to",
        "message": "Número fora do padrão +55DDDNÚMERO."
      }
    ],
    "request_id": "req_2c7v9q"
  }
}
Códigos
CódigoHTTPTítuloDescrição
validation_error422Parâmetros inválidosUm ou mais campos não passaram na validação. O campo details lista cada problema.
invalid_request400Requisição malformadaO corpo não é um JSON válido ou o content-type não é aceito.
authentication_required401Autenticação obrigatóriaEnvie Authorization: Bearer <token> obtido em POST /v1/auth/token.
invalid_api_key401Chave de API inválidaA chave não existe, foi revogada ou pertence a outro ambiente.
invalid_token401Token inválidoO token Bearer não foi reconhecido. Gere um novo em POST /v1/auth/token.
token_expired401Token expiradoO token Bearer venceu (validade de 48 horas). Gere um novo.
forbidden403Sem permissãoA credencial não pode executar esta operação.
template_not_approved403Modelo não aprovadoEm produção, o texto precisa corresponder a um modelo aprovado do workspace. Nada foi cobrado.
identity_required403Titular não verificadoEnvios em produção exigem o cadastro do titular (nome, CPF e data de nascimento) concluído no console e não recusado na verificação. Nada foi cobrado.
not_found404Não encontradoO recurso não existe ou não pertence a este workspace.
conflict409ConflitoA mesma Idempotency-Key foi usada com um corpo diferente, ou o recurso mudou desde a leitura.
insufficient_balance402Saldo insuficienteO workspace não tem créditos para este envio. Recarregue via PIX no console. Nada foi enviado.
rate_limited429Limite de requisiçõesAguarde o tempo indicado em Retry-After antes de tentar novamente.
provider_unavailable503Operadora indisponívelA rota de envio não respondeu. O envio permanece na fila e será tentado novamente.
internal_error500Erro internoFalha inesperada. Informe o request_id ao suporte.

Em 429 rate_limited, o header Retry-After informa quantos segundos esperar. Os SDKs expõem esse valor em error.retryAfter / error.retry_after. 503 provider_unavailable não descarta o envio: ele permanece na fila e é tentado novamente.

SDKs

Os SDKs oficiais cobrem a API inteira, trocam a chave pelo token Bearer na primeira chamada, guardam o token em memória e renovam ao receber 401. Erros viram exceções tipadas com code, status, requestId e retryAfter.

TypeScript
pnpm add smskit
Python
pip install smskit
TypeScript
import { SMSKit, SMSKitError } from "smskit";

const sms = new SMSKit(process.env.SMSKIT_KEY!, {
  baseUrl: "https://api.smskit.dev", // opcional
});

try {
  const sent = await sms.send({
    to: ["+5511999990123", "+5521988880456"],
    template: "order-confirmed",
    variables: { empresa: "Studio", pedido: "1042", link: "https://exemplo.com/p/1042" },
    idempotencyKey: "pedido-1042",
  });
  const status = await sms.get(sent.id);
  const { balance } = await sms.account();
} catch (error) {
  if (error instanceof SMSKitError) {
    console.error(error.code, error.status, error.requestId, error.retryAfter);
  }
}

Construtor: new SMSKit(apiKey, { baseUrl?, timeoutMs?, fetch? }) em TypeScript; SMSKit(api_key, base_url=, timeout=) em Python. baseUrl muda o destino das chamadas (útil para um ambiente local); o padrão é https://api.smskit.dev.

Métodos
AçãoTypeScriptPython
Enviar SMSsms.send({ to, text | template + variables, kind?, scheduledAt?, metadata?, idempotencyKey? })sms.send(to=, text=, template=, variables=, kind=, scheduled_at=, metadata=, idempotency_key=)
Consultar enviosms.get(smsId)sms.get(sms_id)
Listar enviossms.list({ limit?, startingAfter? })sms.list(limit=20, starting_after=None)
Conta e saldosms.account()sms.account()
Modelossms.templates()sms.templates()
Listar webhookssms.webhooks.list()sms.webhooks()
Criar webhooksms.webhooks.create({ url, events, description? })sms.create_webhook(url=, events=, description=)
Remover webhooksms.webhooks.delete(webhookId)sms.delete_webhook(webhook_id)
Testar webhooksms.webhooks.test(webhookId)sms.test_webhook(webhook_id)
Verificar assinaturaawait verifySignature(secret, header, rawBody)verify_signature(secret, header, body_bytes)

MCP para agentes

O servidor MCP expõe as ferramentas abaixo por HTTP streamable em <MCP_URL>/mcp. A chave de API vai no header Authorization; use uma chave sk_test_ para o agente ensaiar sem enviar nem cobrar nada.

Configuração do cliente MCP
{
  "mcpServers": {
    "smskit": {
      "url": "https://mcp.smskit.dev/mcp",
      "headers": { "Authorization": "Bearer sk_live_..." }
    }
  }
}
Ferramentas
FerramentaO que faz
sms_sendEnvia um SMS: to e text (modelo aprovado) ou template + variables.
sms_statusConsulta um envio e o status por destinatário.
sms_listLista os envios mais recentes do workspace.
account_balanceSaldo de créditos e modo (live/test) da credencial.
templates_listModelos do workspace, com variáveis e aprovação.

Limites e preço

Limites
LimiteValorObservação
Tamanho da mensagem160 caracteresApós substituir as variáveis do modelo.
Destinatários por requisição1.000Rota de utilidade. Na rota de autenticação, 100.
Chaves de API por workspace20Revogue e recrie sem afetar as demais.
Webhooks por workspace10Até 6 tentativas por evento.

Como o preço é calculado

Um crédito por segmento, por destinatário. Texto GSM-7 cabe em 160 caracteres num único segmento e em 153 por segmento a partir do segundo; com emojis ou caracteres fora do GSM-7 a codificação passa a Unicode e os limites caem para 70 e 67. A resposta de POST /v1/sms traz segments e credits já calculados; nada é cobrado quando o envio é recusado.

Preço por crédito (BRL)
A partir dePor segmento
500 créditosR$ 0,110
1.000 créditosR$ 0,100
5.000 créditosR$ 0,090
10.000 créditosR$ 0,080
30.000 créditosR$ 0,075