Atendimento humano
Receber o aviso, assumir a conversa, responder e devolver ao bot
O bot atende sozinho até certo ponto. Quando alguém precisa entrar, a API permite fazer isso do sistema que a sua equipe já usa, sem abrir o painel do Intelibot.
São duas metades: o webhook avisa, e as rotas de conversa agem.
O aviso: webhooks
Sem webhook, saber que alguém está esperando exigiria consultar a lista de conversas em laço. Isso custa dinheiro dos dois lados e chega atrasado.
Registre uma URL por agente:
curl -X POST https://api.intelibot.com.br/v1/agents/$AGENTE/webhooks \
-H "Authorization: Bearer $INTELIBOT_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"url": "https://seusistema.com.br/intelibot",
"eventos": ["handoff.requested", "message.received"]
}'A resposta traz o segredo. Ele aparece uma única vez: a listagem nunca
devolve esse campo. Guarde no momento em que criar.
Os eventos
| Evento | Quando dispara |
|---|---|
conversation.started | Alguém começou uma conversa |
message.received | O visitante escreveu |
message.sent | O agente respondeu |
handoff.requested | O visitante pediu uma pessoa |
lead.captured | O agente capturou um contato |
conversation.closed | A conversa terminou |
Conferir a assinatura
Cada entrega leva três cabeçalhos:
X-Intelibot-Event: handoff.requested
X-Intelibot-Delivery: 8f3c... (id único da entrega)
X-Intelibot-Signature: sha256=<hmac do corpo, com o seu segredo>Confira a assinatura antes de confiar no conteúdo. Em Node:
import { createHmac, timingSafeEqual } from 'node:crypto'
function assinaturaConfere(corpoCru, cabecalho, segredo) {
const esperado = 'sha256=' + createHmac('sha256', segredo).update(corpoCru).digest('hex')
const a = Buffer.from(esperado)
const b = Buffer.from(cabecalho ?? '')
return a.length === b.length && timingSafeEqual(a, b)
}Use o corpo cru, antes de qualquer JSON.parse: reserializar muda os
espaços e a assinatura deixa de bater.
O corpo tem sempre a mesma forma:
{
"type": "handoff.requested",
"agentId": "...",
"conversationId": "...",
"timestamp": "2026-09-06T22:31:00.000Z",
"data": {}
}Não há reentrega automática: se o seu endpoint estiver fora do ar, aquele evento se perde. Responda rápido, com 2xx, e faça o trabalho pesado depois.
A ação: operar a conversa
Com o conversationId do evento em mãos, são três rotas.
Assumir
Pausa o bot e marca a conversa como aguardando atendimento. O visitante é avisado de que alguém entrou.
curl -X POST https://api.intelibot.com.br/v1/conversations/$CONVERSA/handoff \
-H "Authorization: Bearer $INTELIBOT_CHAVE"Responder
curl -X POST https://api.intelibot.com.br/v1/conversations/$CONVERSA/messages \
-H "Authorization: Bearer $INTELIBOT_CHAVE" \
-H "Content-Type: application/json" \
-d '{"mensagem":"Oi! Sou a Ana, vou te ajudar.","atendente":"Ana"}'A mensagem chega ao visitante pelo canal em que a conversa nasceu, site ou WhatsApp. Você não precisa saber qual é.
atendente é obrigatório. É o nome que o visitante vê assinando a
mensagem. Ele não tem valor padrão de propósito: a chave é da conta e não sabe
quem está do outro lado, então uma mensagem sem esse campo apareceria assinada
por ninguém e não daria para auditar depois.
Devolver ao bot
curl -X POST https://api.intelibot.com.br/v1/conversations/$CONVERSA/resolve \
-H "Authorization: Bearer $INTELIBOT_CHAVE"O agente volta a responder na próxima mensagem do visitante.
O fluxo inteiro
visitante pede uma pessoa
-> webhook handoff.requested chega no seu sistema
-> POST /v1/conversations/:id/handoff (bot pausado)
-> POST /v1/conversations/:id/messages (quantas vezes precisar)
-> POST /v1/conversations/:id/resolve (bot religado)Ler o que o visitante escreveu enquanto isso é
GET /v1/conversations/:id, que devolve a conversa com todas as mensagens na
ordem.
O que isso não consome
Nenhuma das três rotas gasta o limite de chamadas da API: elas não acionam o
modelo. O que consome é POST /v1/agents/:id/chat.