whatsapp-bsp / api / v1 / docs
Voltar ao Dashboard

Documentação da API

Bem-vindo à API do WhatsApp Connect. Nossa API permite integrar o WhatsApp Business Cloud diretamente no seu sistema.

Requisitos no Facebook

Antes de conectar à API oficial do WhatsApp (Meta), é necessário completar algumas configurações na sua conta do Facebook Business. Siga os passos abaixo na ordem indicada.

Passo 1 — Verificação da Empresa

Acesse a Central de Segurança do Business Manager e inicie o processo de verificação da sua empresa. Isso é fundamental para aumentar seus limites de envio de mensagens.

1
Inicie a Verificação na Central de Segurança

Clique no link abaixo para acessar a Central de Segurança da sua conta.

business.facebook.com/latest/settings/security_center

Passo 2 — Preencher Dados da Empresa

Acesse as configurações do Business Manager e preencha as informações da sua empresa. Isso é obrigatório para a Meta liberar o envio de mensagens em escala.

2
Acesse o link abaixo e preencha todos os campos solicitados

Razão social, CNPJ, endereço e telefone comercial.

business.facebook.com/latest/settings/business_info
Conta Pessoal (sem CNPJ)
Se você não possui empresa registrada, preencha o seu nome completo no campo "Razão social da empresa". Os demais campos podem ser preenchidos com seus dados pessoais normalmente.

Passo 3 — Cadastrar Cartão de Crédito

O envio de templates (mensagens ativas) é cobrado diretamente pela Meta. Para habilitar o envio, é necessário cadastrar um método de pagamento na sua conta Business.

3
Acesse o Hub de Faturamento

Clique no link abaixo para ir direto para a página de pagamentos.

business.facebook.com/latest/billing_hub/accounts
2
Selecione "Contas do WhatsApp Business"

Na tela de faturamento, localize e clique na opção Contas do WhatsApp Business para adicionar seu cartão de crédito vinculado especificamente ao número do WhatsApp que será utilizado na API.

Importante: Sem cartão cadastrado, o envio de templates de marketing e utilidade ficará bloqueado pela Meta. Mensagens dentro da janela de 24h (respostas) não são cobradas.

Custos de Envio de Templates

A Meta cobra por conversa iniciada via template, e não por mensagem individual. Os preços variam de acordo com a categoria do template:

Marketing
$0,06
por conversa iniciada
Templates promocionais, ofertas, campanhas
Utilidade
$0,006
por conversa iniciada
Confirmações, lembretes, notificações transacionais
Dica: Prefira templates de Utilidade para notificações automáticas (agendamentos, cobranças, confirmações). Além de custar 10x menos, eles têm taxas de entrega mais altas pois não são filtrados como spam.

Janelas de Conversa

A Meta trabalha com o conceito de janela de conversa: um período em que você pode trocar mensagens livremente sem custo adicional após o template inicial ter sido enviado.

24h
Conversa Padrão

Quando um cliente envia uma mensagem para o seu número, uma janela de 24 horas é aberta. Durante esse período, você pode responder livremente com qualquer tipo de mensagem, sem custo de template.

72h
Lead de Anúncios (Click-to-WhatsApp)

Quando o lead chega ao WhatsApp a partir de um anúncio Click-to-WhatsApp do Facebook/Instagram, a janela de conversa é ampliada para 72 horas, permitindo mais tempo para o atendimento sem custo adicional.

Fora da janela: Se a janela expirar e você precisar retomar o contato, será necessário enviar um template (marketing ou utilidade) para reabrir a conversa, e o custo correspondente será cobrado.

Nome de Exibição (Display Name)

Quando sua empresa utiliza a API Oficial do WhatsApp Business (Meta) para falar com clientes, o nome que aparece no perfil é o seu Nome de Exibição (ou Display Name). Ele funciona como a identidade e o cartão de visitas da sua empresa no aplicativo.

Ter um nome aprovado é essencial para transmitir confiança, ajudar no reconhecimento imediato da marca e, futuramente, para a obtenção do selo verde de Conta Comercial Oficial (OBA).

1. Diretrizes de Aprovação da Meta

A Meta possui regras estritas para a aprovação do Nome de Exibição. Ele deve refletir de forma consistente a sua marca externa e seguir as regras de formatação abaixo:

Regras de Formatação e Escrita

  • Tamanho Mínimo: O nome deve conter no mínimo 3 caracteres.
  • Gramática e Capitalização: Use maiúsculas e minúsculas corretamente (ex: Padaria Delícia). Não utilize todo o texto em caixa alta (ALL CAPS) (ex: PADARIA DELÍCIA), a menos que a sua marca seja registrada ou conhecida dessa forma (ex: IKEA, BMW).
  • Espaçamento: Não insira espaços extras entre as letras (ex: P a d a r i a será rejeitado).
  • Caracteres Especiais: Emojis, símbolos de marca registrada (como ®, ™), caracteres especiais desnecessários ou pontuação excessiva são estritamente proibidos (ex: Padaria Delícia! ✨).

Regras de Conteúdo e Associação

  • Sem Termos Genéricos: Nomes compostos apenas por palavras comuns como Moda, Roupas, Suporte ou apenas localizações como São Paulo, Brasil serão reprovados. O nome deve conter um identificador único da sua empresa (ex: Moda Estilo, Padaria Delícia São Paulo).
  • Consistência de Branding: O nome deve corresponder exatamente a como a empresa é conhecida no mercado (no site institucional, redes sociais, logotipo e documentos fiscais/CNPJ). A Meta confere essas informações durante a análise.
  • Associação com a Conta (WABA): Se o nome de exibição for de uma sub-marca ou departamento específico, a relação com a empresa principal deve ser clara (ex: Atendimento - Padaria Delícia).
  • Proibição de Nomes Individuais: Não use o nome completo de uma pessoa física sozinho (ex: João Silva será rejeitado, use João Silva Advocacia ou Consultório Dr. João Silva).
  • Termos Oficiais/Verificados: Não use palavras como "Oficial", "Verificado", "Official" ou "Verified" no nome, a menos que a conta já possua o selo de verificação oficial da Meta.
  • Sem Menção à Meta/WhatsApp: Não inclua os termos WhatsApp, Meta, Facebook ou Instagram no nome (ex: Suporte WhatsApp da Minha Empresa é proibido).
  • Evite URLs Completas: Não use formatos de sites com www. ou e-mails (ex: www.padariadelicia.com é rejeitado, mas PadariaDelicia.com é aceito se for o nome comercial da marca).
  • Proibido Promoções: O nome não pode conter mensagens promocionais, cupons ou frases de efeito (ex: Padaria Delícia - 20% OFF ou A Melhor Padaria da Cidade serão rejeitados).
Importante: O WhatsApp verifica ativamente a consistência do nome. Se a sua empresa se chama "Padaria Delícia", mas o site cadastrado ou as redes sociais utilizam outro nome sem qualquer ligação óbvia, o nome será rejeitado até que a associação seja comprovada ou o nome ajustado.

2. Exemplos de Nomes Aceitos vs. Rejeitados

O Que Pode (Aprovado) O Que Não Pode (Rejeitado) Motivo da Rejeição
Padaria Delícia PADARIA DELÍCIA Uso incorreto de caixa alta (ALL CAPS).
Loja Estilo São Paulo São Paulo Nome geográfico genérico.
Informática Silva Computadores Nome comercial genérico.
Atendimento - Padaria Delícia Suporte Termo de departamento sem o nome da marca.
PadariaDelicia.com www.padariadelicia.com Formato de URL completa (evitar phishing).
Padaria Delícia Padaria Delícia - Promoção Contém texto promocional no nome.
Minha Empresa Minha Empresa no WhatsApp Uso não autorizado de marcas registradas da Meta.
Clínica de Estética Bella Estética Bella Oficial Sugere verificação oficial sem possuir o selo.
Ana Souza Nutrição Ana Souza Nome de pessoa física sem identificador comercial.

3. O Que Fazer se Seu Nome For Rejeitado?

Se o seu Nome de Exibição for rejeitado, o processo de ajuste e reanálise é rápido e simples:

1
Revisar e Ajustar

Edite o nome no Painel do WhatsApp Manager na Meta de acordo com as diretrizes acima.

2
Comprovar Presença Digital (Branding)

Certifique-se de que o nome comercial desejado está claramente visível no site institucional e nas redes sociais da empresa vinculadas ao portfólio de negócios.

3
Enviar para Nova Análise

Submeta o novo nome. O WhatsApp costuma analisar novas solicitações dentro de um prazo que varia de **alguns minutos a até 24 horas**.

Boas Práticas & Prevenção de Banimento (2026)

Em 2026, a Meta intensificou significativamente as políticas de segurança e a inteligência dos seus algoritmos para proteger a experiência dos usuários no WhatsApp. Este guia apresenta os principais fatores que determinam a saúde do seu número e as diretrizes recomendadas para manter sua operação segura na API Oficial e no Modo de Coexistência.

1. O Cenário de Banimentos no WhatsApp

Os algoritmos de detecção da Meta evoluíram. Hoje, o foco de monitoramento está predominantemente no comportamento das contas comerciais e na qualidade das interações, e não puramente no volume bruto de mensagens enviadas.

Principais Fatores que Levam ao Banimento

  • Falta de Consentimento (Opt-in): Enviar mensagens ativas para contatos que não autorizaram a comunicação é o gatilho mais rápido para restrições. Listas frias ou bases compradas resultam em bloqueios quase instantâneos.
  • Comportamento Automatizado Não Oficial (Pirata): A utilização de ferramentas piratas, extensões de navegadores e APIs não oficiais que simulam interações humanas de forma fria é facilmente detectada pelos ritmos e padrões previsíveis dos envios.
  • Disparos em Massa Abruptos: Iniciar volumes elevados de mensagens repentinamente, sem aquecimento prévio ou respeitando os limites dos Messaging Tiers da Meta.
  • Alta Taxa de Denúncias (O Fator Mais Crítico): O botão "Denunciar Spam" ou "Bloquear" clicado pelos clientes finais é o fator com maior peso. Se o Quality Rating (Índice de Qualidade) do número cair para a cor vermelha (Low Quality), o número sofrerá sanções imediatas.
Mitos Comuns: O que NÃO causa banimento
A Meta não penaliza contas legítimas por:
  • Receber um alto volume de mensagens recebidas (Inbound).
  • Responder a milhares de clientes simultaneamente de forma legítima e contextual.
  • Apresentar crescimento orgânico de interações ou usar o WhatsApp Business App original manualmente.

2. O Uso Manual como "Trust Signal"

Ao contrário das ferramentas piratas, o uso manual e autêntico do WhatsApp é considerado o maior sinal de confiança (Trust Signal) para os algoritmos de segurança da Meta.

Por que o atendimento manual protege o seu número?
  • Humanização Natural: Padrões de digitação, pausas naturais, tempo de resposta variável e uso de vocabulários diversificados geram um comportamento 100% orgânico e seguro contra os robôs anti-spam.
  • Redução Drástica de Denúncias: O atendimento prestado por um agente humano tende a ser muito mais assertivo, resolvendo o problema do cliente de imediato, o que diminui a probabilidade dele clicar em "Denunciar Spam".
  • Frequência de Manutenção: A única exigência operacional do modo de coexistência é abrir o WhatsApp Business App no celular pelo menos uma vez a cada 13 dias para manter a chave da API ativa. O uso contínuo manual é benéfico e saudável para a conta.

3. Limites e Quantidades de Envio

Existe uma diferença conceitual e prática fundamental entre iniciar conversas através do WhatsApp Business App (celular) e através da Cloud API (automação):

Característica Pelo App de Celular (Manual) Pela Cloud API (Automação)
Necessidade de Templates Não (Mensagem livre) Sim (Obrigatoriamente aprovado pela Meta)
Recomendação de Limites 20 a 50 contatos frios/dia (sem histórico ou número salvo na agenda). Muito maior se os contatos forem clientes fidelizados. Controlado estritamente por Messaging Tiers.
Messaging Tiers (Volume) Não aplicável. Tier 0: 250 destinatários únicos/dia (Não verificado)
Tier 1: 1.000 destinatários únicos/dia (Verificado)
Tier 2: 10.000 destinatários únicos/dia
Tier 3: 100.000 destinatários únicos/dia
Janela de Conversa Livre Sempre livre. Livre por 24h após a última mensagem recebida do cliente.
Regra de Ouro dos Tiers: Para aumentar seu Tier na API (de 1.000 para 10.000, por exemplo), você deve enviar pelo menos a metade do seu limite diário atual em mensagens com alta qualidade em um período de 7 dias. O upgrade é automático pela Meta.

4. Boas Práticas Operacionais

No Modo de Coexistência (App + API)

  • Intervenção Humana Transparente: Utilize o aplicativo móvel para assumir conversas complexas em que o robô não está conseguindo guiar o cliente de forma assertiva.
  • Sincronização de Estado: Assegure-se de pausar a automação do robô quando a conversa estiver sob atendimento manual para evitar o envio de respostas simultâneas e incoerentes.
  • Manutenção de Conexão: Abra o aplicativo móvel pelo menos uma vez a cada 13 dias para evitar que a Meta desvincule a Cloud API por inatividade do app companheiro.
  • Conexões Suportadas: Lembre-se de que ao ativar a Coexistência, conexões antigas do WhatsApp Web ou aplicativos para desktop do Windows serão desconectados, pois o sistema aceita apenas dispositivos companheiros compatíveis com o espelhamento de eventos.
  • Desconexão do Número: Para desconectar um número em modo de coexistência da plataforma BSP e liberar a exclusão no Facebook Business Manager, o processo correto deve ser feito pelo app no celular — chamadas de API (deregister, subscribed_apps) não funcionam para esse tipo de conexão. Veja o passo a passo abaixo.
