Referência da API

Agents

Crie e versiona configurações de agents dentro de um projeto.

#Endpoints

MétodoCaminhoDescrição
POST/v1/projects/:projectId/agentsCria um agent e publica a versão 1.
POST/v1/projects/:projectId/agents/:idAplica patch com lock otimista e publica nova versão.
POST/v1/projects/:projectId/agents/:id/duplicateDuplica o agent como um agent novo (v1), com overrides opcionais de nome e modelo.
POST/v1/projects/:projectId/agents/:id/archiveArquiva o agent.
POST/v1/projects/:projectId/agents/:id/versions/:version/restoreRestaura uma versão histórica como nova versão corrente.
PUT/v1/projects/:projectId/agents/:id/mcp-servers/:name/headersRotaciona os headers de um servidor MCP sem publicar versão.
GET/v1/projects/:projectId/agents/:id/versionsLista versões por cursor.
GET/v1/projects/:projectId/agents/:idLê a versão atual ou uma versão específica.
GET/v1/projects/:projectId/agentsLista agents ATIVOS por cursor, com filtros opcionais de nome e arquivamento.

#Criar agent

ts
const agent = await client.agents.create({
name: 'Assistente operacional',
model: 'anthropic/claude-haiku-4-5',
system: 'Responda com clareza e peça dados faltantes antes de concluir.',
tools: ['web_search', 'memory_read'],
});

#Atualizar agent

Atualizações exigem a version atual. Se outra mudança publicou uma versão mais nova, a API retorna conflito (agent.version_conflict, 409).

ts
const updated = await client.agents.update(agent.id, {
  version: agent.version,
  system: 'Responda com clareza, peça dados faltantes e cite fontes quando pesquisar.',
});

O corpo tem semântica de patch: campo omitido preserva o valor atual. Campos de lista (tools, skills, serverlessTools, knowledgeBases) e objetos de configuração (defaults, multiagent, browser) substituem o valor inteiro — não há merge campo a campo. A exceção é metadata, que mescla por chave.

Um patch que não muda nada é no-op: o agent volta na resposta sem publicar versão nova.

#Limpar campos no update

Alguns campos não têm "valor vazio" representável: o schema exige objeto preenchido, então mandar o objeto vazio é inválido e omitir o campo significa preservar. Para esses, a limpeza tem sinal próprio — null.

SinalEfeito
multiagent: nullDesliga o coordenador (o agent volta a ser um agent comum).
browser: nullVolta ao browser self-hosted (o padrão).
defaults: nullLimpa os padrões de execução (ambiente, cofres e memória de uma vez).
recordBrowser: false ou nullDesliga a gravação de browser para replay.

Onde o valor vazio existe, ele é o sinal — sem null:

SinalEfeito
metadata: { "chave": "" }String vazia remove aquela chave.
knowledgeBases: []Desvincula todas as bases de conhecimento.
mcpServers[].headers: {}Apaga a credencial daquele servidor MCP.
json
{
  "version": 7,
  "multiagent": null,
  "defaults": null
}

Campo omitido continua preservando. null só é aceito nos campos da primeira tabela.

#Duplicar agent

Duplicar cria um agent novo (nasce na v1, com histórico próprio) copiando a config corrente da origem. O corpo carrega só overrides opcionais de name e model — passar só model é o atalho para clonar o mesmo agent com outro modelo e comparar desempenho entre eles.

http
POST /v1/projects/:projectId/agents/:id/duplicate
ts
// Uma variante por modelo, a partir do mesmo agent base:
const haiku = await client.agents.duplicate(agent.id, {
  name: 'Triagem — Haiku',
  model: 'anthropic/claude-haiku-4-5',
});
const flash = await client.agents.duplicate(agent.id, {
  name: 'Triagem — DeepSeek Flash',
  model: 'deepseek/deepseek-v4-flash-0731',
});

