Pular para o conteúdo

Cota e uso

O Turbo Notify mede duas cotas independentes por número vinculado (main ou alias extra): mensagens enviadas e contatos distintos contactados. As duas cotas são por número: cada número tem sua própria cota, e uma organização com N números tem N vezes a cota do plano.

Só o que sai pelo Turbo Notify (origin: "tn") consome cota; mensagens enviadas direto do celular (origin: "native") não contam.

Ciclo avaliado: quando a cota reinicia

O período de medição das duas cotas é o ciclo de faturamento atual da organização (de cycle_start até cycle_end, o período corrente da assinatura). resets_at sempre coincide com cycle_end: a cota reinicia na virada do ciclo.

  • used e quota são sempre medidos no ciclo que está aberto.
  • Quando o ciclo fecha (renovação da assinatura), os contadores zeram e um novo período [cycle_start, cycle_end) começa.
  • cycle_start e cycle_end são os mesmos para todos os números da organização (o ciclo é da assinatura, não do número); só used e quota variam por número.

Tabela de planos (por número, por ciclo)

Equivalência com os nomes comerciais dos planos: Gratuito = FREE · Lobo Solitário = SOLO · Empresarial = BUSINESS · Personalizado = CUSTOM.

PlanoMensagens/cicloContatos distintos/cicloNúmeros extras (máx.)
FREE30020
SOLO1.8001000
BUSINESS50.0005.0001.000
CUSTOM500.00050.0001.000

Os preços de cada plano estão na página Cobrança do dashboard e em turbonotify.com. Sua organização pode pedir ao suporte um limite personalizado, que substitui o teto do plano por número.

O campo tier nas respostas abaixo é sempre um dos 4 valores acima, em maiúsculas ("FREE", "SOLO", "BUSINESS", "CUSTOM").

Grupos e mensagens recebidas

  • Um envio para grupo consome 1 unidade da cota de mensagens e zero da cota de contatos: um grupo não é um contato.
  • Mensagens recebidas não consomem nenhuma das duas cotas.
  • Só envios com origin: "tn" consomem a cota de mensagens; só contatos contactados pelo Turbo Notify consomem a cota de contatos.

O que conta na cota

Um envio pelo Turbo Notify só consome a unidade de mensagem e a unidade de contato se chegar ao WhatsApp (ou enquanto ainda está a caminho dele).

  • A API recusou o envio (por exemplo 429 por espaçamento entre envios, mensagem repetida ou limite de destinatários por dia): nada é consumido.
  • O envio foi aceito (202), mas falhou antes de chegar ao WhatsApp (por exemplo message.send.failed com number_not_connected ou falha ao baixar a mídia): as duas unidades são devolvidas logo depois da falha, em até alguns minutos. used volta a refletir só o que chegou.
  • O envio não foi confirmado dentro do tempo limite de confirmação (message.send.failed com message_timeout): a unidade não é devolvida, porque a mensagem ainda pode ter saído do seu número. Se ela chegar ao WhatsApp depois, o envio passa a sent e continua contando; se você reenviar, o novo envio conta por si só.
  • A mensagem chegou ao WhatsApp e a entrega falhou depois: ela conta, como qualquer mensagem que saiu do seu número.

As mensagens de teste enviadas pelo dashboard do Turbo Notify não consomem a cota de mensagens nem a de contatos.

Os limites de ritmo do envio (espaçamento, mensagens por minuto, destinatários por dia) contam tentativas, não entregas: uma tentativa recusada continua contando para esses limites.

Envio para grupos exige plano Empresarial ou superior

Enviar mensagem ou indicador de digitação para um group_id exige o recurso groups:messages, disponível a partir do plano Empresarial. Nos planos Gratuito e Lobo Solitário você ainda pode receber mensagens de grupo, listar grupos e consultar detalhes. Só o envio para grupo é bloqueado:

Status HTTP: 402
{
  "error": "feature_not_available"
}

Veja Grupos: Visão geral e Limitações de grupos.

Endpoint: uso agregado da conta

GET /v1/usage

Escopo obrigatório: nenhum: qualquer chave de API válida.