Como desconectar um número em Coexistência da plataforma BSP:
  1. Primeiro remova o número pela plataforma (botão Desconectar no dashboard)
  2. No celular, abra o WhatsApp Business
  3. Acesse Configurações → Conta → Plataforma Business
  4. Toque em Desconectar

Somente após esse passo a lixeira no Facebook Business Manager será liberada para excluir o número. Tentativas de desconectar via API (DELETE /subscribed_apps ou POST /deregister) retornam erro pois o vínculo de coexistência é gerenciado pelo app do celular, não pela Cloud API.

Na API Oficial Direta (Alta Performance)

  • Implemente o Double Opt-in: Sempre confirme se o usuário realmente deseja receber comunicações automáticas da sua marca antes de iniciar os fluxos transacionais ou promocionais.
  • Facilite o Opt-out (Cancelamento): Sempre dê a opção para o cliente parar de receber mensagens (ex: um botão de resposta escrito "Sair" ou "Cancelar"). É muito melhor o cliente sair da sua lista voluntariamente do que ele clicar no botão "Denunciar Spam" da Meta.
  • Aquecimento de Números Novos (Warm-up): Nunca inicie disparando 1.000 mensagens no primeiro dia de um número novo. Comece com 50 mensagens para clientes altamente engajados (que com certeza irão interagir), e dobre o volume a cada 2 dias se o Quality Rating se mantiver verde.
  • Preserve o Propósito do Template: Nunca mude a intenção de um template aprovado. Injetar links promocionais ou propagandas dentro de um template aprovado para "Atualizações Transacionais" causará a suspensão permanente do seu template e prejudicará o número.
  • Evite Loops Infinitos de Automação: Garanta que o fluxo do robô sempre possibilite o transbordo para atendimento humano ou a saída do menu para não frustrar o usuário.

Autenticação

Todas as requisições devem incluir seus tokens de acesso nos cabeçalhos HTTP. Você pode gerar esses tokens em seu dashboard.

Headers Requeridos
X-API-Key: sua_chave_de_api
X-API-Secret: seu_segredo_de_api

Início Rápido

Base URL

Endpoint Principal
https://api.covercut.com.br/api/v1

Webhooks

Nossos webhooks notificam seu sistema em tempo real sobre novas mensagens e mudanças de status.

Configuração

Acesse Configurações > Webhook no dashboard e informe a URL onde deseja receber os dados.

Validar Assinatura (Segurança)

Cada envio contém o header X-BSP-Signature. Use-o para garantir que a mensagem veio de nós.

PHP — Validação de Assinatura
$signature = hash_hmac('sha256', $payload_bruto, $webhook_secret);
if (hash_equals($_SERVER['HTTP_X_BSP_SIGNATURE'], $signature)) {
    // Autêntico
}

Eventos de Mensagem

Exemplo de Payload — Nova Mensagem
{
  "event": "message",
  "direction": "inbound",
  "contact": {
    "wa_id": "5547999999999",
    "user_id": "BR.13491208655302741918",
    "name": "João Silva"
  },
  "message": {
    "id": "wamid...",
    "type": "text",
    "text": "Oi!"
  }
}
Exemplo Completo (Headers + Body)
{
  "headers": {
    "content-type": "application/json",
    "x-bsp-signature": "28a2a4200aaa6c457bfecca27d97f6a0b1dfef32f1bfa64b6aa8bfff2de4c429",
    "x-bsp-timestamp": "1778884885"
  },
  "body": {
    "event": "message",
    "from_number_id": "950147584848138",
    "contact": {
      "wa_id": "554799999999",
      "name": "Sandro"
    },
    "message": {
      "id": "wamid.HBgMNTU0N...",
      "type": "text",
      "text": "Ola"
    }
  }
}

Validar no n8n (Sem Código)

A forma mais simples de validar a segurança no n8n é:

  • Adicione um nó Crypto (Action: Hmac).
  • No campo Value, use: {{ JSON.stringify($json.body) }}.
  • No campo Secret, use seu Webhook Secret do Dashboard.
  • No campo Algorithm, use sha256.
  • Compare o resultado com o header x-bsp-signature.

Sincronização e Coexistência

Quando seu cliente conecta o número mantendo o aplicativo **WhatsApp Business** móvel ativo (Modo Coexistence), a Meta disponibiliza a sincronização do histórico das conversas e contatos salvos no celular. Nossa API recebe esses pacotes e os repassa de forma estruturada para o seu webhook.

Importante: Processamento Assíncrono

O volume de dados enviado no histórico de conversas dos últimos 6 meses pode ser extremamente grande (vários megabytes divididos em pacotes). É fundamental que o seu webhook processe esse evento de forma assíncrona (colocando em uma fila de background) e retorne imediatamente um status 200 OK para evitar que a API sofra timeout.

1. Webhook de Histórico de Conversas (history)

Este webhook é disparado automaticamente pela Meta logo após a conexão inicial do número no modo Coexistence, trazendo todo o histórico de conversas e mensagens dos últimos 6 meses segmentado por threads (conversas de cada contato).

Payload do Webhook — Evento history
{
  "event": "history",
  "from_number_id": "123456789012345",
  "history": {
    "metadata": {
      "phase": 1,
      "chunk_order": 1,
      "progress": 100
    },
    "threads": [
      {
        "id": "5547999999999",
        "context": {
          "wa_id": "5547999999999",
          "username": "sandro_dev",
          "user_id": "US.ENT.11815799212886844830"
        },
        "messages": [
          {
            "from": "5547999999999",
            "to": "5547888888888",
            "id": "wamid.HBgLNTUxMTk5OTk5...",
            "timestamp": "1715802120",
            "type": "text",
            "text": {
              "body": "Olá! Gostaria de saber mais sobre o plano SaaS."
            },
            "history_context": {
              "status": "read"
            }
          },
          {
            "from": "5547888888888",
            "to": "5547999999999",
            "id": "wamid.HBgLNTUxMTk5OTk5X2VjaG8...",
            "timestamp": "1715802180",
            "type": "text",
            "text": {
              "body": "Com certeza! Segue nosso catálogo de recursos."
            },
            "history_context": {
              "status": "sent"
            }
          }
        ]
      }
    ]
  }
}

Campos de Controle e Paginação do Histórico

CampoTipoDescrição
metadata.phaseinteger1: Mensagens mais recentes (entrega rápida);
2: Histórico profundo dos últimos 6 meses.
metadata.chunk_orderintegerOrdenação do pacote recebido (1, 2, 3...). Útil para rastrear a ordem de importação.
metadata.progressintegerPercentual de progresso da sincronização de 0 a 100%.
threads[].idstringIdentificador do contato dono do chat (Telefone ou BSUID).
threads[].contextobjectIdentificadores de privacidade adicionais da Meta (introduzidos em 2026).
messages[].history_context.statusstringO último status conhecido daquela mensagem histórica: sent, delivered, read, ou failed.

2. Webhook de Contatos do Celular (smb_app_state_sync)

Recebido após a sincronização inicial, repassando a agenda telefônica completa do aplicativo WhatsApp Business móvel do cliente.

Payload do Webhook — Evento smb_app_state_sync
{
  "event": "smb_app_state_sync",
  "from_number_id": "123456789012345",
  "smb_app_state_sync": {
    "contacts": [
      {
        "full_name": "Sandro Dev",
        "first_name": "Sandro",
        "phone_number": "5547999999999",
        "username": "sandro_dev",
        "user_id": "US.ENT.11815799212886844830"
      },
      {
        "full_name": "Maria Design",
        "first_name": "Maria",
        "phone_number": "5547988888888",
        "username": "maria_dsgn",
        "user_id": "US.ENT.99815799212886844112"
      }
    ]
  }
}

3. Eventos de Conexão e Offboarding (account_update)

Recebido quando um cliente do modelo Coexistence desinstala, limpa os dados ou re-registra o aplicativo do WhatsApp Business no celular. Esses eventos são cruciais para pausar campanhas de mensagens quando a Cloud API cai e retomá-las automaticamente quando ela volta.

Payload do Webhook — Eventos de account_update
{
  "event": "account_update",
  "timestamp": "2026-05-20T10:00:00-03:00",
  "from_number_id": "123456789012345",
  "account_update": {
    "phone_number": "5547999999999",
    "event": "ACCOUNT_OFFBOARDED" // Pode ser ACCOUNT_OFFBOARDED ou ACCOUNT_RECONNECTED
  }
}

Como Forçar a Sincronização via API

Se você desenvolve um SaaS e deseja forçar o envio imediato desses webhooks pela Meta (útil para acelerar a sincronização logo após a conexão do cliente no seu painel), faça uma requisição para o nosso endpoint dedicado:

POST POST /api/v1/numbers/sync_coexistence
POST https://api.covercut.com.br/api/v1/numbers/sync_coexistence
Headers:
  X-API-Key: sua_chave
  X-API-Secret: seu_segredo
  Content-Type: application/json

Body:
{
  "from": "123456789012345" // phone_number_id dono do número
}
Exemplo de Resposta — 200 OK
{
  "success": true,
  "message": "Sincronização iniciada com sucesso. Os dados serão transmitidos assincronamente em pacotes via Webhook.",
  "results": {
    "contacts": "Iniciado (contacts_sync_req_01)",
    "history": "Iniciado (history_sync_req_02)"
  }
}

4. Webhook de Status com Precificação (v24.0+)

Com as novas regras da Meta (Maio/2026), o webhook de status agora inclui detalhes sobre a cobrança de conversas individuais e de grupos (modelo PMP — Per-Message Pricing).

Payload do Webhook — Evento status
{
  "event": "status",
  "timestamp": "2026-05-19T14:15:00-03:00",
  "from_number_id": "123456789012345",
  "status": {
    "id": "wamid.HBgLNTUxM...",
    "status": "delivered",
    "recipient": "5547999999999",
    "pricing": {
      "billable": true,
      "pricing_model": "PMP",
      "type": "regular",
      "category": "group_marketing"
    }
  }
}

Os campos de precificação são mapeados da seguinte forma:

  • pricing.pricing_model: O modelo de cobrança. Para grupos, sempre retornará PMP (Per-Message Pricing).
  • pricing.type: Pode ser regular (cobrado) ou free_group_customer_service (grátis dentro da janela de serviço do grupo).
  • pricing.category: Categoria da mensagem. Exemplo: group_marketing, group_utility, ou group_service.

5. Webhooks da API de Grupos

Para gerenciar fluxos de grupos, você receberá notificações estruturadas de ciclo de vida, participantes e configurações.

Evento: group_lifecycle_update

Disparado ao criar ou deletar grupos. Contém o link de convite na criação.

{
  "event": "group_lifecycle_update",
  "timestamp": "2026-05-19T14:16:00-03:00",
  "from_number_id": "123456789012345",
  "from_number": "5547999999999",
  "data": {
    "event": "create",
    "group_id": "120363214587@g.us",
    "invite_link": "https://chat.whatsapp.com/L1M2N3O4P5Q6"
  }
}

Evento: group_participants_update

Disparado quando participantes entram ou saem do grupo.

{
  "event": "group_participants_update",
  "timestamp": "2026-05-19T14:17:00-03:00",
  "from_number_id": "123456789012345",
  "from_number": "5547999999999",
  "data": {
    "event": "join",
    "group_id": "120363214587@g.us",
    "participants": [
      {
        "user_id": "BR.874136928504",
        "wa_id": "5547888888888"
      }
    ]
  }
}

Business-Scoped User IDs (BSUID) — Junho 2026

⚠️ CRÍTICO: A partir de 01 de julho de 2026, a Meta descontinuará o envio de mensagens por número de telefone. Todos os webhooks incluirão from_user_id (BSUID) como identificador primário. Seu sistema está preparado para receber mensagens apenas com BSUID, sem número.

O que é BSUID?

BSUID (Business-Scoped User ID) é um identificador único gerado pela Meta para cada par usuário-negócio. Formato: CC.xxxxx (ex: BR.5519999999999) ou o username do WhatsApp (ex: joao.silva).

Estrutura do Webhook com BSUID

Exemplo — Mensagem com BSUID (Julho 2026+)
{
  "event": "message",
  "direction": "inbound",
  "contact": {
    "user_id": "BR.13491208655302741918",
    "username": "joao.silva",
    "name": "João Silva"
  },
  "message": {
    "id": "wamid...",
    "type": "text",
    "text": "Oi, tudo bem?"
  }
}

Transição (Junho 2026) — Dual Mode

Durante a transição, webhooks incluem ambos número e BSUID. Seu sistema escolhe qual usar:

Exemplo — Mensagem com Número + BSUID
{
  "event": "message",
  "direction": "inbound",
  "contact": {
    "wa_id": "5547999999999",      ← número (pode ser NULL em julho)
    "user_id": "BR.xxxxx",          ← BSUID (novo identificador)
    "username": "joao.silva",       ← username opcional
    "name": "João Silva"
  },
  "message": { ... }
}

Recomendações de Implementação

  • Use BSUID como identificador primário: Se user_id estiver presente, use-o. Fallback para wa_id apenas se BSUID não existir.
  • Armazene username: Novos contatos vêm com username — capture e exiba quando disponível.
  • Suporte ambos: Até julho de 2026, você pode receber ambos os campos. Não remova o suporte a números.
  • Teste antes de julho: Ative BSUID em seu Meta Developer Console para testar webhooks SEM número.

