Í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

RecursoPara quê
ChatConverse com o agente a partir do seu produto e monte a sua própria inbox.
MensagensEnvie mensagens pelo WhatsApp conectado ao agente — notificações do seu sistema, o primeiro contato com um cliente ou a resposta do seu atendente..
AgentesListe, leia, crie, altere e exclua agentes pelo seu sistema.
Configuração do agentePausa, 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 conhecimentoO que o agente sabe além do prompt.
Intenções e skillsO que o agente sabe fazer.
CatálogoOs produtos que o agente oferece.
CanaisConecte um número de WhatsApp a um agente: crie o canal, peça o QR Code e consulte até o status virar CONNECTED..
WebhooksEm vez de consultar a API em laço, receba um POST no seu servidor a cada mensagem que entra ou sai.
Funil de vendasLeve para o funil o lead que nasce fora do WhatsApp — no site, no ERP, num formulário de terceiro.

Primeira vez aqui?

Comece pelo guia de início rápido: em 10 minutos você tem o agente respondendo dentro do seu sistema.
URL base
https://api.geniushub.online/api/v1
Primeira chamada
curl -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

A chave dá acesso aos seus agentes e consome os seus créditos. Chame a API sempre a partir do seu backend e guarde a chave em variável de ambiente ou cofre de segredos — nunca no código do front-end ou no repositório.
Cabeçalho de autenticação
x-api-key: ghk_nSVrCckA1a235xAh5a3Vhjmglor5FJMpQ4o2SYfYGzA
Resposta sem chave válida
{
  "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).

StatuserrorQuando acontece
400VALIDATION_FAILEDCampo ausente ou fora do formato. details aponta cada campo.
400BAD_REQUESTRegra de negócio: agente sem WhatsApp conectado, contato bloqueado, nome de agente ambíguo.
401UNAUTHENTICATEDCabeçalho x-api-key ausente, ou chave inexistente, vencida ou revogada.
403FORBIDDENA chave não tem acesso ao agente, ou o papel da conta não permite a operação.
404NOT_FOUNDAgente, canal ou conversa não existe na sua organização — ou a rota não existe.
409CONFLICTO chatId já pertence a uma conversa de outro canal.
429RATE_LIMITEDLimite de requisições excedido. Aguarde e tente de novo.
429MASS_SEND_BLOCKEDEnvio recusado por parecer disparo em massa. O campo limit diz qual teto. Repetir igual não passa.
5xxINTERNAL_ERRORFalha nossa ou de um provedor. É seguro tentar de novo com espera crescente.
Corpo de erro
{
  "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.

RotaLimite
POST /v1/chat30 requisições por minuto
POST /v1/messages/send60 requisições por minuto
Demais rotas20 por segundo e 300 por minuto, por chave
Qualquer rota, por endereço IP600 por minuto; quem estoura fica 5 minutos bloqueado
Chave inválida, por endereço IP10 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.

limitTeto
mensagensSemResposta2 mensagens para um número que nunca escreveu; a próxima só depois da resposta.
contatosNovosPorDia30 números novos que nunca escreveram, por agente, a cada 24 horas.
mesmoConteudoPorHoraO mesmo texto ou arquivo para no máximo 20 números por hora.
enviosPorHora120 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 é registradoDe onde vem
Origem: APIDa chave que autenticou a chamada. Não há campo para escolher a origem: uma integração nunca aparece como o painel.
Chave usadaNome e id da chave. Dê um nome por sistema ("ERP", "Site", "n8n") para saber quem fez o quê.
Endereço IP e User-AgentDa 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 sistemaDo campo externalUser, quando você o envia.
Campos alteradosSó 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

O 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, o requestId do 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?

Revogue a chave em Configurações → Integração (API) e emita outra. A revogação vale na chamada seguinte. Se a sua integração roda em servidores com IP variável (serverless), alertas de IP novo são esperados.
Envio identificado
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" }
  }'
Resposta
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

POST/api/v1/chat

Envia 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ório

    Id do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.

  • chatIdstringobrigatório

    Identificador 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ório

    Texto do usuário. Até 8000 caracteres.

  • senderNamestringopcional

    Nome do usuário, para o agente tratá-lo pelo nome.

Retorno

O objeto de resposta do agente.

  • handoff: true significa que o agente pediu atendimento humano. Avise a sua equipe e, se quiser, chame POST /v1/chat/takeover. O motivo vem em handoffReason.
  • files aparece quando o agente quis enviar um arquivo. A url é assinada e de validade curta: baixe ou exiba assim que receber.
  • reply vazio é 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.
POST /v1/chat
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"
  }'
