Endpoints, autenticação, schemas de request/response, e códigos de erro.
Todas as rotas /api/whatsapp/* requerem autenticação por chave de API:
curl https://api.vzdapplication.com/api/whatsapp/channels \ -H "Authorization: Bearer vzd_SUA_CHAVE_AQUI"
A chave está em seu header Authorization como Bearer <chave>. Nunca a revele.
https://api.vzdapplication.com
Cria uma sessão de conexão para o cliente autentificar seu WhatsApp Business.
channel.connect
| Campo | Tipo | Descrição |
|---|---|---|
onboarding_mode * | enum | COEXISTENCE ou CLOUD_API_ONLY. Padrão: COEXISTENCE |
return_url | string | URL aonde redirecionar após conexão concluída (até 2048 caracteres) |
client_reference | string | ID interno seu para rastreamento (até 128 caracteres) |
label | string | Rótulo para identificar este canal no painel (até 120 caracteres) |
{
"connect_session_id": "550e8400-e29b-41d4-a716-446655440000",
"connect_url": "https://app.vzdapplication.com/connect?session=...",
"expires_at": "2024-01-15T14:00:00.000Z"
}
| Status | Código | Descrição |
|---|---|---|
| 402 | payment_required | Sem crédito ou plano suspenso |
| 429 | too_many_requests | Limite de criação de sessões excedido |
Consulta o status de uma sessão de conexão.
{
"connect_session_id": "550e8400-e29b-41d4-a716-446655440000",
"client_reference": "seu-id-interno",
"status": "CONNECTED|FAILED|EXPIRED",
"failure_reason": null,
"channel": {
"channel_id": "ch_xxx",
"waba_id": "100234567890",
"phone_number_id": "5511999887766",
"phone_number": "+55 (11) 99988-7766",
"display_name": "Beleza ABC",
"status": "CONNECTED"
}
}
Revoga uma sessão antes da conclusão. Útil para timeout.
204 (sem conteúdo)
Registra origem de retorno (webhook). Precisa fazer isso antes de conectar qualquer cliente.
| Campo | Tipo |
|---|---|
origin * | string URL (até 255 caracteres) |
label * | string (até 120 caracteres) |
{
"id": "org_550e8400-e29b-41d4-a716-446655440000",
"origin": "https://seu-dominio.com.br",
"label": "Produção",
"created_at": "2024-01-15T10:00:00.000Z"
}
Lista origens registradas.
{
"origins": [
{
"id": "org_xxx",
"origin": "https://seu-dominio.com.br",
"label": "Produção",
"created_at": "2024-01-15T10:00:00.000Z"
}
]
}
Revoga uma origem de retorno registrada. Deixa de receber webhooks nesse endpoint.
204 (sem conteúdo)
Lista canais WhatsApp conectados da sua conta.
{
"data": [
{
"id": "ch_xxx",
"wabaId": "100234567890",
"phoneNumberId": "5511999887766",
"phoneNumber": "+55 (11) 99988-7766",
"displayName": "Beleza ABC",
"status": "CONNECTED|DEGRADED|REVOKED",
"onboardingMode": "COEXISTENCE",
"webhookSubscribedAt": "2024-01-15T10:00:00.000Z",
"lastErrorMessage": null,
"createdAt": "2024-01-15T09:55:00.000Z"
}
]
}
Lista mensagens recebidas e echoes (respostas pelo celular). Até 30 por padrão, ordenadas por recência.
| Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
phone_number_id | string | — | Filtrar por número (opcional) |
limit | int | 30 | Quantos registros (máximo 100) |
{
"data": [
{
"wamid": "wamid.HhBmRGVmAUH7...",
"from": "5511987654321",
"direction": "INBOUND|OUTBOUND",
"origin": "CLOUD_API|BUSINESS_APP_ECHO",
"type": "text|image|document|audio|video|location|interactive",
"text": "Olá! Qual é o horário?",
"mediaUrl": "https://...",
"timestamp": "2024-01-15T10:00:00.000Z",
"sentAt": "2024-01-15T10:00:00.000Z"
}
]
}
Importante: BUSINESS_APP_ECHO = cliente respondeu pelo celular. Certifique-se de filtrar antes de entregar a uma IA, senão ela responderá a si mesma.
Status de entrega das mensagens enviadas (enviada, entregue, lida, falha).
{
"data": [
{
"wamid": "wamid.HhBmRGVmAUH7...",
"status": "SENT|DELIVERED|READ|FAILED",
"timestamp": "2024-01-15T10:00:05.000Z",
"occurredAt": "2024-01-15T10:00:05.000Z",
"failureReason": null
}
]
}
Envia mensagem de texto livre. Só funciona dentro da janela de 24 horas desde a última mensagem do cliente.
| Campo | Tipo | Descrição |
|---|---|---|
phone_number_id * | string | Seu número (ex: "5511999887766") |
to * | string | Número do cliente (ex: "5511987654321") |
body * | string | Texto da mensagem (até 4096 caracteres) |
preview_url | boolean | Gerar preview de URLs? Padrão: false |
reply_to_wamid | string | Responder a qual mensagem? (opcional) |
idempotency_key | string | Chave de idempotência (8-128 caracteres, opcional) |
sync | boolean | Esperar resposta (201)? Padrão: false (202 + job_id) |
{
"status": "queued",
"job_id": "job_550e8400-e29b-41d4-a716-446655440000"
}
{
"status": "sent",
"wamid": "wamid.HhBmRGVmAUH7AglMkZGVzQ==",
"message_id": "msg_2024_001",
"recipient_wa_id": "5511987654321"
}
| Status | Código |
|---|---|
| 402 | payment_required — sem crédito |
| 404 | channel_not_found — número não existe em sua conta |
| 409 | channel_revoked — cliente revogou acesso |
Envia mensagem template. Funciona em qualquer momento — templates são pré-aprovados.
| Campo | Tipo |
|---|---|
phone_number_id * | string |
to * | string |
template_name * | string (nome do template) |
language_code * | string (ex: "pt_BR") |
components | array (parâmetros do template) |
sync | boolean (padrão: false) |
Idêntico a /messages/text
Cria novo template na conta do cliente. Fica em revisão na Meta por minutos até horas.
| Campo | Tipo |
|---|---|
phone_number_id * | string |
name * | string (use versão: confirmacao_v2) |
language * | string (ex: "pt_BR") |
category * | enum: MARKETING, UTILITY, AUTHENTICATION |
components * | array |
allow_category_change | boolean (padrão: false) |
{
"name": "confirmacao_v2",
"language": "pt_BR",
"status": "PENDING_REVIEW",
"id": "123456789",
"category": "UTILITY"
}
Armadilha: Template apagado bloqueia o nome por 30 dias. Use nome versionado (v1, v2…) desde o início.
Lista templates da conta.
| Parâmetro | Tipo |
|---|---|
phone_number_id * | string |
limit | int (padrão: 20, máximo: 100) |
status | APPROVED, PENDING_REVIEW, REJECTED, PAUSED, DISABLED |
name | string (buscar por nome) |
after | string (paginação) |
{
"data": [
{
"name": "confirmacao_v2",
"language": "pt_BR",
"status": "APPROVED",
"id": "123456789",
"category": "UTILITY"
}
],
"paging": { "next_cursor": "xxx" }
}
Apaga template. Nome fica bloqueado por 30 dias.
| Parâmetro | Tipo |
|---|---|
phone_number_id * | string |
name * | string |
{
"deleted": true,
"name": "confirmacao_v2",
"name_reuse_blocked_days": 30
}
Registra URL de webhook. Você recebe POST assinado com cada evento.
| Campo | Tipo |
|---|---|
webhook_url * | https://seu-dominio (obrigatório HTTPS) |
{
"webhook_url": "https://seu-dominio.com.br/webhooks/whatsapp",
"webhook_secret": "sk_whk_abc123..."
}
O segredo aparece uma única vez. Guarde com segurança — não há rota para ler de volta.
Remove webhook. Você volta a depender de polling.
204 (sem conteúdo)
| Código | HTTP | Significado |
|---|---|---|
invalid_request | 400 | Validação falhou (campo obrigatório faltando, formato inválido) |
unauthorized | 401 | Chave de API inválida ou ausente |
invalid_signature | 401 | Assinatura HMAC do webhook inválida — valide usando o segredo |
payment_required | 402 | Sem crédito ou plano suspenso. Veja checkout_url na resposta |
forbidden | 403 | Acesso negado (ex: webhook URL interna) |
channel_not_found | 404 | Número não existe em sua conta |
connect_session_not_found | 404 | Sessão de conexão não existe ou nunca foi criada |
channel_authorization_rejected | 409 | Crítico: Token do canal foi recusado pela Meta. Reconecte o número. |
channel_revoked | 409 | Cliente revogou permissão de acesso no Gerenciador de Negócios da Meta |
connect_session_in_progress | 409 | Sessão de conexão já está em progresso — espere conclusão |
email_already_registered | 409 | E-mail já registrado |
connect_session_gone | 410 | Sessão de conexão expirou — crie uma nova |
too_many_requests | 429 | Rate limit excedido. Espere (ver header Retry-After) |
template_catalog_unavailable | 503 | Meta API indisponível, tente novamente em instantes |
graph_api_error | 502 | Meta retornou erro. Veja campo context da resposta |