Calling API — Webhooks de Chamadas (v25.0+)

Quando usuários ligam para seu número WhatsApp, você recebe webhooks detalhados sobre o evento de chamada com informações completas do chamador, incluindo BSUID e username.

Tipos de Eventos de Chamada

StatusDescrição
incomingChamada entrante iniciada pelo usuário
missedChamada não atendida
rejectedVocê rejeitou a chamada
acceptedVocê aceitou a chamada
connectedConexão estabelecida (início da conversa)
endedChamada finalizada

Exemplo de Webhook — Chamada Recebida

Payload — Nova Chamada Entrante
{
  "event": "call",
  "timestamp": "2026-06-01T10:30:00-03:00",
  "from_number_id": "950147584848138",
  "from_number": "+55 47 9999-9999",
  "call": {
    "id": "call_HBgM...",
    "status": "incoming",
    "duration_seconds": 0,
    "from": "5547999999999",
    "from_user_id": "BR.13491208655302741918",
    "from_username": "joao.silva",
    "from_name": "João Silva",
    "to_user_id": "seu_bsuid_aqui",
    "contacts": [{
      "user_id": "BR.13491208655302741918",
      "username": "joao.silva",
      "profile": {
        "name": "João Silva"
      }
    }]
  }
}

Exemplo — Chamada Finalizada (com duração)

Payload — Chamada Encerrada
{
  "event": "call",
  "timestamp": "2026-06-01T10:35:45-03:00",
  "from_number": "+55 47 9999-9999",
  "call": {
    "id": "call_HBgM...",
    "status": "ended",
    "duration_seconds": 312,     ← 5 minutos 12 segundos
    "from_user_id": "BR.xxxxx",
    "from_username": "joao.silva",
    "from_name": "João Silva"
  }
}

Casos de Uso

  • Rastreamento de chamadas: Armazene call_id, from_user_id, duration_seconds para análise.
  • CRM integration: Sincronize automaticamente chamadas entrantes com seu CRM usando BSUID.
  • Alertas: Notifique agentes sobre chamadas perdidas ou rejeitadas.
  • Relatórios: Gere dashboards de volume de chamadas e duração média por período.

Rastreamento de Origem — Facebook Ads

Quando usuários iniciam conversa através de anúncios do Facebook, você recebe dados detalhados sobre a campanha que gerou o contato. Ideal para análise de ROI e origem de leads.

Campo referral no Webhook

Presente apenas quando o usuário chegou via Facebook Ads ou outro canal de origem Meta:

Exemplo — Mensagem com Referral (Facebook Ads)
{
  "event": "message",
  "direction": "inbound",
  "contact": {
    "wa_id": "5547999999999",
    "user_id": "BR.xxxxx",
    "name": "João Silva"
  },
  "message": {
    "id": "wamid...",
    "type": "text",
    "text": "Poderia me passar mais informações?",
    "referral": {
      "source_type": "ad",
      "source_id": "120249258250040188",
      "source_url": "https://fb.me/6Y5vfFmfx",
      "headline": "Converse conosco",
      "ctwa_clid": "AfgryxuX3no-rLzpWHK9py-sp-..."
    }
  }
}

Campos de Referral

CampoTipoDescrição
source_typestringTipo de origem: "ad", "conversation_referral", etc.
source_idstringID único da campanha/anúncio na Meta.
source_urlstringURL que o usuário clicou para iniciar a conversa.
headlinestringTexto do botão ou copy do anúncio.
ctwa_clidstringID de clique do WhatsApp para rastreamento granular.

Integração com Analytics

  • ROI por Campanha: Agrupe source_id e calcule custo/conversão.
  • Performance por Headline: Compare qual copy do anúncio gera mais engajamento.
  • Atribuição Multi-canal: Cruzar dados com Google Analytics usando ctwa_clid.
Nota: O campo referral só aparece quando o usuário inicia conversa através de um anúncio. Não está presente em mensagens iniciadas manualmente.

Webhook de Alertas

Configure um endpoint separado para receber alertas operacionais como quedas de qualidade ou suspensões.

Mensagens

POST Enviar Mensagem de Texto

Envia uma mensagem de texto simples. Use to para enviar ao número de telefone ou recipient para enviar ao BSUID do usuário (veja IDs de Usuário).

Múltiplos Números Conectados:

Se você possui mais de um número ativo, adicione o parâmetro "from": "ID_DO_SEU_NUMERO" no JSON para especificar por qual canal enviar a mensagem. Caso não seja informado, será utilizado o primeiro número conectado.

POST /api/v1/messages/send (Por Número)
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "text",
  "text": {
    "body": "Olá! Como posso ajudar?"
  }
}
POST /api/v1/messages/send (Por BSUID)
{
  "from": "123456789012345",
  "recipient": "BR.13491208655302741918",
  "type": "text",
  "text": {
    "body": "Olá! Como posso ajudar?"
  }
}

Resposta

JSON — 200 OK
{
  "success": true,
  "message": "Mensagem enviada com sucesso",
  "message_id": "wamid.HBgLNTU0Nzk5...",
  "from": "1234567890",
  "to": "5547999999999",
  "user_id": "BR.13491208655302741918"
}

POST Enviar Imagem

POST /api/v1/messages/send (Via Link)
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "image",
  "image": {
    "link": "https://exemplo.com/imagem.jpg",
    "caption": "Legenda da imagem"
  }
}
POST /api/v1/messages/send (Via Link - Por BSUID)
{
  "from": "123456789012345",
  "recipient": "BR.13491208655302741918",
  "type": "image",
  "image": {
    "link": "https://exemplo.com/imagem.jpg",
    "caption": "Legenda da imagem"
  }
}
POST /api/v1/messages/send (Via Media ID)
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "image",
  "image": {
    "id": "8451871321564",
    "caption": "Legenda opcional"
  }
}
POST /api/v1/messages/send (Via Media ID - Por BSUID)
{
  "from": "123456789012345",
  "recipient": "BR.13491208655302741918",
  "type": "image",
  "image": {
    "id": "8451871321564",
    "caption": "Legenda opcional"
  }
}

POST Enviar Vídeo

POST /api/v1/messages/send (Via Link)
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "video",
  "video": {
    "link": "https://exemplo.com/video.mp4",
    "caption": "Legenda opcional"
  }
}
POST /api/v1/messages/send (Via Link - Por BSUID)
{
  "from": "123456789012345",
  "recipient": "BR.13491208655302741918",
  "type": "video",
  "video": {
    "link": "https://exemplo.com/video.mp4",
    "caption": "Legenda opcional"
  }
}
POST /api/v1/messages/send (Via Media ID)
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "video",
  "video": {
    "id": "8451871321564"
  }
}
POST /api/v1/messages/send (Via Media ID - Por BSUID)
{
  "from": "123456789012345",
  "recipient": "BR.13491208655302741918",
  "type": "video",
  "video": {
    "id": "8451871321564"
  }
}

POST Enviar Áudio

Para enviar um arquivo de áudio simples. Se quiser que o áudio apareça como uma mensagem de voz (voice note gravado na hora), o arquivo deve estar no formato .ogg (codec opus) e você deve incluir o parâmetro "voice": true.

POST /api/v1/messages/send (Via Link)
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "audio",
  "audio": {
    "link": "https://exemplo.com/audio.mp3"
  }
}
POST /api/v1/messages/send (Via Link - Por BSUID)
{
  "from": "123456789012345",
  "recipient": "BR.13491208655302741918",
  "type": "audio",
  "audio": {
    "link": "https://exemplo.com/audio.mp3"
  }
}
POST /api/v1/messages/send (Voice Note via Media ID)
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "audio",
  "audio": {
    "id": "8451871321564",
    "voice": true
  }
}
POST /api/v1/messages/send (Voice Note via Media ID - Por BSUID)
{
  "from": "123456789012345",
  "recipient": "BR.13491208655302741918",
  "type": "audio",
  "audio": {
    "id": "8451871321564",
    "voice": true
  }
}

POST Enviar Documento

POST /api/v1/messages/send (Via Link)
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "document",
  "document": {
    "link": "https://exemplo.com/arquivo.pdf",
    "filename": "documento.pdf"
  }
}
POST /api/v1/messages/send (Via Link - Por BSUID)
{
  "from": "123456789012345",
  "recipient": "BR.13491208655302741918",
  "type": "document",
  "document": {
    "link": "https://exemplo.com/arquivo.pdf",
    "filename": "documento.pdf"
  }
}
POST /api/v1/messages/send (Via Media ID)
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "document",
  "document": {
    "id": "8451871321564",
    "filename": "boleto.pdf"
  }
}
POST /api/v1/messages/send (Via Media ID - Por BSUID)
{
  "from": "123456789012345",
  "recipient": "BR.13491208655302741918",
  "type": "document",
  "document": {
    "id": "8451871321564",
    "filename": "boleto.pdf"
  }
}

POST Enviar Sticker (Figurinha)

POST /api/v1/messages/send (Via Link)
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "sticker",
  "sticker": {
    "link": "https://exemplo.com/figurinha.webp"
  }
}
POST /api/v1/messages/send (Via Link - Por BSUID)
{
  "from": "123456789012345",
  "recipient": "BR.13491208655302741918",
  "type": "sticker",
  "sticker": {
    "link": "https://exemplo.com/figurinha.webp"
  }
}
POST /api/v1/messages/send (Via Media ID)
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "sticker",
  "sticker": {
    "id": "8451871321564"
  }
}
POST /api/v1/messages/send (Via Media ID - Por BSUID)
{
  "from": "123456789012345",
  "recipient": "BR.13491208655302741918",
  "type": "sticker",
  "sticker": {
    "id": "8451871321564"
  }
}

POST Enviar Localização

POST /api/v1/messages/send
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "location",
  "location": {
    "latitude": -26.9195,
    "longitude": -49.0661,
    "name": "Covercut",
    "address": "Rua Exemplo, 123"
  }
}
POST /api/v1/messages/send (Por BSUID)
{
  "from": "123456789012345",
  "recipient": "BR.13491208655302741918",
  "type": "location",
  "location": {
    "latitude": -26.9195,
    "longitude": -49.0661,
    "name": "Covercut",
    "address": "Rua Exemplo, 123"
  }
}

POST Enviar Contato

POST /api/v1/messages/send
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "contacts",
  "contacts": [
    {
      "name": { "formatted_name": "João Silva", "first_name": "João" },
      "phones": [{ "phone": "5547999999999", "type": "CELL" }]
    }
  ]
}
POST /api/v1/messages/send (Por BSUID)
{
  "from": "123456789012345",
  "recipient": "BR.13491208655302741918",
  "type": "contacts",
  "contacts": [
    {
      "name": { "formatted_name": "João Silva", "first_name": "João" },
      "phones": [{ "phone": "5547999999999", "type": "CELL" }]
    }
  ]
}

POST Enviar Reação

POST /api/v1/messages/send
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "reaction",
  "reaction": {
    "message_id": "wamid.xxx",
    "emoji": "👍"
  }
}
POST /api/v1/messages/send (Por BSUID)
{
  "from": "123456789012345",
  "recipient": "BR.13491208655302741918",
  "type": "reaction",
  "reaction": {
    "message_id": "wamid.xxx",
    "emoji": "👍"
  }
}

POST Responder / Citar Mensagem

Para responder uma mensagem específica (fazendo com que ela apareça como citação no balão), inclua o campo context com o message_id (wamid) da mensagem original. Funciona com qualquer tipo de mensagem: texto, imagem, vídeo, áudio, documento, interativo, etc.

O message_id da mensagem recebida chega pelo webhook no campo message.id.

POST /api/v1/messages/send — Responder com texto
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "text",
  "text": {
    "body": "Claro! Vou verificar isso agora mesmo."
  },
  "context": {
    "message_id": "wamid.HBgLNTU0Nzk5OTk5OTk5..."
  }
}
POST /api/v1/messages/send — Responder com texto (Por BSUID)
{
  "from": "123456789012345",
  "recipient": "BR.13491208655302741918",
  "type": "text",
  "text": {
    "body": "Claro! Vou verificar isso agora mesmo."
  },
  "context": {
    "message_id": "wamid.HBgLNTU0Nzk5OTk5OTk5..."
  }
}
POST /api/v1/messages/send — Responder com imagem
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "image",
  "image": {
    "link": "https://exemplo.com/imagem.jpg",
    "caption": "Aqui está o comprovante!"
  },
  "context": {
    "message_id": "wamid.HBgLNTU0Nzk5OTk5OTk5..."
  }
}
POST /api/v1/messages/send — Responder com imagem (Por BSUID)
{
  "from": "123456789012345",
  "recipient": "BR.13491208655302741918",
  "type": "image",
  "image": {
    "link": "https://exemplo.com/imagem.jpg",
    "caption": "Aqui está o comprovante!"
  },
  "context": {
    "message_id": "wamid.HBgLNTU0Nzk5OTk5OTk5..."
  }
}
Como obter o message_id para responder:

Ao receber uma mensagem pelo webhook, o campo message.id contém o wamid. Armazene-o e passe-o no campo context.message_id ao responder. Veja a seção Webhooks para o formato do payload.

POST Enviar Mensagem Interativa

Crie uma experiência dinâmica com menus de lista, botões de resposta rápida ou botões de link externo (CTA URL).

POST Enviar Botões de Resposta Rápida

Envia uma mensagem com até 3 botões de resposta rápida. Ideal para confirmações simples.

