Esta é uma tradução automática do documento original em inglês. Em caso de conflito entre esta tradução e a versão original em inglês, a versão em inglês prevalecerá. Ler a versão original em inglês
API Pública
O Caiioo inclui uma API REST que permite controlar tudo programaticamente: executar agentes, gerenciar ferramentas, agendar tarefas e muito mais. A API vive no mesmo servidor local que alimenta o app de desktop e a ponte do navegador.
URL Base: http://localhost:3847/v1
Autenticação: Duas formas de autenticar, ambas controladas pela alternância de API nas configurações:
Para consumidores externos (scripts, integrações, curl): Defina um token de acesso à API em Configurações > Acesso à API, depois use-o como um token Bearer:
curl -H \"Authorization: Bearer SEU_TOKEN_API\" http://localhost:3847/v1/providers
Para o app local (automático):
O app de desktop Caiioo, as extensões de navegador e os apps móveis autenticam-se automaticamente através do cabeçalho de autenticação de retransmissão existente (X-Relay-Auth). Nenhuma configuração manual é necessária — o app cuida disso nos bastidores.
Configuração:
- Abra as Configurações do Caiioo > Acesso à API
- Ative a opção Habilitar API Pública
- Defina um token de acesso à API (qualquer string que você escolher — trate-a como uma senha)
- Use esse token em todas as solicitações da API
A API está disponível em localhost e através do retransmissor privado. Verifique GET /v1/auth/info (sem necessidade de autenticação) para o status atual e instruções de configuração.
Provedores e Modelos
Descubra quais provedores de LLM estão configurados e quais modelos estão disponíveis.
Listar provedores:
GET /v1/providers
Retorna todos os tipos de provedores configurados (Anthropic, OpenAI, Google, OpenRouter, Ollama, Poe, MLX, Baseten e outros conforme adicionados) com sinalizadores de capacidade (supportsVision, supportsToolCalling, supportsStreaming, etc.) e se uma chave de API está configurada.
Listar modelos para um provedor:
GET /v1/providers/anthropic/models
Retorna o catálogo de modelos para esse provedor. Cada modelo inclui id, displayName e contextLength onde disponível.
Catálogo unificado de todos os provedores:
GET /v1/models
Mescla modelos de todos os provedores configurados em uma única lista. Provedores sem chaves de API são ignorados e listados em warnings.
Agentes
Agentes são o núcleo do caiioo. Cada agente é um Modo — uma personalidade configurada com seu próprio prompt de sistema, ferramentas, variáveis e skills.
Listar todos os agentes:
GET /v1/agents
Retorna agentes integrados (Shopping, Workplace, Geral) e quaisquer agentes personalizados que você criou. Cada um é marcado com source: \"builtin\" ou source: \"custom\".
Criar um agente personalizado:
POST /v1/agents
Content-Type: application/json
{
\"id\": \"meu-agente-de-pesquisa\",
\"branding\": {
\"name\": \"Agente de Pesquisa\",
\"description\": \"Pesquisa na web e resume descobertas\"
},
\"defaultSettings\": {
\"systemPrompt\": \"Você é um assistente de pesquisa. Sempre cite as fontes.\",
\"enabledTools\": { \"web_browsing\": true, \"search_tools\": true }
},
\"settingLevels\": {}
}
Retorna 201 com o agente criado. Um vector clock é anexado automaticamente para sincronização.
Atualizar um agente:
PATCH /v1/agents/meu-agente-de-pesquisa
Content-Type: application/json
{ \"branding\": { \"name\": \"Agente de Pesquisa\", \"description\": \"Descrição atualizada\" } }
Mescla o patch no agente existente e incrementa o vector clock. Agentes integrados retornam 403 — eles são apenas leitura.
Deletar um agente:
DELETE /v1/agents/meu-agente-de-pesquisa
Exclusão lógica via tombstone (sincroniza entre dispositivos). Retorna 204.
Executando Agentes
Este é o evento principal — invoque um agente para processar uma mensagem.
Modo Síncrono
Aguarde a resposta completa:
POST /v1/runs
Content-Type: application/json
{
"agentId": "general",
"input": { "message": "Como está o tempo em Paris hoje?" },
"mode": "sync"
}
Retorna 200 com { content, usage, status: "completed" } após o agente terminar. Se o agente falhar, retorna 500 com { error, status: "error" }.
Modo Assíncrono
Dispare e esqueça — útil para tarefas de longa duração:
POST /v1/runs
Content-Type: application/json
{
"agentId": "my-research-agent",
"input": { "message": "Escreva uma análise de 2000 palavras sobre tendências de energia renovável" },
"mode": "async"
}
Retorna 202 imediatamente com { runId, threadId, status: "running" }.
Consultar status:
GET /v1/runs/{runId}
Retorna { run: { runId, threadId, agentId, status, createdAt, content?, usage?, error? } }. O status é um entre running, completed, error ou cancelled.
Transmitir eventos em tempo real (SSE):
GET /v1/runs/{runId}/events
Retorna um text/event-stream com cada evento do agente conforme acontece: GENERATION_STARTED, STREAMING_CONTENT, chamadas de ferramentas, atividade de subagentes e o evento final (GENERATION_COMPLETE, GENERATION_ERROR ou GENERATION_CANCELLED). O fluxo termina após o evento final.
Cancelar uma execução:
POST /v1/runs/{runId}/cancel
Retorna { run: { ..., status: "cancelled" } }.
Threads
Threads são conversas. Cada execução de agente ocorre dentro de uma thread, e as threads persistem entre as sessões. A API permite listar, ler, criar e gerenciar threads programaticamente.
Listar todas as threads (apenas metadados):
GET /v1/threads
Retorna as threads do perfil atual com as mensagens removidas para fins de performance. Cada thread inclui id, title, createdAt, updatedAt, modeId, archived e estatísticas de uso.
Obter uma thread com mensagens completas:
GET /v1/threads/{id}
Retorna a thread completa, incluindo seu array de messages — cada mensagem do usuário, resposta do assistente, chamada de ferramenta e resultado de ferramenta.
Obter apenas as mensagens:
GET /v1/threads/{id}/messages
Retorna apenas o array de messages — mais leve que o objeto completo da thread quando você precisa apenas da conversa.
Criar uma thread:
POST /v1/threads
Content-Type: application/json
{ "title": "Research project", "modeId": "general" }
Retorna 201 com a nova thread. Por padrão, a API NÃO altera a thread ativa do app — passe "setActive": true no corpo se desejar esse comportamento. A nova thread aparece na barra lateral imediatamente (via transmissão WebSocket).
Atualizar uma thread:
PATCH /v1/threads/{id}
Content-Type: application/json
{ "title": "Renamed project", "archived": true }
Campos atualizáveis: title, modeId, archived, lastUsedModel. As alterações são transmitidas para a barra lateral em tempo real.
Excluir uma thread:
DELETE /v1/threads/{id}
Realiza a exclusão lógica (soft-delete) da thread (tombstone para sincronização). Retorna 204. Threads excluídas movem-se para a lixeira e podem ser recuperadas até que a lixeira seja esvaziada.
Thread ativa:
GET /v1/threads/active # Retorna { threadId }
PUT /v1/threads/active # Corpo: { "threadId": "..." }
Gerenciamento da lixeira:
GET /v1/threads/trash/count # Retorna { count }
POST /v1/threads/trash/empty # Retorna { deletedCount, protectedCount }
Threads protegidas (retidas via o seletor de retenção de dados) são excluídas do esvaziamento da lixeira.
Continuando uma conversa via API:
Para enviar uma mensagem de acompanhamento em uma thread existente, use POST /v1/runs com o ID da thread:
POST /v1/runs
Content-Type: application/json
{
"agentId": "general",
"threadId": "existing-thread-id",
"input": { "message": "Follow up on that last point" },
"mode": "sync"
}
O agente visualiza todo o histórico da conversa a partir da thread.
Anexos
Anexos são arquivos vinculados a threads — capturas de tela, PDFs, documentos, imagens carregadas, artefatos gerados. A API permite listar, carregar, baixar e gerenciá-los.
Listar todos os anexos (apenas metadados):
GET /v1/attachments
Retorna metadados de anexos para o perfil atual. Campos pesados (dataUrl, extractedContent, extractedImages) são removidos — use os endpoints de detalhes ou conteúdo para esses.
Listar anexos para um thread específico:
GET /v1/threads/{threadId}/attachments
Obter metadados do anexo:
GET /v1/attachments/{id}
Retorna metadados completos, incluindo extractedContent (texto OCR, markdown analisado), contentType, fileName, size e um sinalizador hasContent. O binário bruto NÃO está incluído — use o endpoint /content para isso.
Baixar binário do anexo:
GET /v1/attachments/{id}/content
Retorna o arquivo bruto com os cabeçalhos Content-Type e Content-Disposition corretos. Direcione isso para um arquivo:
curl -o saida.pdf \
-H "Authorization: Bearer $API_TOKEN" \
http://localhost:3847/v1/attachments/{id}/content
Carregar um anexo:
POST /v1/attachments
Content-Type: application/json
{
"threadId": "thread-id",
"type": "user_upload",
"contentType": "application/pdf",
"fileName": "relatorio.pdf",
"description": "Relatório trimestral",
"dataUrl": "data:application/pdf;base64,JVBERi0xLjQ..."
}
A dataUrl é uma URL de dados codificada em base64. Retorna 201 com o novo ID do anexo. O anexo é vinculado ao thread especificado.
Atualizar metadados do anexo:
PATCH /v1/attachments/{id}
Content-Type: application/json
{ "description": "Descrição atualizada", "fileName": "novo-nome.pdf" }
Excluir um anexo:
DELETE /v1/attachments/{id}
Exclusão lógica via tombstone. Retorna 204.
Servidores MCP
Gerencie suas conexões de servidor MCP (Model Context Protocol) — os servidores que dão aos agentes acesso a ferramentas externas e fontes de dados.
Listar servidores configurados:
GET /v1/mcp-servers
Retorna todas as configurações de servidor MCP para o perfil atual. Campos sensíveis (authToken, env, credentialId) são removidos da resposta.
Obter a configuração de um servidor:
GET /v1/mcp-servers/{id}
Adicionar um novo servidor MCP:
POST /v1/mcp-servers
Content-Type: application/json
{
"id": "my-server",
"name": "My MCP Server",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/files"],
"serverType": "local"
}
Para servidores HTTP remotos, use "url" em vez de "command":
{
"id": "remote-server",
"name": "Remote API",
"url": "https://my-mcp-server.example.com/sse",
"serverType": "remote"
}
Atualizar um servidor:
PATCH /v1/mcp-servers/{id}
Content-Type: application/json
{ "name": "Renamed Server", "args": ["-y", "@mcp/server-v2"] }
Ativar/desativar um servidor:
POST /v1/mcp-servers/{id}/toggle
Content-Type: application/json
{ "enabled": false }
Excluir um servidor:
DELETE /v1/mcp-servers/{id}
Gerenciamento de Processos
Para servidores MCP locais (stdio), você pode gerenciar o processo do servidor diretamente.
Listar processos em execução:
GET /v1/mcp-servers/processes
Retorna os processos do servidor em execução com pid, startedAt e status running.
Iniciar um servidor:
POST /v1/mcp-servers/{id}/start
Lê o command/args/env da configuração do servidor e gera o processo. Retorna o status do processo.
Parar um servidor:
POST /v1/mcp-servers/{id}/stop
Encerra graciosamente o processo do servidor (SIGTERM com fallback para SIGKILL).
Chamar um método JSON-RPC diretamente:
POST /v1/mcp-servers/{id}/call
Content-Type: application/json
{ "method": "tools/list", "params": {} }
Envia uma requisição JSON-RPC 2.0 bruta para o servidor e retorna o resultado. Útil para depuração ou para chamar métodos não expostos através da API de ferramentas.
Ferramentas e Conjuntos de Ferramentas
Navegue e invoque as ferramentas que os agentes usam — navegação na web, pesquisa, calendário, Gmail, Slate e muito mais.
Listar conjuntos de ferramentas (agrupados):
GET /v1/toolkits
Retorna ferramentas incorporadas agrupadas por categoria (Produtividade, Pesquisa, Utilitários, etc.) e quaisquer servidores MCP conectados como conjuntos de ferramentas separados, cada um com suas ações listadas.
Listar todas as ferramentas (lista simples):
GET /v1/tools
GET /v1/tools?source=embedded # Apenas ferramentas integradas
GET /v1/tools?source=mcp # Apenas ferramentas de servidor MCP
Obter detalhes da ferramenta com esquema de entrada:
GET /v1/tools/calculator
Retorna o JSON Schema da ferramenta para seus parâmetros de entrada, para que você possa validar antes de invocar.
Invocar uma ferramenta diretamente:
POST /v1/tools/calculator/invoke
Content-Type: application/json
{ "input": { "expression": "sqrt(144) + 3^2" } }
Retorna { result }. A entrada é validada contra o esquema da ferramenta — entradas inválidas retornam 422 com detalhes. Ferramentas MCP remotas retornam 501 com orientação para usar /v1/runs em vez disso (elas requerem o transporte de subprocesso do agente).
Conectores
Gerencie integrações OAuth — Google, Microsoft, GitHub, Notion, Slack e muito mais.
Navegar no catálogo de integrações disponíveis:
GET /v1/connectors/catalog
Retorna todos os provedores OAuth registrados com seu nome, categoria e escopos padrão.
Listar suas contas conectadas:
GET /v1/connectors
Retorna conexões ativas para o perfil atual. Os tokens nunca são expostos — apenas metadados (provedor, e-mail, status, escopos, carimbos de data/hora).
Verificar a integridade da conexão:
POST /v1/connectors/{id}/test
Retorna { health: { status, isTokenExpired, canRefresh } }.
Remover uma conexão:
DELETE /v1/connectors/{id}
A criação de novas conexões requer o fluxo interativo de OAuth via interface do usuário do aplicativo ou as rotas /auth/*.
Gatilhos
Agende agentes para serem executados automaticamente — resumos diários, relatórios semanais, monitoramento baseado em intervalos.
Listar gatilhos:
GET /v1/triggers
Criar um gatilho agendado:
POST /v1/triggers
Content-Type: application/json
{
"name": "Resumo Matinal",
"prompt": "Resuma meus e-mails não lidos e o calendário de hoje",
"modeId": "general",
"schedule": { "type": "daily", "time": "08:00" }
}
Tipos de agendamento suportados:
{ "type": "interval", "minutes": 60 }— a cada N minutos (mín 15, máx 1440){ "type": "daily", "time": "09:00" }— diariamente em um horário específico{ "type": "weekly", "day": "mon", "time": "09:00" }— semanalmente{ "type": "weekdays", "time": "08:30" }— de segunda a sexta-feira{ "type": "daysOfWeek", "days": ["mon", "wed", "fri"], "time": "10:00" }— dias específicos{ "type": "monthly", "dayOfMonth": 1, "time": "09:00" }— mensalmente{ "type": "manual" }— apenas quando disparado via API
Disparar um gatilho manualmente:
POST /v1/triggers/{id}/fire
Retorna 202 com um threadId para a execução resultante.
Atualizar ou excluir:
PATCH /v1/triggers/{id}
DELETE /v1/triggers/{id}
Webhooks
Gatilhos de webhook permitem que serviços externos (CI/CD, monitoramento, construtores de formulários) acionem a execução de um agente via HTTP.
Criar um gatilho de webhook:
POST /v1/triggers
Content-Type: application/json
{
"name": "Hook de deploy",
"prompt": "Um deploy aconteceu: {{webhook.body}}",
"modeId": "general",
"kind": "webhook"
}
Retorna 201 com um webhookSecret e webhookPath. Guarde o segredo — você precisará dele para assinar as cargas úteis.
Enviar um webhook:
# Calcular HMAC-SHA256 do corpo bruto da solicitação
SIGNATURE=$(echo -n '{"repo":"my-app","branch":"main"}' | openssl dgst -sha256 -hmac "$WEBHOOK_SECRET" | awk '{print $2}')
POST /v1/webhooks/{triggerId}
Content-Type: application/json
X-Webhook-Signature: $SIGNATURE
{"repo": "my-app", "branch": "main"}
O endpoint do webhook NÃO requer autenticação bearer — ele usa verificação HMAC em vez disso. Retorna 202 com o threadId da execução despachada. O marcador {{webhook.body}} no prompt do gatilho é substituído pelo corpo bruto da solicitação.
Funções Personalizadas
Crie suas próprias ferramentas que os agentes podem chamar. As funções são escritas em JavaScript ou Python e executadas em um sandbox.
Listar funções:
GET /v1/functions
Criar uma função:
POST /v1/functions
Content-Type: application/json
{
"name": "calcular_imc",
"description": "Calcula o Índice de Massa Corporal a partir da altura e peso",
"language": "javascript",
"source": "return { imc: (input.weightKg / (input.heightM * input.heightM)).toFixed(1) };",
"inputSchema": {
"type": "object",
"properties": {
"weightKg": { "type": "number" },
"heightM": { "type": "number" }
},
"required": ["weightKg", "heightM"]
}
}
As funções JavaScript recebem input e devem retornar um resultado. As funções Python definem uma variável result:
# Exemplo em Python
result = {"imc": round(input["weightKg"] / (input["heightM"] ** 2), 1)}
Executar uma função diretamente:
POST /v1/functions/{id}/execute
Content-Type: application/json
{ "input": { "weightKg": 75, "heightM": 1.80 } }
Segurança: JavaScript é executado no sandbox vm do Node (sem acesso ao sistema de arquivos ou rede, tempo limite de 10s). Python é executado como um subprocesso com um tempo limite de 30s. Ambos validam a entrada antes da execução.
Atualizar ou excluir:
PATCH /v1/functions/{id}
DELETE /v1/functions/{id}
Fluxos de Trabalho
Orquestre múltiplos agentes em um DAG (grafo acíclico dirigido) — execute etapas em paralelo sempre que possível e alimente as saídas de etapas anteriores em etapas posteriores.
Validar um grafo de fluxo de trabalho:
POST /v1/workflows/validate
Content-Type: application/json
{
"graph": {
"nodes": [
{ "id": "research", "agentId": "general", "prompt": "Pesquisar tendências de energia renovável" },
{ "id": "analyze", "agentId": "general", "prompt": "Pesquisar preços da concorrência" },
{ "id": "report", "agentId": "general", "prompt": "Escrever um relatório combinando: {{outputs.research}} e {{outputs.analyze}}", "dependsOn": ["research", "analyze"] }
]
}
}
Retorna { valid: true/false, errors: [...] }. Verifica ciclos, IDs duplicados e referências de dependência ausentes.
Executar um fluxo de trabalho:
POST /v1/workflows/execute
Content-Type: application/json
{
"graph": {
"nodes": [
{ "id": "research", "agentId": "general", "prompt": "Pesquisar tendências de energia renovável" },
{ "id": "summarize", "agentId": "general", "prompt": "Resumir: {{outputs.research}}", "dependsOn": ["research"] }
]
}
}
Retorna { status: "completed", outputs: { research: "...", summarize: "..." }, nodeResults: {...} }.
Nós independentes (sem dependências compartilhadas) são executados em paralelo. O marcador {{outputs.nodeId}} no prompt de um nó é substituído pelo conteúdo de saída do nó upstream nomeado. Cada nó é uma execução completa de agente, portanto, pode usar ferramentas, navegar na web e acessar todos os recursos do agente de destino.
Bases de Conhecimento
Organize documentos em coleções pesquisáveis que os agentes podem consultar.
Listar bases de conhecimento:
GET /v1/knowledge/bases
Criar uma base de conhecimento:
POST /v1/knowledge/bases
Content-Type: application/json
{ "name": "Artigos de Pesquisa" }
Retorna 201 com o novo ID da base.
Carregar um documento para uma base de conhecimento:
POST /v1/knowledge/bases/{id}/documents
Content-Type: application/json
{
"fileName": "artigo-de-pesquisa.pdf",
"contentType": "application/pdf",
"dataUrl": "data:application/pdf;base64,JVBERi0xLjQ...",
"description": "Tendências de energia renovável 2026"
}
O campo dataUrl é uma URL de dados codificada em base64. Retorna 201 com os metadados do documento.
Listar documentos em uma base de conhecimento:
GET /v1/knowledge/bases/{id}/documents
Pesquisar dentro de uma base de conhecimento:
POST /v1/knowledge/bases/{id}/search
Content-Type: application/json
{ "query": "energia renovável" }
Retorna documentos correspondentes com base no nome do arquivo e na descrição. A pesquisa semântica (vetorial) chegará em uma versão futura.
Excluir um documento ou base de conhecimento:
DELETE /v1/knowledge/bases/{id}/documents/{docId}
DELETE /v1/knowledge/bases/{id}
Exportar e Importar Agentes
Compartilhe agentes como pacotes portáteis — entre dispositivos, equipes ou o Community Hub.
Exportar um agente:
POST /v1/agents/{id}/export
Retorna um pacote JSON contendo a definição do agente, requisitos de ferramentas (derivados das ferramentas habilitadas), requisitos de conectores (quais provedores OAuth são necessários) e templates de gatilhos. Metadados de sincronização são removidos — o pacote é um projeto limpo e autossuficiente.
Importar um agente:
POST /v1/agents/import
Content-Type: application/json
{
\"package\": {
\"$schema\": \"caiioo.agent.package/v1\",
\"agent\": {
\"id\": \"agente-de-pesquisa-compartilhado\",
\"branding\": { \"name\": \"Agente de Pesquisa\", \"description\": \"Da equipe\" },
\"defaultSettings\": { \"systemPrompt\": \"Você pesquisa coisas.\" },
\"settingLevels\": {}
},
\"toolRequirements\": [
{ \"toolId\": \"web_browsing\", \"enabled\": true },
{ \"toolId\": \"search_tools\", \"enabled\": true }
]
}
}
Retorna 201 com o agente instalado. Colisões de ID com agentes integrados ou existentes retornam 409.
Tratamento de Erros
A API usa códigos de status HTTP padrão:
| Código | Significado |
|---|---|
200 |
Sucesso |
201 |
Criado |
202 |
Aceito (operação assíncrona iniciada) |
204 |
Excluído (sem conteúdo) |
400 |
Solicitação inválida — verifique o campo error para detalhes |
401 |
Não autorizado — segredo de sessão ausente ou inválido |
403 |
Proibido — ex: tentando modificar um agente integrado |
404 |
Não encontrado |
409 |
Conflito — ex: ID do agente já existe |
422 |
Erro de validação — a entrada não corresponde ao esquema da ferramenta |
500 |
Erro do servidor — verifique o campo error |
501 |
Não implementado — o recurso existe, mas não está disponível desta forma |
503 |
Serviço indisponível — armazenamento ou provedor não pronto |
Todas as respostas de erro incluem { "error": "mensagem legível por humanos" }.
Exemplo de Início Rápido
Aqui está um fluxo de trabalho completo: criar um agente, executá-lo e transmitir os resultados.
# 1. Criar um agente personalizado
curl -X POST http://localhost:3847/v1/agents \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "quick-summarizer",
"branding": { "name": "Resumidor Rápido" },
"defaultSettings": {
"systemPrompt": "Resuma qualquer entrada de forma concisa em 3 tópicos.",
"enabledTools": { "web_browsing": true }
},
"settingLevels": {}
}'
# 2. Executá-lo de forma assíncrona
RUN=$(curl -s -X POST http://localhost:3847/v1/runs \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "agentId": "quick-summarizer", "input": { "message": "Resuma https://en.wikipedia.org/wiki/Artificial_intelligence" }, "mode": "async" }')
RUN_ID=$(echo $RUN | jq -r '.runId')
# 3. Transmitir os eventos
curl -N http://localhost:3847/v1/runs/$RUN_ID/events \
-H "Authorization: Bearer $API_TOKEN"
# 4. Exportar o agente para compartilhamento
curl -X POST http://localhost:3847/v1/agents/quick-summarizer/export \
-H "Authorization: Bearer $API_TOKEN"
This guide is maintained by the Caiioo team using Slate, our built-in editor.