Índice da documentação
Referência da API · v1
API do Genius Hub
A API do Genius Hub coloca o seu agente de IA dentro do seu produto: converse com ele a partir do seu site ou app, monte a sua própria inbox de atendimento, envie mensagens pelo WhatsApp e receba eventos em tempo real no seu servidor.
É uma API REST: recebe e devolve JSON, usa os métodos e os códigos de status HTTP padrão e se autentica por chave. Tudo fica sob /api/v1 — qualquer caminho fora desta referência responde 404.
Recursos
| Recurso | Para quê |
|---|---|
| Chat | Converse com o agente a partir do seu produto e monte a sua própria inbox. |
| Mensagens | Envie mensagens pelo WhatsApp conectado ao agente — notificações do seu sistema, o primeiro contato com um cliente ou a resposta do seu atendente.. |
| Agentes | Liste, leia, crie, altere e exclua agentes pelo seu sistema. |
| Configuração do agente | Pausa, horário de atendimento, follow-up, preferências de conversa, foto, emergência, pessoas a chamar e o funil que o agente alimenta — as abas de configuração do estúdio do agente.. |
| Base de conhecimento | O que o agente sabe além do prompt. |
| Intenções e skills | O que o agente sabe fazer. |
| Catálogo | Os produtos que o agente oferece. |
| Canais | Conecte um número de WhatsApp a um agente: crie o canal, peça o QR Code e consulte até o status virar CONNECTED.. |
| Webhooks | Em vez de consultar a API em laço, receba um POST no seu servidor a cada mensagem que entra ou sai. |
| Funil de vendas | Leve para o funil o lead que nasce fora do WhatsApp — no site, no ERP, num formulário de terceiro. |
Primeira vez aqui?
https://api.geniushub.online/api/v1curl -X POST "https://api.geniushub.online/api/v1/chat" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"agentId":"ID_DO_AGENTE","chatId":"teste-1","message":"Olá!"}'Autenticação
Toda requisição leva a chave da sua organização no cabeçalho x-api-key. As chaves começam com ghk_ e são emitidas no painel, em Configurações → Integração (API), pelo titular da conta ou por um administrador.
Na mesma tela ficam os IDs para a integração: o ID de cada agente (o agentId das rotas) e o ID de cada canal de WhatsApp (o {id} de /v1/channels), com botão de copiar. Pela API, GET /v1/agents lista os agentes e GET /v1/agents/{agentId} traz os canais em instances.
- O valor completo aparece uma única vez, na criação. O Hub guarda só um hash: se perder, revogue e emita outra.
- A chave age em nome da conta que a emitiu e herda o papel dela. Rotas marcadas com Permissão exigem chave de titular ou administrador.
- Escopo por agente: ao criar a chave, selecione os agentes que ela pode acessar. Chamadas a outros agentes recebem
403. Chaves sem agentes selecionados alcançam todos os agentes da conta. - A revogação é imediata: a chamada seguinte com a chave recebe
401. - O token de login do painel não vale em
/api/v1, e a chave não vale nas rotas do painel.
Nunca exponha a chave no navegador
x-api-key: ghk_nSVrCckA1a235xAh5a3Vhjmglor5FJMpQ4o2SYfYGzA{
"statusCode": 401,
"error": "UNAUTHENTICATED",
"message": "Chave de API inválida ou revogada.",
"path": "/api/v1/chat"
}Erros
A API usa os códigos HTTP convencionais: 2xx é sucesso, 4xx é um problema na requisição e 5xx é falha do nosso lado. Todo erro tem o mesmo formato, com a mensagem em português pronta para exibir. Erros de validação trazem details campo a campo, e erros 500 trazem um requestId para citar ao suporte — o mesmo valor do cabeçalho X-Request-Id, que vem em toda resposta (veja Rastreabilidade).
| Status | error | Quando acontece |
|---|---|---|
400 | VALIDATION_FAILED | Campo ausente ou fora do formato. details aponta cada campo. |
400 | BAD_REQUEST | Regra de negócio: agente sem WhatsApp conectado, contato bloqueado, nome de agente ambíguo. |
401 | UNAUTHENTICATED | Cabeçalho x-api-key ausente, ou chave inexistente, vencida ou revogada. |
403 | FORBIDDEN | A chave não tem acesso ao agente, ou o papel da conta não permite a operação. |
404 | NOT_FOUND | Agente, canal ou conversa não existe na sua organização — ou a rota não existe. |
409 | CONFLICT | O chatId já pertence a uma conversa de outro canal. |
429 | RATE_LIMITED | Limite de requisições excedido. Aguarde e tente de novo. |
429 | MASS_SEND_BLOCKED | Envio recusado por parecer disparo em massa. O campo limit diz qual teto. Repetir igual não passa. |
5xx | INTERNAL_ERROR | Falha nossa ou de um provedor. É seguro tentar de novo com espera crescente. |
{
"statusCode": 400,
"error": "VALIDATION_FAILED",
"message": "Informe o número com DDD.",
"path": "/api/v1/messages/send",
"timestamp": "2026-10-02T13:40:12.884Z",
"details": [
{ "campo": "phone", "mensagem": "Informe o número com DDD." }
]
}Limites de uso
Os limites protegem o seu saldo de créditos e o atendimento dos seus contatos. Ao ultrapassá-los, a API responde 429; espere alguns segundos e repita, de preferência com espera exponencial.
| Rota | Limite |
|---|---|
POST /v1/chat | 30 requisições por minuto |
POST /v1/messages/send | 60 requisições por minuto |
| Demais rotas | 20 por segundo e 300 por minuto, por chave |
| Qualquer rota, por endereço IP | 600 por minuto; quem estoura fica 5 minutos bloqueado |
| Chave inválida, por endereço IP | 10 recusas em 10 minutos bloqueiam o IP por 15 minutos |
Além disso, cada resposta do agente consome créditos da organização, exatamente como no WhatsApp.
Envio pelo WhatsApp não é disparo em massa
POST /v1/messages/send é para atendimento e avisos. O WhatsApp bane o número que manda para lista fria — e com ele vai todo o atendimento. Por isso a API recusa com 429 MASS_SEND_BLOCKED o envio que tem esse formato. Conversas com quem já escreveu para o agente não entram nos dois primeiros tetos.
| limit | Teto |
|---|---|
mensagensSemResposta | 2 mensagens para um número que nunca escreveu; a próxima só depois da resposta. |
contatosNovosPorDia | 30 números novos que nunca escreveram, por agente, a cada 24 horas. |
mesmoConteudoPorHora | O mesmo texto ou arquivo para no máximo 20 números por hora. |
enviosPorHora | 120 envios por agente por hora. |
Rastreabilidade e auditoria
Tudo o que a sua integração faz fica registrado na trilha de auditoria da organização: cada mensagem enviada, cada alteração de agente, canal ou webhook e cada tentativa recusada. O titular da conta consulta tudo em Configurações → Atividade, com filtro por origem (painel, API ou sistema), por período e por chave.
| O que é registrado | De onde vem |
|---|---|
| Origem: API | Da chave que autenticou a chamada. Não há campo para escolher a origem: uma integração nunca aparece como o painel. |
| Chave usada | Nome e id da chave. Dê um nome por sistema ("ERP", "Site", "n8n") para saber quem fez o quê. |
| Endereço IP e User-Agent | Da conexão que fez a chamada. |
| Protocolo (X-Request-Id) | Do cabeçalho que você enviou ou, se não enviou, gerado pelo Hub. |
| Usuário do seu sistema | Do campo externalUser, quando você o envia. |
| Campos alterados | Só os nomes dos campos. O conteúdo (prompt, telefone, senha) não entra na trilha. |
Quem, no seu sistema, enviou a mensagem
Em POST /v1/messages/send, envie o objeto opcional externalUser com o id (até 100 caracteres) e o name (até 120) do usuário que disparou o envio, como o atendente logado no seu ERP. Ele é gravado na mensagem, aparece na conversa como via API · ERP · Maria Souza e volta na resposta em externalUserId e externalUserName.
O mesmo objeto vale em POST /v1/chat/takeover e POST /v1/chat/release: quem assumiu aparece no painel como Maria Souza (via API), volta na lista de conversas em takenOverExternalUserId e takenOverExternalUserName e fica na trilha de auditoria como CONVERSA_ASSUMIDA ou CONVERSA_DEVOLVIDA.
Informação sua, não verificada pelo Hub
externalUser serve para você rastrear o seu pessoal. Ele não muda a permissão do envio, que é sempre a da chave. Não use quebras de linha, < ou > (a requisição recebe 400) e não coloque dados sensíveis, como CPF ou e-mail pessoal.Protocolo da requisição
- Toda resposta traz o cabeçalho
X-Request-Id, inclusive as de erro. Guarde-o no seu log: é por ele que o suporte acha a chamada. - Você pode enviar o seu próprio
x-request-id(o número do pedido, por exemplo): letras, números,.,_,:e-, até 64 caracteres. Fora disso, o Hub gera outro. - Em erros
500, orequestIddo corpo é o mesmo valor do cabeçalho.
Alertas de segurança
Os titulares da conta recebem um e-mail quando:
- uma chave é criada ou revogada;
- uma chave é usada a partir de um endereço IP que ela ainda não tinha usado (o primeiro uso não gera alerta);
- alguém tenta usar uma chave revogada ou vencida, que é o sinal mais comum de vazamento;
- o webhook da organização é alterado.
Recebeu um alerta que não reconhece?
curl -X POST "https://api.geniushub.online/api/v1/messages/send" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "x-request-id: erp-pedido-4821" \
-H "Content-Type: application/json" \
-d '{
"agentId": "593eb3c4-08f5-437f-a377-d2d59da4fb10",
"phone": "5577999990000",
"message": "Seu pedido #4821 saiu para entrega.",
"externalUser": { "id": "42", "name": "Maria Souza" }
}'HTTP/1.1 201 Created
X-Request-Id: erp-pedido-4821
{
"status": "QUEUED",
"message": {
"id": "7f2c1a90-…",
"origem": "API",
"apiKey": { "id": "fc6cb506-…", "name": "ERP", "prefix": "ghk_QNEgn3vY" },
"externalUserId": "42",
"externalUserName": "Maria Souza"
}
}Recurso
Chat
Converse com o agente a partir do seu produto e monte a sua própria inbox. O histórico fica no Genius Hub, amarrado ao chatId que você escolhe — você não precisa guardar nem reenviar o contexto.
Enviar mensagem ao agente
/api/v1/chatEnvia a mensagem do seu usuário ao agente e devolve a resposta gerada, na mesma chamada. Não passa por WhatsApp: serve para o chat do seu site, app ou sistema interno.
- Limite:
- 30 requisições por minuto
Corpo da requisição
agentIdstringobrigatórioId do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.
chatIdstringobrigatórioIdentificador estável da conversa no seu sistema (até 120 caracteres). O mesmo valor continua a conversa; um valor novo começa do zero. Não use um número de telefone — ele colide com as conversas de WhatsApp do agente.
messagestringobrigatórioTexto do usuário. Até 8000 caracteres.
senderNamestringopcionalNome do usuário, para o agente tratá-lo pelo nome.
Retorno
O objeto de resposta do agente.
handoff: truesignifica que o agente pediu atendimento humano. Avise a sua equipe e, se quiser, chamePOST /v1/chat/takeover. O motivo vem emhandoffReason.filesaparece quando o agente quis enviar um arquivo. Aurlé assinada e de validade curta: baixe ou exiba assim que receber.replyvazio é resposta válida: o contato está bloqueado ou silenciado, e a mensagem foi apenas registrada.- Cada chamada consome créditos da organização, como qualquer resposta do agente.
curl -X POST "https://api.geniushub.online/api/v1/chat" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agentId": "593eb3c4-08f5-437f-a377-d2d59da4fb10",
"chatId": "cliente-8842",
"message": "Vocês entregam em Brumado?",
"senderName": "Ana"
}'{
"agentId": "593eb3c4-08f5-437f-a377-d2d59da4fb10",
"chatId": "cliente-8842",
"reply": "Entregamos sim, Ana! O prazo para Brumado é de 2 dias úteis.",
"messageId": "9a41c0de-…",
"toolCallsExecuted": [],
"handoff": false
}Listar conversas
/api/v1/chat/sessions/{agentId}As 100 conversas mais recentes do agente, de todos os canais (API, WhatsApp, web), da mais nova para a mais antiga. É a coluna da esquerda da sua inbox.
Parâmetros de caminho
agentIdstringobrigatórioId do agente.
Retorno
Uma lista de conversas.
handoffStatusresume quem está com a conversa:AGENT(a IA responde),WAITING(o agente pediu uma pessoa) ouHUMAN(alguém assumiu).channeldiz de onde a conversa veio:API,WHATSAPPouWEB.contactAvataré a foto de perfil do contato no WhatsApp, ounull. A URL expira em alguns dias: baixe a imagem se for guardá-la. Veja Foto do contato, na seção de webhooks.
curl -X GET "https://api.geniushub.online/api/v1/chat/sessions/593eb3c4-08f5-437f-a377-d2d59da4fb10" \
-H "x-api-key: $GENIUS_API_KEY"[
{
"id": "b1e0f3c2-…",
"chatId": "5577999990000",
"channel": "WHATSAPP",
"contactName": "Ana",
"contactAvatar": "https://…",
"updatedAt": "2026-10-02T13:40:12.884Z",
"messageCount": 14,
"lastMessage": "Meu pedido já saiu?",
"handoffStatus": "WAITING",
"handoffReason": "Cliente pediu para falar com uma pessoa",
"handoffRequestedAt": "2026-10-02T13:39:58.120Z",
"takenOverAt": null,
"isBlocked": false,
"isMuted": false
}
]Ler histórico
/api/v1/chat/history/{agentId}/{chatId}As mensagens de uma conversa, em ordem cronológica (até 200).
Parâmetros de caminho
agentIdstringobrigatórioId do agente.
chatIdstringobrigatórioO
chatIdda conversa (codifique comencodeURIComponent).
Retorno
Uma lista de mensagens. Lista vazia quando a conversa não existe.
role: "user"é o contato;role: "model"é tudo que saiu do Hub — resposta do agente ou de um atendente.replyTotraz o trecho citado quando a mensagem responde a outra.
curl -X GET "https://api.geniushub.online/api/v1/chat/history/593eb3c4-08f5-437f-a377-d2d59da4fb10/cliente-8842" \
-H "x-api-key: $GENIUS_API_KEY"[
{
"id": "7f2c1a90-…",
"role": "user",
"content": "Vocês entregam em Brumado?",
"createdAt": "2026-10-02T13:40:10.102Z",
"replyTo": null
},
{
"id": "9a41c0de-…",
"role": "model",
"content": "Entregamos sim, Ana! O prazo para Brumado é de 2 dias úteis.",
"createdAt": "2026-10-02T13:40:12.884Z",
"replyTo": null
}
]Assumir conversa
/api/v1/chat/takeoverPassa a conversa para atendimento humano: o agente para de responder aquele contato até ela ser devolvida. Use quando alguém da sua equipe for atender.
Corpo da requisição
agentIdstringobrigatórioId do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.
chatIdstringobrigatórioA conversa a assumir.
Retorno
A conversa atualizada.
- Conversa inexistente responde 404.
curl -X POST "https://api.geniushub.online/api/v1/chat/takeover" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agentId": "593eb3c4-08f5-437f-a377-d2d59da4fb10",
"chatId": "5577999990000"
}'{
"id": "b1e0f3c2-…",
"chatId": "5577999990000",
"isHumanTakenOver": true,
"takenOverAt": "2026-10-02T13:41:00.000Z"
}Devolver ao agente
/api/v1/chat/releaseEncerra o atendimento humano e devolve a conversa para a IA. Também limpa o pedido de atendimento pendente.
Corpo da requisição
agentIdstringobrigatórioId do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.
chatIdstringobrigatórioA conversa a devolver.
Retorno
A conversa atualizada.
curl -X POST "https://api.geniushub.online/api/v1/chat/release" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agentId": "593eb3c4-08f5-437f-a377-d2d59da4fb10",
"chatId": "5577999990000"
}'{
"id": "b1e0f3c2-…",
"chatId": "5577999990000",
"isHumanTakenOver": false,
"takenOverAt": null
}Recurso
Mensagens
Envie mensagens pelo WhatsApp conectado ao agente — notificações do seu sistema, o primeiro contato com um cliente ou a resposta do seu atendente.
Enviar pelo WhatsApp
/api/v1/messages/sendEnvia texto e/ou arquivo para um número pelo canal do agente. A mensagem sai como de um atendente: intacta, sem assinatura e sem ser dividida em partes. Se a conversa ainda não existir, ela é aberta.
- Limite:
- 60 requisições por minuto
Corpo da requisição
agentIdstringobrigatórioAgente cujo número envia a mensagem.
phonestringobrigatórioNúmero com DDI e DDD. Aceita pontuação: “(77) 99999-0000” e “5577999990000” caem na mesma conversa.
messagestringopcionalTexto, até 8000 caracteres. Obrigatório se não houver
file; com arquivo, vira a legenda.fileobjectopcionalArquivo a enviar (imagem, áudio, vídeo ou documento).
contentstringobrigatórioConteúdo em base64, com ou sem o prefixo
data:<mime>;base64,.fileNamestringobrigatórioNome do arquivo, com extensão.
mimeTypestringobrigatórioTipo do arquivo, ex.:
application/pdfouaudio/webm;codecs=opus.asVoiceNotebooleanopcionalSó para áudio.
trueenvia como mensagem de voz do WhatsApp (a bolha com onda, como um áudio gravado no celular). Ausente oufalseenvia como arquivo, com o nome original.
replyToIdstringopcionalId de uma mensagem da mesma conversa, para enviar como resposta citada.
externalUserobjectopcionalQuem, no seu sistema, enviou a mensagem (o atendente logado no seu ERP, por exemplo). Aparece no histórico da conversa como “via API · chave · nome” e na trilha de auditoria. É informação sua, não verificada pelo Hub: a permissão do envio é sempre a da chave.
idstringopcionalId do usuário no seu sistema, até 100 caracteres.
namestringopcionalNome do usuário, até 120 caracteres. Sem quebras de linha,
<ou>.
Retorno
A confirmação de que a mensagem entrou na fila de envio.
QUEUEDsignifica aceita e garantida, não entregue no aparelho. Falhas do provedor viram novas tentativas. Para saber quando saiu, assine o eventomessage.sent.- Sem número conectado no agente, a resposta é 400. Contato bloqueado também é 400.
- Se o número já tiver uma conversa de outro canal (ex.: criada por
POST /v1/chat), a resposta é 409. - Formatos de
file: imagem (JPG, PNG, WEBP, GIF, até 5 MB), vídeo (MP4, MOV, WEBM, até 16 MB), áudio (OGG, MP3, M4A, AAC, WEBM, WAV, AMR, até 16 MB) e documento (PDF, Word, Excel, PowerPoint, TXT, CSV, ZIP, RAR, até 16 MB). Outro formato é 400. - Mensagem de voz aceita qualquer um dos formatos de áudio: o Hub converte para o formato de voz do WhatsApp na entrega.
- Todo envio fica registrado com a chave que o fez, o IP de origem e o
externalUser, se informado. O dono da conta vê isso em Configurações → Atividade. - Toda resposta traz o cabeçalho
X-Request-Id. Guarde-o no seu log: é o que o suporte usa para achar a requisição. Você também pode enviar o seu próprio (letras, números,.,_,:e-, até 64 caracteres).
curl -X POST "https://api.geniushub.online/api/v1/messages/send" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agentId": "593eb3c4-08f5-437f-a377-d2d59da4fb10",
"phone": "5577999990000",
"message": "Seu pedido #4821 saiu para entrega.",
"externalUser": {
"id": "42",
"name": "Maria Souza"
}
}'{
"status": "QUEUED",
"agentId": "593eb3c4-08f5-437f-a377-d2d59da4fb10",
"chatId": "5577999990000",
"sessionId": "b1e0f3c2-…",
"instanceId": "ab9aedfe-4c1f-4f0e-9a52-1d7e2c9b0c11",
"message": {
"id": "7f2c1a90-…",
"role": "model",
"content": "Seu pedido #4821 saiu para entrega.",
"createdAt": "2026-10-02T13:40:12.884Z"
}
}Baixar mídia da conversa
/api/v1/media/{agentId}?path={path}Devolve um link temporário para baixar uma foto, áudio, vídeo ou documento de uma conversa. Use com o mediaUrl (/uploads/...) que chega no webhook ou no histórico, que sozinho não abre sem login.
- Limite:
- 120 requisições por minuto
Parâmetros de caminho
agentIdstringobrigatórioAgente dono da conversa.
pathstringobrigatórioNa query string: o
mediaUrl/uploads/...do webhook ou do histórico, comencodeURIComponent.
Retorno
O link assinado e a validade em segundos.
pathé o caminho/uploads/...exatamente como veio (codifique comencodeURIComponent). Só caminhos de conversa (/uploads/chats/...e/uploads/inbound/...) são aceitos; outro caminho é 400.- Arquivo de outro agente é 404.
- O link vale 10 minutos. O arquivo continua no Hub até a conversa ser limpa: baixe e guarde no seu sistema se precisar dele depois disso.
curl -X GET "https://api.geniushub.online/api/v1/media/593eb3c4-08f5-437f-a377-d2d59da4fb10?path=%2Fuploads%2Finbound%2F…%2Faudio.ogg" \
-H "x-api-key: $GENIUS_API_KEY"{
"url": "https://api.geniushub.online/uploads/inbound/593eb3c4-08f5-437f-a377-d2d59da4fb10/5577999990000/1729520000-ab12cd-audio.ogg?token=…",
"expiresIn": 600
}Recurso
Agentes
Liste, leia, crie, altere e exclua agentes pelo seu sistema. As rotas chamam exatamente o mesmo código do painel, então as regras e os limites do plano são os mesmos. Toda configuração que o estúdio do agente oferece tem uma rota nesta seção e nas quatro seguintes. Ainda só no painel: fluxos, Google Agenda, Conta Azul e Instagram.
Listar agentes
/api/v1/agentsTodos os agentes que a chave alcança, cada um com a configuração completa. Chave restrita vê só os agentes do escopo.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Retorno
A lista de agentes.
curl -X GET "https://api.geniushub.online/api/v1/agents" \
-H "x-api-key: $GENIUS_API_KEY"[
{
"id": "593eb3c4-08f5-437f-a377-d2d59da4fb10",
"name": "Atendimento Loja Centro",
"status": "ACTIVE",
"isPaused": false,
"aiProvider": "GEMINI",
"aiModel": "gemini-3.7-flash",
"counts": { "intentions": 2, "files": 5, "sessions": 318, "instances": 1 },
"whatsappConnected": true
}
]Consultar agente
/api/v1/agents/{agentId}O agente com toda a configuração em profile — prompt, modelo, horário, follow-up, preferências, emergência — e as intenções, os arquivos e os canais.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
agentIdstringobrigatórioId do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.
Retorno
{ profile, intentions, files, instances, counts }.
curl -X GET "https://api.geniushub.online/api/v1/agents/593eb3c4-08f5-437f-a377-d2d59da4fb10" \
-H "x-api-key: $GENIUS_API_KEY"{
"profile": {
"id": "593eb3c4-08f5-437f-a377-d2d59da4fb10",
"name": "Atendimento Loja Centro",
"behavior": "Você atende clientes da Loja Centro…",
"isPaused": false,
"operatingHours": { "enabled": true, "timezone": "America/Sao_Paulo" },
"followUpEnabled": true,
"useEmojis": true,
"useCatalog": false
},
"intentions": [],
"files": [{ "id": "…", "fileName": "tabela.pdf" }],
"instances": [{ "id": "ab9aedfe-4c1f-4f0e-9a52-1d7e2c9b0c11", "status": "CONNECTED" }],
"counts": { "intentions": 0, "files": 1, "instances": 1, "sessions": 318 }
}Criar agente
/api/v1/agentsCria um agente na organização da chave. Respeita o limite de agentes do plano.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN), sem restrição de agentes
Corpo da requisição
namestringobrigatórioNome do agente, de 2 a 80 caracteres.
behaviorstringobrigatórioO prompt: quem ele é, como fala, o que pode e o que não pode. De 10 a 200 000 caracteres.
typestringopcionalSUPPORT,SALEouPERSONAL.statusstringopcionalACTIVE,TRAININGouDISABLED.jobNamestringopcionalEmpresa ou área que ele representa.
jobDescriptionstringopcionalContexto do negócio (até 4000).
jobSitestringopcionalSite da empresa.
communicationTypestringopcionalTom de voz (até 40).
aiProviderstringopcionalProvedor de IA. Veja
GET /v1/ai-models.aiModelstringopcionalModelo de IA. Combinação fora da lista é recusada.
avatarstringopcionalURL da foto. Vazio sorteia uma.
proposalEnabledbooleanopcionalGera propostas comerciais em PDF.
responseLengthnumberopcionalExtensão das respostas, 1 a 5. Só chave de ADMIN.
Retorno
O agente criado.
- Uma chave restrita a agentes específicos recebe 403: o agente novo nasceria fora do escopo dela.
curl -X POST "https://api.geniushub.online/api/v1/agents" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Atendimento Loja Centro",
"behavior": "Você atende clientes da Loja Centro. Responda em português, de forma curta e cordial.",
"jobName": "Loja Centro",
"type": "SALE",
"aiProvider": "GEMINI",
"aiModel": "gemini-3.7-flash"
}'{
"id": "7d1b2c3e-…",
"name": "Atendimento Loja Centro",
"status": "ACTIVE",
"aiModel": "gemini-3.7-flash"
}Alterar agente
/api/v1/agents/{agentId}Altera perfil, prompt e modelo. Envie só os campos que quer mudar — os mesmos de Criar agente, mais useCatalog.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
agentIdstringobrigatórioId do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.
Corpo da requisição
behaviorstringopcionalNovo prompt.
aiModelstringopcionalNovo modelo.
useCatalogbooleanopcionalLiga ou desliga o catálogo nas conversas.
maxChannels, maxClientsnumberopcionalLimites contratados. Só chave de ADMIN.
Retorno
O perfil atualizado.
- Campo desconhecido é recusado com 400 — nada é ignorado em silêncio.
curl -X PUT "https://api.geniushub.online/api/v1/agents/593eb3c4-08f5-437f-a377-d2d59da4fb10" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"behavior": "Você atende clientes da Loja Centro. Nunca prometa prazo que não esteja na base."
}'{
"id": "593eb3c4-08f5-437f-a377-d2d59da4fb10",
"name": "Atendimento Loja Centro",
"behavior": "Você atende clientes da Loja Centro. Nunca prometa prazo…"
}Excluir agente
/api/v1/agents/{agentId}Exclui o agente e, em cascata, as conversas, os arquivos e os canais dele. Não pode ser desfeito.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
agentIdstringobrigatórioId do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.
Retorno
Confirmação da exclusão.
curl -X DELETE "https://api.geniushub.online/api/v1/agents/593eb3c4-08f5-437f-a377-d2d59da4fb10" \
-H "x-api-key: $GENIUS_API_KEY"{ "success": true }Modelos de IA
/api/v1/ai-modelsOs valores aceitos em aiProvider e aiModel.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Retorno
Os provedores e seus modelos.
curl -X GET "https://api.geniushub.online/api/v1/ai-models" \
-H "x-api-key: $GENIUS_API_KEY"[
{ "provider": "GEMINI", "models": [{ "value": "gemini-3.7-flash", "label": "Gemini 3.7 Flash (Recomendado)" }] },
{ "provider": "OPENAI", "models": [{ "value": "gpt-5.6-terra", "label": "GPT-5.6 Terra (Recomendado)" }] }
]Recurso
Configuração do agente
Pausa, horário de atendimento, follow-up, preferências de conversa, foto, emergência, pessoas a chamar e o funil que o agente alimenta — as abas de configuração do estúdio do agente.
Endpoints
- PUT
/v1/agents/{agentId}/pause - PUT
/v1/agents/{agentId}/operating-hours - PUT
/v1/agents/{agentId}/follow-up - PUT
/v1/agents/{agentId}/conversation-prefs - POST
/v1/agents/{agentId}/avatar - PUT
/v1/agents/{agentId}/emergency - POST
/v1/agents/{agentId}/callable-people - GET
/v1/agents/{agentId}/callable-people/groups - POST
/v1/agents/{agentId}/callable-people/{personId}/test - PUT
/v1/agents/{agentId}/pipeline/{pipelineId}
Pausar ou retomar
/api/v1/agents/{agentId}/pausePausado, o agente continua recebendo e gravando as mensagens, mas não responde.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
agentIdstringobrigatórioId do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.
Corpo da requisição
isPausedbooleanobrigatóriotruepausa,falseretoma.
Retorno
O novo estado.
curl -X PUT "https://api.geniushub.online/api/v1/agents/593eb3c4-08f5-437f-a377-d2d59da4fb10/pause" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"isPaused": true
}'{ "agentId": "593eb3c4-08f5-437f-a377-d2d59da4fb10", "isPaused": true }Horário de atendimento
/api/v1/agents/{agentId}/operating-hoursSubstitui o expediente inteiro. Fora do horário, o agente responde a mensagem de ausência sem consultar a IA.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
agentIdstringobrigatórioId do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.
Corpo da requisição
operatingHoursobjectobrigatórioO expediente.
enabledbooleanopcionalLiga o controle de horário.
timezonestringopcionalFuso IANA, ex.:
America/Sao_Paulo.outOfHoursMessagestringopcionalMensagem de ausência (até 1000).
noticeCooldownHoursnumberopcionalHoras de silêncio entre dois avisos ao mesmo contato (0–720).
scheduleobjectopcionalmonday…sunday, cada um{ active, windows: [{ start, end }] }emHH:MM. Até 6 faixas por dia.exceptionsobject[]opcionalFeriados e plantões:
{ date (YYYY-MM-DD, ou MM-DD com annual), label?, annual?, message?, windows? }. Comwindows, a data abre só nelas.
Retorno
O expediente gravado.
- Hora fora de
HH:MM, dia com outro nome ou fuso inválido respondem 400 com o caminho do campo.
curl -X PUT "https://api.geniushub.online/api/v1/agents/593eb3c4-08f5-437f-a377-d2d59da4fb10/operating-hours" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"operatingHours": {
"enabled": true,
"timezone": "America/Sao_Paulo",
"outOfHoursMessage": "Estamos fora do horário. Voltamos amanhã às 8h.",
"schedule": {
"monday": {
"active": true,
"windows": [
{
"start": "08:00",
"end": "12:00"
},
{
"start": "13:00",
"end": "18:00"
}
]
},
"sunday": {
"active": false
}
},
"exceptions": [
{
"date": "12-25",
"label": "Natal",
"annual": true
}
]
}
}'{ "agentId": "593eb3c4-08f5-437f-a377-d2d59da4fb10", "operatingHours": { "enabled": true, "timezone": "America/Sao_Paulo" } }Follow-up e devolução
/api/v1/agents/{agentId}/follow-upMensagens de retomada quando o contato para de responder, e devolução automática à IA da conversa assumida por um humano.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
agentIdstringobrigatórioId do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.
Corpo da requisição
followUpEnabledbooleanopcionalLiga o follow-up.
followUpsobject[]opcionalAté 3 etapas
{ delayMinutes (1–43200), message (até 1000) }.autoReleaseMinutesnumberopcionalDevolve à IA a conversa assumida após N minutos sem atividade (0 desliga).
autoReleaseWaitingMinutesnumberopcionalIdem, para a conversa que ficou esperando um humano.
Retorno
A configuração gravada.
curl -X PUT "https://api.geniushub.online/api/v1/agents/593eb3c4-08f5-437f-a377-d2d59da4fb10/follow-up" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"followUpEnabled": true,
"followUps": [
{
"delayMinutes": 60,
"message": "Ficou alguma dúvida? Posso ajudar."
}
],
"autoReleaseMinutes": 1440
}'{ "followUpEnabled": true, "followUps": [{ "delayMinutes": 60, "message": "Ficou alguma dúvida? Posso ajudar." }] }Preferências de conversa
/api/v1/agents/{agentId}/conversation-prefsEstilo, temas sensíveis, leitura de imagens e documentos, teto de interações, tempo de resposta e opções do WhatsApp. Só altera os campos enviados.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
agentIdstringobrigatórioId do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.
Corpo da requisição
useEmojisbooleanopcionalPermite emojis.
signAgentNamebooleanopcionalAssina as respostas com o nome do agente.
restrictTopicsbooleanopcionalRecusa assuntos fora do escopo do prompt.
sensitiveThemesobject[]opcionalAté 50
{ id, name, action, active?, keywords? }. Substitui a lista.splitLongRepliesbooleanopcionalDivide respostas longas em várias mensagens.
analyzeImagesbooleanopcionalLê as imagens que o contato manda (gasta créditos).
documentReaderProviderstringopcionalAUTO,GEMINI,TEXTRACT,REKOGNITIONouDEEPSEEK.documentReaderModestringopcionalTEXTRACT_TEXT,TEXTRACT_TABLESouTEXTRACT_FORMS.imageReaderModelstring | nullopcionalModelo DeepSeek que lê as fotos (lista em
GET /ai/models/deepseek/vision). Vazio usadeepseek-flash.imageReaderThinkingstringopcionalRaciocínio do leitor DeepSeek:
OFF(padrão),LOWouHIGH.imageAnalysisHintstring | nullopcionalO que a leitura deve observar nas fotos deste negócio (até 1000 caracteres).
maxInteractionsnumberopcionalTeto de respostas por conversa (0–200; 0 = sem teto).
replyWaitSecondsnumberopcionalTempo de resposta:
0(imediata) ou de5a15segundos de silêncio do contato antes de responder (padrão 5). Mensagens seguidas dentro desse tempo viram uma resposta só.evoReadMessagesbooleanopcionalMarca as mensagens como lidas no WhatsApp.
evoRejectCallbooleanopcionalRecusa ligações.
evoCallMessagestringopcionalMensagem enviada ao recusar a ligação.
evoIgnoreGroupsbooleanopcionalIgnora grupos.
evoAlwaysOnlinebooleanopcionalMantém o número como online.
Retorno
As preferências gravadas.
curl -X PUT "https://api.geniushub.online/api/v1/agents/593eb3c4-08f5-437f-a377-d2d59da4fb10/conversation-prefs" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"useEmojis": false,
"splitLongReplies": true,
"maxInteractions": 40,
"replyWaitSeconds": 6
}'{ "useEmojis": false, "splitLongReplies": true, "maxInteractions": 40, "replyWaitSeconds": 6 }Enviar foto
/api/v1/agents/{agentId}/avatarTroca a foto do agente. A imagem vai em base64.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
agentIdstringobrigatórioId do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.
Corpo da requisição
avatarDataUristringobrigatórioImagem em data URI (
data:image/png;base64,…), até ~4 MB.fileNamestringopcionalNome do arquivo.
Retorno
O endereço da nova foto.
curl -X POST "https://api.geniushub.online/api/v1/agents/593eb3c4-08f5-437f-a377-d2d59da4fb10/avatar" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"avatarDataUri": "data:image/png;base64,iVBORw0KGgo…",
"fileName": "logo.png"
}'{ "success": true, "avatarUrl": "https://…/uploads/avatars/…png" }Emergência
/api/v1/agents/{agentId}/emergencyO marcador que o prompt manda a IA escrever numa emergência e o aviso que o sistema garante na resposta. GET na mesma rota lê a configuração.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
agentIdstringobrigatórioId do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.
Corpo da requisição
emergencyMarkerstringopcionalPalavra visível com que a IA abre a resposta numa emergência (ex.: "Emergência"), de 3 a 60 caracteres. Fica no texto; o sistema garante o aviso e aciona as pessoas de emergência. Vazio desliga o acionamento automático.
emergencyNoticestringopcionalAviso ao contato (até 400).
Retorno
A configuração gravada.
curl -X PUT "https://api.geniushub.online/api/v1/agents/593eb3c4-08f5-437f-a377-d2d59da4fb10/emergency" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"emergencyMarker": "Emergência",
"emergencyNotice": "Já acionei nossa equipe. Em caso de risco, ligue 192."
}'{ "emergencyMarker": "Emergência", "emergencyNotice": "Já acionei nossa equipe…" }Cadastrar pessoa ou grupo a chamar
/api/v1/agents/{agentId}/callable-peopleUma pessoa, ou um grupo do WhatsApp da equipe, que o agente pode acionar quando o atendimento pede alguém. Até 10 por agente. No grupo, o aviso pode marcar membros: fixos, todos ou escolhidos pela IA. GET na mesma rota lista; PATCH e DELETE em /callable-people/{personId} editam e removem.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
agentIdstringobrigatórioId do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.
Corpo da requisição
namestringobrigatórioNome (até 60) — é por ele que o agente escolhe o destino.
targetTypestringopcionalPERSON(padrão) ouGROUP.phonestringopcionalSó de
PERSON, e obrigatório nele: WhatsApp com DDI e DDD.groupJidstringopcionalSó de
GROUP, e obrigatório nele: ojiddeGET /callable-people/groups. O número do agente precisa estar no grupo e poder enviar.mentionModestringopcionalGrupo:
FIXED(padrão, marca os demembers),AI(a IA escolhe entremembers),ALL(todos) ouNONE.membersarrayopcionalGrupo, até 20:
{ id, name, whenToMention }.idvem deGET /callable-people/groups/{groupJid}/participants;whenToMention(até 200) é obrigatório no modoAI.sectorstringopcionalÁrea (até 60).
whenToCallstringopcionalQuando chamar (até 400). É o que a IA lê para decidir.
activebooleanopcionalDesativado, o agente não o oferece.
includeTranscriptbooleanopcionalJunta as últimas mensagens da conversa ao aviso. Padrão
true.notifyInTestModebooleanopcionalO Modo Teste do painel também manda o aviso de verdade, marcado como teste. Padrão
false.shareWithContactbooleanopcionalSó de
PERSON: envia o número dela ao contato.callOnEmergencybooleanopcionalAcionado automaticamente numa emergência.
mentionAllOnEmergencybooleanopcionalGrupo: num aviso de emergência, marca todos.
Retorno
O cadastro criado.
curl -X POST "https://api.geniushub.online/api/v1/agents/593eb3c4-08f5-437f-a377-d2d59da4fb10/callable-people" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Financeiro",
"targetType": "GROUP",
"groupJid": "120363000000000001@g.us",
"mentionMode": "AI",
"members": [
{
"id": "111111111111111@lid",
"name": "Carla",
"whenToMention": "boletos e segunda via"
},
{
"id": "222222222222222@lid",
"name": "Diego",
"whenToMention": "negociação de dívidas"
}
],
"whenToCall": "Boletos, segunda via e negociação de dívidas."
}'{ "id": "…", "name": "Financeiro", "targetType": "GROUP", "groupName": "Equipe Financeiro", "mentionMode": "AI", "active": true }Grupos do WhatsApp do agente
/api/v1/agents/{agentId}/callable-people/groupsOs grupos de que o número do agente participa, para usar como destino. Só para números conectados pela Evolution. GET /callable-people/groups/{groupJid}/participants traz os membros (id, phone, name, admin) e se o número do agente pode enviar (agenteNoGrupo, agentePodeEnviar).
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
agentIdstringobrigatórioId do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.
Retorno
A lista de grupos.
curl -X GET "https://api.geniushub.online/api/v1/agents/593eb3c4-08f5-437f-a377-d2d59da4fb10/callable-people/groups" \
-H "x-api-key: $GENIUS_API_KEY"[{ "jid": "120363000000000001@g.us", "name": "Equipe Financeiro", "size": 8, "announce": false }]Enviar aviso de teste
/api/v1/agents/{agentId}/callable-people/{personId}/testManda ao destino uma mensagem de teste, com as marcações que o aviso real usaria. Se a entrega falhar, o cadastro passa a trazer lastDeliveryError.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
agentIdstringobrigatórioId do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.
personIdstringobrigatórioId do cadastro.
Retorno
Quem foi marcado.
curl -X POST "https://api.geniushub.online/api/v1/agents/593eb3c4-08f5-437f-a377-d2d59da4fb10/callable-people/…/test" \
-H "x-api-key: $GENIUS_API_KEY"{ "enviado": true, "marcados": ["Carla", "Diego"] }Ligar ao funil
/api/v1/agents/{agentId}/pipeline/{pipelineId}Liga o agente a um funil: cada contato novo vira um negócio na etapa de entrada. GET /v1/agents/{agentId}/pipeline mostra a ligação atual; DELETE na mesma rota desliga.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
agentIdstringobrigatórioId do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.
pipelineIdstringobrigatórioId do funil.
Corpo da requisição
entryStageIdstringobrigatórioEtapa em andamento em que o negócio nasce.
createOnstringopcionalFIRST_MESSAGE,FIRST_FIELDouMANUAL.enabledbooleanopcionalLiga ou pausa a captura.
Retorno
A ligação gravada.
- Um agente alimenta um funil ativo por vez: ativar com outro já ativo responde 409.
curl -X PUT "https://api.geniushub.online/api/v1/agents/593eb3c4-08f5-437f-a377-d2d59da4fb10/pipeline/7f3e1c2a-9b4d-4e8f-a1c6-5d2b8e9f0a13" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entryStageId": "…",
"createOn": "FIRST_MESSAGE",
"enabled": true
}'{ "pipelineId": "7f3e1c2a-9b4d-4e8f-a1c6-5d2b8e9f0a13", "agentId": "593eb3c4-08f5-437f-a377-d2d59da4fb10", "entryStageId": "…", "createOn": "FIRST_MESSAGE", "enabled": true }Recurso
Base de conhecimento
O que o agente sabe além do prompt. Arquivos vão em base64 dentro do JSON. A extração e a indexação rodam em segundo plano: o envio responde antes de o arquivo estar pesquisável — acompanhe por knowledge/status. Extrair PDF e imagem gasta créditos de IA.
Enviar arquivo ou texto
/api/v1/agents/{agentId}/filesPDF, DOCX, planilha, imagem ou texto puro. GET na mesma rota lista os arquivos com o estado da indexação.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
agentIdstringobrigatórioId do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.
Corpo da requisição
fileNamestringobrigatórioNome com extensão.
contentstringobrigatórioTexto, ou o arquivo em base64. Até 20 MB.
fileTypestringopcionalTipo (ex.:
pdf). Sem ele, vale a extensão.
Retorno
O arquivo registrado.
curl -X POST "https://api.geniushub.online/api/v1/agents/593eb3c4-08f5-437f-a377-d2d59da4fb10/files" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"fileName": "politica-de-trocas.txt",
"content": "Trocas em até 30 dias com nota fiscal…"
}'{ "id": "f3a1…", "fileName": "politica-de-trocas.txt", "indexStatus": "PENDING", "downloadUrl": null, "extractionNote": null }Adicionar página web
/api/v1/agents/{agentId}/files/websiteO conteúdo da página é baixado e indexado como texto. Endereços internos são recusados.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
agentIdstringobrigatórioId do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.
Corpo da requisição
urlstringobrigatórioURL completa.
titlestringopcionalTítulo.
Retorno
O arquivo registrado.
- Para vídeo, use
POST /v1/agents/{agentId}/files/videocom{ videoUrl, title?, textContent? }— o vídeo não é transcrito, vale otextContent.
curl -X POST "https://api.geniushub.online/api/v1/agents/593eb3c4-08f5-437f-a377-d2d59da4fb10/files/website" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://lojacentro.com.br/faq",
"title": "Perguntas frequentes"
}'{ "id": "f3a2…", "fileName": "Perguntas frequentes" }Estado da indexação
/api/v1/agents/{agentId}/knowledge/statusQuantos arquivos e trechos estão indexados e se há indexação em andamento.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
agentIdstringobrigatórioId do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.
Retorno
O estado da base.
GET /v1/agents/{agentId}/knowledge/search?q=…mostra o que o agente encontraria para uma pergunta.POST /v1/agents/{agentId}/knowledge/reindexcom{ force? }reindexa a base.
curl -X GET "https://api.geniushub.online/api/v1/agents/593eb3c4-08f5-437f-a377-d2d59da4fb10/knowledge/status" \
-H "x-api-key: $GENIUS_API_KEY"{
"ready": true,
"totals": { "files": 5, "indexed": 4, "pending": 1, "failed": 0, "chunks": 212 },
"files": [{ "id": "f3a1…", "fileName": "tabela.pdf", "indexStatus": "INDEXED", "chunkCount": 48 }]
}Como o agente usa o arquivo
/api/v1/files/{fileId}/usageBuscado só quando relevante ou sempre no contexto, e se o agente pode enviar o arquivo ao contato.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
fileIdstringobrigatórioId do arquivo.
Corpo da requisição
usageModestringopcionalRETRIEVED(quando relevante) ouALWAYS(sempre no contexto).enviavelAoClientebooleanopcionalO agente pode mandar o arquivo ao contato.
instructionsstringopcionalComo interpretar o arquivo (até 4000).
Retorno
O arquivo atualizado.
GET /v1/files/{fileId}/contentdevolve o texto extraído;POST /v1/files/{fileId}/indexreindexa só ele.
curl -X PATCH "https://api.geniushub.online/api/v1/files/f3a1…/usage" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"usageMode": "ALWAYS",
"enviavelAoCliente": true
}'{ "id": "f3a1…", "usageMode": "ALWAYS", "enviavelAoCliente": true }Remover arquivo
/api/v1/files/{fileId}Remove o arquivo e os trechos indexados dele.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
fileIdstringobrigatórioId do arquivo.
Retorno
Confirmação.
curl -X DELETE "https://api.geniushub.online/api/v1/files/f3a1…" \
-H "x-api-key: $GENIUS_API_KEY"{ "success": true }Recurso
Intenções e skills
O que o agente sabe fazer. Intenção é uma chamada HTTP que ele dispara durante a conversa — consultar pedido, agendar, emitir boleto. Skill é uma instrução carregada quando o assunto aparece.
Criar intenção
/api/v1/agents/{agentId}/intentionsGET na mesma rota lista as intenções. PATCH e DELETE em /v1/intentions/{intentionId} editam (com active e standaloneUse) e removem.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
agentIdstringobrigatórioId do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.
Corpo da requisição
descriptionstringobrigatórioQuando usar (3 a 200).
urlstringobrigatórioEndereço chamado. Endereço interno é recusado.
httpMethodstringopcionalGET,POST,PUT,PATCHouDELETE.instructionsstringopcionalComo usar o resultado (até 4000).
fieldsobject[]opcionalO que perguntar ao contato antes:
{ name, type?: STRING|NUMBER|BOOLEAN|ARRAY|OBJECT, description?, required? }.headers, paramsobject[]opcional{ name, value? }.requestBodystringopcionalCorpo da requisição, com variáveis.
responseModestringopcionalINTERPRET(a IA resume) ouLITERAL(repassa).outputVariablesobject[]opcional{ name, expression }: o que guardar da resposta.
Retorno
A intenção criada.
curl -X POST "https://api.geniushub.online/api/v1/agents/593eb3c4-08f5-437f-a377-d2d59da4fb10/intentions" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"description": "Consultar o status de um pedido",
"url": "https://erp.lojacentro.com.br/pedidos/{{numero}}",
"httpMethod": "GET",
"fields": [
{
"name": "numero",
"type": "STRING",
"description": "Número do pedido",
"required": true
}
]
}'{ "id": "i9c2…", "description": "Consultar o status de um pedido", "active": true }Criar skill
/api/v1/agents/{agentId}/skillsGET na mesma rota lista; PATCH e DELETE em /skills/{skillId} editam e removem.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
agentIdstringobrigatórioId do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.
Corpo da requisição
namestringobrigatórioNome único no agente (até 80).
descriptionstringobrigatórioQuando a skill vale (até 500).
contentstringopcionalA instrução em si.
triggersstring[]opcionalPalavras que puxam a skill.
loadModestringopcionalALWAYSouON_DEMAND.prioritynumberopcionalOrdem entre skills.
activebooleanopcionalDesativada, não é carregada.
Retorno
A skill criada.
curl -X POST "https://api.geniushub.online/api/v1/agents/593eb3c4-08f5-437f-a377-d2d59da4fb10/skills" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "trocas",
"description": "Quando o contato quer trocar ou devolver um produto",
"content": "Peça o número da nota…",
"loadMode": "ON_DEMAND"
}'{ "id": "s1…", "name": "trocas", "loadMode": "ON_DEMAND", "active": true }Recurso
Catálogo
Os produtos que o agente oferece. Use para manter preço e estoque sincronizados com o seu ERP.
Consultar catálogo
/api/v1/agents/{agentId}/catalogProdutos (inclusive inativos) com mídia, o estado do catálogo e os limites de arquivo. PUT .../catalog/enabled com { useCatalog } liga ou desliga.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
agentIdstringobrigatórioId do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.
Retorno
O catálogo.
curl -X GET "https://api.geniushub.online/api/v1/agents/593eb3c4-08f5-437f-a377-d2d59da4fb10/catalog" \
-H "x-api-key: $GENIUS_API_KEY"{
"useCatalog": true,
"settings": { "presentation": "ON_REQUEST", "maxItems": 3, "showPrice": true, "sendMedia": true },
"items": [{ "id": "p1…", "name": "Tênis Corrida", "price": 299.9, "stock": 12, "media": [] }]
}Como o agente usa o catálogo
/api/v1/agents/{agentId}/catalog/settingsQuando buscar, como apresentar, quantos itens mostrar, se mostra preço e mídia.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
agentIdstringobrigatórioId do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.
Corpo da requisição
description, whenToSearch, qualification, noResults, nextActionstringopcionalInstruções (até 4000 cada).
presentationstringopcionalON_REQUEST,AFTER_QUALIFICATIONouWHEN_RELEVANT.maxItemsnumberopcionalItens por resposta (1 a 5).
sendMediabooleanopcionalEnvia as fotos do produto.
showPricebooleanopcionalMostra o preço.
Retorno
A configuração gravada.
curl -X PUT "https://api.geniushub.online/api/v1/agents/593eb3c4-08f5-437f-a377-d2d59da4fb10/catalog/settings" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"presentation": "AFTER_QUALIFICATION",
"maxItems": 3,
"showPrice": true
}'{ "presentation": "AFTER_QUALIFICATION", "maxItems": 3, "showPrice": true, "sendMedia": true }Cadastrar produto
/api/v1/agents/{agentId}/catalog/productsPATCH /v1/products/{productId} altera (campos ausentes ficam como estão); DELETE remove — para só esconder, use isActive: false.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
agentIdstringobrigatórioId do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.
Corpo da requisição
namestringobrigatórioNome.
pricenumberopcionalPreço.
stocknumberopcionalEstoque.
description, category, details, callToAction, availabilitystringopcionalDescrição e informações do produto.
aliasesstring[]opcionalOutros nomes pelos quais o contato pede o produto.
attributesobjectopcionalAtributos livres (cor, tamanho), valores texto, número ou booleano.
isActivebooleanopcionalInativo, o agente não oferece.
Retorno
O produto criado.
curl -X POST "https://api.geniushub.online/api/v1/agents/593eb3c4-08f5-437f-a377-d2d59da4fb10/catalog/products" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Tênis Corrida",
"price": 299.9,
"stock": 12,
"category": "Calçados",
"attributes": {
"cor": "azul",
"tamanho": 42
}
}'{ "id": "p1…", "name": "Tênis Corrida", "price": 299.9, "stock": 12, "isActive": true }Anexar foto ou vídeo
/api/v1/products/{productId}/mediaAté 4 imagens ou 1 vídeo por produto. DELETE /v1/product-media/{mediaId} remove.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
productIdstringobrigatórioId do produto.
Corpo da requisição
contentstringobrigatórioArquivo em base64, com ou sem
data:.fileNamestringobrigatórioNome com extensão.
mimeTypestringopcionalTipo do arquivo.
Retorno
A mídia anexada.
curl -X POST "https://api.geniushub.online/api/v1/products/p1…/media" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "data:image/jpeg;base64,/9j/4AAQ…",
"fileName": "tenis.jpg"
}'{ "id": "m1…", "productId": "p1…", "kind": "IMAGE", "url": "https://…/tenis.jpg", "fileName": "tenis.jpg" }Recurso
Canais
Conecte um número de WhatsApp a um agente: crie o canal, peça o QR Code e consulte até o status virar CONNECTED.
Criar canal
/api/v1/channelsRegistra um número para o agente e configura o recebimento de mensagens no provedor.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Corpo da requisição
agentIdstringobrigatórioAgente que vai responder neste número.
providerstringopcionalEVOLUTION(padrão) ouZAPI.displayNamestringopcionalNome do canal na sua lista, até 60 caracteres.
zapiInstanceIdstringopcionalObrigatório com
provider: "ZAPI".zapiTokenstringopcionalObrigatório com
provider: "ZAPI".zapiClientTokenstringopcionalClient token da conta Z-API, quando houver.
Retorno
O canal criado.
curl -X POST "https://api.geniushub.online/api/v1/channels" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agentId": "593eb3c4-08f5-437f-a377-d2d59da4fb10",
"displayName": "Loja Centro · WhatsApp"
}'{
"instance": {
"id": "ab9aedfe-4c1f-4f0e-9a52-1d7e2c9b0c11",
"instanceName": "loja-centro-7d1b-1",
"status": "DISCONNECTED",
"agent": { "id": "593eb3c4-08f5-437f-a377-d2d59da4fb10", "name": "Atendimento Loja Centro" }
}
}Gerar QR Code
/api/v1/channels/{id}/connectInicia o pareamento e devolve o QR Code para ler no celular que vai atender.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
idstringobrigatórioId do canal.
Retorno
O QR Code e o status do pareamento.
- O QR Code expira em poucos segundos. Chame de novo para gerar outro em vez de guardar o primeiro.
curl -X POST "https://api.geniushub.online/api/v1/channels/ab9aedfe-4c1f-4f0e-9a52-1d7e2c9b0c11/connect" \
-H "x-api-key: $GENIUS_API_KEY"{
"status": "CONNECTING",
"qrCode": "data:image/png;base64,iVBORw0KGgo…"
}Consultar canal
/api/v1/channels/{id}A situação do canal, consultada no provedor na hora. Consulte a cada poucos segundos depois do QR Code até o status virar CONNECTED.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
idstringobrigatórioId do canal.
Retorno
O canal.
status:DISCONNECTED,CONNECTING,CONNECTEDouERROR. OqrCodesó vem preenchido emCONNECTING.
curl -X GET "https://api.geniushub.online/api/v1/channels/ab9aedfe-4c1f-4f0e-9a52-1d7e2c9b0c11" \
-H "x-api-key: $GENIUS_API_KEY"{
"id": "ab9aedfe-4c1f-4f0e-9a52-1d7e2c9b0c11",
"instanceName": "loja-centro-7d1b-1",
"status": "CONNECTED",
"phoneNumber": "5577999990000",
"connectedAt": "2026-10-02T13:47:20.551Z",
"qrCode": null
}Excluir canal
/api/v1/channels/{id}Desconecta o número e remove o canal. As conversas do agente continuam no histórico.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
idstringobrigatórioId do canal.
Retorno
Confirmação da exclusão.
curl -X DELETE "https://api.geniushub.online/api/v1/channels/ab9aedfe-4c1f-4f0e-9a52-1d7e2c9b0c11" \
-H "x-api-key: $GENIUS_API_KEY"{ "success": true }Recurso
Webhooks
Em vez de consultar a API em laço, receba um POST no seu servidor a cada mensagem que entra ou sai. Configure pelo agente (agentId) para receber todos os canais dele — WhatsApp, Instagram e /v1/chat — ou por número (instanceId) para só o tráfego daquele WhatsApp. Com os dois, o do número vence para aquele número e nada chega em dobro.
Configurar webhook
/api/v1/webhooks/configDefine para onde vão os eventos de um agente ou de um número. Informe um alvo só. Chamar de novo para o mesmo alvo substitui a configuração anterior.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Corpo da requisição
agentIdstringopcionalAgente cujos canais disparam os eventos (todos: WhatsApp, Instagram e
/v1/chat). Use este ouinstanceId.instanceIdstringopcionalNúmero de WhatsApp que dispara os eventos (só ele). Use este ou
agentId.urlstringobrigatórioURL
https://pública do seu servidor. Endereços internos são recusados.eventsstring[]opcionalmessage.received,message.sente os eventos do funil:card.created,card.stage_changed,card.won,card.lost. Omitido, assina só as mensagens; os eventos do funil são escolha explícita.secretstringopcionalSeu segredo de assinatura (16 a 200 caracteres). Omitido, o Hub gera um.
Retorno
A configuração, com o segredo de assinatura.
- O
secretsó é exibido nesta resposta. Guarde-o: é com ele que você confere a assinatura de cada entrega. agentIdeinstanceIdjuntos, ou nenhum dos dois, respondem400.
curl -X POST "https://api.geniushub.online/api/v1/webhooks/config" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agentId": "593eb3c4-08f5-437f-a377-d2d59da4fb10",
"url": "https://seusistema.com.br/hooks/genius",
"events": [
"message.received",
"message.sent"
]
}'{
"id": "c88a5b1e-…",
"scope": "AGENT",
"agent": { "id": "593eb3c4-08f5-437f-a377-d2d59da4fb10", "name": "Atendimento" },
"instanceId": null,
"url": "https://seusistema.com.br/hooks/genius",
"events": ["message.received", "message.sent"],
"isActive": true,
"lastStatus": null,
"lastError": null,
"secret": "6f1c9d0b7e…",
"aviso": "Guarde este segredo: ele não é exibido de novo."
}Consultar webhook do agente
/api/v1/webhooks/config/agent/{agentId}A configuração do agente e o resultado da última entrega — o primeiro lugar para olhar quando os eventos param de chegar.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
agentIdstringobrigatórioId do agente.
Retorno
A configuração, sem o segredo.
curl -X GET "https://api.geniushub.online/api/v1/webhooks/config/agent/593eb3c4-08f5-437f-a377-d2d59da4fb10" \
-H "x-api-key: $GENIUS_API_KEY"{
"scope": "AGENT",
"agent": { "id": "593eb3c4-08f5-437f-a377-d2d59da4fb10", "name": "Atendimento" },
"instanceId": null,
"url": "https://seusistema.com.br/hooks/genius",
"events": ["message.received", "message.sent"],
"isActive": true,
"lastStatus": 200,
"lastError": null,
"lastDeliveryAt": "2026-10-02T13:52:03.771Z"
}Desativar webhook do agente
/api/v1/webhooks/config/agent/{agentId}Para de enviar os eventos do agente. A configuração fica guardada e volta a valer com um novo POST /v1/webhooks/config.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
agentIdstringobrigatórioId do agente.
Retorno
A configuração desativada.
curl -X DELETE "https://api.geniushub.online/api/v1/webhooks/config/agent/593eb3c4-08f5-437f-a377-d2d59da4fb10" \
-H "x-api-key: $GENIUS_API_KEY"{
"scope": "AGENT",
"isActive": false
}Consultar webhook do número
/api/v1/webhooks/config/{instanceId}A configuração de um número e o resultado da última entrega.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
instanceIdstringobrigatórioId do canal.
Retorno
A configuração, sem o segredo.
curl -X GET "https://api.geniushub.online/api/v1/webhooks/config/ab9aedfe-4c1f-4f0e-9a52-1d7e2c9b0c11" \
-H "x-api-key: $GENIUS_API_KEY"{
"scope": "INSTANCE",
"instanceId": "ab9aedfe-4c1f-4f0e-9a52-1d7e2c9b0c11",
"url": "https://seusistema.com.br/hooks/genius",
"events": ["message.received", "message.sent"],
"isActive": true,
"lastStatus": 200,
"lastError": null,
"lastDeliveryAt": "2026-10-02T13:52:03.771Z"
}Desativar webhook do número
/api/v1/webhooks/config/{instanceId}Para de enviar os eventos do número. Se o agente tiver webhook próprio, ele volta a receber o tráfego deste número.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
instanceIdstringobrigatórioId do canal.
Retorno
A configuração desativada.
curl -X DELETE "https://api.geniushub.online/api/v1/webhooks/config/ab9aedfe-4c1f-4f0e-9a52-1d7e2c9b0c11" \
-H "x-api-key: $GENIUS_API_KEY"{
"instanceId": "ab9aedfe-4c1f-4f0e-9a52-1d7e2c9b0c11",
"isActive": false
}Recurso
Funil de vendas
Leve para o funil o lead que nasce fora do WhatsApp — no site, no ERP, num formulário de terceiro. O negócio criado pela API passa pelas mesmas regras do quadro e dispara as mesmas automações e webhooks (card.*). Exige chave sem restrição de agentes.
Listar funis
/api/v1/pipelinesOs funis ativos da organização, com quantos negócios abertos cada um tem.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Retorno
A lista de funis.
curl -X GET "https://api.geniushub.online/api/v1/pipelines" \
-H "x-api-key: $GENIUS_API_KEY"{
"items": [{ "id": "7f3e1c2a-9b4d-4e8f-a1c6-5d2b8e9f0a13", "name": "Vendas", "currency": "BRL", "abertos": 42 }]
}Consultar funil
/api/v1/pipelines/{id}O funil com etapas e campos — é daqui que saem os ids de etapa e as chaves dos campos personalizados.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
idstringobrigatórioId do funil.
Retorno
O funil com stages e fields.
curl -X GET "https://api.geniushub.online/api/v1/pipelines/7f3e1c2a-9b4d-4e8f-a1c6-5d2b8e9f0a13" \
-H "x-api-key: $GENIUS_API_KEY"{
"id": "7f3e1c2a-9b4d-4e8f-a1c6-5d2b8e9f0a13",
"name": "Vendas",
"stages": [{ "id": "…", "name": "Novo lead", "kind": "OPEN" }],
"fields": [{ "key": "cidade", "label": "Cidade", "type": "TEXT" }]
}Criar negócio
/api/v1/pipelines/{id}/cardsCria um negócio com origem API. Sem stageId, entra na primeira etapa em andamento. Telefone com negócio aberto no mesmo funil é recusado.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
idstringobrigatórioId do funil.
Corpo da requisição
titlestringobrigatórioTítulo do negócio.
stageIdstringopcionalEtapa de entrada.
amountnumberopcionalValor.
contactNamestringopcionalNome do contato.
contactPhonestringopcionalTelefone com DDI e DDD.
contactEmailstringopcionalE-mail do contato.
dataobjectopcionalCampos personalizados, pela chave do campo.
utmobjectopcionalutm_source,utm_medium,utm_campaign,utm_content,utm_term. Outras chaves são descartadas.
Retorno
O negócio criado.
curl -X POST "https://api.geniushub.online/api/v1/pipelines/7f3e1c2a-9b4d-4e8f-a1c6-5d2b8e9f0a13/cards" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Maria Souza",
"contactName": "Maria Souza",
"contactPhone": "5511999999999",
"data": {
"cidade": "Recife"
},
"utm": {
"utm_source": "site",
"utm_campaign": "outubro"
}
}'{
"id": "c1d2…",
"title": "Maria Souza",
"source": "API",
"attribution": { "utm_source": "site", "utm_campaign": "outubro" }
}Consultar negócio
/api/v1/cards/{cardId}O negócio com campos, origem e histórico.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
cardIdstringobrigatórioId do negócio.
Retorno
O negócio com events.
curl -X GET "https://api.geniushub.online/api/v1/cards/c1d2…" \
-H "x-api-key: $GENIUS_API_KEY"{ "id": "c1d2…", "stageId": "…", "events": [] }Mover negócio
/api/v1/cards/{cardId}/moveMuda o negócio de etapa. Etapa de ganho ou perda fecha o negócio; lostReason alimenta o relatório de perdas.
- Permissão:
- Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)
Parâmetros de caminho
cardIdstringobrigatórioId do negócio.
Corpo da requisição
stageIdstringobrigatórioEtapa de destino.
lostReasonstringopcionalMotivo, quando o destino é uma etapa de perda.
Retorno
O negócio na etapa nova.
curl -X POST "https://api.geniushub.online/api/v1/cards/c1d2…/move" \
-H "x-api-key: $GENIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"stageId": "…"
}'{ "id": "c1d2…", "stageId": "…", "closedAt": null }Objeto do evento
Com o webhook configurado, o Hub faz um POST com JSON no seu endereço a cada evento. O envelope é sempre { event, deliveryId, sentAt, data }, e o formato de data depende do evento. Este formato é contrato: campos novos podem ser adicionados, mas os existentes não mudam sem aviso.
Eventos
| Evento | Quando |
|---|---|
message.received | O contato escreveu. |
message.sent | Saiu uma mensagem para o contato — do agente, de um atendente ou de uma automação. |
card.created | Negócio criado no funil. |
card.stage_changed | Negócio mudou para uma etapa em andamento. |
card.won | Negócio movido para uma etapa de ganho. |
card.lost | Negócio movido para uma etapa de perda. |
Campos de data — mensagens
| Campo | Descrição |
|---|---|
channel | WHATSAPP, INSTAGRAM ou API. |
instanceId | Número de WhatsApp. null nos outros canais. |
agentId | Agente da conversa. |
chatId | Contato no canal: telefone (WhatsApp), id do contato (Instagram) ou o chatId que você escolheu (/v1/chat). É o mesmo valor usado nas rotas de chat. |
direction | inbound (o contato escreveu) ou outbound (saiu para o contato). |
text | O que a pessoa escreveu, sem nada acrescentado — ou a legenda do arquivo. null quando veio só arquivo. Use este campo para ler a mensagem. |
transcription | Transcrição do áudio recebido. Só na entrada. |
mediaDescription | Descrição da imagem recebida, quando o agente está configurado para ler imagens. Só na entrada. |
content | A mensagem como foi gravada no histórico (o que o agente leu). Com arquivo, junta marcação [Imagem: url], transcrição ou descrição e legenda, uma por linha. Mantido por compatibilidade — prefira text, transcription e mediaDescription. |
origin | Só na saída: AGENT (resposta do agente), HUMAN (atendente ou /v1/messages/send) ou SYSTEM (automação). |
mediaKind | image, audio, video, document, sticker, location, contact, unknown — ou null para texto. |
mediaUrl, fileName, mimeType | Dados do arquivo, quando houver. O link é do storage do Hub e não expira com o provedor. |
sizeBytes | Tamanho do arquivo. Só na entrada. |
senderName | Nome do contato no canal, quando disponível. Só na entrada. |
contactAvatar | URL da foto de perfil do contato no WhatsApp, ou null. Expira em alguns dias — veja Foto do contato, logo abaixo. |
providerMessageId | Id da mensagem no WhatsApp. null fora dele. |
O que dispara, por canal
| Canal | message.received | message.sent |
|---|---|---|
| Cada mensagem do contato, assim que é gravada — antes de a IA responder. | Toda mensagem aceita pelo provedor: agente, atendente, automação. | |
| Cada mensagem de texto do contato. | A resposta do agente, depois que a Meta aceitou. | |
/v1/chat | Cada chamada. | A resposta do agente (que também vem no corpo da resposta). |
Instagram e /v1/chat exigem o webhook do agente
agentId. Configurado só por instanceId, você recebe apenas o tráfego daquele número.O que não dispara
- Mensagem duplicada reentregue pelo provedor, e mensagem antiga (mais de 10 min) da sincronização de histórico do WhatsApp.
- Grupos (a menos que o agente atenda grupos) e listas de transmissão do WhatsApp.
- Mensagem digitada direto no celular da loja, e mensagem que falhou na entrega.
- Contato bloqueado no Instagram ou em
/v1/chat: a mensagem é descartada. - Mensagem do atendente fora do WhatsApp, e o Modo Teste do painel.
Campos de data — funil
card: o negócio inteiro —id,pipelineId,pipelineName,title,amount,currency,contactName,contactPhone,contactEmail,contactAvatar,source,attribution(UTMs),data(campos personalizados),labels,lostReason.stage: etapa atual (id,name,kind:OPEN,WONouLOST).fromStage: etapa anterior,nullemcard.created.instanceIdénullquando o agente não tem WhatsApp. Negócio sem agente não dispara webhook.- Os eventos do funil não vêm por padrão: inclua-os em
eventsao configurar.
Entrega e novas tentativas
- Responda com qualquer status
2xxem até 10 segundos. Processe o evento depois, numa fila. - Em falha, o Hub tenta de novo após 2 s e 8 s (3 tentativas). Esgotadas, o evento é descartado — a mensagem continua disponível pelo histórico. Redirecionamentos não são seguidos.
- A mesma mensagem pode chegar mais de uma vez. Use
deliveryId(ouproviderMessageId) para ignorar repetições. A ordem de chegada não é garantida: ordene porsentAt. - O resultado da última entrega fica em
lastStatus,lastErrorelastDeliveryAtdeGET /v1/webhooks/config/agent/{agentId}(ou/config/{instanceId}).
POST /hooks/genius HTTP/1.1
Content-Type: application/json
User-Agent: GeniusHub-Webhook/1
X-Genius-Event: message.received
X-Genius-Delivery: 3b0f6d4e-8a1c-4f55-9a77-1f0c2e9b7d10
X-Genius-Timestamp: 1790948523640
X-Genius-Signature: sha256=9f86d081884c7d659a2feaa0c55ad015…
{
"event": "message.received",
"deliveryId": "3b0f6d4e-8a1c-4f55-9a77-1f0c2e9b7d10",
"sentAt": "2026-10-02T13:42:03.640Z",
"data": {
"channel": "WHATSAPP",
"instanceId": "ab9aedfe-4c1f-4f0e-9a52-1d7e2c9b0c11",
"agentId": "593eb3c4-08f5-437f-a377-d2d59da4fb10",
"chatId": "5577999990000",
"direction": "inbound",
"text": "segue o áudio",
"transcription": "Meu pedido já saiu?",
"mediaDescription": null,
"content": "[Áudio: https://<storage>/…/audio.ogg]
Transcrição: Meu pedido já saiu?
segue o áudio",
"mediaKind": "audio",
"mediaUrl": "https://<storage>/…/audio.ogg",
"fileName": "audio.ogg",
"mimeType": "audio/ogg",
"sizeBytes": 18234,
"senderName": "Ana",
"contactAvatar": "https://pps.whatsapp.net/v/t61…",
"providerMessageId": "3EB0C767D26A1B2C"
}
}{
"event": "card.stage_changed",
"deliveryId": "8d2e1f0a-…",
"sentAt": "2026-10-02T14:10:00.000Z",
"data": {
"instanceId": "ab9aedfe-4c1f-4f0e-9a52-1d7e2c9b0c11",
"agentId": "593eb3c4-08f5-437f-a377-d2d59da4fb10",
"card": {
"id": "c1d2…",
"pipelineId": "f0a1…",
"pipelineName": "Vendas",
"title": "Maria Souza",
"amount": 1500,
"currency": "BRL",
"contactName": "Maria Souza",
"contactPhone": "5511999999999",
"contactEmail": null,
"contactAvatar": null,
"source": "WHATSAPP",
"attribution": { "utm_source": "site" },
"data": { "cidade": "Recife" },
"labels": ["quente"],
"lostReason": null
},
"stage": { "id": "…", "name": "Proposta", "kind": "OPEN" },
"fromStage": { "id": "…", "name": "Novo lead" }
}
}Foto do contato
A foto de perfil do contato no WhatsApp vem pronta no campo contactAvatar — nas respostas da API e nos eventos de webhook. Com ela a sua inbox mostra o rosto de quem escreveu, sem nenhuma chamada a mais.
Onde ela vem
| Onde | Campo |
|---|---|
GET /v1/chat/sessions/{agentId} | contactAvatar em cada conversa da lista. |
Eventos message.received e message.sent | data.contactAvatar |
Eventos card.* do funil | data.card.contactAvatar |
Como o Hub obtém a foto
- Usa a foto já guardada na conversa. Se ainda não houver — ou se o link guardado já venceu — busca no WhatsApp e guarda para as próximas. Assim, a URL que você recebe está válida no momento da entrega.
- A busca tem tempo limitado: se o WhatsApp demorar, a resposta e o evento saem sem a foto, com
null, e ela aparece numa chamada seguinte. A foto nunca atrasa nem derruba um evento. nulltambém significa que o contato não tem foto pública (privacidade do WhatsApp) ou que o provedor do canal não a fornece. Mostre um avatar com as iniciais decontactNamenesse caso.- Fora do WhatsApp (
INSTAGRAM,API,WEB) o Hub não busca foto: o campo vemnull.
A URL expira
pps.whatsapp.net) e deixa de funcionar em alguns dias. Não guarde a URL: assim que ela chegar, baixe a imagem e sirva a sua cópia. Se o download falhar, mostre as iniciais do contato — não trate isso como erro.// GET /v1/chat/sessions/{agentId}
[{ "chatId": "5577999990000", "contactName": "Ana",
"contactAvatar": "https://pps.whatsapp.net/v/t61…" }]
// Webhook message.received / message.sent
{ "event": "message.received",
"data": { "chatId": "5577999990000", "senderName": "Ana",
"contactAvatar": "https://pps.whatsapp.net/v/t61…" } }
// Webhook card.*
{ "event": "card.created",
"data": { "card": { "contactName": "Ana",
"contactAvatar": null } } }// Ao receber o evento: baixe a foto e guarde a SUA cópia.
async function guardarFoto(chatId, contactAvatar) {
if (!contactAvatar) return null; // sem foto: use as iniciais
const resposta = await fetch(contactAvatar);
if (!resposta.ok) return null; // URL já expirada
const imagem = Buffer.from(await resposta.arrayBuffer());
return storage.salvar(`contatos/${chatId}.jpg`, imagem); // S3, disco…
}Verificar a assinatura
O seu endereço de webhook é público, então qualquer um pode enviar um POST para ele. Para ter certeza de que o evento veio do Genius Hub, confira a assinatura de toda entrega:
- 1Leia
X-Genius-Timestamp(milissegundos desde 1970) e recuse entregas com mais de 5 minutos. - 2Monte a string
{timestamp}.{corpo cru}— o corpo exatamente como chegou, antes de qualquer parse. - 3Calcule o HMAC-SHA256 dela com o
secretdo webhook e prefixe comsha256=. - 4Compare com
X-Genius-Signatureusando comparação em tempo constante.
import crypto from "node:crypto";
import express from "express";
const app = express();
const CINCO_MINUTOS = 5 * 60 * 1000;
// Use o corpo CRU: qualquer reserialização muda os bytes e invalida a assinatura.
app.post("/hooks/genius", express.raw({ type: "application/json" }), (req, res) => {
const timestamp = req.header("X-Genius-Timestamp") ?? "";
const recebida = req.header("X-Genius-Signature") ?? "";
const corpo = req.body.toString("utf8");
// 1. Recuse entregas antigas (o timestamp está em milissegundos).
if (Math.abs(Date.now() - Number(timestamp)) > CINCO_MINUTOS) {
return res.sendStatus(400);
}
// 2. Recalcule a assinatura e compare em tempo constante.
const esperada =
"sha256=" +
crypto
.createHmac("sha256", process.env.GENIUS_WEBHOOK_SECRET)
.update(`${timestamp}.${corpo}`)
.digest("hex");
const valida =
recebida.length === esperada.length &&
crypto.timingSafeEqual(Buffer.from(recebida), Buffer.from(esperada));
if (!valida) return res.sendStatus(401);
// 3. Responda 2xx rápido e processe depois (fila, job…).
const evento = JSON.parse(corpo);
enfileirar(evento);
res.sendStatus(200);
});