Resposta
{
  "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

GET/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ório

    Id do agente.

Retorno

Uma lista de conversas.

  • handoffStatus resume quem está com a conversa: AGENT (a IA responde), WAITING (o agente pediu uma pessoa) ou HUMAN (alguém assumiu).
  • channel diz de onde a conversa veio: API, WHATSAPP ou WEB.
  • contactAvatar é a foto de perfil do contato no WhatsApp, ou null. A URL expira em alguns dias: baixe a imagem se for guardá-la. Veja Foto do contato, na seção de webhooks.
GET /v1/chat/sessions/{agentId}
curl -X GET "https://api.geniushub.online/api/v1/chat/sessions/593eb3c4-08f5-437f-a377-d2d59da4fb10" \
  -H "x-api-key: $GENIUS_API_KEY"
Resposta
[
  {
    "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

GET/api/v1/chat/history/{agentId}/{chatId}

As mensagens de uma conversa, em ordem cronológica (até 200).

Parâmetros de caminho

  • agentIdstringobrigatório

    Id do agente.

  • chatIdstringobrigatório

    O chatId da conversa (codifique com encodeURIComponent).

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.
  • replyTo traz o trecho citado quando a mensagem responde a outra.
GET /v1/chat/history/{agentId}/{chatId}
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"
Resposta
[
  {
    "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

POST/api/v1/chat/takeover

Passa 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ório

    Id do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.

  • chatIdstringobrigatório

    A conversa a assumir.

Retorno

A conversa atualizada.

  • Conversa inexistente responde 404.
POST /v1/chat/takeover
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"
  }'
Resposta
{
  "id": "b1e0f3c2-…",
  "chatId": "5577999990000",
  "isHumanTakenOver": true,
  "takenOverAt": "2026-10-02T13:41:00.000Z"
}

Devolver ao agente

POST/api/v1/chat/release

Encerra o atendimento humano e devolve a conversa para a IA. Também limpa o pedido de atendimento pendente.

Corpo da requisição

  • agentIdstringobrigatório

    Id do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.

  • chatIdstringobrigatório

    A conversa a devolver.

Retorno

A conversa atualizada.

POST /v1/chat/release
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"
  }'
Resposta
{
  "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

POST/api/v1/messages/send

Envia 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ório

    Agente cujo número envia a mensagem.

  • phonestringobrigatório

    Número com DDI e DDD. Aceita pontuação: “(77) 99999-0000” e “5577999990000” caem na mesma conversa.

  • messagestringopcional

    Texto, até 8000 caracteres. Obrigatório se não houver file; com arquivo, vira a legenda.

  • fileobjectopcional

    Arquivo a enviar (imagem, áudio, vídeo ou documento).

    • contentstringobrigatório

      Conteúdo em base64, com ou sem o prefixo data:<mime>;base64,.

    • fileNamestringobrigatório

      Nome do arquivo, com extensão.

    • mimeTypestringobrigatório

      Tipo do arquivo, ex.: application/pdf ou audio/webm;codecs=opus.

    • asVoiceNotebooleanopcional

      Só para áudio. true envia como mensagem de voz do WhatsApp (a bolha com onda, como um áudio gravado no celular). Ausente ou false envia como arquivo, com o nome original.

  • replyToIdstringopcional

    Id de uma mensagem da mesma conversa, para enviar como resposta citada.

  • externalUserobjectopcional

    Quem, 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.

    • idstringopcional

      Id do usuário no seu sistema, até 100 caracteres.

    • namestringopcional

      Nome do usuário, até 120 caracteres. Sem quebras de linha, < ou >.

Retorno

A confirmação de que a mensagem entrou na fila de envio.

  • QUEUED significa aceita e garantida, não entregue no aparelho. Falhas do provedor viram novas tentativas. Para saber quando saiu, assine o evento message.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).
POST /v1/messages/send
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"
    }
  }'
Resposta
{
  "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"
  }
}

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

GET/api/v1/agents

Todos 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.

GET /v1/agents
curl -X GET "https://api.geniushub.online/api/v1/agents" \
  -H "x-api-key: $GENIUS_API_KEY"
Resposta
[
  {
    "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

GET/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ório

    Id 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 }.

GET /v1/agents/{agentId}
curl -X GET "https://api.geniushub.online/api/v1/agents/593eb3c4-08f5-437f-a377-d2d59da4fb10" \
  -H "x-api-key: $GENIUS_API_KEY"
Resposta
{
  "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

POST/api/v1/agents

Cria 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ório

    Nome do agente, de 2 a 80 caracteres.

  • behaviorstringobrigatório

    O prompt: quem ele é, como fala, o que pode e o que não pode. De 10 a 200 000 caracteres.

  • typestringopcional

    SUPPORT, SALE ou PERSONAL.

  • statusstringopcional

    ACTIVE, TRAINING ou DISABLED.

  • jobNamestringopcional

    Empresa ou área que ele representa.

  • jobDescriptionstringopcional

    Contexto do negócio (até 4000).

  • jobSitestringopcional

    Site da empresa.

  • communicationTypestringopcional

    Tom de voz (até 40).

  • aiProviderstringopcional

    Provedor de IA. Veja GET /v1/ai-models.

  • aiModelstringopcional

    Modelo de IA. Combinação fora da lista é recusada.

  • avatarstringopcional

    URL da foto. Vazio sorteia uma.

  • proposalEnabledbooleanopcional

    Gera propostas comerciais em PDF.

  • responseLengthnumberopcional

    Extensã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.
POST /v1/agents
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"
  }'
Resposta
{
  "id": "7d1b2c3e-…",
  "name": "Atendimento Loja Centro",
  "status": "ACTIVE",
  "aiModel": "gemini-3.7-flash"
}

Alterar agente

PUT/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ório

    Id do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.

Corpo da requisição

  • behaviorstringopcional

    Novo prompt.

  • aiModelstringopcional

    Novo modelo.

  • useCatalogbooleanopcional

    Liga ou desliga o catálogo nas conversas.

  • maxChannels, maxClientsnumberopcional

    Limites contratados. Só chave de ADMIN.

Retorno

O perfil atualizado.

  • Campo desconhecido é recusado com 400 — nada é ignorado em silêncio.
PUT /v1/agents/{agentId}
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."
  }'
