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:

  1. Abra as Configurações do Caiioo > Acesso à API
  2. Ative a opção Habilitar API Pública
  3. Defina um token de acesso à API (qualquer string que você escolher — trate-a como uma senha)
  4. 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.