Pontos de contrato:

  • A cópia é server-side. Fazer o mesmo com GET + create clonaria os headers de servidor MCP já redigidos pela leitura; pelo endpoint, o clone nasce com a credencial vigente do armazém selado.
  • name ausente vira <origem> (cópia). O nome não precisa ser único — renomeie depois se quiser.
  • Duplicar é uma escrita e passa pela mesma validação do create. Config da origem que não vale mais hoje (skill removida, base desvinculada, modelo do override incompatível) responde 422 agent.duplicate_invalid com a causa no contexto. Falha de infraestrutura propaga com o código dela.
  • Origem arquivada duplica normalmente — o clone nasce ativo (é o jeito de reviver um agent arquivado).

#Restaurar uma versão

Restaurar copia a config de uma versão histórica e publica como nova versão corrente — o histórico nunca é reescrito.

http
POST /v1/projects/:projectId/agents/:id/versions/:version/restore

A versão de origem vai no path. O corpo carrega apenas a versão corrente esperada, para o lock otimista:

json
{ "version": 12 }
ts
const restored = await client.agents.restoreVersion(agent.id, {
  fromVersion: 3,
  version: agent.version,
});

Pontos de contrato:

  • A cópia é server-side. O corpo não carrega config. Isso importa porque a leitura redige o valor dos headers de servidor MCP: fazer o mesmo restore à mão (GET com ?version= seguido de update) apagaria a credencial. Pelo endpoint de restore, os headers são preservados.
  • Credencial rotacionada não volta. Os headers vigentes do armazém selado são reaplicados sobre o snapshot restaurado. Restaurar a v3 depois de uma rotação na v7 mantém a credencial da v7 — restaurar config nunca quis dizer voltar credencial.
  • Restaurar é uma escrita e passa pela mesma validação. Se a config antiga não vale mais no mundo de hoje (subagente do roster arquivado, base de conhecimento desvinculada, skill removida, ambiente ou cofre do padrão de execução apagado, modelo incompatível), a resposta é 422 agent.restore_invalid e a message nomeia a versão de origem e a causa. Falha de infraestrutura propaga com o código dela — o 422 significa "esta versão não vale mais", e repetir não resolve.
  • Restaurar a config que já é a corrente é no-op: devolve o agent sem publicar versão nova.

#Listar agents

A listagem devolve apenas agents ativos: um agent arquivado sai da lista. Use status para mudar isso — active (padrão), archived (só os arquivados) ou all (os dois, útil para auditoria e para resolver o nome de um agent arquivado a partir do id).

ts
const ativos = await client.agents.list();
const arquivados = await client.agents.list({ status: 'archived' });
const todos = await client.agents.list({ status: 'all', name: 'atendimento' });

O cursor de paginação vale para o conjunto de filtros que o gerou: ao trocar status (ou name), recomece da primeira página.

#Padrões de execução

defaults define o ambiente, os cofres e os repositórios de memória que uma session deste agent usa quando quem cria a session não disse nada. Antes disso, cada chamada, automação e canal precisava repetir a mesma lista.

json
{
  "defaults": {
    "environmentId": "env_...",
    "vaultIds": ["vault_..."],
    "resources": [
      { "memoryStoreId": "ms_...", "memoryStoreName": "Procedimentos", "mode": "read-only" }
    ]
  }
}
CampoTipoObservação
environmentIdstringAmbiente montado por padrão. Ausente = ambiente padrão do projeto.
vaultIdsarrayAté 16 cofres. Aceita id (vault_...) ou nome na escrita; a resposta traz sempre id.
resourcesarrayAté 16 mounts de memória. memoryStoreId aceita id (ms_...) ou nome.

memoryStoreName é obrigatório no corpo, mas o valor gravado vem sempre da store real — é um snapshot legível, nunca um nome divergente do id.

Precedência, aplicada na criação da session (nunca em runtime):

text
explícito da chamada  >  default do agent  >  default da conta