POST /api/v1/messages/send
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "interactive",
  "interactive": {
    "type": "button",
    "header": { "type": "text", "text": "Confirmação" },
    "body": { "text": "Você gostaria de agendar agora?" },
    "footer": { "text": "Selecione uma opção" },
    "action": {
      "buttons": [
        { "type": "reply", "reply": { "id": "btn_yes", "title": "Sim" } },
        { "type": "reply", "reply": { "id": "btn_no", "title": "Não" } }
      ]
    }
  }
}
POST /api/v1/messages/send (Por BSUID)
{
  "from": "123456789012345",
  "recipient": "BR.13491208655302741918",
  "type": "interactive",
  "interactive": {
    "type": "button",
    "header": { "type": "text", "text": "Confirmação" },
    "body": { "text": "Você gostaria de agendar agora?" },
    "footer": { "text": "Selecione uma opção" },
    "action": {
      "buttons": [
        { "type": "reply", "reply": { "id": "btn_yes", "title": "Sim" } },
        { "type": "reply", "reply": { "id": "btn_no", "title": "Não" } }
      ]
    }
  }
}

1. Menu de Lista (List Message)

POST /api/v1/messages/send
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "interactive",
  "interactive": {
    "type": "list",
    "header": { "type": "text", "text": "Título do Menu" },
    "body": { "text": "Escolha uma opção abaixo:" },
    "footer": { "text": "Rodapé opcional" },
    "action": {
      "button": "Ver Opções",
      "sections": [
        {
          "title": "Serviços",
          "rows": [
            { "id": "id1", "title": "Corte de Cabelo", "description": "30 minutos" },
            { "id": "id2", "title": "Barba Completa", "description": "20 minutos" }
          ]
        }
      ]
    }
  }
}
POST /api/v1/messages/send (Por BSUID)
{
  "from": "123456789012345",
  "recipient": "BR.13491208655302741918",
  "type": "interactive",
  "interactive": {
    "type": "list",
    "header": { "type": "text", "text": "Título do Menu" },
    "body": { "text": "Escolha uma opção abaixo:" },
    "footer": { "text": "Rodapé opcional" },
    "action": {
      "button": "Ver Opções",
      "sections": [
        {
          "title": "Serviços",
          "rows": [
            { "id": "id1", "title": "Corte de Cabelo", "description": "30 minutos" },
            { "id": "id2", "title": "Barba Completa", "description": "20 minutos" }
          ]
        }
      ]
    }
  }
}

2. Botões de Resposta Rápida (Reply Buttons)

POST /api/v1/messages/send
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "interactive",
  "interactive": {
    "type": "button",
    "body": { "text": "Você gostaria de agendar agora?" },
    "action": {
      "buttons": [
        { "type": "reply", "reply": { "id": "btn_yes", "title": "Sim" } },
        { "type": "reply", "reply": { "id": "btn_no", "title": "Não" } }
      ]
    }
  }
}
POST /api/v1/messages/send (Por BSUID)
{
  "from": "123456789012345",
  "recipient": "BR.13491208655302741918",
  "type": "interactive",
  "interactive": {
    "type": "button",
    "body": { "text": "Você gostaria de agendar agora?" },
    "action": {
      "buttons": [
        { "type": "reply", "reply": { "id": "btn_yes", "title": "Sim" } },
        { "type": "reply", "reply": { "id": "btn_no", "title": "Não" } }
      ]
    }
  }
}

3. Botão de URL (CTA URL)

Envia uma mensagem interativa com um botão que abre um link externo. Este é o novo recurso oficial da Meta que substitui a necessidade de templates para links simples.

POST /api/v1/messages/send
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "interactive",
  "interactive": {
    "type": "cta_url",
    "header": { "type": "text", "text": "Confira nosso site" },
    "body": { "text": "Clique no botão abaixo para ver as ofertas exclusivas que preparamos para você hoje." },
    "footer": { "text": "Ofertas válidas por tempo limitado" },
    "action": {
      "name": "cta_url",
      "parameters": {
        "display_text": "Ver Ofertas",
        "url": "https://sua-loja.com.br/ofertas"
      }
    }
  }
}
POST /api/v1/messages/send (Por BSUID)
{
  "from": "123456789012345",
  "recipient": "BR.13491208655302741918",
  "type": "interactive",
  "interactive": {
    "type": "cta_url",
    "header": { "type": "text", "text": "Confira nosso site" },
    "body": { "text": "Clique no botão abaixo para ver as ofertas exclusivas que preparamos para você hoje." },
    "footer": { "text": "Ofertas válidas por tempo limitado" },
    "action": {
      "name": "cta_url",
      "parameters": {
        "display_text": "Ver Ofertas",
        "url": "https://sua-loja.com.br/ofertas"
      }
    }
  }
}
Notas Importantes:

• O display_text do botão aceita no máximo 20 caracteres.

• O cabeçalho (header) é opcional e aceita text, image, video ou document.

• Este tipo de mensagem não requer aprovação prévia da Meta (diferente de templates).

POST Indicador de Digitação + Marcar como Lida

Em uma única chamada, este endpoint faz duas coisas simultaneamente:

  • Marca a mensagem como lida — o remetente vê os dois tiques azuis (✓✓)
  • Exibe o "digitando..." — o indicador de digitação aparece para o contato

Use o message_id (wamid) recebido no evento de webhook da mensagem inbound.

POST /api/v1/messages/typing
{
  "message_id": "wamid.xxx"
}

Opcional — se tiver múltiplos números, especifique qual usar com o campo from:

Com múltiplos números
{
  "message_id": "wamid.xxx",
  "from": "phone_number_id"
}

POST Carrossel de Mídia Interativo

Envie uma mensagem interativa com 2 a 10 cartões em formato de carrossel horizontal. Cada cartão pode ter uma imagem ou vídeo no cabeçalho, texto no corpo e um botão de URL ou de resposta rápida.

Regras da Meta para Carrosséis:

• A mensagem deve ter entre 2 e 10 cartões.

• O campo body.text principal (acima dos cartões) é obrigatório.

• Cada cartão deve ter cabeçalho do tipo image ou video.

• O tipo e a quantidade de botões deve ser igual em todos os cartões.

Endpoint dedicado

POST /api/v1/messages/carousel
POST https://api.covercut.com.br/api/v1/messages/carousel

Parâmetros

Campo Tipo Obrigatório Descrição
from string Condicional Phone Number ID do remetente. Obrigatório se há múltiplos números conectados.
to string Sim* Telefone do destinatário. Use to ou recipient.
recipient string Sim* BSUID do destinatário. Use to ou recipient.
body.text string Sim Texto principal exibido acima dos cartões.
cards array Sim Array de 2 a 10 cartões do carrossel.
cards[].header.type string Sim image ou video.
cards[].header.image.link string Condicional URL pública da imagem. Use link ou id.
cards[].header.image.id string Condicional Media ID da imagem (upload prévio). Use link ou id.
cards[].body.text string Não Texto descritivo exibido no corpo do cartão.
cards[].action object Sim Botão do cartão — cta_url ou quick_reply (veja exemplos abaixo).

Exemplo 1 — Carrossel com Botão de URL (CTA URL)

POST /api/v1/messages/carousel
{
  "from": "123456789012345",
  "to": "5547999999999",
  "body": {
    "text": "Confira nossas promoções da semana! 🔥"
  },
  "cards": [
    {
      "header": {
        "type": "image",
        "image": {
          "link": "https://exemplo.com/promo1.jpg"
        }
      },
      "body": {
        "text": "Produto A — De R$99 por R$59,90"
      },
      "action": {
        "name": "cta_url",
        "parameters": {
          "display_text": "Ver Produto",
          "url": "https://sua-loja.com.br/produto-a"
        }
      }
    },
    {
      "header": {
        "type": "image",
        "image": {
          "link": "https://exemplo.com/promo2.jpg"
        }
      },
      "body": {
        "text": "Produto B — Frete Grátis acima de R$100"
      },
      "action": {
        "name": "cta_url",
        "parameters": {
          "display_text": "Ver Produto",
          "url": "https://sua-loja.com.br/produto-b"
        }
      }
    }
  ]
}
POST /api/v1/messages/carousel (Por BSUID)
{
  "from": "123456789012345",
  "recipient": "BR.13491208655302741918",
  "body": {
    "text": "Confira nossas promoções da semana! 🔥"
  },
  "cards": [
    {
      "header": {
        "type": "image",
        "image": {
          "link": "https://exemplo.com/promo1.jpg"
        }
      },
      "body": {
        "text": "Produto A — De R$99 por R$59,90"
      },
      "action": {
        "name": "cta_url",
        "parameters": {
          "display_text": "Ver Produto",
          "url": "https://sua-loja.com.br/produto-a"
        }
      }
    },
    {
      "header": {
        "type": "image",
        "image": {
          "link": "https://exemplo.com/promo2.jpg"
        }
      },
      "body": {
        "text": "Produto B — Frete Grátis acima de R$100"
      },
      "action": {
        "name": "cta_url",
        "parameters": {
          "display_text": "Ver Produto",
          "url": "https://sua-loja.com.br/produto-b"
        }
      }
    }
  ]
}

Exemplo 2 — Carrossel com Botões de Resposta Rápida

POST /api/v1/messages/carousel
{
  "from": "123456789012345",
  "to": "5547999999999",
  "body": {
    "text": "Escolha o serviço que deseja agendar 📅"
  },
  "cards": [
    {
      "header": {
        "type": "image",
        "image": {
          "link": "https://exemplo.com/servico-corte.jpg"
        }
      },
      "body": {
        "text": "Corte de Cabelo — R$45,00 (30 min)"
      },
      "action": {
        "buttons": [
          {
            "type": "quick_reply",
            "quick_reply": {
              "id": "agendar_corte",
              "title": "Agendar"
            }
          }
        ]
      }
    },
    {
      "header": {
        "type": "image",
        "image": {
          "link": "https://exemplo.com/servico-barba.jpg"
        }
      },
      "body": {
        "text": "Barba Completa — R$35,00 (20 min)"
      },
      "action": {
        "buttons": [
          {
            "type": "quick_reply",
            "quick_reply": {
              "id": "agendar_barba",
              "title": "Agendar"
            }
          }
        ]
      }
    },
    {
      "header": {
        "type": "image",
        "image": {
          "link": "https://exemplo.com/servico-combo.jpg"
        }
      },
      "body": {
        "text": "Combo Completo — R$70,00 (50 min)"
      },
      "action": {
        "buttons": [
          {
            "type": "quick_reply",
            "quick_reply": {
              "id": "agendar_combo",
              "title": "Agendar"
            }
          }
        ]
      }
    }
  ]
}
POST /api/v1/messages/carousel (Por BSUID)
{
  "from": "123456789012345",
  "recipient": "BR.13491208655302741918",
  "body": {
    "text": "Escolha o serviço que deseja agendar 📅"
  },
  "cards": [
    {
      "header": {
        "type": "image",
        "image": {
          "link": "https://exemplo.com/servico-corte.jpg"
        }
      },
      "body": {
        "text": "Corte de Cabelo — R$45,00 (30 min)"
      },
      "action": {
        "buttons": [
          {
            "type": "quick_reply",
            "quick_reply": {
              "id": "agendar_corte",
              "title": "Agendar"
            }
          }
        ]
      }
    },
    {
      "header": {
        "type": "image",
        "image": {
          "link": "https://exemplo.com/servico-barba.jpg"
        }
      },
      "body": {
        "text": "Barba Completa — R$35,00 (20 min)"
      },
      "action": {
        "buttons": [
          {
            "type": "quick_reply",
            "quick_reply": {
              "id": "agendar_barba",
              "title": "Agendar"
            }
          }
        ]
      }
    },
    {
      "header": {
        "type": "image",
        "image": {
          "link": "https://exemplo.com/servico-combo.jpg"
        }
      },
      "body": {
        "text": "Combo Completo — R$70,00 (50 min)"
      },
      "action": {
        "buttons": [
          {
            "type": "quick_reply",
            "quick_reply": {
              "id": "agendar_combo",
              "title": "Agendar"
            }
          }
        ]
      }
    }
  ]
}

Resposta

JSON — 200 OK
{
  "success": true,
  "message": "Carrossel enviado com sucesso",
  "message_id": "wamid.HBgLNTU0Nzk5...",
  "from": "123456789012345",
  "to": "5547999999999",
  "user_id": "BR.13491208655302741918"
}
Atenção — Consistência de Botões:

Todos os cartões do carrossel devem usar o mesmo tipo e a mesma quantidade de botões. Por exemplo, se o primeiro cartão tem 1 botão quick_reply, todos os demais cartões também devem ter exatamente 1 botão quick_reply. Misturar cta_url com quick_reply resultará em erro.

Mensagens de Catálogo e Produto

Envie produtos do seu catálogo do WhatsApp diretamente na conversa — sem precisar de template aprovado. Use o endpoint dedicado:

Endpoint
POST https://api.covercut.com.br/api/v1/messages/catalog
Pré-requisitos e Limitações:
  • Catálogo vinculado: Crie o catálogo no Commerce Manager e vincule ao WABA do número antes de usar.
  • catalog_id e SKUs: O catalog_id e os product_retailer_id (SKUs) são obtidos no Commerce Manager da Meta.
  • Janela de 24h: Esses tipos de mensagem só podem ser enviados dentro da janela de atendimento ativa (o cliente precisa ter iniciado uma conversa nas últimas 24h). Fora da janela, use um Template de Catálogo aprovado.

POST Produto Único (Single Product)

Exibe um card interativo com um único produto do catálogo. O cliente pode ver detalhes, adicionar ao carrinho e iniciar o checkout.