Resposta
{
  "id": "593eb3c4-08f5-437f-a377-d2d59da4fb10",
  "name": "Atendimento Loja Centro",
  "behavior": "Você atende clientes da Loja Centro. Nunca prometa prazo…"
}

Excluir agente

DELETE/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ório

    Id 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.

DELETE /v1/agents/{agentId}
curl -X DELETE "https://api.geniushub.online/api/v1/agents/593eb3c4-08f5-437f-a377-d2d59da4fb10" \
  -H "x-api-key: $GENIUS_API_KEY"
Resposta
{ "success": true }

Modelos de IA

GET/api/v1/ai-models

Os valores aceitos em aiProvider e aiModel.

Permissão:
Chave emitida por titular da conta (OWNER) ou administrador (ADMIN)

Retorno

Os provedores e seus modelos.

GET /v1/ai-models
curl -X GET "https://api.geniushub.online/api/v1/ai-models" \
  -H "x-api-key: $GENIUS_API_KEY"
Resposta
[
  { "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)" }] }
]

Pausar ou retomar

PUT/api/v1/agents/{agentId}/pause

Pausado, 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ório

    Id do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.

Corpo da requisição

  • isPausedbooleanobrigatório

    true pausa, false retoma.

Retorno

O novo estado.

PUT /v1/agents/{agentId}/pause
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
  }'
Resposta
{ "agentId": "593eb3c4-08f5-437f-a377-d2d59da4fb10", "isPaused": true }

Horário de atendimento

PUT/api/v1/agents/{agentId}/operating-hours

Substitui 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ório

    Id do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.

Corpo da requisição

  • operatingHoursobjectobrigatório

    O expediente.

    • enabledbooleanopcional

      Liga o controle de horário.

    • timezonestringopcional

      Fuso IANA, ex.: America/Sao_Paulo.

    • outOfHoursMessagestringopcional

      Mensagem de ausência (até 1000).

    • noticeCooldownHoursnumberopcional

      Horas de silêncio entre dois avisos ao mesmo contato (0–720).

    • scheduleobjectopcional

      monday … sunday, cada um { active, windows: [{ start, end }] } em HH:MM. Até 6 faixas por dia.

    • exceptionsobject[]opcional

      Feriados e plantões: { date (YYYY-MM-DD, ou MM-DD com annual), label?, annual?, message?, windows? }. Com windows, 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.
PUT /v1/agents/{agentId}/operating-hours
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
        }
      ]
    }
  }'
Resposta
{ "agentId": "593eb3c4-08f5-437f-a377-d2d59da4fb10", "operatingHours": { "enabled": true, "timezone": "America/Sao_Paulo" } }

Follow-up e devolução

PUT/api/v1/agents/{agentId}/follow-up

Mensagens 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ório

    Id do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.

Corpo da requisição

  • followUpEnabledbooleanopcional

    Liga o follow-up.

  • followUpsobject[]opcional

    Até 3 etapas { delayMinutes (1–43200), message (até 1000) }.

  • autoReleaseMinutesnumberopcional

    Devolve à IA a conversa assumida após N minutos sem atividade (0 desliga).

  • autoReleaseWaitingMinutesnumberopcional

    Idem, para a conversa que ficou esperando um humano.

Retorno

A configuração gravada.

PUT /v1/agents/{agentId}/follow-up
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
  }'
Resposta
{ "followUpEnabled": true, "followUps": [{ "delayMinutes": 60, "message": "Ficou alguma dúvida? Posso ajudar." }] }

Preferências de conversa

PUT/api/v1/agents/{agentId}/conversation-prefs

Estilo, 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ório

    Id do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.