O sinal de "explícito" é a presença do campo, não o conteúdo. vaultIds: [] é uma afirmação ("esta session roda sem cofre") e vence o default do agent; campo ausente é silêncio e cai no default. Para environmentId, cuja forma vazia não é representável, o explícito vazio é environmentId: null (ambiente base da conta).

Mudar defaults não afeta sessions que já existem: uma session é autocontida depois de nascer.

Os ponteiros são validados na escrita — ambiente inexistente ou arquivado, cofre ou store que não existem no escopo devolvem 422 com o código correspondente na tabela de erros. Recusar aqui evita um padrão quebrado que só falharia meses depois, num disparo sem dono.

#Permissões por tool

toolPermissions mapeia nome de tool → política. Ele é um override do padrão por origem:

Origem da toolPadrão
Built-in / server-sidealways_allow
Tool de servidor MCPalways_ask
PolíticaComportamento
always_allowA plataforma executa a tool quando o modelo pedir.
always_askO loop pausa: a session vai para idle com stopReason igual a requires_action e aguarda um evento user.tool_confirmation.
json
{
  "toolPermissions": {
    "web_fetch": "always_allow",
    "browser_login": "always_ask",
    "billing__create_invoice": "always_ask"
  }
}

Não existe deny: a política decide quando pedir confirmação, não o que remover do toolset (remover é editar tools). A chave é validada só de forma — nomear uma tool que o agent não oferece é inofensivo, e o namespacing de MCP (<servidor>__<tool>) vale aqui também. A mesma política é editável no console, na tela do agent.

Uma tool always_ask que ninguém confirma pendura a session em requires_action até alguém responder. Em execuções sem operador — um caso de experimento, ou um subagente em delegação foreground — isso vira erro explícito, na hora, em vez de espera.

#Multi-agente (coordenador e roster)

Um agent com multiagent.type: "coordinator" delega a um roster de outros agents. Cada subagente roda como uma session filha, com contexto próprio, e o modelo enxerga uma tool delegate_to_<role> por entrada.

json
{
  "multiagent": {
    "type": "coordinator",
    "roster": [
      {
        "agentId": "agent_...",
        "version": 4,
        "role": "pesquisador",
        "mode": "background",
        "readonly": true,
        "model": "anthropic/claude-haiku-4-5"
      }
    ],
    "budget": { "maxDelegations": 12 }
  }
}
CampoTipoObservação
agentIdstringAgent alvo. Não pode ser o próprio coordenador nem outro coordenador (profundidade 1).
versionnumberVersão pinada. Omitida, a API resolve a corrente na escrita e grava o número.
rolestringHandle único, kebab-case, até 48 caracteres. Vira o nome da tool delegate_to_<role>.
modestringforeground (o coordenador espera) ou background (dispara e coleta depois).
readonlybooleanConfina o subagente a tools de leitura, em todas as origens.
modelstring ou objetoOverride do modelo do subagente. Substitui por inteiro; ausente = o modelo do próprio agent alvo.
outputSchemaobjectJSON Schema do output esperado, injetado na descrição da tool de delegação.

Limite de 20 entradas por roster; budget.maxDelegations é o teto de spawns na árvore de delegação — estourado, o coordenador recusa novas delegações e conclui com o que já tem.

Política de arquivado. Arquivar um subagente impede vínculos novos (a validação de roster recusa com 422 agent.invalid_roster), mas não interrompe o que já está pinado: o coordenador delega para uma versão congelada, e ela continua existindo. Um coordenador em execução não cai por causa de uma decisão administrativa tomada em outra aba.

Como consequência, editar um coordenador só re-valida o roster quando o multiagent muda. Renomear o coordenador ou trocar o prompt não vira 422 por causa de um subagente arquivado sem relação com a edição. Restore de versão é a exceção: ele valida o roster por inteiro.

#Servidores MCP e rotação de headers

mcpServers declara servidores MCP remotos. O name é o namespace das tools expostas ao modelo (<name>__<toolName>): precisa ser único e não pode conter __.