POST /api/v1/messages/catalog
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "product",
  "body": {
    "text": "Confira este produto em promoção!"
  },
  "footer": {
    "text": "Estoque limitado"
  },
  "action": {
    "catalog_id": "SEU_CATALOG_ID",
    "product_retailer_id": "SKU_DO_PRODUTO"
  }
}
POST /api/v1/messages/catalog (Por BSUID)
{
  "from": "123456789012345",
  "recipient": "BR.13491208655302741918",
  "type": "product",
  "body": {
    "text": "Confira este produto em promoção!"
  },
  "footer": {
    "text": "Estoque limitado"
  },
  "action": {
    "catalog_id": "SEU_CATALOG_ID",
    "product_retailer_id": "SKU_DO_PRODUTO"
  }
}
Campos opcionais:

body, footer e header são opcionais no produto único. O card do produto (imagem, título e preço) é exibido automaticamente a partir do catálogo.

POST Multi-Produtos (Product List)

Exibe uma lista com até 30 produtos organizados em até 10 seções. Ideal para vitrines e recomendações personalizadas.

POST /api/v1/messages/catalog
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "product_list",
  "header": {
    "type": "text",
    "text": "Produtos em Destaque"
  },
  "body": {
    "text": "Selecionamos estes itens especialmente para você 🛍️"
  },
  "footer": {
    "text": "Frete grátis acima de R$200"
  },
  "action": {
    "catalog_id": "SEU_CATALOG_ID",
    "sections": [
      {
        "title": "Mais Vendidos",
        "product_items": [
          { "product_retailer_id": "SKU_1" },
          { "product_retailer_id": "SKU_2" },
          { "product_retailer_id": "SKU_3" }
        ]
      },
      {
        "title": "Novidades",
        "product_items": [
          { "product_retailer_id": "SKU_4" },
          { "product_retailer_id": "SKU_5" }
        ]
      }
    ]
  }
}
POST /api/v1/messages/catalog (Por BSUID)
{
  "from": "123456789012345",
  "recipient": "BR.13491208655302741918",
  "type": "product_list",
  "header": {
    "type": "text",
    "text": "Produtos em Destaque"
  },
  "body": {
    "text": "Selecionamos estes itens especialmente para você 🛍️"
  },
  "footer": {
    "text": "Frete grátis acima de R$200"
  },
  "action": {
    "catalog_id": "SEU_CATALOG_ID",
    "sections": [
      {
        "title": "Mais Vendidos",
        "product_items": [
          { "product_retailer_id": "SKU_1" },
          { "product_retailer_id": "SKU_2" },
          { "product_retailer_id": "SKU_3" }
        ]
      },
      {
        "title": "Novidades",
        "product_items": [
          { "product_retailer_id": "SKU_4" },
          { "product_retailer_id": "SKU_5" }
        ]
      }
    ]
  }
}

POST Catálogo Completo (Catalog Message)

Envia um botão que abre o catálogo completo do negócio no WhatsApp. O parâmetro thumbnail_product_retailer_id é opcional e define qual produto aparece como capa.

POST /api/v1/messages/catalog
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "catalog_message",
  "body": {
    "text": "Confira todo o nosso catálogo com preços e disponibilidade em tempo real! 🛒"
  },
  "footer": {
    "text": "Entrega para todo o Brasil"
  },
  "action": {
    "name": "catalog_message",
    "parameters": {
      "thumbnail_product_retailer_id": "SKU_CAPA"
    }
  }
}
POST /api/v1/messages/catalog (Por BSUID)
{
  "from": "123456789012345",
  "recipient": "BR.13491208655302741918",
  "type": "catalog_message",
  "body": {
    "text": "Confira todo o nosso catálogo com preços e disponibilidade em tempo real! 🛒"
  },
  "footer": {
    "text": "Entrega para todo o Brasil"
  },
  "action": {
    "name": "catalog_message",
    "parameters": {
      "thumbnail_product_retailer_id": "SKU_CAPA"
    }
  }
}

Resposta (todos os tipos)

JSON — 200 OK
{
  "success": true,
  "message": "Mensagem de catálogo enviada com sucesso",
  "message_id": "wamid.HBgLNTU0Nzk5...",
  "from": "123456789012345",
  "to": "5547999999999"
}

GET Consultar Status da Mensagem

Consulte o status de entrega das mensagens enviadas pelo seu número. Use este endpoint para sincronizar os status sent, delivered, read e failed com o seu banco de dados.

GET /api/v1/messages/status
GET https://api.covercut.com.br/api/v1/messages/status

Parâmetros de Query

ParâmetroTipoDescrição
wamidstringID único da mensagem (WAID).
statusstringFiltra por: sent, delivered, read ou failed.
limitintegerQuantidade por página (Padrão 50, Máx 100).
Exemplo de Resposta — 200 OK
{
  "success": true,
  "messages": [
    {
      "wamid": "wamid.HBgLNTUxMTk5OTk5OTk5...",
      "status": "read",
      "recipient": "5511999990000",
      "created_at": "2025-01-10 14:32:00"
    }
  ]
}

GET Exportar Logs (CSV)

Gere e baixe um arquivo .csv completo contendo o histórico de mensagens, facilitando a importação em ferramentas de BI, ERPs ou CRMs para retenção própria.

GET /api/v1/messages/export
GET https://api.covercut.com.br/api/v1/messages/export

Parâmetros de Query Opcionais

ParâmetroTipoDescrição
statusstringFiltra por: sent, delivered, read ou failed.
fromstringFiltra pelo número de origem que enviou a mensagem.
recipientstringFiltra pelo telefone de destino.
sincestringData de início. Formato YYYY-MM-DD (Ex: 2026-05-01).
untilstringData final. Formato YYYY-MM-DD (Ex: 2026-05-31).
Exemplo de Requisição (cURL)
curl -X GET "https://api.covercut.com.br/api/v1/messages/export?since=2026-05-01&until=2026-05-31" \
     -H "X-API-Key: sua-chave-api" \
     -H "X-API-Secret: seu-secret-api" \
     --output logs_maio.csv

Gestão de Templates

Crie, gerencie e envie templates de mensagem aprovados pela Meta.

Enviar Template

Inicie conversas com mensagens pré-aprovadas. Use to (telefone) ou recipient (BSUID) como destino.

Quando usar o campo components?

O campo components serve para preencher variáveis dinâmicas do seu template (exemplo: {{1}}, {{2}}) ou para enviar arquivos de mídia no cabeçalho.

  • Se o seu template for apenas um texto fixo (sem variáveis e sem arquivos), você não precisa enviar o components no JSON. Basta enviar apenas o nome e o idioma.
  • Se o seu template tiver variáveis no texto, você deve enviar o type: body preenchendo cada variável.
  • Se o seu template não tiver variáveis no texto, mas exigir um arquivo de imagem/vídeo/documento, você deve enviar apenas o type: header com o link/id do arquivo.

Template sem variáveis (texto fixo)

Quando o template não possui nenhuma variável ({{1}}, {{2}}…) nem cabeçalho de mídia, basta enviar o name e o language. O campo components é completamente opcional nesse caso.

POST /api/v1/messages/template (sem variáveis)
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "template",
  "template": {
    "name": "boas_vindas",
    "language": { "code": "pt_BR" }
  }
}

Template com variáveis no texto

Quando o template contém variáveis ({{1}}, {{2}}…), envie o componente body com os valores que substituirão cada variável, na mesma ordem.

POST /api/v1/messages/template (com variáveis)
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "template",
  "template": {
    "name": "confirmacao_pedido",
    "language": { "code": "pt_BR" },
    "components": [
      {
        "type": "body",
        "parameters": [
          { "type": "text", "text": "João Silva" },
          { "type": "text", "text": "#4521" }
        ]
      }
    ]
  }
}

Templates com Mídia (Imagem/Vídeo/Documento)

Para templates que possuem cabeçalho de mídia, use o componente header. Se ele não tiver variáveis de texto, remova o bloco body do exemplo abaixo:

Exemplo: Template com Vídeo
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "template",
  "template": {
    "name": "video_promo",
    "language": { "code": "pt_BR" },
    "components": [
      {
        "type": "header",
        "parameters": [
          {
            "type": "video",
            "video": { "link": "https://suisite.com/video.mp4" }
          }
        ]
      },
      {
        "type": "body",
        "parameters": [
          { "type": "text", "text": "Sandro" }
        ]
      }
    ]
  }
}

Templates com Botões Dinâmicos

Templates podem ter botões de Call to Action (Link/Telefone), Quick Reply ou Copy Code (copiar código).

Exemplo: Botão URL Dinâmico
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "template",
  "template": {
    "name": "confirmacao_agendamento",
    "language": { "code": "pt_BR" },
    "components": [
      {
        "type": "body",
        "parameters": [{ "type": "text", "text": "15/05 às 14h" }]
      },
      {
        "type": "button",
        "sub_type": "url",
        "index": 0,
        "parameters": [
          { "type": "text", "text": "agendar/id_123" }
        ]
      }
    ]
  }
}

Botão Copiar Código (Copy Code)

Permite que o cliente toque num botão e o código seja copiado automaticamente para a área de transferência — ideal para chaves PIX, cupons ou códigos de acesso.

Restrições confirmadas pela Meta: exclusivo para categoria MARKETING. O texto do botão é fixo ("Copiar código da oferta") e não pode ser customizado. A interface do Meta Business Manager não exibe essa opção — o template deve ser criado via nossa plataforma ou pela API. Não funciona no WhatsApp Web.
1. Criar o template (via nossa plataforma)

No dashboard, crie um template de categoria Marketing e adicione um botão "Copiar Código (Cupom)". O payload enviado à Meta será:

Criar template com botão COPY_CODE
{
  "from": "123456789012345",
  "name": "cupom_desconto",
  "category": "MARKETING",
  "language": "pt_BR",
  "components": [
    {
      "type": "BODY",
      "text": "Olá, {{1}}! Use o código abaixo para obter {{2}} de desconto.",
      "example": {
        "body_text": [["João", "20%"]]
      }
    },
    {
      "type": "BUTTONS",
      "buttons": [
        {
          "type": "COPY_CODE",
          "example": ["DESCONTO20"]
        }
      ]
    }
  ]
}
2. Enviar a mensagem

Após aprovação, passe o código real no parâmetro coupon_code. O parâmetro usa "type": "coupon_code" (não "text").

Enviar mensagem com botão Copiar Código
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "template",
  "template": {
    "name": "cupom_desconto",
    "language": { "code": "pt_BR" },
    "components": [
      {
        "type": "body",
        "parameters": [
          { "type": "text", "text": "João" },
          { "type": "text", "text": "20%" }
        ]
      },
      {
        "type": "button",
        "sub_type": "copy_code",
        "index": 0,
        "parameters": [
          { "type": "coupon_code", "coupon_code": "DESCONTO20" }
        ]
      }
    ]
  }
}
Limitações: código limitado a 15 caracteres. Apenas 1 botão COPY_CODE por template. Não funciona no WhatsApp Web. A Meta pode rejeitar templates cujo conteúdo seja transacional (ex: cobrança PIX) — o botão é destinado a cupons e ofertas promocionais.

Templates de Solicitação de Pagamento (Brasil)

Permite que comerciantes solicitem pagamentos via PIX dinâmico, Boleto ou Link de pagamento diretamente na conversa do WhatsApp, sem necessidade da integração de Detalhes do Pedido. Disponível para categorias Marketing e Utilidade.

Vantagens: até 3 botões de pagamento por template (um de cada tipo); integração simplificada — o código/link real é enviado dinamicamente ao disparar a mensagem; combina com outros tipos de botões e com modelos de oferta por tempo limitado.

1. Criar o template

No dashboard selecione o botão "Solicitação de Pagamento (BR)" e escolha o tipo. O texto do botão é fixado pela Meta conforme o tipo escolhido.

TipoTexto fixo do botãoCampo obrigatório no envio
pix_dynamic_codeCopy Pix codepix_dynamic_code.code
boletoCopy Boleto codeboleto.digitable_line
payment_linkOpen payment linkpayment_link.uri
Criar template com 3 botões de pagamento
{
  "from": "123456789012345",
  "name": "cobranca_pagamento",
  "category": "UTILITY",
  "language": "pt_BR",
  "components": [
    {
      "type": "BODY",
      "text": "Olá, {{1}}! Sua fatura de R$ {{2}} está disponível. Escolha a forma de pagamento:"
    },
    {
      "type": "BUTTONS",
      "buttons": [
        {
          "type": "PAYMENT_REQUEST",
          "text": "Copy Pix code",
          "payment_setting": {
            "type": "pix_dynamic_code",
            "pix_dynamic_code": { "code": "00020101021226700014br.gov.bcb.pix..." }
          }
        },
        {
          "type": "PAYMENT_REQUEST",
          "text": "Copy Boleto code",
          "payment_setting": {
            "type": "boleto",
            "boleto": { "digitable_line": "03399026944140000002628346101018898510000008848" }
          }
        },
        {
          "type": "PAYMENT_REQUEST",
          "text": "Open payment link",
          "payment_setting": {
            "type": "payment_link",
            "payment_link": { "uri": "https://exemplo.com/pagar/123" }
          }
        }
      ]
    }
  ]
}

2. Enviar a mensagem

O código/link real é passado nos parâmetros do botão com sub_type: "payment_request". O index corresponde à posição do botão (0, 1, 2).

