WhatsApp Gateway API

Documentação completa da API

Base URLs

🌐 Produção:

https://wpp.pixel12digital.com.br

🔧 Desenvolvimento Local:

http://localhost:3000

IMPORTANTE - Rotas Públicas da API:

  • A API pública está disponível em /api/*
  • NÃO existe /v1/* nem /api/v1/* - use apenas /api/*
  • Em produção, todos os exemplos abaixo usam https://wpp.pixel12digital.com.br
  • Para desenvolvimento local, substitua por http://localhost:3000

Início Rápido

Configure o Secret: Todas as requisições (exceto /api/status) requerem o header X-Gateway-Secret
Crie um Canal: Use POST /api/channels para criar uma nova sessão
Obtenha o QR Code: Use GET /api/channels/:channel/qr e escaneie com WhatsApp
Envie Mensagens: Use POST /api/messages para enviar mensagens
Configure Webhooks: Use POST /api/webhooks para receber eventos em tempo real
POST /api/messages
Enviar mensagem de texto via WhatsApp

Parâmetros:

Parâmetro Tipo Descrição
channel obrigatório string ID da sessão/canal
to obrigatório string Número do destinatário (ex: 5511999999999)
text obrigatório string Texto da mensagem

Request (Produção):

cURL
curl -X POST https://wpp.pixel12digital.com.br/api/messages \
  -H "Content-Type: application/json" \
  -H "X-Gateway-Secret: <SEU_SECRET>" \
  -d '{
    "channel": "Pixel12 Digital",
    "to": "5511999999999",
    "text": "Olá! Teste do gateway."
  }'

Request (Desenvolvimento):

cURL
curl -X POST http://localhost:3000/api/messages \
  -H "Content-Type: application/json" \
  -H "X-Gateway-Secret: <SEU_SECRET>" \
  -d '{
    "channel": "Pixel12 Digital",
    "to": "5511999999999",
    "text": "Olá! Teste do gateway."
  }'

Response (200 OK) - Schema:

Campo Tipo Obrigatório Descrição
success boolean Sempre true em caso de sucesso
message_id string | null - Pode ser null - ID da mensagem (assíncrono via driver)
channel string ID do canal usado
to string Número de destino
status string Status do envio (sent, queued)
timestamp string (ISO 8601) Data/hora do envio
correlationId string (UUID) Chave de rastreamento - use para cruzar logs, eventos e webhooks

Response (200 OK) - Exemplo com message_id:

{
  "success": true,
  "message_id": "msg_123ABC",
  "channel": "Pixel12 Digital",
  "to": "5511999999999",
  "status": "sent",
  "timestamp": "2026-01-08T15:00:00.000Z",
  "correlationId": "550e8400-e29b-41d4-a716-446655440000"
}

Response (200 OK) - Exemplo com message_id null:

{
  "success": true,
  "message_id": null,
  "channel": "Pixel12 Digital",
  "to": "5511999999999",
  "status": "sent",
  "timestamp": "2026-01-08T15:00:00.000Z",
  "correlationId": "550e8400-e29b-41d4-a716-446655440000"
}

⚠️ Por que message_id pode ser null?

Dependendo do driver (WPPConnect/Baileys), o message_id não é retornado de forma síncrona. O rastreamento confiável é feito via correlationId que permite cruzar logs, eventos de webhook (message.ack) e logs do sistema. Use correlationId para rastrear o status real da mensagem.

Rastreamento com correlationId:
  • Use correlationId para cruzar logs + eventos de webhook + logs do sistema
  • O webhook message.ack também inclui o correlationId para correlação
  • O message_id pode chegar assincronamente via webhook message.ack
  • Para rastreamento confiável, não dependa apenas de message_id - use correlationId

Response (400 Bad Request):

{
  "success": false,
  "error": "channel (session_id) is required",
  "correlationId": "550e8400-e29b-41d4-a716-446655440000"
}
GET /api/channels
Listar todas as sessões/canais disponíveis. Retorna um array com id, name e status de cada canal.

Request (Produção):

cURL
curl -H "X-Gateway-Secret: <SEU_SECRET>" \
  https://wpp.pixel12digital.com.br/api/channels

Request (Desenvolvimento):

cURL
curl -H "X-Gateway-Secret: <SEU_SECRET>" \
  http://localhost:3000/api/channels

Response (200 OK) - Schema:

Campo Tipo Obrigatório Descrição
success boolean Sempre true em caso de sucesso
channels array Array de objetos de canal (pode ser vazio [])
channels[].id string NUNCA null/vazio - ID do canal (usar como Channel ID)
channels[].name string NUNCA null/vazio - Nome do canal
channels[].status string Status: connected, disconnected, qr_required, connecting
total number Total de canais (equivalente a channels.length)
correlationId string (UUID) ID de correlação para rastreamento

Response (200 OK) - Exemplo Real:

{
  "success": true,
  "channels": [
    {
      "id": "ImobSites",
      "name": "ImobSites",
      "status": "connected"
    },
    {
      "id": "Pixel12 Digital",
      "name": "Pixel12 Digital",
      "status": "connected"
    }
  ],
  "total": 2,
  "correlationId": "550e8400-e29b-41d4-a716-446655440000"
}
Garantia de Contrato:
  • O campo id é a chave oficial para "Channel ID" nas integrações
  • Os campos id e name NUNCA são null ou vazios - sempre retornam valores válidos
  • Use channels[].id como Channel ID para fazer requisições subsequentes (enviar mensagens, obter QR code, etc.)
  • Se não houver canais, o array será [] e total será 0
GET /api/channels/:channel
Obter informações e status de um canal específico

Request (Produção):

cURL
curl -H "X-Gateway-Secret: <SEU_SECRET>" \
  https://wpp.pixel12digital.com.br/api/channels/Pixel12%20Digital

Request (Desenvolvimento):

cURL
curl -H "X-Gateway-Secret: <SEU_SECRET>" \
  http://localhost:3000/api/channels/Pixel12%20Digital

Response (200 OK):

{
  "success": true,
  "channel": {
    "id": "Pixel12 Digital",
    "name": "Pixel12 Digital",
    "status": "connected"
  },
  "created_at": "2024-01-15T10:00:00.000Z",
  "updated_at": "2024-01-15T10:30:00.000Z",
  "correlationId": "550e8400-e29b-41d4-a716-446655440000"
}

Response (404 Not Found):

{
  "success": false,
  "error": "Channel not found",
  "correlationId": "550e8400-e29b-41d4-a716-446655440000"
}
Nota: O campo channel retorna um objeto com id, name e status. O id deve ser usado como Channel ID nas integrações.
POST /api/channels
Criar uma nova sessão/canal

Request (Produção):

cURL
curl -X POST https://wpp.pixel12digital.com.br/api/channels \
  -H "X-Gateway-Secret: <SEU_SECRET>" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "session-id"
  }'

Request (Desenvolvimento):

cURL
curl -X POST http://localhost:3000/api/channels \
  -H "X-Gateway-Secret: <SEU_SECRET>" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "session-id"
  }'
GET /api/channels/:channel/qr
Obter QR code para conectar WhatsApp

Request (Produção):

cURL
curl -H "X-Gateway-Secret: <SEU_SECRET>" \
  https://wpp.pixel12digital.com.br/api/channels/session-id/qr

Request (Desenvolvimento):

cURL
curl -H "X-Gateway-Secret: <SEU_SECRET>" \
  http://localhost:3000/api/channels/session-id/qr
POST /api/webhooks
Configurar webhook global para receber eventos de todos os canais

Request (Produção):

cURL
curl -X POST https://wpp.pixel12digital.com.br/api/webhooks \
  -H "X-Gateway-Secret: <SEU_SECRET>" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://seu-servidor.com/webhook",
    "secret": "optional-secret"
  }'

Request (Desenvolvimento):

cURL
curl -X POST http://localhost:3000/api/webhooks \
  -H "X-Gateway-Secret: <SEU_SECRET>" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://seu-servidor.com/webhook",
    "secret": "optional-secret"
  }'
POST /api/channels/:channel/webhook
Configurar webhook específico para um canal

Request (Produção):

cURL
curl -X POST https://wpp.pixel12digital.com.br/api/channels/session-id/webhook \
  -H "X-Gateway-Secret: <SEU_SECRET>" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://seu-servidor.com/webhook"
  }'

Request (Desenvolvimento):

cURL
curl -X POST http://localhost:3000/api/channels/session-id/webhook \
  -H "X-Gateway-Secret: <SEU_SECRET>" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://seu-servidor.com/webhook"
  }'

Eventos de Webhook

Quando um webhook está configurado, o gateway envia eventos HTTP POST para a URL configurada.

Headers dos Webhooks:

Content-Type: application/json
X-Correlation-ID: 550e8400-e29b-41d4-a716-446655440000
X-Webhook-Secret: <SEU_WEBHOOK_SECRET>  (se configurado)
User-Agent: WhatsApp-Gateway-Wrapper/1.0
Importante: O receptor deve validar o header X-Webhook-Secret antes de processar o evento, comparando com o secret configurado no webhook.

Evento: message

Disparado quando uma mensagem é recebida no WhatsApp

{
  "event": "message",
  "channel": "Pixel12 Digital",
  "timestamp": "2026-01-08T23:45:12Z",
  "correlationId": "550e8400-e29b-41d4-a716-446655440000",
  "message": {
    "id": "msg_123",
    "from": "5511999999999",
    "to": "SEU_NUMERO",
    "text": "Oi, tudo bem?",
    "type": "text"
  }
}

Evento: message.ack

Disparado quando há confirmação de envio/entrega/leitura

{
  "event": "message.ack",
  "channel": "Pixel12 Digital",
  "timestamp": "2026-01-08T23:45:20Z",
  "correlationId": "550e8400-e29b-41d4-a716-446655440000",
  "ack": {
    "messageId": "msg_123",
    "status": "sent"
  }
}

Valores típicos de status: queued, sent, delivered, read, failed

Rastreamento: O campo correlationId permite correlacionar este ACK com a requisição original de envio de mensagem. Use-o para cruzar logs e eventos.

Evento: connection.update

Disparado quando o status da sessão muda

{
  "event": "connection.update",
  "channel": "Pixel12 Digital",
  "timestamp": "2026-01-08T23:45:30Z",
  "correlationId": "550e8400-e29b-41d4-a716-446655440000",
  "connection": {
    "status": "connected"
  }
}

Valores possíveis: connected, disconnected, connecting, qr_required

Requisitos do Endpoint Cliente:

Seu endpoint webhook DEVE atender aos seguintes requisitos:
  • HTTPS público: O endpoint deve ser acessível via HTTPS público (não localhost/privado)
  • Resposta rápida: Responder com HTTP 200 OK em até 5 segundos
  • Idempotência: Processar eventos de forma idempotente (use correlationId ou eventId se disponível)
  • Validação de segurança: Validar o header X-Webhook-Secret antes de processar
  • Enfileiramento: Recomenda-se enfileirar o processamento (não bloquear o gateway)
  • Retries: O gateway pode tentar reenviar eventos em caso de falha (timeout, 5xx, etc.)
Comportamento em Falha:
  • Se o endpoint retornar HTTP 5xx ou timeout, o gateway pode tentar reenviar
  • Eventos são enviados de forma assíncrona - falhas não bloqueiam o processamento principal
  • Use correlationId para identificar eventos duplicados e evitar processamento duplo

Padronização de Erros

Todos os erros da API seguem um schema padronizado com correlationId para rastreamento.

Schema Padrão de Erro:

{
  "success": false,
  "error": "Mensagem de erro descritiva",
  "correlationId": "550e8400-e29b-41d4-a716-446655440000"
}
Rastreamento de Erros:
  • Use correlationId para cruzar logs do gateway e identificar a requisição que causou o erro
  • Todos os erros incluem correlationId mesmo quando não há autenticação
  • Guarde o correlationId ao reportar problemas para facilitar o diagnóstico

Códigos HTTP e Erros:

401 Unauthorized
Secret key ausente ou inválida

Exemplo de Resposta:

{
  "success": false,
  "error": "Missing X-Gateway-Secret header",
  "correlationId": "550e8400-e29b-41d4-a716-446655440000"
}
Solução: Adicione o header X-Gateway-Secret na requisição com uma secret key válida.
403 Forbidden
Secret key inválida ou não autorizada

Exemplo de Resposta:

{
  "success": false,
  "error": "Invalid X-Gateway-Secret",
  "correlationId": "550e8400-e29b-41d4-a716-446655440000"
}
Solução: Verifique se a secret key está correta. Em produção, entre em contato com o administrador para obter a secret key válida.
400 Bad Request
Payload inválido ou campos obrigatórios ausentes

Exemplo de Resposta:

{
  "success": false,
  "error": "channel (session_id) is required",
  "correlationId": "550e8400-e29b-41d4-a716-446655440000"
}
Solução: Verifique se todos os campos obrigatórios foram enviados. Consulte a documentação do endpoint para ver os campos requeridos.
404 Not Found
Recurso não encontrado (canal, rota inexistente)

Exemplo 1 - Canal não encontrado:

{
  "success": false,
  "error": "Channel not found",
  "correlationId": "550e8400-e29b-41d4-a716-446655440000"
}

Exemplo 2 - Rota inexistente:

{
  "success": false,
  "error": "Route not found: /api/v1/messages",
  "correlationId": "550e8400-e29b-41d4-a716-446655440000"
}
⚠️ IMPORTANTE: A API pública está em /api/*. NÃO existe /v1/* nem /api/v1/*. Se você receber 404 em rotas com /v1/, verifique se está usando a rota correta /api/*.
Solução: Verifique se o canal existe usando GET /api/channels. Para rotas, use apenas /api/* (sem /v1/).
429 Too Many Requests
Rate limit excedido (se implementado)

Exemplo de Resposta:

{
  "success": false,
  "error": "Too many requests. Please try again later.",
  "correlationId": "550e8400-e29b-41d4-a716-446655440000"
}
Solução: Aguarde alguns segundos antes de fazer novas requisições. Implemente retry com backoff exponencial.
500 Internal Server Error
Erro interno do servidor

Exemplo de Resposta:

{
  "success": false,
  "error": "Internal server error",
  "correlationId": "550e8400-e29b-41d4-a716-446655440000"
}
Solução: Guarde o correlationId e reporte o problema ao suporte. Tente novamente após alguns segundos.

Validação em Produção

Checklist completo para validar uma nova integração antes de colocar em produção.

Passo 1: Listar Canais Disponíveis

cURL
curl -H "X-Gateway-Secret: <SEU_SECRET>" \
  https://wpp.pixel12digital.com.br/api/channels
✓ Verificar:
  • A resposta contém um array channels com objetos {id, name, status}
  • Os campos id e name não são null ou vazios
  • Anote o id do canal que deseja usar (ex: "Pixel12 Digital")

Passo 2: Confirmar Status do Canal

cURL
curl -H "X-Gateway-Secret: <SEU_SECRET>" \
  https://wpp.pixel12digital.com.br/api/channels/Pixel12%20Digital
✓ Verificar: O status do canal deve ser "connected" antes de enviar mensagens.
  • Se status: "qr_required" - obtenha o QR code e escaneie com WhatsApp
  • Se status: "disconnected" - reconecte o canal
  • Apenas status: "connected" permite enviar mensagens

Passo 3: Enviar Mensagem de Teste

cURL
curl -X POST https://wpp.pixel12digital.com.br/api/messages \
  -H "X-Gateway-Secret: <SEU_SECRET>" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "Pixel12 Digital",
    "to": "5511999999999",
    "text": "Mensagem de teste da integração"
  }'
✓ Verificar:
  • A resposta contém "success": true
  • O message_id pode ser null - isso é normal!
  • O correlationId está presente - guarde-o para rastreamento
  • A mensagem foi realmente entregue no WhatsApp (confirme visualmente)

Passo 4: Configurar Webhook e Validar Recebimento

cURL
curl -X POST https://wpp.pixel12digital.com.br/api/channels/Pixel12%20Digital/webhook \
  -H "X-Gateway-Secret: <SEU_SECRET>" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://seu-servidor.com/api/whatsapp/webhook"
  }'
✓ Verificar:
  • O endpoint webhook é HTTPS público (não localhost)
  • O endpoint responde com HTTP 200 OK em até 5 segundos
  • Envie uma mensagem de teste para o número conectado
  • Confirme que o webhook recebeu o evento message
  • Valide o header X-Webhook-Secret se configurado

Passo 5: Validar Rastreamento com correlationId

✓ Verificar:
  • Quando enviar uma mensagem, guarde o correlationId da resposta
  • Confirme que o webhook message.ack inclui o mesmo correlationId
  • Use o correlationId para cruzar logs e eventos
  • Não dependa apenas de message_id - ele pode ser null na resposta inicial

Troubleshooting

Problemas comuns e como resolvê-los

Problema: Route not found (404) ao usar /v1/*

Erro: {"success": false, "error": "Route not found: /api/v1/messages"}
✅ Solução: A API pública está em /api/*, não em /api/v1/* ou /v1/*.

Errado: POST /api/v1/messages
Correto: POST /api/messages

Problema: 401 Unauthorized

Erro: {"success": false, "error": "Missing X-Gateway-Secret header"}
✅ Solução: Adicione o header X-Gateway-Secret em todas as requisições (exceto /api/status).

Exemplo: -H "X-Gateway-Secret: sua-secret-key"

Problema: 403 Forbidden

Erro: {"success": false, "error": "Invalid X-Gateway-Secret"}
✅ Solução: Verifique se a secret key está correta. Em produção, entre em contato com o administrador.

Problema: message_id é null na resposta

Atenção: {"success": true, "message_id": null, ...}
✅ Isso é normal! Dependendo do driver (WPPConnect/Baileys), o message_id não é retornado de forma síncrona.

Solução:
  • Use correlationId para rastrear a mensagem
  • O message_id pode chegar via webhook message.ack
  • Não dependa apenas de message_id - use correlationId para rastreamento confiável

Problema: Webhook não recebe eventos

Sintoma: O webhook foi configurado, mas não recebe eventos
✅ Verificações:
  • O endpoint webhook é HTTPS público (não localhost ou IP privado)
  • O endpoint responde com HTTP 200 OK rapidamente (até 5 segundos)
  • Verifique os logs do gateway para erros de entrega de webhook
  • Confirme que o canal está "connected"
  • Teste enviando uma mensagem real para o número conectado

Problema: GET /api/channels retorna id/name como null

Erro: {"channels": [{"id": null, "name": null, ...}]}
✅ Isso NÃO deveria acontecer! Os campos id e name devem sempre ter valores válidos.

Solução: Guarde o correlationId e reporte o problema ao suporte. Isso pode indicar um bug no gateway.

Python

import requests

BASE_URL = "https://wpp.pixel12digital.com.br"  # Use http://localhost:3000 para desenvolvimento
SECRET = "seu-secret-key"

headers = {
    "X-Gateway-Secret": SECRET,
    "Content-Type": "application/json"
}

# Enviar mensagem
response = requests.post(
    f"{BASE_URL}/api/messages",
    json={
        "channel": "session-id",
        "to": "5511999999999",
        "text": "Olá!"
    },
    headers=headers
)
print(response.json())

Node.js

const axios = require('axios');

const BASE_URL = 'https://wpp.pixel12digital.com.br'; // Use 'http://localhost:3000' para desenvolvimento
const SECRET = 'seu-secret-key';

const headers = {
  'X-Gateway-Secret': SECRET,
  'Content-Type': 'application/json'
};

// Enviar mensagem
axios.post(`${BASE_URL}/api/messages`, {
  channel: 'session-id',
  to: '5511999999999',
  text: 'Olá!'
}, { headers })
  .then(response => console.log(response.data))
  .catch(error => console.error(error));

🐘 PHP

$baseUrl = 'https://wpp.pixel12digital.com.br'; // Use 'http://localhost:3000' para desenvolvimento
$secret = 'seu-secret-key';

$headers = [
    'X-Gateway-Secret: ' . $secret,
    'Content-Type: application/json'
];

$data = [
    'channel' => 'session-id',
    'to' => '5511999999999',
    'text' => 'Olá!'
];

$ch = curl_init($baseUrl . '/api/messages');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$response = curl_exec($ch);
curl_close($ch);

echo $response;