Cache: a resposta é retornada com Cache-Control: no-store, no-cache, must-revalidate e Pragma: no-cache: ou seja, não é cacheável. Não armazene o corpo em cache; refaça a chamada sempre que precisar de dados atualizados.

GET /v1/usage é o total da conta: messages e contacts no nível raiz somam o uso de todos os números da organização, e quota é a soma das cotas de cada número (uma organização com 2 números em um plano de 100 por ciclo informa quota: 200). resets_at é o cycle_end do ciclo atual da organização (o mesmo para todo número). A resposta também traz numbers[]: uma entrada por número ativo (principal e extras), com o detalhamento used/quota/remaining de cada cota, sem resets_at nem tier por entrada (os dois já valem para todos no nível raiz).

Status HTTP: 200
{
  "messages": {
    "used": 1234,
    "quota": 1800,
    "remaining": 566,
    "resets_at": "2026-07-01T00:00:00Z",
    "tier": "SOLO"
  },
  "contacts": {
    "used": 87,
    "quota": 100,
    "remaining": 13,
    "resets_at": "2026-07-01T00:00:00Z",
    "tier": "SOLO"
  },
  "numbers": [
    {
      "alias": "main",
      "messages": {
        "used": 1234,
        "quota": 1800,
        "remaining": 566
      },
      "contacts": {
        "used": 87,
        "quota": 100,
        "remaining": 13
      }
    }
  ]
}

GET /v1/usage/messages

O mesmo total da conta, só para a cota de mensagens, também com seu próprio numbers[] (entradas só com messages), para quem consulta apenas essa cota sem precisar do total de contatos:

Status HTTP: 200
{
  "messages": {
    "used": 1234,
    "quota": 1800,
    "remaining": 566,
    "resets_at": "2026-07-01T00:00:00Z",
    "tier": "SOLO"
  },
  "numbers": [
    {
      "alias": "main",
      "messages": {
        "used": 1234,
        "quota": 1800,
        "remaining": 566
      }
    }
  ]
}

Endpoints por número

  • GET /v1/numbers/{ref}/messages/quota: cota de mensagens do número (rota plana para o principal: GET /v1/messages/quota, equivalente a GET /v1/numbers/main/messages/quota).
  • GET /v1/numbers/{ref}/contacts/quota: cota de contatos do número (rota plana para o principal: GET /v1/contacts/quota).

Os dois retornam o mesmo formato: a situação daquele número no ciclo atual.

Status HTTP: 200
{
  "used": 1234,
  "quota": 1800,
  "remaining": 566,
  "cycle_start": "2026-06-01T00:00:00Z",
  "cycle_end": "2026-07-01T00:00:00Z",
  "resets_at": "2026-07-01T00:00:00Z",
  "tier": "SOLO"
}

resets_at sempre repete cycle_end, para quem lê só um campo. Diferente de GET /v1/usage, estes dois endpoints trazem cycle_start e cycle_end explicitamente, porque descrevem um número.

Pelo Servidor MCP, um agente consulta o mesmo com get_usage, get_message_quota e get_contact_quota. Essas três ferramentas não exigem escopo: qualquer chave válida as usa.

Prazo de retenção de conteúdo

Além da cota, cada plano define por quantas horas o conteúdo de uma mensagem (texto, legenda, referência de mídia, transcrição, preview) fica guardado. O prazo de conteúdo é de 1 hora por padrão, até 7 horas no Lobo Solitário e até 72 horas no Empresarial e no Personalizado. Passado esse prazo, o Turbo Notify apaga o conteúdo de vez. Só o conteúdo expira: a mensagem continua disponível pela API por 12 meses.

  • GET /v1/numbers/{ref}/messages continua listando a mensagem, com content_expired: true e preview vazio.
  • A consulta .../messages/{id}, os sub-recursos .../status, .../receipts e .../reactions, e as ações .../reply, .../edit, .../delete e .../react continuam funcionando, nas rotas aninhadas e nas planas.
  • O registro da mensagem (metadados: status, datas, participantes) fica 12 meses, igual para todo plano, independentemente do prazo de conteúdo escolhido.

Os prazos por plano, como escolher um prazo maior e o ciclo de vida completo do conteúdo e dos metadados estão em Retenção das mensagens.