Enviar mensagem com botões de pagamento
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "template",
  "template": {
    "name": "cobranca_pagamento",
    "language": { "code": "pt_BR" },
    "components": [
      {
        "type": "body",
        "parameters": [
          { "type": "text", "text": "João" },
          { "type": "text", "text": "150,00" }
        ]
      },
      {
        "type": "button",
        "sub_type": "payment_request",
        "index": "0",
        "parameters": [{
          "type": "action",
          "action": {
            "payment_request": {
              "payment_setting": {
                "type": "pix_dynamic_code",
                "pix_dynamic_code": { "code": "00020101021226700014br.gov.bcb.pix..." }
              }
            }
          }
        }]
      },
      {
        "type": "button",
        "sub_type": "payment_request",
        "index": "1",
        "parameters": [{
          "type": "action",
          "action": {
            "payment_request": {
              "payment_setting": {
                "type": "boleto",
                "boleto": { "digitable_line": "03399026944140000002628346101018898510000008848" }
              }
            }
          }
        }]
      },
      {
        "type": "button",
        "sub_type": "payment_request",
        "index": "2",
        "parameters": [{
          "type": "action",
          "action": {
            "payment_request": {
              "payment_setting": {
                "type": "payment_link",
                "payment_link": { "uri": "https://exemplo.com/pagar/123" }
              }
            }
          }
        }]
      }
    ]
  }
}

Template Detalhes do Pedido (Brasil)

Template com formato especial ORDER_DETAILS que exibe itens do pedido, subtotal, impostos e opções de pagamento (PIX, Boleto, Link). Ideal para faturas e cobranças detalhadas. Disponível para categorias Marketing e Utilidade.

1. Criar o template

No dashboard selecione Formato: Detalhes do Pedido. O botão ORDER_DETAILS é adicionado automaticamente.

Criar template Order Details
{
  "from": "123456789012345",
  "name": "fatura_detalhada",
  "category": "UTILITY",
  "language": "pt_BR",
  "display_format": "ORDER_DETAILS",
  "components": [
    {
      "type": "HEADER",
      "format": "DOCUMENT",
      "text": "Sua Fatura"
    },
    {
      "type": "BODY",
      "text": "Olá, {{1}}! Segue sua fatura. Escolha a forma de pagamento."
    },
    {
      "type": "BUTTONS",
      "buttons": [
        { "type": "ORDER_DETAILS", "text": "Ver detalhes do pedido" }
      ]
    }
  ]
}

2. Enviar a mensagem

O payload de envio inclui os itens do pedido, valores e o código de pagamento no componente do botão com sub_type: "order_details". Os valores usam offset: 100 (centavos).

Enviar mensagem Order Details com PIX dinâmico
{
  "from": "123456789012345",
  "to": "5547999999999",
  "type": "template",
  "template": {
    "name": "fatura_detalhada",
    "language": { "code": "pt_BR" },
    "components": [
      {
        "type": "body",
        "parameters": [
          { "type": "text", "text": "João" }
        ]
      },
      {
        "type": "button",
        "sub_type": "order_details",
        "index": 0,
        "parameters": [{
          "type": "action",
          "action": {
            "order_details": {
              "reference_id": "PEDIDO-001-2026",
              "type": "digital-goods",
              "payment_type": "br",
              "payment_settings": [{
                "type": "pix_dynamic_code",
                "pix_dynamic_code": {
                  "code": "00020101021226700014br.gov.bcb.pix...",
                  "merchant_name": "Empresa LTDA",
                  "key": "39580525000189",
                  "key_type": "CNPJ"
                }
              }],
              "currency": "BRL",
              "total_amount": { "value": 15000, "offset": 100 },
              "order": {
                "status": "pending",
                "items": [{
                  "retailer_id": "PROD-001",
                  "name": "Plano Mensal",
                  "amount": { "value": 15000, "offset": 100 },
                  "quantity": 1
                }],
                "subtotal": { "value": 15000, "offset": 100 },
                "tax": { "value": 0, "offset": 100, "description": "Sem impostos" }
              }
            }
          }
        }]
      }
    ]
  }
}
Offset: todos os valores monetários usam offset: 100 — ou seja, "value": 15000 = R$ 150,00. O campo reference_id deve ser único por pedido para rastreamento. Tipos de chave PIX aceitos: CNPJ, CPF, EMAIL, PHONE, RANDOM.

Enviar Template de Marketing

Endpoint dedicado (alias) para disparo de Custom Marketing Templates, com suporte a parâmetros nomeados.

POST /api/v1/messages/marketing
{
  "from": "123456789012345",
  "to": "5547999999999",
  "template": {
    "name": "oferta_especial_maio",
    "language": { "code": "pt_BR" },
    "components": [
      {
        "type": "body",
        "parameters": [
          { "type": "text", "parameter_name": "discount_code", "text": "BEMVINDO20" },
          { "type": "text", "parameter_name": "discount_amount", "text": "20%" }
        ]
      }
    ]
  }
}

Listar Templates da Meta

Consulte todos os templates de mensagem cadastrados na sua conta WABA diretamente da Meta. Este endpoint retorna o status de aprovação, categoria e componentes de cada template.

GET Listar Templates

Requer Autenticação

Este endpoint exige o envio do seu Token de API no cabeçalho da requisição (Authorization: Bearer SEU_TOKEN).

GET /api/v1/templates/list
GET https://api.covercut.com.br/api/v1/templates/list

Upload de Exemplo (Mídia)

A Meta exige que templates com cabeçalho de mídia (imagem, vídeo ou documento) possuam um arquivo de exemplo. Use este endpoint para obter o header_handle necessário para a criação do template.

POST Obter Handle

POST /api/v1/media/upload_handle
POST https://api.covercut.com.br/api/v1/media/upload_handle

Request Body (Multipart)

CampoTipoDescrição
filefileO arquivo de imagem/vídeo (Máx 5MB).
fromstringO phone_number_id que será dono do template.
Exemplo de Resposta — 200 OK
{
  "success": true,
  "header_handle": "h/4_C_A0B1C2D3E4F5G6H7I8J9K0L1M2N3O4P5Q6"
}

Criar Template

Envia um novo template de mensagem para análise da Meta. Você deve especificar a categoria (MARKETING ou UTILITY) e os componentes (HEADER, BODY, FOOTER, BUTTONS).

POST Criar Template

O endpoint de criação aceita variáveis tanto Posicionais (ex: {{1}}, {{2}}) quanto Nomeadas (ex: {{nome}}, {{pedido_id}}).

Limites e Regras da Meta
  • Tamanhos máximos: Cabeçalho (60 caracteres), Corpo (1024 caracteres), Rodapé (60 caracteres).
  • Formato de Variáveis Nomeadas: Apenas letras minúsculas, números e sublinhados (ex: {{customer_name}}). Letras maiúsculas ou espaços resultarão em erro.
  • Exemplos: Todo componente com variável precisa do campo example. O formato do exemplo muda caso use variáveis nomeadas.
POST /api/v1/templates/create
POST https://api.covercut.com.br/api/v1/templates/create

Exemplo Payload (Variáveis Posicionais - Padrão)

{
  "name": "boas_vindas",
  "category": "MARKETING",
  "language": "pt_BR",
  "components": [
    {
      "type": "BODY",
      "text": "Olá {{1}}, bem-vindo!",
      "example": {
        "body_text": [ ["João"] ]
      }
    }
  ]
}

Exemplo Payload (Variáveis Nomeadas)

Quando utilizar nomes nas variáveis, é obrigatório enviar "parameter_format": "NAMED" e o bloco example muda para um array de objetos.

{
  "name": "boas_vindas_nomeado",
  "category": "MARKETING",
  "language": "pt_BR",
  "parameter_format": "NAMED",
  "components": [
    {
      "type": "BODY",
      "text": "Olá {{nome_cliente}}, bem-vindo!",
      "example": {
        "body_text_named_params": [
          { "param_name": "nome_cliente", "example": "João" }
        ]
      }
    }
  ]
}

Criar Template de Marketing (Simplificado)

Versão simplificada para criação rápida de templates promocionais com suporte nativo a botões de CTA.

POST Criar Marketing

POST /api/v1/templates/marketing/create
{
  "name": "oferta_especial_maio",
  "language": "pt_BR",
  "components": [
    {
      "type": "BODY",
      "text": "Temos uma oferta especial para você!"
    }
  ]
}

Editar Template

Atualiza o conteúdo de um template existente. Note que templates em uso podem exigir nova análise da Meta após a edição.

POST Editar Template

POST /api/v1/templates/update
{
  "template_id": "111222333444555",
  "components": [
    {
      "type": "BODY",
      "text": "Novo texto do corpo do template"
    }
  ]
}

Excluir Template

Remove permanentemente um template da sua conta WABA.

DELETE Excluir

DELETE /api/v1/templates/delete
{
  "name": "nome_do_template_a_excluir"
}

Baixar Mídia

Use este endpoint para baixar arquivos recebidos via Webhook. A API resolve a autenticação com a Meta automaticamente.

GET Obter Mídia

Endpoint
GET /api/v1/media/get?id={media_id}&from={phone_number_id}
Autenticação Obrigatória: Mesmo sendo uma requisição GET, você deve enviar os headers X-API-Key e X-API-Secret.

Parâmetro from (Recomendado): Identificador do número que recebeu a mídia. Obrigatório se você gerencia múltiplos números para garantir o uso do token correto. Pode ser o phone_number_id ou o número completo.

Adicione &mode=stream para receber o arquivo binário direto (download).

POST Fazer Upload de Mídia

Use este endpoint para enviar um arquivo para os servidores da Meta. O upload permite que você use o media_id para enviar mensagens, o que é mais rápido e confiável que o uso de links externos.

Opção 1: Formulário (multipart/form-data)

POST /api/v1/media/upload
Content-Type: multipart/form-data

file: [arquivo físico]
from: [phone_number_id - obrigatório se tiver mais de um número]

Opção 2: JSON com Base64 (Ideal para IA)

Se você possui o conteúdo do arquivo em Base64 (comum em IAs de áudio), pode enviar diretamente via JSON:

POST /api/v1/media/upload
Content-Type: application/json

{
  "file_base64": "T2dnUwACAAAAAAAA...",
  "filename": "audio.ogg",
  "filetype": "audio/ogg",
  "from": "phone_number_id" // Obrigatório se tiver mais de um número
}
Resposta
{
  "success": true,
  "message": "Upload concluído com sucesso",
  "media_id": "8451871321564"
}

Integração com n8n

Como Fazer Upload de Arquivos (POST)

Se você utiliza o n8n e precisa fazer o upload de um arquivo gerado em nós anteriores (como áudios do ElevenLabs), configure o seu nó HTTP Request da seguinte maneira:

  • Method: POST
  • Send Body: Habilitado
  • Body Content Type: Form-Data (muito importante!)
  • Specify Body: Using Fields Below
Atenção para Múltiplos Números:

Se você tiver mais de um número conectado e estiver fazendo o envio de arquivos (imagem, áudio, vídeo ou PDF) pelo n8n, é obrigatório incluir o campo from no body. Isso é necessário para que o sistema saiba de qual número está sendo feito o upload para a Meta.

Em Body Parameters, adicione os seguintes campos:

Nome: file
Tipo (Type): n8n Binary Data / Binary File
Input Data Field Name: data (ou o nome da propriedade onde está o arquivo)

Nome: from (Obrigatório se tiver mais de um número)
Tipo (Type): Text
Value: Seu ID do Número

Como Baixar Arquivos (GET)

Configure o nó HTTP Request com o Method GET, inclua seus Headers de autenticação (X-API-Key) e marque a opção Response Format como File para o n8n extrair a mídia perfeitamente.

Gestão de Grupos

Gerencie grupos onde o seu número de negócio é administrador ou membro. Você pode listar grupos, criar novos e gerenciar links de convite.

Elegibilidade e Requisitos de Grupos:

A API de Grupos da Meta está disponível exclusivamente para contas comerciais oficiais (Official Business Account - OBA) na Cloud API tradicional. Ela NÃO está disponível para números que utilizam o aplicativo móvel WhatsApp Business ou que estão no modelo de Coexistência (Multi-solution Conversations).

Limites e Restrições Oficiais (Meta):
  • Capacidade: Máximo de 8 participantes por grupo.
  • Quantidade: Máximo de 10.000 grupos por número comercial.
  • Negócios: Apenas 1 número comercial Cloud API (WABA) por grupo.
  • Mensagens Não Suportadas: Chamadas (Calling), mensagens temporárias, visualização única (view-once), mensagens de autenticação, mensagens de comércio e mensagens interativas.
  • Ações Não Suportadas: Esconder lista de participantes por administradores, editar mensagens e deletar mensagens.
Fluxo de Convite (Invite-only):

Por políticas de privacidade da Meta, sistemas não podem adicionar usuários diretamente em grupos. Você deve seguir este fluxo:

  1. Crie o grupo usando o endpoint /api/v1/groups/create. A resposta do webhook conterá o evento group_lifecycle_update com o link de convite (invite_link).
  2. Crie um modelo de mensagem (Template) do tipo especial "Group invite upon request" no Gerenciador de Negócios e aguarde a aprovação da Meta.
  3. Envie esse template de convite para o usuário final via API informando os parâmetros do grupo (JID, nome e ícone).
  4. Quando o usuário aceitar o convite e entrar no grupo, o seu sistema receberá a confirmação através do webhook group_participants_update.

POST Criar Grupo

Cria um novo grupo no WhatsApp e define as configurações iniciais.

POST /api/v1/groups/create
{
  "from": "PHONE_NUMBER_ID", // Opcional
  "subject": "Nome do Grupo",
  "description": "Descrição do grupo (opcional)",
  "join_approval_mode": "auto_approve" // "auto_approve" ou "approval_required"
}

