Documentação da API
Bem-vindo à API do WhatsApp Connect. Nossa API permite integrar o WhatsApp Business Cloud diretamente no seu sistema para enviar mensagens, receber atualizações e gerenciar conversas.
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 — 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.
Razão social, CNPJ, endereço e telefone comercial.
business.facebook.com/latest/settings/business_infoSe 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 2 — 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.
Clique no link abaixo para ir direto para a página de pagamentos.
business.facebook.com/latest/billing_hub/accountsNa 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.
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:
Templates promocionais, ofertas, campanhas
Confirmações, lembretes, notificações transacionais
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.
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.
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.
Início Rápido
Base URL
https://api.covercut.com.br/api/v1
Autenticação
Todas as requisições devem incluir seus tokens de acesso nos cabeçalhos HTTP. Você pode gerar esses tokens em seu dashboard.
X-API-Key: sua_chave_de_api
X-API-Secret: seu_segredo_de_api
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).
{
"to": "5547999999999",
"type": "text",
"text": {
"body": "Olá! Como posso ajudar?"
}
}
{
"recipient": "BR.13491208655302741918",
"type": "text",
"text": {
"body": "Olá! Como posso ajudar?"
}
}
Resposta
{
"success": true,
"message": "Mensagem enviada com sucesso",
"message_id": "wamid.HBgLNTU0Nzk5...",
"from": "1234567890",
"to": "5547999999999",
"user_id": "BR.13491208655302741918" // presente quando disponível
}
POST Enviar Imagem
{
"to": "5547999999999",
"type": "image",
"image": {
"link": "https://exemplo.com/imagem.jpg",
"caption": "Legenda da imagem"
}
}
POST Enviar Vídeo
{
"to": "5547999999999",
"type": "video",
"video": {
"link": "https://exemplo.com/video.mp4",
"caption": "Legenda opcional"
}
}
POST Enviar Áudio
{
"to": "5547999999999",
"type": "audio",
"audio": {
"link": "https://exemplo.com/audio.mp3"
}
}
POST Enviar Documento
{
"to": "5547999999999",
"type": "document",
"document": {
"link": "https://exemplo.com/arquivo.pdf",
"filename": "documento.pdf"
}
}
POST Enviar Localização
{
"to": "5547999999999",
"type": "location",
"location": {
"latitude": -26.9195,
"longitude": -49.0661,
"name": "Covercut",
"address": "Rua Exemplo, 123"
}
}
POST Enviar Contato
{
"to": "5547999999999",
"type": "contacts",
"contacts": [
{
"name": { "formatted_name": "João Silva", "first_name": "João" },
"phones": [{ "phone": "5547999999999", "type": "CELL" }]
}
]
}
POST Enviar Reação
{
"to": "5547999999999",
"type": "reaction",
"reaction": {
"message_id": "wamid.xxx",
"emoji": "👍"
}
}
POST Enviar Mensagem Interativa
Crie uma experiência dinâmica com menus de lista ou botões de resposta rápida.
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.
{
"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" } }
]
}
}
}
1. Menu de Lista (List Message)
{
"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" }
]
}
]
}
}
}
2. Botões de Resposta Rápida (Reply Buttons)
{
"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 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.
{
"message_id": "wamid.xxx"
}
Opcional — se tiver múltiplos números, especifique qual usar com o campo from:
{
"message_id": "wamid.xxx",
"from": "phone_number_id"
}
Atualmente não existe um endpoint separado apenas para marcar como lida. Chame
/typing sempre que quiser que o remetente veja os tiques azuis — o indicador de digitação some automaticamente após alguns segundos ou quando você enviar a próxima mensagem.
POST Enviar Template
Inicie conversas com mensagens pré-aprovadas. Use to (telefone) ou recipient (BSUID) como destino.
{
"to": "5547999999999",
"type": "template",
"template": {
"name": "nome_do_template",
"language": { "code": "pt_BR" },
"components": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "Nome Cliente" }
]
}
]
}
}
Templates com Mídia (Imagem/Vídeo/Documento)
Para templates que possuem cabeçalho de mídia, use o componente header:
{
"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) ou Quick Reply.
{
"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" }
]
}
]
}
}
POST Enviar Template de Marketing
Endpoint dedicado (alias) para disparo de Custom Marketing Templates, com suporte a parâmetros nomeados.
{
"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%" }
]
}
]
}
}
POST Enviar para Grupo (Oficial)
Funcionalidade oficial da Meta (novembro/2025) para comunicação em grupos. O campo recipient_type deve ser explicitamente definido como group.
{
"messaging_product": "whatsapp",
"recipient_type": "group",
"to": "Y2FwaV9ncm91cDoxNzA1NTU1MDEzOToxMjAzNjM0MDQ2OTQyMzM4MjAZD", // ID do grupo oficial
"type": "text",
"text": {
"preview_url": true,
"body": "Olá grupo! Esta é uma mensagem de teste enviada via API Oficial."
}
}
Exemplo: Envio de Mídia em Grupo (Imagem/Vídeo/Áudio/PDF)
{
"recipient_type": "group",
"to": "GROUP_ID_HERE",
"type": "image",
"image": {
"link": "https://exemplo.com/imagem.jpg",
"caption": "Imagem para o grupo"
}
}
{
"recipient_type": "group",
"to": "GROUP_ID_HERE",
"type": "document",
"document": {
"link": "https://exemplo.com/arquivo.pdf",
"filename": "relatorio.pdf"
}
}
{
"recipient_type": "group",
"to": "GROUP_ID_HERE",
"type": "video",
"video": {
"link": "https://exemplo.com/video.mp4",
"caption": "Vídeo para o grupo"
}
}
{
"recipient_type": "group",
"to": "GROUP_ID_HERE",
"type": "audio",
"audio": {
"link": "https://exemplo.com/audio.mp3"
}
}
O identificador do grupo deve ser capturado através dos webhooks de entrada (campo
message.group_id) ou retornado por APIs de gestão de grupos da Meta.
Status de 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 Consultar Status
Retorna uma lista paginada de mensagens com seus status de entrega. Todos os parâmetros são opcionais — sem filtros, retorna as 50 mensagens mais recentes.
GET /api/v1/messages/status
Parâmetros de Query
| Parâmetro | Tipo | Descrição |
|---|---|---|
wamid | string | ID único da mensagem (ex: wamid.XXX...). Retorna apenas este registro. |
status | string | Filtra por status: sent, delivered, read ou failed. |
from | string | Filtra pelo número de origem (display_phone_number ou phone_number_id). |
recipient | string | Filtra pelo número do destinatário. |
since | string | Data/hora de início. Aceita ISO 8601 ou YYYY-MM-DD. |
until | string | Data/hora de fim. Aceita ISO 8601 ou YYYY-MM-DD. |
limit | integer | Quantidade de registros por página. Padrão: 50. Máximo: 200. |
offset | integer | Deslocamento para paginação. Padrão: 0. |
curl -X GET "https://api.covercut.com.br/api/v1/messages/status?status=read&since=2025-01-01&limit=100" \
-H "X-API-Key: sua_api_key" \
-H "X-API-Secret: seu_api_secret"
curl -X GET "https://api.covercut.com.br/api/v1/messages/status?wamid=wamid.HBgLNTUxMTk5..." \
-H "X-API-Key: sua_api_key" \
-H "X-API-Secret: seu_api_secret"
Resposta
{
"success": true,
"total": 243,
"count": 50,
"limit": 50,
"offset": 0,
"messages": [
{
"wamid": "wamid.HBgLNTUxMTk5...",
"status": "read",
"direction": "outbound",
"message_type": "text",
"recipient": "5511999990000",
"from_number": "+55 11 98888-0000",
"from_number_id": "1234567890",
"created_at": "2025-01-10 14:32:00"
},
{
"wamid": "wamid.HBgLNTUxMTk4...",
"status": "failed",
"direction": "outbound",
"message_type": "template",
"recipient": "5511988880000",
"from_number": "+55 11 98888-0000",
"from_number_id": "1234567890",
"template_name": "agendamento_confirmado",
"created_at": "2025-01-10 13:10:00",
"error": {
"code": "131026",
"message": "Message undeliverable"
}
}
]
}
Use
total e offset para navegar pelos resultados. Para buscar a próxima página, incremente o offset pelo valor de limit.offset = offset + limit
Os status são atualizados em tempo real via webhook da Meta. Use este endpoint para reconciliar ou popular seu banco de dados. Para receber atualizações instantâneas, configure seu webhook de eventos.
Listar Templates da Meta
Consulte todos os templates de mensagem cadastrados na sua conta WABA (WhatsApp Business Account) diretamente da Meta. Útil para popular seletores de templates em interfaces de envio ou para sincronizar status de aprovação.
GET Listar Templates
Retorna os templates cadastrados na WABA associada ao número ativo do cliente. Os resultados são ordenados por status (APPROVED primeiro) e depois em ordem alfabética pelo nome.
GET /api/v1/templates/list
Parâmetros de Query (todos opcionais)
| Parâmetro | Tipo | Descrição |
|---|---|---|
from | string | Filtra pelo phone_number_id de um número específico do cliente. Se omitido, usa o primeiro número ativo. |
status | string | Filtra pelo status do template: APPROVED, PENDING, REJECTED, PAUSED, DISABLED. |
category | string | Filtra pela categoria: MARKETING, UTILITY ou AUTHENTICATION. |
name | string | Filtra por substring do nome do template (case-insensitive). Ex: boas_vindas retorna todos os templates cujo nome contém esse trecho. |
limit | integer | Quantidade máxima de templates retornados. Padrão: 200. Máximo: 500. |
curl -X GET "https://api.covercut.com.br/api/v1/templates/list?status=APPROVED" \
-H "X-API-Key: sua_api_key" \
-H "X-API-Secret: seu_api_secret"
curl -X GET "https://api.covercut.com.br/api/v1/templates/list?category=UTILITY&name=confirmacao" \
-H "X-API-Key: sua_api_key" \
-H "X-API-Secret: seu_api_secret"
Resposta
{
"success": true,
"message": "Templates listados com sucesso",
"waba_id": "123456789012345",
"phone_number_id": "987654321098765",
"total": 3,
"templates": [
{
"id": "111222333444555",
"name": "agendamento_confirmado",
"status": "APPROVED",
"category": "UTILITY",
"language": "pt_BR",
"components": [
{
"type": "BODY",
"text": "Olá {{1}}, seu agendamento para {{2}} foi confirmado!"
},
{
"type": "FOOTER",
"text": "Responda CANCELAR para desmarcar."
}
],
"quality_score": { "score": "HIGH" },
"last_updated_time": "2026-01-15T10:30:00+0000"
},
{
"id": "666777888999000",
"name": "promocao_janeiro",
"status": "APPROVED",
"category": "MARKETING",
"language": "pt_BR",
"components": [
{ "type": "HEADER", "format": "IMAGE" },
{
"type": "BODY",
"text": "Aproveite {{1}}% de desconto em todos os produtos!"
}
],
"quality_score": { "score": "MEDIUM" },
"last_updated_time": "2026-01-10T08:00:00+0000"
},
{
"id": "101112131415161",
"name": "recuperacao_senha",
"status": "PENDING",
"category": "AUTHENTICATION",
"language": "pt_BR",
"components": [
{
"type": "BODY",
"text": "Seu código de verificação é {{1}}. Válido por 10 minutos.",
"add_security_recommendation": true
},
{
"type": "FOOTER",
"code_expiration_minutes": 10
},
{
"type": "BUTTONS",
"buttons": [{ "type": "OTP", "otp_type": "COPY_CODE", "text": "Copiar código" }]
}
],
"quality_score": null,
"last_updated_time": "2026-04-01T14:00:00+0000"
}
]
}
Cada objeto no array templates contém: id, name, status, category, language, components, quality_score, rejected_reason (quando reprovado) e last_updated_time.
O filtro ?name= é aplicado localmente após receber a lista da Meta — a API da Meta não suporta busca por substring. Para grandes contas com muitos templates, isso pode reduzir a performance. Use os filtros de status e category para pre-filtrar no lado da Meta antes de aplicar o filtro de nome.
Gestão de Templates
Os endpoints abaixo são proxies diretos para a API oficial da Meta. Nenhum dado é armazenado no BSP — tudo é enviado e recebido em tempo real da sua conta WABA. Você precisa de um número ativo com Access Token válido.
Templates criados ou editados passam por revisão automática da Meta antes de ficarem disponíveis para envio. O tempo médio é de alguns minutos a algumas horas. Use o endpoint Listar Templates para monitorar o status.
POST Criar Template
Envia um novo template de mensagem para a sua WABA. Após a criação, o template ficará com status PENDING até ser revisado pela Meta.
POST /api/v1/templates/create
Parâmetros do Body (JSON)
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
name | string | Sim | Nome único do template. Apenas letras minúsculas, números e _. Ex: agendamento_confirmado |
category | string | Sim | MARKETING, UTILITY ou AUTHENTICATION |
language | string | Sim | Código de idioma. Ex: pt_BR, en_US, es |
components | array | Sim | Array de componentes do template (HEADER, BODY, FOOTER, BUTTONS) |
allow_category_change | boolean | Não | Se true, permite que a Meta reclassifique a categoria automaticamente para evitar rejeição |
from | string | Não | phone_number_id específico. Se omitido, usa o primeiro número ativo |
curl -X POST "https://api.covercut.com.br/api/v1/templates/create" \
-H "X-API-Key: sua_api_key" \
-H "X-API-Secret: seu_api_secret" \
-H "Content-Type: application/json" \
-d '{
"name": "agendamento_confirmado",
"category": "UTILITY",
"language": "pt_BR",
"allow_category_change": true,
"components": [
{
"type": "BODY",
"text": "Olá {{1}}, seu agendamento para {{2}} está confirmado! Qualquer dúvida, responda esta mensagem."
},
{
"type": "FOOTER",
"text": "Responda CANCELAR para desmarcar."
}
]
}'
curl -X POST "https://api.covercut.com.br/api/v1/templates/create" \
-H "X-API-Key: sua_api_key" \
-H "X-API-Secret: seu_api_secret" \
-H "Content-Type: application/json" \
-d '{
"name": "oferta_especial_maio",
"category": "MARKETING",
"language": "pt_BR",
"components": [
{
"type": "HEADER",
"format": "IMAGE",
"example": { "header_handle": ["https://exemplo.com/banner.jpg"] }
},
{
"type": "BODY",
"text": "Aproveite {{1}}% de desconto em toda a loja até {{2}}!",
"example": { "body_text": [["20", "31/05"]] }
},
{
"type": "BUTTONS",
"buttons": [
{ "type": "URL", "text": "Ver ofertas", "url": "https://exemplo.com/ofertas" }
]
}
]
}'
Resposta
{
"success": true,
"message": "Template criado com sucesso. Aguarde a revisão da Meta.",
"template_id": "111222333444555",
"status": "PENDING",
"name": "agendamento_confirmado",
"category": "UTILITY",
"language": "pt_BR",
"waba_id": "123456789012345",
"phone_number_id": "987654321098765"
}
POST Criar Template de Marketing Customizado
Endpoint dedicado para criação de modelos promocionais usando formatação com parâmetros nomeados (parameter_format: "named").
POST /api/v1/templates/marketing
Exemplo de Payload
{
"name": "meu_modelo_marketing",
"category": "MARKETING",
"language": "pt_BR",
"parameter_format": "named",
"components": [
{
"type": "body",
"text": "Seu código é *{{discount_code}}*, válido até {{expiration_date}}.",
"example": {
"body_text_named_params": [
{ "param_name": "discount_code", "example": "BEMVINDO" },
{ "param_name": "expiration_date", "example": "amanhã" }
]
}
}
]
}
POST Editar Template
Atualiza os components de um template existente. Após a edição, o template voltará para revisão da Meta com status PENDING.
Apenas os componentes (texto, botões) podem ser editados. Nome, categoria e idioma são imutáveis — para alterá-los, exclua o template e recrie. Templates com status APPROVED e REJECTED podem ser editados; templates PENDING não.
POST /api/v1/templates/update
Parâmetros do Body (JSON)
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
template_id | string | Sim | ID numérico do template (obtido via Listar Templates) |
components | array | Sim | Lista completa dos novos componentes (substitui os existentes) |
from | string | Não | phone_number_id específico para autenticar a requisição |
curl -X POST "https://api.covercut.com.br/api/v1/templates/update" \
-H "X-API-Key: sua_api_key" \
-H "X-API-Secret: seu_api_secret" \
-H "Content-Type: application/json" \
-d '{
"template_id": "111222333444555",
"components": [
{
"type": "BODY",
"text": "Olá {{1}}, seu agendamento para {{2}} foi confirmado e está com tudo certo!"
},
{
"type": "FOOTER",
"text": "Dúvidas? Responda esta mensagem."
}
]
}'
Resposta
{
"success": true,
"message": "Template atualizado com sucesso. As alterações serão revisadas pela Meta.",
"template_id": "111222333444555",
"updated": true
}
DELETE Excluir Template
Remove um template da sua WABA. Aceita também requisições POST para clientes que não suportam HTTP DELETE com body.
Após a exclusão, o nome do template fica bloqueado por 30 dias na Meta — você não poderá criar outro template com o mesmo nome nesse período. Se omitir o template_id, todas as variantes de idioma do template serão excluídas.
DELETE /api/v1/templates/delete
POST /api/v1/templates/delete ← alternativa para clientes sem suporte a DELETE
Parâmetros do Body (JSON)
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
name | string | Sim | Nome do template a excluir |
template_id | string | Não | Se informado, exclui apenas a variante de idioma específica. Se omitido, exclui todas as línguas |
from | string | Não | phone_number_id específico para autenticar a requisição |
curl -X DELETE "https://api.covercut.com.br/api/v1/templates/delete" \
-H "X-API-Key: sua_api_key" \
-H "X-API-Secret: seu_api_secret" \
-H "Content-Type: application/json" \
-d '{
"name": "agendamento_confirmado"
}'
curl -X DELETE "https://api.covercut.com.br/api/v1/templates/delete" \
-H "X-API-Key: sua_api_key" \
-H "X-API-Secret: seu_api_secret" \
-H "Content-Type: application/json" \
-d '{
"name": "agendamento_confirmado",
"template_id": "111222333444555"
}'
Resposta
{
"success": true,
"message": "Template excluído em todos os idiomas com sucesso. O nome ficará bloqueado por 30 dias na Meta.",
"deleted": true,
"name": "agendamento_confirmado",
"template_id": null,
"scope": "all_languages",
"waba_id": "123456789012345"
}
{
"success": true,
"message": "Variante de idioma do template excluída com sucesso.",
"deleted": true,
"name": "agendamento_confirmado",
"template_id": "111222333444555",
"scope": "language_variant",
"waba_id": "123456789012345"
}
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.
GET Listar Grupos
Retorna uma lista de todos os grupos em que o número de telefone do BSP é membro. Útil para descobrir o group_id oficial.
GET /api/v1/groups/list
{
"success": true,
"data": [
{ "id": "Y2FwaV9...", "name": "Grupo de Vendas" },
{ "id": "Y2FwaV9...", "name": "Suporte N2" }
]
}
POST Criar Grupo
Cria um novo grupo e adiciona participantes iniciais. Note que há limites de participantes para contas Business (geralmente até 10).
{
"name": "Nome do Novo Grupo",
"description": "Descrição opcional",
"participants": [
"5547999999999",
"BR.13491208655302741918"
]
}
GET Ver Informações do Grupo
Obtém detalhes de um grupo específico, incluindo nome, descrição e participantes.
GET /api/v1/groups/info?group_id=GROUP_ID_HERE
GET / POST Gerenciar Link de Convite
Obtenha ou resete o link de convite do grupo. Use POST (com corpo contendo group_id) para invalidar o link anterior e gerar um novo.
GET /api/v1/groups/invite_link?group_id=GROUP_ID_HERE
POST /api/v1/groups/invite_link
{ "group_id": "GROUP_ID_HERE" }
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.
Gestão Individual por Número
No dashboard de Webhooks, você encontrará uma tabela de Status de Número. Ela permite gerenciar cada conexão de forma independente:
- Configuração Geral: Define uma URL padrão que funciona como "reserva" (fallback).
- Controle por Número: Cada número pode ser ativado ou desativado individualmente, permitindo que você pause as notificações de um celular específico sem afetar os outros.
- URLs Exclusivas: Se você precisar enviar os dados de um número para um sistema diferente, basta clicar em "Configurar" ao lado do número desejado.
Opções de Controle
- Ativar/Desativar: Você pode pausar o recebimento de webhooks sem precisar remover a URL configurada.
- Ignorar Grupos: Se esta opção estiver ativa, o sistema filtrará automaticamente todas as mensagens vindas de grupos, entregando apenas mensagens de conversas individuais no seu webhook.
Validar Assinatura (Segurança)
Cada envio contém o header X-BSP-Signature. Use-o para garantir que a mensagem veio de nós.
$signature = hash_hmac('sha256', $payload_bruto, $webhook_secret);
if (hash_equals($_SERVER['HTTP_X_BSP_SIGNATURE'], $signature)) {
// Autêntico
}
Validar no n8n (Sem código)
A forma mais simples de validar no n8n é usando o nó Crypto:
- Adicione um nó Crypto após o Webhook.
- Action: Hmac
- Value:
{{ JSON.stringify($json.body) }} - Secret: Seu Webhook Secret
- Algorithm: sha256
- Aí é só comparar o resultado com o header
x-bsp-signature.
Preparamos um fluxo base para o n8n que já inclui tratamento de dados e exemplos de envio de mensagens.
Baixar conexao_base.jsonEventos de Mensagem
Nova Mensagem
O campo contact.user_id (BSUID) está sempre presente. O campo contact.wa_id contém o telefone e pode ser omitido se o usuário tiver username ativo e não houver contato recente. O campo contact.username aparece apenas quando o usuário adotou um username no WhatsApp.
{
"event": "message",
"timestamp": "2026-03-31T10:30:00-03:00",
"from_number_id": "123456789",
"from_number": "+55 47 99999-9999",
"direction": "inbound",
"contact": {
"wa_id": "5547999999999", // telefone — pode ser omitido (veja nota acima)
"user_id": "BR.13491208655302741918", // BSUID — sempre presente
"name": "João Silva",
"username": "@joaosilva" // presente apenas se o usuário tiver username
},
"message": {
"id": "wamid...",
"type": "text",
"timestamp": 1743413400,
"text": "Oi!",
"group_id": "Y2FwaV9..." // Identificador único do grupo (se aplicável)
}
}
user_id (BSUID)A partir de 2026, usuários com username podem não ter
wa_id no webhook. Use contact.user_id como identificador principal e mantenha wa_id como complemento quando disponível.
Status
O campo status.recipient contém o telefone do destinatário ou o BSUID — use-o como identificador universal. Quando a mensagem foi enviada por BSUID e o telefone não está disponível, apenas o BSUID é retornado.
{
"event": "status",
"timestamp": "2026-03-31T10:30:05-03:00",
"from_number_id": "123456789",
"status": {
"id": "wamid...",
"status": "delivered",
"recipient": "5547999999999" // telefone OU BSUID OU GROUP_ID dependendo de como a mensagem foi enviada
}
}
Webhook de Alertas
Além do webhook de mensagens, você pode configurar um endpoint separado para receber alertas operacionais gerados pelo BSP — como quedas de qualidade, suspensões e vencimento de assinatura. Isso permite rotear avisos para ferramentas de monitoramento (Slack, PagerDuty, etc.) sem misturar com o fluxo de mensagens.
Configuração
Acesse Configurações > Webhook no dashboard e localize a seção Webhook de Alertas. Informe a URL de destino e ative o envio. Um secret será gerado automaticamente na primeira vez que você salvar.
alert.number_id no payload identifica qual número originou o alerta (quando aplicável).
Headers Enviados
Content-Type: application/json
X-BSP-Signature: <sha256_hmac(payload, alert_webhook_secret)>
X-BSP-Timestamp: <unix_timestamp>
A assinatura é calculada da mesma forma que o webhook de mensagens: hash_hmac('sha256', $payload_bruto, $alert_webhook_secret). Use o Alert Webhook Secret exibido no dashboard (diferente do secret do webhook de mensagens).
Payload do Evento alert
{
"event": "alert",
"timestamp": "2026-03-19T10:30:00-03:00",
"alert": {
"type": "quality_warning",
"title": "Qualidade do número em queda",
"message": "O número +55 47 99999-9999 está com qualidade YELLOW. Reduza o volume de mensagens não solicitadas.",
"number_id": 42
}
}
Tipos de Alerta
Tipo (alert.type) |
Descrição | number_id |
|---|---|---|
quality_warning |
Qualidade do número caiu para YELLOW — risco de suspensão se continuar. | Sim |
quality_critical |
Qualidade do número caiu para RED. O número foi suspenso automaticamente. | Sim |
tier_change |
O tier de mensagens do número foi alterado pela Meta. | Sim |
suspension |
Assinatura expirada — acesso à API suspenso. | Não |
subscription_expiring |
A assinatura expira em breve. Renovação recomendada. | Não |
info |
Evento informativo (ex: número conectado ou desconectado). | Sim ou Não |
test |
Evento gerado ao clicar em "Testar Agora" no dashboard. | Não |
Validar Assinatura do Alerta
$payload = file_get_contents('php://input');
$signature = hash_hmac('sha256', $payload, $alert_webhook_secret);
if (hash_equals($_SERVER['HTTP_X_BSP_SIGNATURE'], $signature)) {
$data = json_decode($payload, true);
// $data['event'] === 'alert'
// $data['alert']['type'], $data['alert']['number_id'], etc.
}
alert_webhook_enabled estiver desativado, os alertas continuam sendo registrados no painel do dashboard — apenas o envio HTTP é suprimido.
Baixar Mídia
Quando uma mensagem de áudio, imagem, vídeo ou documento chega pelo Webhook, o campo message contém um Media ID. Use este endpoint para baixar o arquivo — a API resolve o token da Meta automaticamente usando as credenciais do seu número conectado.
media_id do webhook → API busca o token do número no banco → chama graph.facebook.com/v25.0/{id} → obtém a URL temporária + mime_type → faz o download autenticado → retorna o arquivo para você.Não é necessário usar o token da Meta diretamente. A API cuida de toda a autenticação.
GET Modo Base64 (padrão)
Retorna o conteúdo do arquivo codificado em Base64 dentro de um JSON. Ideal para processar o arquivo no mesmo fluxo ou enviá-lo para uma API de transcrição via body JSON.
// Resposta de sucesso
{
"success": true,
"message": "Mídia processada com sucesso",
"media_id": "1234567890",
"mime_type": "audio/ogg; codecs=opus",
"filesize": 14532,
"base64": "T2dnUwACAAAAAAAA..."
}
GET Modo Stream (binário direto)
Adicionando mode=stream, o endpoint retorna o arquivo binário diretamente com os headers Content-Type e Content-Disposition corretos — equivalente ao Response Format: File do n8n.
// Headers da resposta (arquivo binário)
Content-Type: audio/ogg; codecs=opus
Content-Disposition: attachment; filename="1234567890.ogg"
Content-Length: 14532
Cache-Control: no-store
// Corpo: bytes do arquivo
Use este modo quando precisar do arquivo como binário — por exemplo, para enviar ao Whisper (OpenAI) ou qualquer outra API que aceite upload de arquivo.
Tipos de Mídia e Campos no Webhook
Cada tipo de mídia recebida expõe o id em um campo diferente dentro do objeto message:
| Tipo | Campo no message |
Exemplo de mime_type |
|---|---|---|
| Áudio | message.audio.id | audio/ogg; codecs=opus |
| Imagem | message.image.id | image/jpeg |
| Vídeo | message.video.id | video/mp4 |
| Documento | message.document.id | application/pdf |
| Sticker | message.sticker.id | image/webp |
Exemplo de payload do Webhook com áudio
{
"event": "message",
"timestamp": "2026-03-22T10:00:00-03:00",
"from_number_id": "123456789",
"contact": {
"wa_id": "5547888889999",
"name": "João Silva"
},
"message": {
"id": "wamid.xxx",
"type": "audio",
"audio": {
"id": "1234567890",
"mime_type": "audio/ogg; codecs=opus"
}
}
}
// Para baixar: GET /api/v1/media/get?id=1234567890
Integração com n8n
Substitua os 3 nodes do fluxo original (GET URL na Meta → Download com Bearer → Processar) por 1 único node HTTP Request:
| Campo n8n | Valor |
|---|---|
| Method | GET |
| URL | https://api.covercut.com.br/api/v1/media/get?id={{ $json.message.audio.id }}&mode=stream |
Header X-API-Key | sua chave de API |
Header X-API-Secret | seu secret de API |
| Response Format | File |
O arquivo chegará como binário, pronto para ser enviado ao próximo node (ex.: OpenAI → Transcribe Recording).
$json.message.audio.id para áudio, $json.message.image.id para imagem, $json.message.video.id para vídeo, $json.message.document.id para documento.
IDs de Usuário no Escopo da Empresa (BSUID)
A partir de 2026, o WhatsApp introduz nomes de usuário opcionais. Para suportá-los, a Meta criou um novo identificador chamado BSUID (Business-Scoped User ID): um código único por usuário, vinculado ao seu portfólio empresarial.
O que muda
| Quando | O que acontece |
|---|---|
| 31/03/2026 | BSUIDs começam a aparecer nos webhooks. O campo contact.user_id passa a estar presente em todas as mensagens recebidas. |
| Maio/2026 | A API passa a aceitar BSUIDs como destinatário de mensagens via campo recipient. |
Formato do BSUID
O BSUID é prefixado com o código do país ISO 3166 alpha-2, seguido de um ponto e até 128 caracteres alfanuméricos:
BR.13491208655302741918
US.13491208655302741918
US.ENT.11815799212886844830 // BSUID principal (portfólios vinculados)
Enviar mensagem por BSUID
Use o campo recipient no lugar de to. Não é necessário formatar como telefone.
{
"recipient": "BR.13491208655302741918",
"type": "text",
"text": { "body": "Olá!" }
}
Receber BSUID nos webhooks
O campo contact.user_id estará presente em todos os webhooks de mensagem recebida. O campo contact.wa_id (telefone) pode ser omitido quando o usuário adotou username e não houve interação nos últimos 30 dias.
"contact": {
"wa_id": "5547999999999", // pode ser omitido
"user_id": "BR.13491208655302741918", // sempre presente
"name": "João Silva",
"username": "@joaosilva" // presente se o usuário tiver username
}
- Armazene o
user_id(BSUID) junto ao número de telefone nos seus registros de contato. - Use
user_idcomo chave principal de identificação — ele está sempre presente. - Não tente enviar mensagens de autenticação (one-tap, zero-tap, copy-code) usando BSUID — esses tipos exigem telefone.
- BSUIDs são específicos ao seu portfólio: o mesmo usuário terá um BSUID diferente em cada empresa.
Se tentar enviar um template de autenticação usando BSUID, a Meta retornará o código
131062: Business-scoped User ID (BSUID) recipients are not supported for this message. Use o número de telefone nesses casos.
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.
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:
- Acesse seu Dashboard no BSP → Meus Números.
- Clique em Configurar ChatWoot no número desejado.
- Preencha os dados e clique em [ Conectar e Configurar ].
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.
3. Recursos Avançados
O BSP oferece controles granulares para melhorar sua operação:
- Ignorar Grupos: Filtra mensagens de grupos para não "poluir" seu Chatwoot.
- Assinar Mensagens: Adiciona o nome do atendente ao final de cada resposta (ex:
- Atendente João). - Reabrir Conversas: Reativa tickets "Resolvidos" no Chatwoot ao receber nova mensagem 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. |
Códigos de Erro
| Código | Descrição |
|---|---|
| 400 | Requisição inválida ou parâmetros faltando. |
| 401 | Credenciais inválidas ou expiradas. |
| 404 | Recurso ou endpoint não encontrado. |
| 429 | Muitas requisições. Rate limit excedido. |
| 500 | Erro interno em nossos servidores. |
| 131062 | Meta: BSUID não suportado para este tipo de mensagem. Templates de autenticação exigem número de telefone. |
Rate Limiting
Nossa API possui limites de segurança para garantir a estabilidade do serviço:
- Plano Básico: 60 requisições por minuto.
- Plano Pro: 180 requisições por minuto.
Suporte
Precisa de ajuda? Nossa equipe técnica está disponível para auxiliar na sua integração.
WhatsApp: (47) 99618-1954