Corpo da requisição

  • useEmojisbooleanopcional

    Permite emojis.

  • signAgentNamebooleanopcional

    Assina as respostas com o nome do agente.

  • restrictTopicsbooleanopcional

    Recusa assuntos fora do escopo do prompt.

  • sensitiveThemesobject[]opcional

    Até 50 { id, name, action, active?, keywords? }. Substitui a lista.

  • splitLongRepliesbooleanopcional

    Divide respostas longas em várias mensagens.

  • analyzeImagesbooleanopcional

    Lê as imagens que o contato manda (gasta créditos).

  • documentReaderProviderstringopcional

    AUTO, GEMINI, TEXTRACT, REKOGNITION ou DEEPSEEK.

  • documentReaderModestringopcional

    TEXTRACT_TEXT, TEXTRACT_TABLES ou TEXTRACT_FORMS.

  • imageReaderModelstring | nullopcional

    Modelo DeepSeek que lê as fotos (lista em GET /ai/models/deepseek/vision). Vazio usa deepseek-flash.

  • imageReaderThinkingstringopcional

    Raciocínio do leitor DeepSeek: OFF (padrão), LOW ou HIGH.

  • imageAnalysisHintstring | nullopcional

    O que a leitura deve observar nas fotos deste negócio (até 1000 caracteres).

  • maxInteractionsnumberopcional

    Teto de respostas por conversa (0–200; 0 = sem teto).

  • replyWaitSecondsnumberopcional

    Tempo de resposta: 0 (imediata) ou de 5 a 15 segundos de silêncio do contato antes de responder (padrão 5). Mensagens seguidas dentro desse tempo viram uma resposta só.

  • evoReadMessagesbooleanopcional

    Marca as mensagens como lidas no WhatsApp.

  • evoRejectCallbooleanopcional

    Recusa ligações.

  • evoCallMessagestringopcional

    Mensagem enviada ao recusar a ligação.

  • evoIgnoreGroupsbooleanopcional

    Ignora grupos.

  • evoAlwaysOnlinebooleanopcional

    Mantém o número como online.

Retorno

As preferências gravadas.

PUT /v1/agents/{agentId}/conversation-prefs
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
  }'
Resposta
{ "useEmojis": false, "splitLongReplies": true, "maxInteractions": 40, "replyWaitSeconds": 6 }

Enviar foto

POST/api/v1/agents/{agentId}/avatar

Troca 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ório

    Id do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.

Corpo da requisição

  • avatarDataUristringobrigatório

    Imagem em data URI (data:image/png;base64,…), até ~4 MB.

  • fileNamestringopcional

    Nome do arquivo.

Retorno

O endereço da nova foto.

POST /v1/agents/{agentId}/avatar
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"
  }'
Resposta
{ "success": true, "avatarUrl": "https://…/uploads/avatars/…png" }

Emergência

PUT/api/v1/agents/{agentId}/emergency

O 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ório

    Id do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.

Corpo da requisição

  • emergencyMarkerstringopcional

    Palavra 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.

  • emergencyNoticestringopcional

    Aviso ao contato (até 400).

Retorno

A configuração gravada.

PUT /v1/agents/{agentId}/emergency
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."
  }'
Resposta
{ "emergencyMarker": "Emergência", "emergencyNotice": "Já acionei nossa equipe…" }

Cadastrar pessoa ou grupo a chamar

POST/api/v1/agents/{agentId}/callable-people

Uma 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ório

    Id do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.

Corpo da requisição

  • namestringobrigatório

    Nome (até 60) — é por ele que o agente escolhe o destino.

  • targetTypestringopcional

    PERSON (padrão) ou GROUP.

  • phonestringopcional

    Só de PERSON, e obrigatório nele: WhatsApp com DDI e DDD.

  • groupJidstringopcional

    Só de GROUP, e obrigatório nele: o jid de GET /callable-people/groups. O número do agente precisa estar no grupo e poder enviar.

  • mentionModestringopcional

    Grupo: FIXED (padrão, marca os de members), AI (a IA escolhe entre members), ALL (todos) ou NONE.

  • membersarrayopcional

    Grupo, até 20: { id, name, whenToMention }. id vem de GET /callable-people/groups/{groupJid}/participants; whenToMention (até 200) é obrigatório no modo AI.

  • sectorstringopcional

    Área (até 60).

  • whenToCallstringopcional

    Quando chamar (até 400). É o que a IA lê para decidir.

  • activebooleanopcional

    Desativado, o agente não o oferece.

  • includeTranscriptbooleanopcional

    Junta as últimas mensagens da conversa ao aviso. Padrão true.

  • notifyInTestModebooleanopcional

    O Modo Teste do painel também manda o aviso de verdade, marcado como teste. Padrão false.

  • shareWithContactbooleanopcional

    Só de PERSON: envia o número dela ao contato.

  • callOnEmergencybooleanopcional

    Acionado automaticamente numa emergência.

  • mentionAllOnEmergencybooleanopcional

    Grupo: num aviso de emergência, marca todos.

Retorno

O cadastro criado.

POST /v1/agents/{agentId}/callable-people
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."
  }'
Resposta
{ "id": "…", "name": "Financeiro", "targetType": "GROUP", "groupName": "Equipe Financeiro", "mentionMode": "AI", "active": true }

