Construa sobre a mesma API sobre a qual nós construímos
Tudo o que a plataforma faz — conversas, contatos, agentes de IA, conhecimento, análises — roda sobre esta API REST. Não existe uma API privada melhor por trás: esta é a única. URL base: `https://api.inteligenciaviva.com/v1`.
Quickstart: sua primeira requisição em 60 segundos
Crie uma chave de API no seu workspace, exporte-a e liste suas conversas. As chaves têm escopo por workspace e podem ser somente leitura ou leitura e escrita.
curl https://api.inteligenciaviva.com/v1/workspaces/WORKSPACE_ID/conversations \
-H "Authorization: Bearer sk_live_..."
Toda resposta é JSON. Endpoints de coleção devolvem arrays `data`; erros devolvem um objeto `error` com `code` e `message` e o status HTTP correspondente.
A API gratuita — sem conta, sem chave
A camada gratuita também fala API. `POST /v1/free/widget-snippet` recebe exatamente a mesma configuração que o gerador visual da página Grátis monta e devolve o snippet HTML pronto para colar — sem autenticação, sem cadastro. Use-a para gerar widgets em lote para sites de clientes, regenerar embeds a partir do CI quando os horários mudam, ou simplesmente para tocar a API antes de pagar um centavo.
curl -X POST https://api.inteligenciaviva.com/v1/free/widget-snippet \
-H "Content-Type: application/json" \
-d @widget-config.json
# → { "snippet": "<link rel=\"stylesheet\" ..." }
Autenticação
Toda requisição leva uma chave de API no cabeçalho `Authorization` como token Bearer. As chaves são criadas e revogadas pela própria API ou pelo painel, por workspace — revogar uma chave corta o acesso imediatamente.
Os endpoints de sessão no nível da conta (registro, login, acesso com Google, troca de ticket, perfil e exclusão de conta sob `/v1/auth`) alimentam nossos próprios apps; para integrações servidor-a-servidor, prefira sempre chaves de API de workspace a sessões de usuário.
Authorization: Bearer sk_live_...
Referência de recursos
Todas as rotas abaixo pendem de `https://api.inteligenciaviva.com/v1/workspaces/{workspaceId}`, salvo indicação em contrário. Esta é a superfície real montada do backend atual — não aspiracional.
Caixa combinada /inbox
| GET | /conversations | Todas as conversas de TODOS os espaços que a credencial atende, numa lista única ordenada por atividade. |
| GET | /conversations/{id} | Uma conversa procurada em todos os seus espaços, sem saber em qual está. Devolve o workspace_id. |
| GET | /workspaces | Os espaços que esta credencial pode atender, com o papel em cada um. |
| GET | /visitantes | Quem está navegando AGORA em todos os seus workspaces, com a página que lê e se já está conversando. É uma foto do momento, não um histórico: não é paginada. Um workspace que não responde não derruba a lista: vai em `casas_sin_responder`. |
Conversas /conversations
| GET | / | Listar conversas, filtráveis por estado. |
| GET | /{id} | Uma conversa com seu estado, canal, contato e atribuição. |
| GET | /{id}/messages | Histórico de mensagens (visitante, agente humano, IA, sistema). |
| POST | /{id}/messages | Enviar uma mensagem à conversa como agente. |
| POST | /{id}/assign | Atribuir a conversa a um agente humano ou a um departamento. |
| POST | /{id}/resolve | Fechar a conversa. Se a IA a fechou sozinha, conta como resolução faturável. |
| POST | / | Abrir uma conversa fora do widget (por exemplo, para migrar um tópico existente). |
| GET | /{id}/ai-turns | «De onde tirou isso?» — o registro de cada turno de IA: em que se apoiou, com qual modelo, quanto demorou e por que transferiu. |
| GET | /{id}/portal-case | Estado do caso que esta conversa abriu no painel de suporte do Portal, com suas respostas. Consultado ao vivo: o estado muda no outro painel. |
| POST | /{id}/read | Marcar a conversa como lida pela equipe (contador de não lidas). |
| POST | /{id}/reopen | Reabrir uma conversa fechada, mantendo o histórico. Sem isso, um fechamento por engano não tinha volta. |
| POST | /{id}/archive | Arquivar ou desarquivar. Sai da caixa sem ser fechada nem perder nada; o corpo é {valor:true|false}. |
| POST | /{id}/pin | Fixar no topo ou soltar. As fixadas encabeçam a primeira página da caixa. Corpo: {valor:true|false}. |
| POST | /{id}/mute | Silenciar os avisos por N horas, ou {horas:null} para voltar a ouvi-la. |
| POST | /{id}/unread | Deixá-la como não lida: recua a marca de leitura para trás da última mensagem do cliente. |
| POST | /{id}/typing | «Digitando…» para o cliente: no WhatsApp quem recebe é a Meta e, no chat web, o widget do visitante. Sem corpo; sempre 204 (nos canais que não o suportam não faz nada) e 404 se a conversa não existe. |
| POST | /{id}/messages/{messageId}/forward | Reencaminhar uma mensagem para outra conversa do mesmo workspace, com o anexo (é copiado, não compartilhado). Corpo: `{to_conversation_id}`. Sai como mensagem do agente. |
| PUT | /{id}/messages/{messageId}/reaction | Reagir com um emoji a uma mensagem do WhatsApp; substitui a reação anterior da empresa e `{emoji:null}` a remove. Só WhatsApp (API da Meta) e só sobre uma mensagem que a Meta já confirmou: senão, 400. |
| POST | /{id}/location | Enviar uma localização pelo WhatsApp: `{lat, lon, name?, address?, reply_to_message_id?}`. Vai primeiro para a Meta: se a Meta a rejeita, nada fica no histórico. Só WhatsApp. |
| POST | /{id}/contact-card | Enviar um cartão de contato pelo WhatsApp: `{name:{formatted_name}, phones?, emails?, reply_to_message_id?}`. Igual à localização: primeiro a Meta, depois o histórico. Só WhatsApp. |
| GET | /{id}/copiloto | O copiloto do agente: o que a IA sugeriu para esta conversa e o que se falou com ela. É privado da equipe: o cliente não vê. |
| POST | /{id}/copiloto | Perguntar algo à IA em particular sobre esta conversa (`{content}`, até 4.000 caracteres). Ela responde AO AGENTE, não ao cliente: nada sai pelo canal. 503 `copilot_unavailable` se não puder responder. |
| POST | /{id}/copiloto/{sugerenciaId}/enviar | Enviar ao cliente uma sugestão do copiloto, como está ou editada (`{content}` opcional). Sai como mensagem do agente, com o autor humano. Uma sugestão é enviada uma única vez: a segunda dá 409 `ya_enviada`. |
| POST | /{id}/resumen | Pedir o resumo da conversa (aberta ou fechada) e atualizar com ele a ficha do contato. Custa uma tarefa do KIT; pedir de novo sem mensagens novas não cobra outra vez. Se não houver resumo, devolve o porquê (`motivo`, `codigo`). |
Contatos /contacts
| GET | / | Listar contatos. |
| GET | /{id} | Um contato com suas identidades e seu histórico de conversas. |
| GET | /{id}/historial | Do que trataram as últimas consultas: as conversas mais recentes com o resumo (`?limit=`, até 25), os totais e a ficha do contato. Abrir não gera a ficha se ela faltar, porque custa dinheiro: pede-se à parte com `?generar=1`. |
Agentes de IA /ai-agents
| GET | / | Listar os agentes de IA do workspace. |
| POST | / | Criar um agente de IA: instruções, departamento, limiar de confiança. |
| PATCH | /{id} | Atualizar instruções, limiar ou departamento. |
| GET | /{id}/knowledge-sources | Fontes de conhecimento associadas a este agente. |
| POST | /{id}/knowledge-sources | Associar uma fonte de conhecimento a este agente. |
| GET | /{aiAgentId} | Um agente de IA: instruções, limiar de confiança, ferramentas e departamento. |
Conhecimento (RAG) /knowledge-sources
| POST | /document | Indexar um documento como conhecimento fundamentado. |
| POST | /url | Indexar uma URL. |
| GET | /{id} | Status e metadados da fonte. |
| DELETE | /{id} | Remover uma fonte e seus vetores. |
| POST | /{id}/reindex | Reler uma fonte de URL sem apagá-la: se o download falhar, nada é alterado. |
| GET | / | Listar as fontes de conhecimento com seu estado de indexação. |
Ficha do negócio /ficha
| GET | / | Listar as unidades (filtros ?estado= e ?tipo=) com os limiares das faixas. |
| POST | / | Criar uma unidade: pergunta, variantes, resposta aprovada, URL e idioma. Um administrador ou uma chave a publica; um agente a propõe. A IA nunca publica. |
| GET | /{id} | Ver uma unidade. |
| PATCH | /{id} | Editar uma unidade; mudar a pergunta ou as variantes recalcula o embedding. |
| DELETE | /{id} | Excluir uma unidade (administrador). |
| POST | /{id}/aprobar | Aprovar uma proposta: passa a ativa e registra quem aprovou (administrador). |
| POST | /{id}/rechazar | Rejeitar uma proposta (administrador). |
| POST | /probar | Pré-visualização: o que a ficha responderia a uma pergunta, com a nota e a faixa (opcional: incluir as propostas). |
| POST | /recalcular | Recalcular os embeddings que faltem ou não batam com o texto (administrador). |
Canais /channels
| GET | / | Listar canais. Vivos hoje: chat web e API; mais canais se conectam à medida que forem lançados. |
| PUT | /{id}/credentials | Definir as credenciais de um canal. |
| PUT | /{id}/status | Habilitar ou desabilitar um canal. |
| POST | / | Criar um canal. |
| GET | /{channelId} | Um canal com seu tipo, estado e configurações. |
| GET | /{channelId}/snippet | A linha única que o cliente cola no site. Todo o resto se configura aqui. |
| GET | /{channelId}/config | A configuração do chat: o publicado (`config`) e o que este canal sobrescreve (`settings`). São diferentes. |
| PUT | /{channelId}/config | Salvar a configuração. Salvar e publicar são o mesmo passo: se a CDN falhar, o PUT falha. |
| POST | /{channelId}/config/publish | Republicar a configuração na CDN sem alterá-la. |
| POST | /{channelId}/avatar | Enviar o rosto do assistente (≤512 KB). Vai para o R2 e é servido pela CDN. |
| POST | /republicar-todos | Republicar todos os canais do workspace. O cron faz isso quando o pacote de textos muda; isto é para não esperar. |
| PUT | /{channelId}/modo | O modo de atendimento do canal: `{modo:"humano"|"hibrido"|"ia"}`. Decide se a IA fala com o cliente. Vale para qualquer tipo de canal (WhatsApp, Telegram, e-mail, widget). Exige ser administrador. |
| PUT | /{channelId}/auto | As mensagens automáticas do canal: `{bienvenida, fueraDeHorario}` (até 1.000 caracteres cada; `null` apaga). A de fora do horário usa o horário do canal. Exige ser administrador. |
| PUT | /{channelId}/tarjeta | O cartão de contato que o agente pode enviar por este canal: `{tarjetaContacto:{name:{formatted_name}, phones?, emails?}}`, com pelo menos um telefone ou e-mail; `null` o remove. Só WhatsApp. Exige ser administrador. |
| PUT | /{channelId}/horario | O horário de atendimento: `{officeHours:{tz, dias:{lun:[["09:00","17:00"]], …}, festivos:["MM-DD" ou "YYYY-MM-DD"]}}`; `null` o remove (24/7). O que não se entende é rejeitado com 400, dizendo o que está errado. Devolve `abiertoAhora`, calculado pelo servidor. Exige ser administrador. |
Agentes humanos e departamentos /agents · /departments
| GET | /agents | Listar os agentes humanos do workspace. |
| POST | /agents/{userId}/departments | Colocar um agente em um departamento. |
| GET | /departments | Listar departamentos. |
| PUT | /departments/{id}/routing-rules | Definir regras de roteamento para conversas recebidas. |
| POST | /agents | Convidar uma pessoa para o workspace, com papel e departamentos. |
| GET | /agents/{userId} | Uma pessoa da equipe. |
| POST | /departments | Criar um departamento com suas regras de roteamento. |
| GET | /departments/{id} | Um departamento. |
Webhooks, chaves, faturamento, análises /webhooks · /api-keys · /billing · /analytics
| POST | /webhooks | Registrar um endpoint; você recebe o segredo de assinatura uma única vez. |
| DELETE | /webhooks/{id} | Remover um endpoint. |
| POST | /api-keys | Criar uma chave (somente leitura ou leitura e escrita). |
| DELETE | /api-keys/{id} | Revogar uma chave imediatamente. |
| GET | /billing/subscription | Plano, resoluções de IA incluídas e uso do período. |
| GET | /analytics | Métricas agregadas do workspace. |
| GET | /webhooks | Listar os endpoints de webhook. |
| GET | /webhooks/{id}/deliveries | Histórico de entregas de um webhook, com retentativas. É o que diz se a falha é sua ou nossa. |
| GET | /api-keys | Listar as chaves. O segredo nunca é devolvido: só o prefixo. |
Ferramentas do agente /conversations/{id} · /canned-responses · /tags · /presence
| GET | /conversations/{id}/notes | Notas internas da conversa. O visitante nunca as vê. |
| POST | /conversations/{id}/notes | Adicionar uma nota interna. |
| DELETE | /conversations/{id}/notes/{noteId} | Excluir uma nota interna. |
| GET | /canned-responses | Respostas prontas do workspace, com seu atalho. |
| POST | /canned-responses | Criar uma resposta pronta. |
| PATCH | /canned-responses/{cannedId} | Editar uma resposta pronta. |
| DELETE | /canned-responses/{cannedId} | Excluir uma resposta pronta. |
| POST | /presence | Batimento de presença: declara que há uma pessoa atendendo. Somente com sessão — uma chave de API que pulsa não é alguém olhando a tela, e é rejeitada com 400. |
| GET | /presence | Há alguém on-line agora? É o que decide se uma transferência espera ou é desviada. |
| GET | /ai-usage | Consumo de inferência do workspace por dia e as conversas que mais gastam. |
| GET | /tags | Etiquetas do workspace. |
| GET | /conversations/{id}/tags | Etiquetas de uma conversa. |
| POST | /conversations/{id}/tags | Etiquetar uma conversa. Cria a etiqueta se não existia. |
| DELETE | /conversations/{id}/tags/{tagId} | Remover uma etiqueta da conversa. |
| POST | /conversations/{id}/transfer | Transferir a conversa para um departamento. Prevalece sobre as regras de roteamento: uma transferência manual não se desfaz sozinha. |
| POST | /contacts/{contactId}/block | Bloquear um contato. Recebe 403 sem detalhes: a quem abusa não se explica como foi detectado. |
| GET | /canned-responses/categories | As categorias já usadas nas respostas predefinidas (texto livre), para autocompletar. |
| POST | /canned-responses/{cannedId}/use | Registrar que uma resposta predefinida foi usada (contador e última vez). Sempre 204, exista ou não: é telemetria de uso, não uma ação. |
Anexos, dispositivos e workspaces /conversations/{id}/attachments · /devices · /workspaces
| POST | /conversations/{id}/attachments | Enviar um anexo como agente. Lista branca estrita e 10 MB: nada que um navegador possa executar entra. |
| GET | /conversations/{id}/attachments | Anexos de uma conversa. |
| GET | /attachments/{attachmentId} | Baixar um anexo. Servido com cabeçalhos rígidos e `nosniff`; só imagens e áudio aparecem embutidos. |
| POST | /devices/register | Registrar o token push de um dispositivo, para avisar uma pessoa quando a IA transferir. Fora do prefixo de workspace: `/v1/devices/register`. |
| POST | /workspaces | Criar um workspace. Fora do prefixo: `/v1/workspaces`. |
| GET | /workspaces/{workspaceId}/retencion/ensayo | O ensaio da purga: quantas conversas e anexos (e bytes) a retenção levaria, sem apagar nada. `?days=` pergunta por um prazo que ainda não está salvo. Exige ser administrador e `analytics:read`. Rota completa: `/v1/workspaces/{workspaceId}/retencion/ensayo`. |
Visitantes ao vivo e tempo real /visitantes · /stream-ticket
| GET | /visitantes | Quem está navegando agora nos sites deste workspace: página, idioma, desde quando e se já tem o chat aberto ou uma conversa. |
| POST | /visitantes/{visitorId}/invitar | Convidar um visitante a abrir o chat, com `{mensaje}` opcional (sem ele, a saudação do widget no idioma dele). Não cria conversa nem gasta IA: a conversa nasce quando o visitante responde. 404 `no_esta` se já saiu; 409 `ya_conversa` se já está conversando. |
| POST | /stream-ticket | Um ticket para abrir o WebSocket do stream com `?ticket=` sem pôr o token na URL. Dura 60 s e serve uma única vez. Vale com sessão ou com chave de API. |
Capacidades do KIT /conversations/{id}/kit
| GET | / | As tarefas do KIT lançadas nesta conversa, com o estado. Ao listá-las, as pendentes são revisadas. |
| GET | /catalogo | Quais capacidades do KIT podem ser lançadas sobre um anexo (`?attachment_id=`) ou sobre o histórico, com busca (`?q=`, `?lang=`). Somente leitura: não custa nada. |
| POST | / | Lançar uma capacidade do KIT (`{action, attachment_id?, params?}`) sobre um anexo ou sobre o histórico. O resultado volta como NOTA INTERNA, nunca para o cliente. Custa dinheiro da carteira do KIT, e o mesmo pedido não é cobrado duas vezes. 202 com a tarefa na fila. |
Telefone (VOICE) /voice
| GET | /llamadas | O registro de chamadas da central do workspace (`?limite=` até 200, `?antes_de=` para paginar). Escopo `voice:read`; 404 se o workspace não tiver central. |
| GET | /llamadas-en-curso | As chamadas que estão acontecendo agora. |
| GET | /aparcadas | As chamadas estacionadas, à espera de que alguém as retome. |
| GET | /grabaciones/{id}/audio | O áudio de uma gravação, servido pela API (sem link público) e sem cache. A central registra quem a ouviu. |
| GET | /extensiones | Os ramais que o painel pode usar como telefone (os reservados não aparecem). |
| POST | /webphone-sesion | Registrar o navegador como telefone de um ramal (`{extension_id}`): devolve uma credencial SIP efêmera, que a central troca a cada canje. Escopo `voice:write`. A chave da central nunca sai do servidor. |
Exemplos reais
Enviar uma mensagem de agente (curl)
curl -X POST \
https://api.inteligenciaviva.com/v1/workspaces/$WS/conversations/$CONV/messages \
-H "Authorization: Bearer $IV_KEY" \
-H "Content-Type: application/json" \
-d '{"content": "Hi! I checked your order — it ships tomorrow."}'Listar conversas (JavaScript)
const res = await fetch(
`https://api.inteligenciaviva.com/v1/workspaces/${WS}/conversations`,
{ headers: { Authorization: `Bearer ${process.env.IV_KEY}` } }
);
const { data } = await res.json();Verificar a assinatura de um webhook (Node)
import { createHmac, timingSafeEqual } from "node:crypto";
function verify(secret, rawBody, header, toleranceSec = 300) {
const { t, v1 } = Object.fromEntries(
header.split(",").map((p) => p.split("="))
);
if (Math.abs(Date.now() / 1000 - Number(t)) > toleranceSec) return false;
const expected = createHmac("sha256", secret)
.update(`${t}.${rawBody}`)
.digest("hex");
return timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
}
Webhooks
Registre um endpoint HTTPS e enviamos cada evento por POST, assinado. O cabeçalho é `iv-signature: t=<unix>,v1=<hex>`, onde `v1` é o HMAC-SHA256 de `<timestamp>.<corpo bruto>` com o segredo do seu endpoint — rejeite qualquer coisa com mais de 5 minutos (proteção contra replay). Entregas com falha são reenviadas automaticamente com assinatura nova, em até 5 tentativas.
| conversation.created | Uma nova conversa começou em qualquer canal. |
| message.created | Chegou uma mensagem (visitante, humano, IA ou sistema). |
| handoff.requested | A IA decidiu que precisa de um humano — o momento exato, com o resumo. |
| conversation.resolved | Uma conversa foi fechada; informa se a IA a fechou sozinha. |
Cada entrega e seu status ficam registrados — um webhook em que você não pode confiar é pior do que nenhum.
Streaming em tempo real
Para interfaces ao vivo, abra um WebSocket contra o stream do workspace e receba os eventos de conversa conforme acontecem — o mesmo canal que nossos próprios apps de agente usam.
wss://api.inteligenciaviva.com/v1/workspaces/{workspaceId}/stream
Erros e limites
Os erros são HTTP convencional: `400` requisição malformada, `401` chave ausente ou inválida, `403` chave sem escopo, `404` recurso que não está neste workspace, `429` limite de taxa (espere e tente de novo com jitter), `5xx` culpa nossa — repita as requisições idempotentes. O corpo sempre traz um `error.code` e um `error.message` humano. Os limites de taxa são por chave e generosos para integrações reais.
Perguntas frequentes
Esta documentação é aspiracional ou a superfície real?
Real. Foi escrita contra as rotas montadas do backend atual. Quando algo aqui diz "em breve", é porque ainda não existe — não documentamos fumaça.
Preciso de um plano pago para usar a API?
Sim — a API faz parte da plataforma paga (o Pro a inclui). O Widget gratuito e o plugin de WordPress são client-side e não precisam de API nenhuma.
Qual é a diferença entre chaves somente leitura e de leitura e escrita?
As somente leitura podem listar e consultar, mas nunca mutar — ideais para dashboards e BI. As de leitura e escrita podem criar mensagens, contatos, agentes de IA e configuração.
Como fico sabendo de mensagens novas — polling ou webhooks?
Webhooks (`message.created`) para servidores, o stream por WebSocket para interfaces ao vivo. Polling funciona, mas você vai esbarrar nos limites de taxa antes de conseguir tempo real.
Como verifico exatamente que um webhook veio de vocês?
Recalcule o HMAC-SHA256 de `<t>.<corpo bruto>` com o segredo do seu endpoint e compare em tempo constante com o valor `v1` do cabeçalho `iv-signature`; rejeite se `t` tiver mais de 300 segundos. O código funcional está nesta página.
O que acontece se meu endpoint de webhooks estiver fora do ar?
Registramos a entrega com falha e tentamos de novo automaticamente com timestamp e assinatura novos, em até 5 tentativas. Se o endpoint tiver sido removido ou desabilitado nesse meio-tempo, as tentativas param de forma limpa.
A IA pode escalar para o meu próprio sistema?
Sim — para isso existe `handoff.requested`. Ele dispara no momento em que a conversa passa para uma pessoa (o visitante pediu, houve sinais de crise ou de frustração, ou a resposta não se apoiava no conhecimento), com o resumo da conversa, para você avisar alguém ou abrir um ticket em outro sistema.
Quais canais posso controlar pela API hoje?
O chat web está vivo de ponta a ponta, e tudo nesta referência funciona hoje. Telegram e outros canais de mensagens se conectam ao mesmo modelo de conversa à medida que forem lançados — sua integração não muda.
Existe SDK?
Um SDK Flutter alimenta nosso próprio app de agente e é a base do SDK white-label do Enterprise. Para servidores, a superfície REST é deliberadamente simples — qualquer cliente HTTP funciona sem wrapper.
Onde reporto um bug da API ou uma lacuna nesta documentação?
Escreva para l@inteligenciaviva.com. Documentação que mente também é bug — tratamos com a mesma seriedade.