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/conversationsTodas 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/workspacesOs espaços que esta credencial pode atender, com o papel em cada um.
GET/visitantesQuem 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}/messagesHistórico de mensagens (visitante, agente humano, IA, sistema).
POST/{id}/messagesEnviar uma mensagem à conversa como agente.
POST/{id}/assignAtribuir a conversa a um agente humano ou a um departamento.
POST/{id}/resolveFechar 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-caseEstado 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}/readMarcar a conversa como lida pela equipe (contador de não lidas).
POST/{id}/reopenReabrir uma conversa fechada, mantendo o histórico. Sem isso, um fechamento por engano não tinha volta.
POST/{id}/archiveArquivar ou desarquivar. Sai da caixa sem ser fechada nem perder nada; o corpo é {valor:true|false}.
POST/{id}/pinFixar no topo ou soltar. As fixadas encabeçam a primeira página da caixa. Corpo: {valor:true|false}.
POST/{id}/muteSilenciar os avisos por N horas, ou {horas:null} para voltar a ouvi-la.
POST/{id}/unreadDeixá-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}/forwardReencaminhar 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}/reactionReagir 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}/locationEnviar 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-cardEnviar 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}/copilotoO 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}/copilotoPerguntar 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}/enviarEnviar 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}/resumenPedir 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}/historialDo 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-sourcesFontes de conhecimento associadas a este agente.
POST/{id}/knowledge-sourcesAssociar 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/documentIndexar um documento como conhecimento fundamentado.
POST/urlIndexar uma URL.
GET/{id}Status e metadados da fonte.
DELETE/{id}Remover uma fonte e seus vetores.
POST/{id}/reindexReler 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}/aprobarAprovar uma proposta: passa a ativa e registra quem aprovou (administrador).
POST/{id}/rechazarRejeitar uma proposta (administrador).
POST/probarPré-visualização: o que a ficha responderia a uma pergunta, com a nota e a faixa (opcional: incluir as propostas).
POST/recalcularRecalcular 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}/credentialsDefinir as credenciais de um canal.
PUT/{id}/statusHabilitar ou desabilitar um canal.
POST/Criar um canal.
GET/{channelId}Um canal com seu tipo, estado e configurações.
GET/{channelId}/snippetA linha única que o cliente cola no site. Todo o resto se configura aqui.
GET/{channelId}/configA configuração do chat: o publicado (`config`) e o que este canal sobrescreve (`settings`). São diferentes.
PUT/{channelId}/configSalvar a configuração. Salvar e publicar são o mesmo passo: se a CDN falhar, o PUT falha.
POST/{channelId}/config/publishRepublicar a configuração na CDN sem alterá-la.
POST/{channelId}/avatarEnviar o rosto do assistente (≤512 KB). Vai para o R2 e é servido pela CDN.
POST/republicar-todosRepublicar todos os canais do workspace. O cron faz isso quando o pacote de textos muda; isto é para não esperar.
PUT/{channelId}/modoO 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}/autoAs 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}/tarjetaO 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}/horarioO 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/agentsListar os agentes humanos do workspace.
POST/agents/{userId}/departmentsColocar um agente em um departamento.
GET/departmentsListar departamentos.
PUT/departments/{id}/routing-rulesDefinir regras de roteamento para conversas recebidas.
POST/agentsConvidar uma pessoa para o workspace, com papel e departamentos.
GET/agents/{userId}Uma pessoa da equipe.
POST/departmentsCriar um departamento com suas regras de roteamento.
GET/departments/{id}Um departamento.

Webhooks, chaves, faturamento, análises /webhooks · /api-keys · /billing · /analytics

POST/webhooksRegistrar um endpoint; você recebe o segredo de assinatura uma única vez.
DELETE/webhooks/{id}Remover um endpoint.
POST/api-keysCriar uma chave (somente leitura ou leitura e escrita).
DELETE/api-keys/{id}Revogar uma chave imediatamente.
GET/billing/subscriptionPlano, resoluções de IA incluídas e uso do período.
GET/analyticsMétricas agregadas do workspace.
GET/webhooksListar os endpoints de webhook.
GET/webhooks/{id}/deliveriesHistórico de entregas de um webhook, com retentativas. É o que diz se a falha é sua ou nossa.
GET/api-keysListar as chaves. O segredo nunca é devolvido: só o prefixo.

Ferramentas do agente /conversations/{id} · /canned-responses · /tags · /presence

GET/conversations/{id}/notesNotas internas da conversa. O visitante nunca as vê.
POST/conversations/{id}/notesAdicionar uma nota interna.
DELETE/conversations/{id}/notes/{noteId}Excluir uma nota interna.
GET/canned-responsesRespostas prontas do workspace, com seu atalho.
POST/canned-responsesCriar uma resposta pronta.
PATCH/canned-responses/{cannedId}Editar uma resposta pronta.
DELETE/canned-responses/{cannedId}Excluir uma resposta pronta.
POST/presenceBatimento 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/presenceHá alguém on-line agora? É o que decide se uma transferência espera ou é desviada.
GET/ai-usageConsumo de inferência do workspace por dia e as conversas que mais gastam.
GET/tagsEtiquetas do workspace.
GET/conversations/{id}/tagsEtiquetas de uma conversa.
POST/conversations/{id}/tagsEtiquetar uma conversa. Cria a etiqueta se não existia.
DELETE/conversations/{id}/tags/{tagId}Remover uma etiqueta da conversa.
POST/conversations/{id}/transferTransferir a conversa para um departamento. Prevalece sobre as regras de roteamento: uma transferência manual não se desfaz sozinha.
POST/contacts/{contactId}/blockBloquear um contato. Recebe 403 sem detalhes: a quem abusa não se explica como foi detectado.
GET/canned-responses/categoriesAs categorias já usadas nas respostas predefinidas (texto livre), para autocompletar.
POST/canned-responses/{cannedId}/useRegistrar 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}/attachmentsEnviar um anexo como agente. Lista branca estrita e 10 MB: nada que um navegador possa executar entra.
GET/conversations/{id}/attachmentsAnexos 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/registerRegistrar o token push de um dispositivo, para avisar uma pessoa quando a IA transferir. Fora do prefixo de workspace: `/v1/devices/register`.
POST/workspacesCriar um workspace. Fora do prefixo: `/v1/workspaces`.
GET/workspaces/{workspaceId}/retencion/ensayoO 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/visitantesQuem 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}/invitarConvidar 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-ticketUm 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/catalogoQuais 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/llamadasO 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-cursoAs chamadas que estão acontecendo agora.
GET/aparcadasAs chamadas estacionadas, à espera de que alguém as retome.
GET/grabaciones/{id}/audioO áudio de uma gravação, servido pela API (sem link público) e sem cache. A central registra quem a ouviu.
GET/extensionesOs ramais que o painel pode usar como telefone (os reservados não aparecem).
POST/webphone-sesionRegistrar 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.createdUma nova conversa começou em qualquer canal.
message.createdChegou uma mensagem (visitante, humano, IA ou sistema).
handoff.requestedA IA decidiu que precisa de um humano — o momento exato, com o resumo.
conversation.resolvedUma 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.