Grupos do WhatsApp do agente

GET/api/v1/agents/{agentId}/callable-people/groups

Os 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ório

    Id do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.

Retorno

A lista de grupos.

GET /v1/agents/{agentId}/callable-people/groups
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"
Resposta
[{ "jid": "120363000000000001@g.us", "name": "Equipe Financeiro", "size": 8, "announce": false }]

Enviar aviso de teste

POST/api/v1/agents/{agentId}/callable-people/{personId}/test

Manda 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ório

    Id do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.

  • personIdstringobrigatório

    Id do cadastro.

Retorno

Quem foi marcado.

POST /v1/agents/{agentId}/callable-people/{personId}/test
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"
Resposta
{ "enviado": true, "marcados": ["Carla", "Diego"] }

Ligar ao funil

PUT/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ório

    Id do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.

  • pipelineIdstringobrigatório

    Id do funil.

Corpo da requisição

  • entryStageIdstringobrigatório

    Etapa em andamento em que o negócio nasce.

  • createOnstringopcional

    FIRST_MESSAGE, FIRST_FIELD ou MANUAL.

  • enabledbooleanopcional

    Liga ou pausa a captura.

Retorno

A ligação gravada.

  • Um agente alimenta um funil ativo por vez: ativar com outro já ativo responde 409.
PUT /v1/agents/{agentId}/pipeline/{pipelineId}
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
  }'
Resposta
{ "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

POST/api/v1/agents/{agentId}/files

PDF, 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ório

    Id do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.

Corpo da requisição

  • fileNamestringobrigatório

    Nome com extensão.

  • contentstringobrigatório

    Texto, ou o arquivo em base64. Até 20 MB.

  • fileTypestringopcional

    Tipo (ex.: pdf). Sem ele, vale a extensão.

Retorno

O arquivo registrado.

POST /v1/agents/{agentId}/files
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…"
  }'
Resposta
{ "id": "f3a1…", "fileName": "politica-de-trocas.txt", "indexStatus": "PENDING", "downloadUrl": null, "extractionNote": null }

Adicionar página web

POST/api/v1/agents/{agentId}/files/website

O 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ório

    Id do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.

Corpo da requisição

  • urlstringobrigatório

    URL completa.

  • titlestringopcional

    Título.

Retorno

O arquivo registrado.

  • Para vídeo, use POST /v1/agents/{agentId}/files/video com { videoUrl, title?, textContent? } — o vídeo não é transcrito, vale o textContent.
POST /v1/agents/{agentId}/files/website
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"
  }'
Resposta
{ "id": "f3a2…", "fileName": "Perguntas frequentes" }

Estado da indexação

GET/api/v1/agents/{agentId}/knowledge/status

Quantos 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ório

    Id 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/reindex com { force? } reindexa a base.
GET /v1/agents/{agentId}/knowledge/status
curl -X GET "https://api.geniushub.online/api/v1/agents/593eb3c4-08f5-437f-a377-d2d59da4fb10/knowledge/status" \
  -H "x-api-key: $GENIUS_API_KEY"
Resposta
{
  "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

PATCH/api/v1/files/{fileId}/usage

Buscado 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ório

    Id do arquivo.

Corpo da requisição

  • usageModestringopcional

    RETRIEVED (quando relevante) ou ALWAYS (sempre no contexto).

  • enviavelAoClientebooleanopcional

    O agente pode mandar o arquivo ao contato.

  • instructionsstringopcional

    Como interpretar o arquivo (até 4000).

Retorno

O arquivo atualizado.

  • GET /v1/files/{fileId}/content devolve o texto extraído; POST /v1/files/{fileId}/index reindexa só ele.
PATCH /v1/files/{fileId}/usage
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
  }'
Resposta
{ "id": "f3a1…", "usageMode": "ALWAYS", "enviavelAoCliente": true }

Remover arquivo

DELETE/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ório

    Id do arquivo.

Retorno

Confirmação.

DELETE /v1/files/{fileId}
curl -X DELETE "https://api.geniushub.online/api/v1/files/f3a1…" \
  -H "x-api-key: $GENIUS_API_KEY"
Resposta
{ "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

POST/api/v1/agents/{agentId}/intentions

GET 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ório

    Id do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.

Corpo da requisição

  • descriptionstringobrigatório

    Quando usar (3 a 200).

  • urlstringobrigatório

    Endereço chamado. Endereço interno é recusado.

  • httpMethodstringopcional

    GET, POST, PUT, PATCH ou DELETE.

  • instructionsstringopcional

    Como usar o resultado (até 4000).

  • fieldsobject[]opcional

    O que perguntar ao contato antes: { name, type?: STRING|NUMBER|BOOLEAN|ARRAY|OBJECT, description?, required? }.

  • headers, paramsobject[]opcional

    { name, value? }.

  • requestBodystringopcional

    Corpo da requisição, com variáveis.

  • responseModestringopcional

    INTERPRET (a IA resume) ou LITERAL (repassa).

  • outputVariablesobject[]opcional

    { name, expression }: o que guardar da resposta.

Retorno

A intenção criada.

POST /v1/agents/{agentId}/intentions
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
      }
    ]
  }'