Erros

402: assinatura inativa

Retornado ao tentar enviar quando a assinatura da organização não permite o uso dos recursos (ACTIVE, e TRIALING dentro do período de teste, são os únicos estados que passam sem restrição):

Status HTTP: 402
{
  "error": "subscription_inactive",
  "message": "Subscription is not active",
  "details": {
    "status": "trial_expired"
  }
}

details.status é um destes valores: trial_expired (período de teste encerrado sem plano pago), past_due (pagamento em atraso: os envios ficam bloqueados até o pagamento ser confirmado) ou missing (organização sem assinatura ativa).

Assinaturas ativas e em período de teste não geram este erro. Uma troca para um plano menor ou um cancelamento agendado não bloqueia envios: a assinatura segue funcionando até o fim do período já pago.

402: recurso indisponível no plano

Status HTTP: 402
{
  "error": "feature_not_available"
}

Hoje os recursos restritos por plano são:

  • Reações (reactions): a partir do Lobo Solitário.
  • Indicador de digitação (typing_indicator): a partir do Lobo Solitário. É a restrição base e vale para toda chamada.
  • Envio de mensagem ou indicador de digitação para grupo (groups:messages): a partir do Empresarial, veja acima.
  • Histórico detalhado de recibos e marcação manual de leitura (read_receipts): a partir do Empresarial, veja Recibos e Marcar como lida.
  • Criação de números extras (extra_numbers): indisponível no Gratuito e no Lobo Solitário, veja Números extras.
  • Reentrega de webhook (webhooks:retries): a partir do Empresarial. No Lobo Solitário cada evento tem uma única tentativa de entrega e, se ela falhar, não há outra; veja Eventos via webhook. No Gratuito não há webhook: use GET /v1/events, disponível em todos os planos.

402: limite de números extras atingido

Retornado por POST /v1/numbers quando a organização já tem max_extra_numbers números extras ativos para o plano (Empresarial 1.000, Personalizado 1.000; Gratuito e Lobo Solitário não têm acesso a números extras):

Status HTTP: 402
{
  "error": "extra_numbers_limit_reached",
  "message": "Extra numbers limit reached for the current plan (1000/1000).",
  "details": {
    "limit": 1000,
    "current": 1000
  }
}

details.limit é o teto max_extra_numbers do plano; details.current é a quantidade atual de números extras ativos da organização.

402: cota de contatos excedida

Status HTTP: 402
{
  "error": "contact_quota_exceeded",
  "message": "Distinct-contacts quota exceeded for tier BUSINESS (5000/5000 this cycle)",
  "details": {
    "quota": 5000,
    "used": 5000,
    "resets_at": "2026-07-01T00:00:00Z",
    "tier": "BUSINESS"
  }
}

429: cota de mensagens excedida

Status HTTP: 429
  • Retry-After: 1296000
{
  "error": "messages_quota_exceeded"
}

Diferente do 402 de contatos, este 429 não carrega details com used/quota/resets_at no corpo. Consulte GET /v1/numbers/{ref}/messages/quota (ou GET /v1/usage/messages) para a situação completa e o resets_at real. O cabeçalho Retry-After traz quantos segundos faltam para a cota do número renovar, ou seja, até resets_at (no exemplo, 15 dias). Repetir o envio antes disso recebe o mesmo 429; para enviar já, use outro número ou mude de plano.

402 vs 429: quando aparecem

402 (contatos)429 (mensagens)
SinalMudar para um plano maiorCota do ciclo esgotada
Cabeçalho Retry-AfterAusentePresente: segundos até resets_at
Corpo com used/quota/resets_atSim (details)Não: consulte o endpoint de cota
Reinicia emresets_at (fim do ciclo atual) ou ao mudar para um plano maiorresets_at (fim do ciclo atual)

Webhooks de cota

  • contact.quota.warning em 80/90/95%.
  • contact.quota.exceeded no estouro.
  • message.quota.warning em 80/90/95%.
  • message.quota.exceeded no estouro.

Ambas as famílias carregam cycle_start/cycle_end no data. Veja Eventos de cota de mensagem, Eventos de contato e Limites de velocidade.