GET / POST Link de Convite

Obtenha ou resete o link de convite do grupo.

Obter Link — GET

GET /api/v1/groups/invite_link
GET /api/v1/groups/invite_link?group_id=GROUP_ID&from=PHONE_NUMBER_ID

Resetar Link — POST

POST /api/v1/groups/invite_link
{
  "from": "PHONE_NUMBER_ID", // Opcional
  "group_id": "ID_DO_GRUPO"
}

POST Enviar para Grupo

Funcionalidade oficial da Meta para comunicação em grupos. Envie mensagens de texto livre, arquivos ou templates aprovados. Lembre-se de definir recipient_type: group.

POST /api/v1/messages/send — Grupo (Texto)
{
  "from": "123456789012345",
  "recipient_type": "group",
  "to": "120363214587@g.us",
  "type": "text",
  "text": { "body": "Olá grupo!" }
}
POST /api/v1/messages/send — Grupo (Template de Convite)
{
  "from": "123456789012345",
  "recipient_type": "individual",
  "to": "5547999999999",
  "type": "template",
  "template": {
    "name": "seu_template_convite",
    "language": { "code": "pt_BR" },
    "components": [
      {
        "type": "body",
        "parameters": [
          {
            "type": "group_invite_link",
            "group_invite_link": {
              "group_jid": "120363214587@g.us",
              "group_name": "Grupo Oficial Covercut",
              "group_icon": "8451871321564"
            }
          }
        ]
      }
    ]
  }
}
Modelo de Faturamento de Grupos (PMP):

O envio de mensagens para grupos segue a precificação baseada em entrega individual (Per-Message Pricing):

  • Você é cobrado por cada mensagem que for efetivamente entregue a um participante do grupo (e não por um custo fixo único).
  • O valor unitário por participante segue a tabela correspondente do país e operadora do participante (código DDI).
  • Sem descontos de volume: Mensagens de utilidade para grupos (Group utility messages) não qualificam para faixas de desconto por volume comercial na Meta.
Janelas de Serviço em Grupos:

Diferente de conversas 1:1 onde cada usuário tem sua própria janela de 24h:

  • Se qualquer participante enviar uma mensagem no grupo, uma janela de serviço de 24h é aberta para todo o grupo.
  • Dentro dessa janela de 24h, você pode enviar mensagens de texto livre (freeform) e templates de utilidade para o grupo totalmente grátis.
  • Mensagens de Marketing e Autenticação são sempre pagas, mesmo que enviadas dentro da janela ativa.
Métricas de Performance de Templates:

A Meta não disponibiliza métricas de performance (como taxa de leitura ou entrega) para modelos de mensagens (Templates) que forem disparados em grupos. Se você precisar rastrear esses dados, crie templates separados e exclusivos para envios de grupos.

GET Listar Grupos

Retorna uma lista de todos os grupos em que o número de telefone do BSP é membro.

GET /api/v1/groups/list
GET /api/v1/groups/list

GET Informações do Grupo

Retorna os detalhes de um grupo (assunto, descrição, participantes, modo de aprovação, etc).

GET /api/v1/groups/info
GET /api/v1/groups/info?group_id=GROUP_ID&from=PHONE_NUMBER_ID

DELETE Excluir Grupo

Exclui o grupo permanentemente da sua conta do WhatsApp Business.

DELETE /api/v1/groups/delete
{
  "from": "PHONE_NUMBER_ID", // Opcional
  "group_id": "ID_DO_GRUPO"
}

Códigos de Erro de Grupos

Abaixo estão listados os códigos de erro específicos retornados pela Meta em operações da Groups API. Utilize esta referência para tratamento de exceções no seu sistema.

Código Erro / Status HTTP Descrição / Solução
131020 Bad Group (400) Não é possível enviar mensagens para grupos que possuem apenas 1 participante (ex: apenas o seu próprio número de negócio). Adicione mais membros antes de enviar mensagens.
131041 Group Unknown (400) O grupo especificado não foi encontrado. Certifique-se de que o group_id (JID) está correto ou se o seu número comercial ainda é membro desse grupo.
131059 Invalid Cursor (400) O cursor de paginação fornecido expirou ou é inválido. Reinicie a paginação da lista de grupos desde o início.
131201 Partial Success (206) A requisição de participantes obteve sucesso parcial. Verifique a lista detalhada de resposta para identificar quais operações ou números de telefone falharam.
131202 Duplicate Participant (400) Foram informados participantes duplicados no array de entrada. Remova as duplicatas da sua requisição.
131204 Participant Overlimit (400) O número de participantes excede o limite oficial permitido pela Meta (máximo de 8 participantes por grupo).
131207 Group Suspended (403) O grupo foi suspenso automaticamente pela Meta por violação das políticas de uso comercial do WhatsApp.
131208 Rate Limit Hit (429) O limite de operações de grupo por minuto do seu número foi atingido. Implemente um fluxo de backoff e reduza a frequência das requisições.
131209 Invalid Aspect Ratio (400) A proporção da imagem do ícone do grupo é inválida. A imagem deve ser estritamente quadrada (proporção 1:1).
131210 Image Too Small (400) A imagem enviada para o ícone do grupo é muito pequena. A largura e altura mínimas devem ser de 192px.
131211 Limit Reached (400) O limite de criação de grupos do seu número de telefone foi atingido (máximo de 10.000 grupos ativos).
131212 Not a Participant (400) O participante especificado não faz parte do grupo informado.
131213 Invalid Request (400) A solicitação de participação (join request) informada não existe ou já foi processada.
131214 Creation Disabled (400) A criação de grupos está temporariamente desativada para este número devido a alto volume de mensagens de marketing enviadas na janela de suporte nos últimos 7 dias.
131215 Not Eligible (400) O número de telefone não é elegível para utilizar a API de Grupos (ex: número em modo sandbox/teste, WhatsApp Business App móvel ou onboarded em modelo de coexistência). O número precisa ser uma Official Business Account (OBA).

Integração ChatWoot (Auto-Config)

Nossa integração oficial permite conectar seu número ao Chatwoot em segundos, sem a necessidade de ferramentas externas como n8n.

Estilo Evolution API: O sistema detecta suas configurações e cria automaticamente a Caixa de Entrada (Inbox) e os Webhooks necessários dentro do seu Chatwoot.

1. O que você precisa:

  • URL da Instância: Ex: https://chat.suaempresa.com
  • ID da Conta: O número que aparece após /accounts/ na URL do Chatwoot.
  • Token de Acesso: Encontrado em Configurações de Perfil > Access Token no seu Chatwoot.

2. Ativando a Integração:

  1. Acesse seu Dashboard no BSP → Meus Números.
  2. Clique em Configurar ChatWoot no número desejado.
  3. Preencha os dados e clique em [ Conectar e Configurar ].
URL que o sistema usará para o Webhook do Chatwoot
https://api.covercut.com.br/api/adapters/chatwoot.php

O BSP configurará essa URL automaticamente no seu Chatwoot. Sempre que um atendente responder por lá, nós receberemos a notificação e enviaremos para o WhatsApp do cliente.

Como Funciona o Fluxo

Sentido Ação do Sistema
WhatsApp → Chatwoot Quando o cliente manda um "Oi", o BSP cria o contato e a conversa no Chatwoot e empurra a mensagem via API.
Chatwoot → WhatsApp Quando o atendente responde no Chatwoot, ele dispara o Webhook para nosso adapter, que envia para a Meta.

Sincronizar Envios via API

Por padrão, mensagens enviadas via API (como notificações automáticas ou bots externos) não aparecem no Chatwoot, pois o Chatwoot só recebe eventos de mensagens que "passam" por ele ou chegam pelo Webhook.

Endpoint Sincronizado: Use este endpoint especial para garantir que mensagens enviadas pelo seu sistema também apareçam no histórico do Chatwoot.
POST /api/v1/messages/send_sync

Este endpoint aceita os mesmos parâmetros do /messages/send, mas realiza uma ação adicional:

  • Envia a mensagem ao cliente via WhatsApp.
  • Cria/Localiza a conversa no Chatwoot.
  • Insere a mensagem como "Saída" (Agent Message) no painel do Chatwoot.
Exemplo de Requisição Sincronizada
{
  "to": "5547999999999",
  "type": "text",
  "text": {
    "body": "Seu pedido #123 foi enviado! 🚚"
  }
}

Com isso, seus atendentes terão o histórico completo da conversa, incluindo as automações disparadas pelo seu sistema.

Business-Scoped User IDs (BSUID) — Junho 2026

O WhatsApp introduz BSUID (Business-Scoped User ID): um identificador único por usuário-negócio que permite suporte a usernames (nomes de usuário), similar ao Instagram. A partir de 01 de julho de 2026, a Meta descontinuará o envio por número de telefone.

Timeline Crítica

DataEventoImpacto
Abril 2026BSUIDs começam a aparecerWebhooks incluem from_user_id (opcional)
Maio 2026API aceita BSUID em envioPode enviar para BSUID ou número
Junho 2026Usernames disponíveisUsuários podem ocultar número
01 Julho 2026❌ Meta descontinua envio por númeroAPENAS BSUID será enviado

O que é um BSUID?

Exemplos de BSUID
BR.13491208655302741918      ← Formato numérico (CC.xxxxx)
BR.5519999999999             ← Com dígitos de telefone
joao.silva                   ← Username (após junho 2026)

Propriedades do BSUID

  • Único por negócio: Cada contato tem um BSUID diferente por empresa.
  • Persistente: Não muda mesmo se o usuário mudar de número ou desabilitar username.
  • Prefixado: Começa com código do país (ex: BR, US, ES).
  • Privado: A Meta garante privacidade — números não são expostos em BSUIDs.

Campos Novos nos Webhooks (Maio 2026+)

CampoLocalizaçãoTipoDescrição
from_user_idmessagesstringBSUID do remetente em mensagens inbound
recipient_user_idstatusesstringBSUID do destinatário em webhooks de status
to_user_idcallsstringBSUID do destinatário em eventos de chamada
to_parent_user_idcallsstringParent BSUID (para contexto de relacionamento)
user_idcontactsstringBSUID do contato
usernamecontactsstringNome de usuário WhatsApp do contato

Exemplo — Transição Junho 2026

Durante a transição, webhooks incluem ambos número e BSUID:

Webhook de Mensagem com Número + BSUID
{
  "from_number": "5547999999999",        ← número (pode ser NULL em julho)
  "contact": {
    "wa_id": "5547999999999",            ← número (pode ser NULL em julho)
    "user_id": "BR.13491208655302741918", ← BSUID (novo!)
    "username": "joao.silva",            ← username (novo!)
    "name": "João Silva"
  }
}

Implementação Recomendada

A partir de 01 de julho de 2026, use BSUID como identificador primário.
  1. Capture BSUID em webhooks:
    • Se from_user_id estiver presente, use como identificador do contato
    • Fallback para wa_id (número) para compatibilidade com período de transição
  2. Armazene username: Novos contatos incluem username — capture para exibição amigável
  3. Envio de mensagens: Até julho, pode enviar para número ou BSUID. A partir de julho, use preferencialmente BSUID.
  4. Teste a transição: Ative BSUID em seu Meta Developer Console e teste webhooks sem o campo de número.

Listar Números Conectados

Retorna todos os números WhatsApp conectados à sua conta. Use este endpoint para descobrir o phone_number_id de cada número — esse é o valor que você passa no campo from ao enviar mensagens.

GET /api/v1/numbers/list
Quando usar?

Ideal para automatizações que precisam descobrir o phone_number_id correto sem acessar o painel. Basta fazer essa chamada uma vez e armazenar os IDs na sua aplicação.

Exemplo de Uso (cURL)
curl --request GET \
  --url 'https://api.covercut.com.br/api/v1/numbers/list' \
  --header 'X-API-Key: sua_api_key' \
  --header 'X-API-Secret: seu_api_secret'
Exemplo de Resposta
{
  "success": true,
  "data": {
    "count": 2,
    "numbers": [
      {
        "phone_number_id": "123456789012345",
        "display_phone_number": "+55 47 99999-0001",
        "status": "active",
        "quality_rating": "GREEN",
        "phone_tier": "TIER_1K",
        "connected_at": "2026-01-10 09:00:00"
      },
      {
        "phone_number_id": "987654321098765",
        "display_phone_number": "+55 81 91234-5678",
        "status": "active",
        "quality_rating": "YELLOW",
        "phone_tier": "TIER_250",
        "connected_at": "2026-03-22 14:30:00"
      }
    ]
  },
  "message": "Números listados com sucesso."
}
Campos da Resposta
CampoTipoDescrição
phone_number_idstringID da Meta. Use como valor de from nos endpoints de envio.
display_phone_numberstringNúmero formatado para exibição (ex: +55 47 99999-0001).
statusstringactive, suspended ou disconnected.
quality_ratingstringAvaliação de qualidade: GREEN, YELLOW ou RED.
phone_tierstringLimite de templates diários: TIER_50, TIER_250, TIER_1K, TIER_10K, TIER_100K.
connected_atstringData e hora em que o número foi conectado.

Consultar Status do Número

Utilize este endpoint para consultar, em tempo real, a avaliação de qualidade de saúde do seu número e o status da conexão diretamente nos servidores da Meta.