Resposta
{ "id": "i9c2…", "description": "Consultar o status de um pedido", "active": true }

Criar skill

POST/api/v1/agents/{agentId}/skills

GET 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ório

    Id do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.

Corpo da requisição

  • namestringobrigatório

    Nome único no agente (até 80).

  • descriptionstringobrigatório

    Quando a skill vale (até 500).

  • contentstringopcional

    A instrução em si.

  • triggersstring[]opcional

    Palavras que puxam a skill.

  • loadModestringopcional

    ALWAYS ou ON_DEMAND.

  • prioritynumberopcional

    Ordem entre skills.

  • activebooleanopcional

    Desativada, não é carregada.

Retorno

A skill criada.

POST /v1/agents/{agentId}/skills
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"
  }'
Resposta
{ "id": "s1…", "name": "trocas", "loadMode": "ON_DEMAND", "active": true }

Consultar catálogo

GET/api/v1/agents/{agentId}/catalog

Produtos (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ório

    Id do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.

Retorno

O catálogo.

GET /v1/agents/{agentId}/catalog
curl -X GET "https://api.geniushub.online/api/v1/agents/593eb3c4-08f5-437f-a377-d2d59da4fb10/catalog" \
  -H "x-api-key: $GENIUS_API_KEY"
Resposta
{
  "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

PUT/api/v1/agents/{agentId}/catalog/settings

Quando 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ório

    Id 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, nextActionstringopcional

    Instruções (até 4000 cada).

  • presentationstringopcional

    ON_REQUEST, AFTER_QUALIFICATION ou WHEN_RELEVANT.

  • maxItemsnumberopcional

    Itens por resposta (1 a 5).

  • sendMediabooleanopcional

    Envia as fotos do produto.

  • showPricebooleanopcional

    Mostra o preço.

Retorno

A configuração gravada.

PUT /v1/agents/{agentId}/catalog/settings
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
  }'
Resposta
{ "presentation": "AFTER_QUALIFICATION", "maxItems": 3, "showPrice": true, "sendMedia": true }

Cadastrar produto

POST/api/v1/agents/{agentId}/catalog/products

PATCH /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ório

    Id do agente. Também aceita o nome ou o id externo, desde que só um agente atenda por ele.

Corpo da requisição

  • namestringobrigatório

    Nome.

  • pricenumberopcional

    Preço.

  • stocknumberopcional

    Estoque.

  • description, category, details, callToAction, availabilitystringopcional

    Descrição e informações do produto.

  • aliasesstring[]opcional

    Outros nomes pelos quais o contato pede o produto.

  • attributesobjectopcional

    Atributos livres (cor, tamanho), valores texto, número ou booleano.

  • isActivebooleanopcional

    Inativo, o agente não oferece.

Retorno

O produto criado.

POST /v1/agents/{agentId}/catalog/products
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
    }
  }'
Resposta
{ "id": "p1…", "name": "Tênis Corrida", "price": 299.9, "stock": 12, "isActive": true }

Anexar foto ou vídeo

POST/api/v1/products/{productId}/media

Até 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ório

    Id do produto.

Corpo da requisição

  • contentstringobrigatório

    Arquivo em base64, com ou sem data:.

  • fileNamestringobrigatório

    Nome com extensão.

  • mimeTypestringopcional

    Tipo do arquivo.

Retorno

A mídia anexada.

POST /v1/products/{productId}/media
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"
  }'
Resposta
{ "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

POST/api/v1/channels

Registra 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ório

    Agente que vai responder neste número.

  • providerstringopcional

    EVOLUTION (padrão) ou ZAPI.

  • displayNamestringopcional

    Nome do canal na sua lista, até 60 caracteres.

  • zapiInstanceIdstringopcional

    Obrigatório com provider: "ZAPI".

  • zapiTokenstringopcional

    Obrigatório com provider: "ZAPI".

  • zapiClientTokenstringopcional

    Client token da conta Z-API, quando houver.

Retorno

O canal criado.

POST /v1/channels
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"
  }'