O valor de headers é write-only. A leitura (GET, listagens, histórico de versões) devolve apenas os nomes das chaves, em headerKeys:

json
{
  "mcpServers": [
    { "name": "billing", "url": "https://mcp.example/v1", "headerKeys": ["Authorization"] }
  ]
}

Para trocar uma credencial, use a rotação — não o update:

http
PUT /v1/projects/:projectId/agents/:id/mcp-servers/:name/headers
json
{ "headers": { "Authorization": "Bearer novo-token" } }
ts
const rotated = await client.agents.rotateMcpHeaders(agent.id, 'billing', {
  Authorization: 'Bearer novo-token',
});

Resposta:

json
{
  "agentId": "agent_...",
  "serverName": "billing",
  "version": 12,
  "headerKeys": ["Authorization"]
}

Contrato da rotação:

  • Não publica versão nova. version na resposta é a corrente, inalterada. Trocar um Authorization por update gravaria o segredo novo no histórico de versões, para sempre.
  • Vale imediatamente, inclusive para sessions já em execução: a credencial é resolvida na hora de conectar ao servidor MCP.
  • Merge por nome: header ausente do corpo é preservado. É o que permite trocar uma credencial sem conhecer as outras — e ninguém consegue lê-las.
  • Exige ao menos um header e exige que o servidor exista na config corrente (404 agent.mcp_server_not_found) — um nome com typo criaria uma credencial órfã que nunca seria usada nem notada.
  • Remover um header continua sendo edição da config: update com o conjunto novo em mcpServers[].headers (o objeto declara o conjunto inteiro; {} limpa).

#Campos principais

CampoTipoObservação
namestringNome de 1 a 200 caracteres.
descriptionstringOpcional, para humanos (até 2000 caracteres).
modelstring ou objetoIdentifica provedor e modelo.
systemstringInstruções persistentes.
toolsarrayBuilt-ins por string ou custom tools serializadas. Até 128, nomes únicos.
mcpServersarrayServidores MCP com name, url e headers opcionais (write-only).
toolPermissionsobjectalways_allow ou always_ask por tool.
skillsarrayReferências pinadas por versão. Até 64.
knowledgeBasesarrayAllowlist de bases (kb_...) acessíveis ao agent. Até 20; ausente = nenhuma.
serverlessToolsarrayTools serverless referenciadas com pin de versão. Até 64.
egressPolicyobjectOverride da política de egress; faz merge com a do workspace, sem relaxá-la.
defaultsobjectAmbiente, cofres e memória padrão da execução.
multiagentobjectCoordenador e roster de subagentes.
browserobjectOnde o navegador roda: self_hosted (padrão), steel_cloud ou browserbase.
recordBrowserbooleanGrava a navegação para replay. Ausente = desligado.
ttsobjectVoz do reply de áudio no WhatsApp.
metadataobjectPares string → string.

A resposta acrescenta id, version, createdAt, updatedAt e archivedAt aos campos da config.

#Erros

CódigoHTTPQuando
agent.not_found404Agent inexistente ou fora do projeto.
agent.version_not_found404?version= (ou a origem do restore) aponta para versão que não existe.
agent.version_conflict409A version enviada não é mais a corrente (alguém gravou no meio).
agent.archived409Escrita em agent arquivado.
agent.restore_invalid422A config da versão de origem não é mais aplicável. details.cause traz o porquê.
agent.invalid_roster422Entrada do roster inexistente, arquivada, auto-referente ou já coordenadora.
agent.unknown_knowledge_base422knowledgeBases referencia base fora do escopo.
agent.environment_not_found422defaults.environmentId não existe no projeto, ou está arquivado.
agent.vault_not_found422defaults.vaultIds referencia cofre que não existe no workspace.
agent.memory_store_not_found422defaults.resources referencia store que não existe no projeto.
agent.mcp_server_not_found404Rotação para um servidor MCP não declarado na config corrente.
serverless.tool_not_found422serverlessTools referencia tool inexistente.

#Conceitos relacionados