GET /api/v1/numbers/status
Parâmetros de Consulta (Query String / JSON Body)
Parâmetro Obrigatório Descrição
from Sim O ID do número de telefone (Phone Number ID) que deseja consultar. Pode ser passado via query string (GET) ou no corpo JSON (POST).
Exemplo de Uso (cURL)
curl --request GET \
  --url 'https://api.covercut.com.br/api/v1/numbers/status?from=SEU_PHONE_NUMBER_ID' \
  --header 'X-API-Key: sua_api_key' \
  --header 'X-API-Secret: seu_api_secret'
Exemplo de Uso (POST com JSON)
curl --request POST \
  --url 'https://api.covercut.com.br/api/v1/numbers/status' \
  --header 'Content-Type: application/json' \
  --header 'X-API-Key: sua_api_key' \
  --header 'X-API-Secret: seu_api_secret' \
  --data '{
    "from": "SEU_PHONE_NUMBER_ID"
}'
Exemplo de Resposta
{
  "success": true,
  "data": {
    "phone_number_id": "123456789012345",
    "display_phone_number": "5547999999999",
    "status": "CONNECTED",
    "quality_rating": "GREEN",
    "name_status": "APPROVED",
    "connected_at": "2026-05-15 10:00:00"
  },
  "message": "Status recuperado com sucesso."
}

Códigos de Erro

CódigoDescrição
400Requisição inválida ou parâmetros faltando.
401Credenciais inválidas ou expiradas.
429Rate limit excedido.
500Erro interno no servidor.

Rate Limiting

  • Plano Básico: 60 requisições/min.
  • Plano Pro: 180 requisições/min.

Suporte

Email: suporte@covercut.com.br
WhatsApp: (47) 99618-1954

Changelog

Histórico completo de atualizações, melhorias e correções da API.

Novo v1.5.0 28 Mai 2026 — CRÍTICO
  • Novo
    Business-Scoped User IDs (BSUID) — Suporte Completo para Junho 2026 — A partir de 01 de julho de 2026, a Meta descontinuará o envio de mensagens por número de telefone. Agora todos os webhooks incluem from_user_id e to_user_id (BSUID — identificadores únicos por usuário-negócio). Seu sistema agora funciona perfeitamente com ou sem número: quando não há from, usa-se o BSUID como identificador primário. Usernames WhatsApp (como Instagram) também são suportados.
  • Novo
    WhatsApp Calling API — Webhooks de Chamadas de Voz — Implementado suporte nativo aos eventos de chamadas (voice calls). Quando usuários ligam para seu número, você recebe webhook com event: "call" contendo call_id, status (incoming, connected, ended, missed, rejected), duration_seconds, além de BSUID e username do chamador. Webhook inclui estrutura completa com nome, username e dados de contato.
  • Novo
    Rastreamento de Origem — Facebook Ads & Referral — Adicionados 5 novos campos para capturar origem de mensagens via Facebook Ads: referral_source_type (ex: "ad"), referral_source_id (ID da campanha), referral_source_url, referral_headline (copy do anúncio) e referral_ctwa_clid. Permite rastreamento de ROI por campanha. Webhook do cliente inclui campo referral completo quando aplicável.
  • Novo
    Documentação Atualizada — Junho 2026 — Adicionada seção completa sobre BSUID e transição para identificação por username. Documentação de webhooks expandida com exemplos de Calling API e referral. Nova página de status com changelog detalhado de implementação e checklist de testes.
  • Melhoria
    Echo Detection Aprimorado — Corrigida lógica de detecção de echo (mensagens de saída recebidas como webhook) para funcionar corretamente quando há apenas BSUID sem número de telefone. Sistema agora suporta transição dual (número + BSUID simultâneos) até julho de 2026.
Novo v1.4.8 21 Mai 2026
  • Novo
    Exportação Programática de Logs CSV via API — Disponibilizado novo endpoint nativo GET /api/v1/messages/export que permite aos clientes e contas SaaS exportarem relatórios completos de histórico bruto em arquivo CSV. Este recurso permite filtrar via query params e facilita a automação de backup (via webhook/cron, n8n ou Make) transferindo o controle do armazenamento a longo prazo diretamente para o cliente.
Novo v1.4.7 20 Mai 2026
  • Novo
    Sistema Multi-Usuário (Equipes) com Controle de Acesso (RBAC) — Implementada aba "Gerenciar Equipe" permitindo adicionar e gerenciar colaboradores com perfis dedicados: admin (acesso total), developer (chaves de API, webhooks e Chatwoot, ocultando áreas financeiras/segurança) e viewer (perfil de apenas leitura com bloqueio de requisições POST).
  • Novo
    Fila e Logs de Entrega de Webhooks — Criada fila de reprocessamento e auditoria persistente de webhooks (bsp_webhook_queue) com rotina de limpeza automatizada (24h de retenção para envios normais e 48h para falhas de rede) e controle de reenvio síncrono.
  • Novo
    Rate Limit Centralizado — Implementado motor global de controle de limites de requisições por rota baseada na tabela bsp_rate_limits, garantindo estabilidade e impedindo abusos nas APIs de mensageria.
  • Melhoria
    Otimizações de Concorrência e Rate Limit na Coexistência — Resolução do erro (#4) Application request limit reached da Meta nos endpoints de sincronização de coexistência. O sistema agora executa um atraso seguro entre as chamadas e gerencia localmente uma trava de 10 minutos (HTTP 429), evitando desperdício de cota da API da Meta.
  • Correção
    Autenticação Híbrida e Resiliência de Migração DDL — Resolvido erro de banco de dados causado por chaves de API migradas em tabelas herdadas (antigas) de chaves de API. O motor de migração em app/db.php agora valida a existência de cada coluna de forma granular no MySQL. Adicionado suporte a autenticação por sessão em validateApiRequest, permitindo que chamadas do próprio painel (como carregamento de templates e mídia) funcionem de maneira transparente e segura usando o cookie de sessão do usuário ativo, corrigindo a "Falha de comunicação".
Novo v1.4.6 20 Mai 2026
  • Novo
    Reconexão de Coexistência (account_update) — Suporte nativo aos novos eventos de reconexão e offboarding (ACCOUNT_OFFBOARDED e ACCOUNT_RECONNECTED) da Meta para clientes em modo Coexistence. Isso permite que softwares parceiros pausem disparos e previnam falhas durante trocas de dispositivo.
Novo v1.4.5 19 Mai 2026
  • Novo
    Suporte à API de Grupos da Meta (Maio 2026) — Habilitados novos eventos de webhooks para controle de grupos (group_lifecycle_update, group_participants_update, etc.). Adicionado o repasse de metadados de precificação PMP (Per-Message Pricing) nos webhooks de status. Documentação de grupos atualizada com as novas diretrizes da Meta.
Novo v1.4.4 19 Mai 2026
  • Novo
    Endpoint de Monitoramento de Número — Adicionado o endpoint GET /api/v1/numbers/status que permite aos clientes SaaS consultarem em tempo real a avaliação de qualidade (quality rating) e o status de conexão dos seus números direto da Graph API da Meta, com sincronização automática do banco de dados local.
Novo v1.4.3 18 Mai 2026
  • Novo
    Filtros Avançados de Busca para Administração — Adicionado um novo sistema unificado de pesquisa rápida nas telas administrativas de Clientes (Index), Números Conectados e Financeiro. Permite localizar clientes de forma instantânea por Nome, E-mail ou Nome da Empresa (e também por IDs de WABA/Telefone ou Número de Telefone na aba de Números), mantendo o estado da busca e do filtro de status persistentes durante a paginação de registros.
  • Novo
    Relatórios e Exportação Premium de Logs — Novo painel de relatório interativo no dashboard de logs, permitindo visualizar volumetria, taxas de conversão (entregues/lidos) e distribuição de erros consolidados. Inclusa exportação em planilha CSV (com BOM UTF-8) e relatórios executivos em formato PDF otimizados para impressão vetorial nativa com suporte a logomarca da empresa do cliente.
  • Novo
    Personalização de Perfil e Logotipo — Nova aba Perfil & Segurança adicionada ao menu lateral, permitindo que cada cliente configure o nome da empresa e insira a URL da logomarca oficial da sua marca, que é consumida e exibida de forma automática e personalizada (white-label) no cabeçalho de todos os relatórios PDF gerados.
  • Novo
    Página de Status do Sistema & Integração Meta — Nova página de status de alta performance (status.php) alimentada de forma automática pela API do UptimeRobot com sistema inteligente de cache de 60s para evitar rate-limits. Conta com linha do tempo de 30 dias de disponibilidade recente por serviço, painel de onboarding interativo para desenvolvedores e integração nativa com a central de monitoramento da Meta (metastatus.com) para acompanhamento da WhatsApp Cloud API.
  • Fix
    Relatório de Logs e Métricas de Sucesso — Corrigida a lógica de cálculo da taxa de sucesso que antes ignorava mensagens em status sent (Enviado), gerando dados imprecisos. Adicionada a capacidade da modal de exportação herdar e processar dinamicamente todos os filtros de pesquisa ativos da tela (Status, Direção, Tipo e Telefone) nas exportações de PDF e planilhas CSV.
  • Fix
    Mapeamento Completo de Erros da API da Meta — Expandida e refinada a tradução de erros oficiais da Meta no ecossistema BSP. Além de corrigir a tradução do erro 131042 (Cobrança/Pagamento), o tradutor agora possui mapeamento humanizado em português para erros de contato bloqueado (130403), formato de mídia incompatível (131053), templates não encontrados/pausados/suspensos (132001, 132015, 132016), limite de volume por segundo da Cloud API (130429), número de remetente inativo (131009), PIN incorreto de 2 etapas (133005), além de experimentos da Meta (130472) e limites de envio.
  • Novo
    Documentação Completa do Carrossel de Mídia — Adicionados exemplos completos de JSON para o endpoint POST /api/v1/messages/carousel, cobrindo carrosseis com botão de URL (CTA URL) e botões de resposta rápida (quick_reply). Tabela de parâmetros expandida com todos os campos do cartão (header, body, action) e exemplo de resposta de sucesso.
Novo v1.4.2 16 Mai 2026
  • Novo
    Documentação de Prévia de Links — Adicionada seção detalhada sobre o funcionamento e requisitos técnicos (Open Graph) para a exibição de prévias de links em mensagens de texto.
Novo v1.4.1 13 Mai 2026
  • Novo
    Suporte Explícito a Múltiplos Números — Documentação atualizada para incluir o parâmetro from em todos os exemplos de envio da API. Isso permite que clientes com mais de um número conectado escolham o canal de saída da mensagem usando o ID do telefone desejado.
Novo v1.4.0 13 Mai 2026
  • Novo
    Envio de Stickers (Figurinhas) — Adicionado suporte ao tipo de mensagem sticker no endpoint POST /api/v1/messages/send, permitindo o envio de figurinhas dinâmicas por link ou ID.
Novo v1.3.0 12 Mai 2026
  • Novo
    Suporte a Respostas Citadas (Reply) via Chatwoot — Ao usar o botão Responder em uma conversa no Chatwoot, a mensagem agora chega no WhatsApp do cliente citando corretamente a mensagem original, igual ao app nativo do WhatsApp.
  • Novo
    Campo context no endpoint de envio — Os endpoints POST /api/v1/messages/send e /send_sync aceitam agora o campo opcional context.message_id para citar uma mensagem ao enviar via API.
    {
      "to": "5511999998888",
      "type": "text",
      "text": { "body": "Olá!" },
      "context": { "message_id": "wamid.HBgM..." }
    }
  • Fix
    Verificação de duplicidade no adapter Chatwoot — Corrigida a lógica que bloqueava indevidamente mensagens enviadas pelo botão Responder do Chatwoot, fazendo com que não chegassem ao WhatsApp.
Fix v1.2.1 11 Mai 2026
  • Fix
    Upload de mídia para Templates com cabeçalho de imagem — Corrigido o fluxo de duas etapas para upload de mídia na criação de templates, resolvendo o erro de "invalid media handle" ao usar token do sistema.
  • Fix
    Persistência de configurações Chatwoot — Resolvido problema onde as configurações da integração com Chatwoot eram perdidas após salvar.
Novo v1.2.0 08 Mai 2026
  • Novo
    Botão de URL (CTA URL) — Suporte ao tipo de mensagem interativa cta_url para enviar botões com link externo.
  • Novo
    Gestão de Templates via Dashboard — Interface completa para criar, editar, visualizar e excluir templates diretamente pelo painel, com suporte a mídia, botões e rodapé.
  • Novo
    Paginação no Painel Admin — Listas de clientes, números e financeiro passaram a usar paginação para melhorar a performance com grande volume de dados.
Novo v1.1.0 04 Mai 2026
  • Novo
    Integração nativa com Chatwoot — Sincronização bidirecional completa: mensagens recebidas do WhatsApp aparecem automaticamente no inbox do atendente, e mensagens enviadas pelo Chatwoot são entregues pelo WhatsApp sem configuração extra.
  • Novo
    Webhook de Alertas — Endpoint dedicado para receber notificações de eventos críticos (falha de entrega, número suspenso, etc.) separado do webhook principal de mensagens.
  • Fix
    Configuração de Webhook — Corrigido erro 500 ao salvar ou atualizar configurações de webhook no dashboard.
Launch v1.0.0 Abril 2026
  • Lançamento inicial da plataforma WhatsApp API Connect
  • Envio de texto, imagem, vídeo, áudio, documento, localização, contato, reação
  • Mensagens interativas (lista e botões) e templates aprovados pela Meta
  • Recebimento via webhook com rastreamento de status de entrega
  • Rate limiting, dashboard de gerenciamento e suporte a grupos (Oficial)
  • BSUID para identificação de usuários sem número de telefone