Resposta
{
  "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

POST/api/v1/channels/{id}/connect

Inicia 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ório

    Id 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.
POST /v1/channels/{id}/connect
curl -X POST "https://api.geniushub.online/api/v1/channels/ab9aedfe-4c1f-4f0e-9a52-1d7e2c9b0c11/connect" \
  -H "x-api-key: $GENIUS_API_KEY"
Resposta
{
  "status": "CONNECTING",
  "qrCode": "data:image/png;base64,iVBORw0KGgo…"
}

Consultar canal

GET/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ório

    Id do canal.

Retorno

O canal.

  • status: DISCONNECTED, CONNECTING, CONNECTED ou ERROR. O qrCode só vem preenchido em CONNECTING.
GET /v1/channels/{id}
curl -X GET "https://api.geniushub.online/api/v1/channels/ab9aedfe-4c1f-4f0e-9a52-1d7e2c9b0c11" \
  -H "x-api-key: $GENIUS_API_KEY"
Resposta
{
  "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

DELETE/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ório

    Id do canal.

Retorno

Confirmação da exclusão.

DELETE /v1/channels/{id}
curl -X DELETE "https://api.geniushub.online/api/v1/channels/ab9aedfe-4c1f-4f0e-9a52-1d7e2c9b0c11" \
  -H "x-api-key: $GENIUS_API_KEY"
Resposta
{ "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

POST/api/v1/webhooks/config

Define 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

  • agentIdstringopcional

    Agente cujos canais disparam os eventos (todos: WhatsApp, Instagram e /v1/chat). Use este ou instanceId.

  • instanceIdstringopcional

    Número de WhatsApp que dispara os eventos (só ele). Use este ou agentId.

  • urlstringobrigatório

    URL https:// pública do seu servidor. Endereços internos são recusados.

  • eventsstring[]opcional

    message.received, message.sent e 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.

  • secretstringopcional

    Seu segredo de assinatura (16 a 200 caracteres). Omitido, o Hub gera um.

Retorno

A configuração, com o segredo de assinatura.

  • O secret só é exibido nesta resposta. Guarde-o: é com ele que você confere a assinatura de cada entrega.
  • agentId e instanceId juntos, ou nenhum dos dois, respondem 400.
POST /v1/webhooks/config
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"
    ]
  }'
Resposta
{
  "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

GET/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ório

    Id do agente.

Retorno

A configuração, sem o segredo.

GET /v1/webhooks/config/agent/{agentId}
curl -X GET "https://api.geniushub.online/api/v1/webhooks/config/agent/593eb3c4-08f5-437f-a377-d2d59da4fb10" \
  -H "x-api-key: $GENIUS_API_KEY"
Resposta
{
  "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

DELETE/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ório

    Id do agente.

Retorno

A configuração desativada.

DELETE /v1/webhooks/config/agent/{agentId}
curl -X DELETE "https://api.geniushub.online/api/v1/webhooks/config/agent/593eb3c4-08f5-437f-a377-d2d59da4fb10" \
  -H "x-api-key: $GENIUS_API_KEY"
Resposta
{
  "scope": "AGENT",
  "isActive": false
}

Consultar webhook do número

GET/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ório

    Id do canal.

Retorno

A configuração, sem o segredo.

GET /v1/webhooks/config/{instanceId}
curl -X GET "https://api.geniushub.online/api/v1/webhooks/config/ab9aedfe-4c1f-4f0e-9a52-1d7e2c9b0c11" \
  -H "x-api-key: $GENIUS_API_KEY"
Resposta
{
  "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

DELETE/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ório

    Id do canal.

Retorno

A configuração desativada.

DELETE /v1/webhooks/config/{instanceId}
curl -X DELETE "https://api.geniushub.online/api/v1/webhooks/config/ab9aedfe-4c1f-4f0e-9a52-1d7e2c9b0c11" \
  -H "x-api-key: $GENIUS_API_KEY"
Resposta
{
  "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

GET/api/v1/pipelines

Os 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.

GET /v1/pipelines
curl -X GET "https://api.geniushub.online/api/v1/pipelines" \
  -H "x-api-key: $GENIUS_API_KEY"
Resposta
{
  "items": [{ "id": "7f3e1c2a-9b4d-4e8f-a1c6-5d2b8e9f0a13", "name": "Vendas", "currency": "BRL", "abertos": 42 }]
}

Consultar funil

GET/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ório

    Id do funil.

Retorno

O funil com stages e fields.

GET /v1/pipelines/{id}
curl -X GET "https://api.geniushub.online/api/v1/pipelines/7f3e1c2a-9b4d-4e8f-a1c6-5d2b8e9f0a13" \
  -H "x-api-key: $GENIUS_API_KEY"
Resposta
{
  "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

POST/api/v1/pipelines/{id}/cards

Cria 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ório

    Id do funil.

Corpo da requisição

  • titlestringobrigatório

    Título do negócio.

  • stageIdstringopcional

    Etapa de entrada.

  • amountnumberopcional

    Valor.

  • contactNamestringopcional

    Nome do contato.

  • contactPhonestringopcional

    Telefone com DDI e DDD.

  • contactEmailstringopcional

    E-mail do contato.

  • dataobjectopcional

    Campos personalizados, pela chave do campo.

  • utmobjectopcional

    utm_source, utm_medium, utm_campaign, utm_content, utm_term. Outras chaves são descartadas.

Retorno

O negócio criado.

POST /v1/pipelines/{id}/cards
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"
    }
  }'
Resposta
{
  "id": "c1d2…",
  "title": "Maria Souza",
  "source": "API",
  "attribution": { "utm_source": "site", "utm_campaign": "outubro" }
}

Consultar negócio

GET/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ório

    Id do negócio.

Retorno

O negócio com events.

GET /v1/cards/{cardId}
curl -X GET "https://api.geniushub.online/api/v1/cards/c1d2…" \
  -H "x-api-key: $GENIUS_API_KEY"
Resposta
{ "id": "c1d2…", "stageId": "…", "events": [] }

Mover negócio

POST/api/v1/cards/{cardId}/move

Muda 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ório

    Id do negócio.

Corpo da requisição

  • stageIdstringobrigatório

    Etapa de destino.

  • lostReasonstringopcional

    Motivo, quando o destino é uma etapa de perda.

Retorno

O negócio na etapa nova.

POST /v1/cards/{cardId}/move
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": "…"
  }'
Resposta
{ "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

EventoQuando
message.receivedO contato escreveu.
message.sentSaiu uma mensagem para o contato — do agente, de um atendente ou de uma automação.
card.createdNegócio criado no funil.
card.stage_changedNegócio mudou para uma etapa em andamento.
card.wonNegócio movido para uma etapa de ganho.
card.lostNegócio movido para uma etapa de perda.

Campos de data — mensagens

CampoDescrição
channelWHATSAPP, INSTAGRAM ou API.
instanceIdNúmero de WhatsApp. null nos outros canais.
agentIdAgente da conversa.
chatIdContato no canal: telefone (WhatsApp), id do contato (Instagram) ou o chatId que você escolheu (/v1/chat). É o mesmo valor usado nas rotas de chat.
directioninbound (o contato escreveu) ou outbound (saiu para o contato).
textO que a pessoa escreveu, sem nada acrescentado — ou a legenda do arquivo. null quando veio só arquivo. Use este campo para ler a mensagem.
transcriptionTranscrição do áudio recebido. Só na entrada.
mediaDescriptionDescrição da imagem recebida, quando o agente está configurado para ler imagens. Só na entrada.
contentA 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.
originSó na saída: AGENT (resposta do agente), HUMAN (atendente ou /v1/messages/send) ou SYSTEM (automação).
mediaKindimage, audio, video, document, sticker, location, contact, unknown — ou null para texto.
mediaUrl, fileName, mimeTypeDados do arquivo, quando houver. O link é do storage do Hub e não expira com o provedor.
sizeBytesTamanho do arquivo. Só na entrada.
senderNameNome do contato no canal, quando disponível. Só na entrada.
contactAvatarURL da foto de perfil do contato no WhatsApp, ou null. Expira em alguns dias — veja Foto do contato, logo abaixo.
providerMessageIdId da mensagem no WhatsApp. null fora dele.

O que dispara, por canal

Canalmessage.receivedmessage.sent
WhatsAppCada mensagem do contato, assim que é gravada — antes de a IA responder.Toda mensagem aceita pelo provedor: agente, atendente, automação.
InstagramCada mensagem de texto do contato.A resposta do agente, depois que a Meta aceitou.
/v1/chatCada chamada.A resposta do agente (que também vem no corpo da resposta).

Instagram e /v1/chat exigem o webhook do agente

Esses canais não têm número de WhatsApp, então só disparam para um webhook configurado com 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, WON ou LOST). fromStage: etapa anterior, null em card.created.
  • instanceId é null quando 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 events ao configurar.

Entrega e novas tentativas

  • Responda com qualquer status 2xx em 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 (ou providerMessageId) para ignorar repetições. A ordem de chegada não é garantida: ordene por sentAt.
  • O resultado da última entrega fica em lastStatus, lastError e lastDeliveryAt de GET /v1/webhooks/config/agent/{agentId} (ou /config/{instanceId}).
Entrega de uma mensagem
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"
  }
}
Evento do funil
{
  "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

OndeCampo
GET /v1/chat/sessions/{agentId}contactAvatar em cada conversa da lista.
Eventos message.received e message.sentdata.contactAvatar
Eventos card.* do funildata.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.
  • null també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 de contactName nesse caso.
  • Fora do WhatsApp (INSTAGRAM, API, WEB) o Hub não busca foto: o campo vem null.

A URL expira

O endereço é do CDN do WhatsApp (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.
Onde a foto aparece
// 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 } } }
Guardar a foto no seu sistema
// 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:

  1. 1Leia X-Genius-Timestamp (milissegundos desde 1970) e recuse entregas com mais de 5 minutos.
  2. 2Monte a string {timestamp}.{corpo cru} — o corpo exatamente como chegou, antes de qualquer parse.
  3. 3Calcule o HMAC-SHA256 dela com o secret do webhook e prefixe com sha256=.
  4. 4Compare com X-Genius-Signature usando comparação em tempo constante.
O timestamp entra na assinatura para impedir que uma entrega capturada seja reenviada mais tarde: trocar a data invalida a assinatura.
Ver o guia de webhooks
Verificação
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);
});