API do Nexus Meta Hub
Proxy autenticado da Graph API da Meta (WhatsApp, Instagram, Facebook) com roteamento de webhooks multi-tenant.
Host base: https://hub.inovetechsolutions.com.br. A API de gestão usa o prefixo /api; o proxy usa /proxy; o webhook da Meta usa /webhook.
Visão geral
O Nexus Meta Hub é um proxy autenticado entre o seu sistema e a Graph API da Meta. Em vez de guardar tokens longos da Meta no seu backend, você cria um canal (conexão) no Hub e recebe uma chave do canal que substitui o token real nas chamadas via /proxy/*. Para receber eventos (mensagens, status), você cadastra webhooks de destino e o Hub reencaminha tudo, resolvendo a limitação da Meta de um webhook por app.
Fluxo típico
- Faça login no painel (uma vez).
- Crie um canal (WhatsApp, Instagram ou Facebook).
- Conecte: pelo painel ou enviando o link público ao cliente final.
- Cadastre um ou mais webhooks de destino (n8n, CRM, etc).
- Seu sistema usa a chave do canal para chamar a Meta via
/proxy/*.
Endpoints sem autenticação
/health— Health-check/api/auth/login— Login (retorna JWT)/api/auth/register— Cadastro de tenant/connect/:token— Página pública de conexão/api/public/:token/config— Config do link público/webhook/meta— Receiver da Meta (verificação + eventos)/proxy/*— Proxy para graph.facebook.com (usa a chave do canal)Autenticação
O Hub usa dois tipos de token, com propósitos diferentes:
| Token | Formato | Onde usar |
|---|---|---|
| API Key (recomendado p/ integrações) | nxh_pk_... | Rotas de gestão /api/* sem login. Persistente e revogável. |
| JWT (sessão) | eyJ... | Rotas de gestão /api/* (painel). Expira em 7 dias. |
| Chave do canal | hub_<prefixo>_<segredo> | Apenas o proxy /proxy/* (chamar a Meta) |
Ambos vão no header Authorization: Bearer <token>.
Login no painel
/api/auth/logincurl -X POST https://hub.inovetechsolutions.com.br/api/auth/login \
-H 'Content-Type: application/json' \
-d '{"email":"voce@empresa.com","password":"sua_senha"}'Resposta: { "success": true, "token": "eyJ...", "user": {...} }. Use esse token como Bearer nas rotas /api/*.
API Keys (server-to-server)
Para integrações que rodam sem login (n8n, CRM, scripts), crie uma API Key no painel (aba API Keys → Nova chave). O valor (nxh_pk_...) é exibido uma única vez. Use-a como Bearer em qualquer rota /api/*, igual ao JWT.
/api/api-keys— Lista suas chaves/api/api-keys— Cria (retorna o valor uma vez)/api/api-keys/:id/revoke— Revoga/api/api-keys/:id— RemoveCriar via API
Body: { "name": "string", "expiresInDays": número | omitido (nunca expira) }.
curl -X POST https://hub.inovetechsolutions.com.br/api/api-keys \
-H 'Authorization: Bearer <JWT>' \
-H 'Content-Type: application/json' \
-d '{"name":"Integração n8n","expiresInDays":90}'Usar a API Key
curl https://hub.inovetechsolutions.com.br/api/channels \
-H 'Authorization: Bearer nxh_pk_xxxxxxxx...'Canais (conexões)
Um canal representa uma conexão Meta (um número de WhatsApp, uma conta de Instagram ou uma página do Facebook). Cada canal tem sua própria chave de proxy e seu link público.
/api/channels— Lista canais/api/channels— Cria canal (pendente)/api/channels/:id/rotate-key— Gera nova chave de proxy/api/channels/:idCriar canal
Campos: name, channelType (whatsapp | instagram | facebook), mode (cloud | byo), e metaAppId (obrigatório no modo byo).
curl -X POST https://hub.inovetechsolutions.com.br/api/channels \
-H 'Authorization: Bearer <JWT>' \
-H 'Content-Type: application/json' \
-d '{"name":"WhatsApp Vendas","channelType":"whatsapp","mode":"cloud"}'A resposta traz id e connect_token (usado no link público). O canal nasce com status pending e vira active após a conexão.
Link público de conexão
Cada canal tem um link que o cliente final abre para conectar a conta dele, sem precisar de login no seu painel:
https://hub.inovetechsolutions.com.br/connect/<connect_token>No painel, cada canal tem o botão Link para copiar essa URL. A página pública usa estes endpoints (sem auth):
/api/public/:token/config— Dados para iniciar o Embedded Signup/api/public/:token/finalize/whatsapp— Finaliza WhatsApp/api/public/:token/begin— Instagram/Facebook (passo 1)/api/public/:token/select— Instagram/Facebook (passo 2: escolher página)WhatsApp (coexistência)
Conecta o número que já roda no WhatsApp Business App do cliente, em coexistência (app + Cloud API no mesmo número). O Hub resolve o WABA e o número direto pelo token (via debug_token), então não depende de dados frágeis da janela. Pré-requisitos no lado do cliente: BM verificada (CNPJ) e, para enviar templates, forma de pagamento.
Instagram / Facebook
O fluxo tem dois passos: o login retorna as páginas do usuário (/begin), e em seguida você escolhe a página/conta (/select). O Hub inscreve a página nos webhooks automaticamente.
Meta App próprio (BYO)
Por padrão os canais usam o app do Hub (modo cloud). Se preferir usar seu próprio app Meta (modo byo), cadastre-o:
/api/meta-apps/api/meta-apps— Cadastra app BYO/api/meta-apps/:idcurl -X POST https://hub.inovetechsolutions.com.br/api/meta-apps \
-H 'Authorization: Bearer <JWT>' \
-H 'Content-Type: application/json' \
-d '{"name":"Meu App","appId":"123...","appSecret":"...","configId":"..."}'A resposta traz o Callback URL e o Verify Token para você configurar no webhook do seu app na Meta (/webhook/meta/<app_id>).
Enviar mensagens (Proxy)
Para chamar a Graph API (enviar mensagens, ler dados, etc), use /proxy/* com a chave do canal no header. O Hub injeta o token real da Meta e devolve a resposta exatamente como a Meta retornaria. O caminho após /proxy/ é o mesmo que você usaria em graph.facebook.com.
/proxy/v25.0/...) ou omitir (/proxy/...) — nesse caso o Hub usa a versão configurada no canal.Ler dados do número (teste rápido)
curl "https://hub.inovetechsolutions.com.br/proxy/<PHONE_NUMBER_ID>?fields=display_phone_number,verified_name,quality_rating" \
-H 'Authorization: Bearer <CHAVE_DO_CANAL>'Enviar texto (WhatsApp)
curl -X POST https://hub.inovetechsolutions.com.br/proxy/<PHONE_NUMBER_ID>/messages \
-H 'Authorization: Bearer <CHAVE_DO_CANAL>' \
-H 'Content-Type: application/json' \
-d '{
"messaging_product": "whatsapp",
"to": "5599999999999",
"type": "text",
"text": { "body": "Olá do Nexus Meta Hub!" }
}'type:"template"). Dentro da janela de 24h você envia texto livre.Enviar via Node.js
const BASE = 'https://hub.inovetechsolutions.com.br/proxy';
const KEY = process.env.HUB_CHANNEL_KEY;
await fetch(`${BASE}/${PHONE_NUMBER_ID}/messages`, {
method: 'POST',
headers: { Authorization: `Bearer ${KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
messaging_product: 'whatsapp', to: '5599999999999',
type: 'text', text: { body: 'Olá!' },
}),
});Messenger (Facebook) e Instagram
Mesma ideia, usando os endpoints da Graph API correspondentes. Ex. Messenger:
curl -X POST https://hub.inovetechsolutions.com.br/proxy/me/messages \
-H 'Authorization: Bearer <CHAVE_DO_CANAL>' \
-H 'Content-Type: application/json' \
-d '{"recipient":{"id":"PSID"},"message":{"text":"Olá pelo Messenger"}}'https://graph.facebook.com por https://hub.inovetechsolutions.com.br/proxy e o token Meta pela chave do canal. O resto fica igual.Receber eventos (Webhooks)
O Hub recebe os eventos da Meta e os reencaminha para uma ou mais URLs HTTPS suas (n8n, CRM, etc), com retry e log. Cada webhook pode mirar todos os canais ou canais específicos, e filtrar por eventos.
/api/webhook-endpoints— Lista/api/webhook-endpoints— Cria/api/webhook-endpoints/:id— Atualiza/api/webhook-endpoints/:idCriar webhook de destino
Campos: name, url (obrigatórios); secret (HMAC), targetAll (default true), channelIds (quando targetAll=false), events (vazio = todos).
curl -X POST https://hub.inovetechsolutions.com.br/api/webhook-endpoints \
-H 'Authorization: Bearer <JWT>' \
-H 'Content-Type: application/json' \
-d '{
"name": "n8n produção",
"url": "https://n8n.seudominio.com/webhook/meta",
"secret": "um-segredo-hmac-forte",
"targetAll": true,
"events": []
}'O que chega no seu webhook
O Hub encaminha o payload no formato padrão da Meta (o mesmo JSON que a Meta envia), com uma entrada (entry) por canal. Headers incluídos:
| Header | Descrição |
|---|---|
X-Hub-Signature-256 | HMAC-SHA256 do corpo (se você definiu secret). Valide antes de processar. |
X-Hub-Event | Tipo do evento (ex. messages) |
X-Hub-Channel | ID do canal no Hub |
X-Hub-Delivery | ID da entrega (para idempotência) |
Validar a assinatura (Node.js)
const crypto = require('crypto');
function valid(rawBody, header, secret){
const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(header));
}Receiver da Meta (Meta → Hub)
Estes endpoints recebem direto da Meta e não são chamados pelo seu sistema. É a URL que você configura no webhook do app na Meta:
/webhook/meta— Verificação (hub.challenge), app Cloud/webhook/meta— Eventos, app Cloud/webhook/meta/:appId— Mesmo, para apps BYODashboard / Logs
/api/dashboard/stats— Métricas (canais, entregas 24h, falhas)/api/dashboard/deliveries— Log de entregas de webhook/api/dashboard/events— Eventos recebidos da Meta (auditoria)No painel, a aba Logs mostra entregas (status, tentativas, HTTP) e eventos recebidos em tempo quase real.
Guia de integração (CRM / SaaS)
1. Modelo mental
O Hub é a única porta entre o seu sistema e a Meta. Saída: seu sistema → /proxy (chave do canal) → Meta. Entrada: Meta → Hub → reencaminha pros seus webhooks. Você nunca lida com tokens da Meta nem com a regra de "um webhook por app".
2. Conectar o cliente
Crie um canal (POST /api/channels) e mande o link público (/connect/<token>) pro cliente. Quando ele conclui, o canal vira active.
3. Receber
Cadastre seu webhook (POST /api/webhook-endpoints) apontando pro seu backend. A partir daí toda mensagem chega lá no formato Meta.
4. Enviar
Guarde a chave do canal e use no /proxy para responder/enviar.
5. Múltiplos clientes
Um canal por número/conta. Cada um tem sua chave e seu link. Os webhooks podem ser um por canal ou um global para todos.
Eventos
O Hub repassa os eventos do WhatsApp/Messenger/Instagram conforme a Meta os envia. Os mais comuns no WhatsApp:
| Evento (field) | O que é |
|---|---|
messages | Mensagem recebida e atualizações de status (sent/delivered/read) |
message_template_status_update | Aprovação/rejeição de template |
account_update | Atualizações da conta |
phone_number_quality_update | Mudança de qualidade do número |
No filtro events de um webhook, use o nome do field (ex. messages). Vazio = recebe tudo.
Erros
Erros do proxy vêm no formato:
{ "error": { "message": "...", "type": "hub_auth" } }| type | Significado |
|---|---|
hub_auth | Chave do canal ausente, inválida ou canal inativo (401/403) |
hub_upstream | Falha ao contatar a Meta (502) |
hub | Erro interno do Hub |
Erros da própria Meta (ex. token expirado, fora da janela de 24h, template não aprovado) são repassados tal qual, com o status e o corpo originais da Graph API.
Rotas de gestão /api/* retornam { "success": false, "error": "..." } com o status HTTP apropriado (400/401/404/409/500).
Referência rápida
| Método | Rota | Auth |
|---|---|---|
| POST | /api/auth/register · /login | — |
| GET/POST/DELETE | /api/channels | JWT |
| POST | /api/channels/:id/rotate-key | JWT |
| GET/POST/DELETE | /api/meta-apps | JWT |
| GET/POST/PUT/DELETE | /api/webhook-endpoints | JWT |
| GET | /api/dashboard/{stats,deliveries,events} | JWT |
| GET/POST | /api/public/:token/* | token público |
| ANY | /proxy/* | chave do canal |
| GET/POST | /webhook/meta[/:appId] | verify token / HMAC |