跳转到内容

API Endpoints

此内容尚不支持你的语言。

Every endpoint requires the x-api-key: <api_key> header unless noted. JSON request and response bodies. Errors follow the shape in REST API → Errors.

List all agents in the tenant. Query params: archived (bool), limit, cursor.

Create an agent. Body: AgentConfig minus the platform-assigned fields (id, version, timestamps).

Get a single agent’s current version.

List all versions of an agent.

Get a specific historical version.

Update an agent. Bumps version. Body: partial AgentConfig.

Archive an agent (soft delete; sessions retain pinned version).

Create a session. Returns SessionMeta.

{
"agent": "agent_...",
"environment_id": "env_...",
"title": "optional"
}

Post the first user turn afterwards via POST /v1/sessions/:id/messages (one-shot, streams reply) or POST /v1/sessions/:id/events (fire-and-forget; pair with a separate SSE consumer).

A session may carry the official budget {"budget": {"type": "limit", "max_list_cost": {"amount": "500", "currency": "USD"}}} (amount in whole USD cents, as an integer string).

  • Active only when both are configured: the session has max_list_cost and its model card has pricing (see Model Cards). If either is missing the budget is inactive — no budget_reached, no error — and the session’s usage.list_cost is absent (Console shows “unpriced”).
  • list_cost = Σ per model request (input_tokens × input_per_mtok + output_tokens × output_per_mtok + cache_read_input_tokens × cache_read_per_mtok + cache_creation_input_tokens × cache_write_per_mtok) / 1M, rounded to the cent.
  • The gate runs before every model request; the request that crosses the cap completes. At the cap the session emits session.thread_status_idle → session.usage → session.status_idle, each with stop_reason: {"type": "budget_reached"} (requires_action outranks it).
  • While paused, only settle events are accepted (user.tool_confirmation, user.tool_result, user.custom_tool_result, user.interrupt); user.message returns 400. An interrupt is accepted and ignored.
  • PATCH /v1/sessions/:id with budget: the budget is create-only (adding one to a session without a budget → 400); a new max_list_cost must be greater than the exact consumed list cost (else 400 budget.max_list_cost must be greater than the session's consumed list cost); budget: null removes it (one-way). Every budget change emits session.updated; one that lifts a budget_reached pause resumes the work automatically.
  • Upstream provider 429/quota errors are not budgets: they surface as session.error / retries_exhausted.

List sessions. Query: agent_id, status, limit, cursor.

Get session metadata + status.

JSON-paginated event log. Query: limit (1–1000, default 100), order (asc|desc), after_seq. Returns { data: SessionEvent[], has_more, next_page }.

Pass Accept: text/event-stream to switch to the SSE variant (or call /v1/sessions/:id/events/stream directly). Default behavior is Anthropic-spec-aligned: no history replay, only the spec event union (third-party @anthropic-ai/sdk parses cleanly). Two opt-ins:

  • ?include=chunks — admit OMA extension events (token chunks, lifecycle, system.user_message_*, session.warning, extra spans like aux.model_call)
  • ?replay=1 (or Last-Event-ID: <seq> header) — replay persisted history before tailing

See REST API → Stream session events for the full event tables.

Full event log as a JSON array (non-streaming).

OpenMA extension that lists durable files deliberately written beneath /mnt/session/outputs. Returns { data, has_more: false }. It is available on the Node entrypoint and on Cloudflare when FILES_BUCKET is configured. This is not currently a generated @anthropic-ai/sdk method, so call it with ordinary HTTP and include anthropic-beta: managed-agents-2026-04-01.

Streams one durable output. Filenames are a single path segment; parent or nested traversal is rejected. The Session is resolved in the authenticated workspace before the backing filesystem or object store is read.

Chatbot one-shot: post a user turn AND stream the response in one HTTP call. Body: { "content": string | ContentBlock[] }. Returns text/event-stream and auto-closes when the turn finishes (session.status_idle). For the fire-and-forget variant (when you already have a separate SSE consumer open), POST to /v1/sessions/:id/events instead with the user.message wrapped in {events:[...]} — returns 202.

Cancel a running session.

Soft-delete a session.

List environment templates.

Create an environment. Body: EnvironmentConfig.

Get one.

Update.

Delete (only if no agents reference it).

List custom + built-in skills.

Upload a custom skill. multipart/form-data with id, display_title, description, and one or more files.

Get metadata.

Download a skill file.

Delete (built-in skills can’t be deleted).

List. Returned objects never include the secret material.

Create. Body includes the secret; subsequent reads will not.

Update — including rotating the secret.

Delete.

POST /v1/vaults/:id/credentials also accepts auth.type: "cap_cli". This is an OpenMA extension, not part of the Anthropic Managed Agents API, so the Anthropic SDK does not type it.

{
"display_name": "GitHub CLI",
"auth": {
"type": "cap_cli",
"cli_id": "gh",
"token": "gho_...",
"refresh_token": "ghr_...",
"expires_at": "2026-09-01T00:00:00Z"
}
}

cli_id must name a builtin CLI spec (gh, glab, aws, gcloud, kubectl, …); anything else is a 400. refresh_token, expires_at and extras are optional. token, refresh_token and extras are write-only: responses carry only type, cli_id and expires_at. cli_id cannot change on update. mcp_oauth_validate refuses cap_cli credentials with a 400.

In a session, the egress proxy injects the newest active cap_cli credential for the CLI whose spec claims the request host, and refreshes it on 401 when the spec has a device flow and a refresh_token is stored. The sandbox only gets the spec’s placeholder environment (for example GITHUB_TOKEN=__cap_managed__), never the token. Injection needs a credential egress proxy. Self-hosted Node does not have one yet: Node managed sessions do not inject cap_cli credentials, or MCP credentials into direct sandbox traffic, until the sandbox layer implements CredentialEgressPort. There, cap_cli credentials are stored but not injected; mcp_oauth and static_bearer credentials still reach MCP servers through the Node MCP proxy.

POST /v1/oma/vaults/:id/cap_cli_device_flow (OpenMA extension)

Section titled “POST /v1/oma/vaults/:id/cap_cli_device_flow (OpenMA extension)”

Starts an OAuth device authorization (RFC 8628) for a CLI with { "cli_id": "gh" }. The response has user_code, verification_uri, interval_seconds, expires_at and an opaque flow_token.

POST /v1/oma/vaults/:id/cap_cli_device_flow/poll (OpenMA extension)

Section titled “POST /v1/oma/vaults/:id/cap_cli_device_flow/poll (OpenMA extension)”

Polls with { "flow_token": "..." }. status is pending, slow_down (with a new interval_seconds and flow_token to use from then on), expired, denied, error, or ready with the credential_id of the new cap_cli credential. On ready, older active cap_cli credentials for the same CLI in that vault are archived.

List per agent.

Create.

List recent entries.

Semantic search. Body: { "query": "...", "limit": 10 }.

Delete the store and its index.

Upload. multipart/form-data with session_id and file.

Download.

Delete.

Model cards may carry list pricing (USD per 1M tokens, decimal strings with ≤6 decimals) used to compute a session’s list_cost:

{
"pricing": {
"version": 1,
"currency": "USD",
"effective_at": "2026-11-01T00:00:00Z",
"input_per_mtok": "3",
"output_per_mtok": "15",
"cache_read_per_mtok": "0.30",
"cache_write_per_mtok": "3.75"
}
}

input_per_mtok and output_per_mtok are required; cache prices default to the input price. pricing: null on update clears it. Pricing has no budget — budgets live on sessions, and are enforced only when the card is priced.

Model Cards are the tenant-scoped executable model registry. A card binds a stable handle (model_id) to a Pi provider, its wire-level model id, endpoint, metadata, and encrypted credential. Keys are AES-256-GCM-encrypted at rest under PLATFORM_ROOT_SECRET; list/retrieve responses surface only the preview.

EndpointShape and purpose
GET /v1/models / GET /v1/models/:idOfficial Managed Agents Model resources. Lists active Model Cards the tenant can execute. Display name, token limits, image/thinking/effort and strict-output capabilities are conservatively projected from Pi metadata. Provider credentials never appear.
POST /v1/oma/models/listOMA setup helper. Body { "provider": "deepseek" } returns Pi’s built-in catalog for that provider. The SDK-first path does not send provider credentials. Optional api_key is a deprecated 0.x compatibility path for Anthropic/OpenAI live discovery.

An unknown custom provider has no discoverable catalog. Create its Model Card directly with base_url and pi_config.api.

List configured model cards.

Add a model card. Runs a 6-second capability probe so a bad key fails loudly. Body:

{
"model_id": "deepseek-fast",
"provider": "deepseek",
"model": "deepseek-v4-flash",
"custom_headers": { "x-extra": "..." },
"api_key": "sk-...",
"pi_config": { "reasoning": true }
}

provider is an open Pi provider id, not an OpenMA enum. Pi built-ins include anthropic, openai, deepseek, openrouter, google, minimax, and more. Legacy aliases ant, oai, ant-compatible, and oai-compatible remain accepted. model_id is the handle used in the official Agent model:

{
"model": {
"id": "deepseek-fast",
"effort": { "type": "high" },
"speed": "standard",
"inference_geo": "us"
}
}

These controls belong to the Agent version, not the Model Card. A Session pins an Agent version and inherits them:

FieldRuntime mapping
effortPi thinkingLevel. Pi normalizes a requested level to the nearest level the resolved model supports.
speed: "standard"Leaves Pi/provider defaults unchanged.
speed: "fast"Anthropic fast mode (speed: fast plus its beta header), or OpenAI priority service tier. Other Pi APIs return an explicit unsupported error.
inference_geoValidated, stored, versioned, and returned; currently ignored by runtime routing.

pi_config accepts Pi’s serializable Model metadata (name, api, reasoning, thinkingLevelMap, input, cost, contextWindow, maxTokens, samplingParams, headers, and compat). It cannot override card identity, provider, wire model, endpoint, or credential. Custom providers must specify pi_config.api so Pi can select a protocol implementation.

Create returns a probe result. The current bounded live probe covers the legacy Anthropic/OpenAI protocols. {"ok":null,"reason":"unsupported_provider"} means the probe was skipped; it is not a Pi runtime rejection.

Rotate the api_key, base_url, headers, or default model. Body shape matches POST. In-flight sessions keep the cached key until next credential resolve.

Delete.

GET /v1/oma/model_cards/:id/key (internal — agent worker only)

Section titled “GET /v1/oma/model_cards/:id/key (internal — agent worker only)”

Returns cleartext credentials for the agent worker. Not exposed publicly.

List shipped + active integrations.

Start the OAuth flow for the integration. Returns a redirect URL.

Revoke the install.

List publications (which agents serve which workspaces).

POST /v1/oma/integrations/:id/publications

Section titled “POST /v1/oma/integrations/:id/publications”

Create a publication.

DELETE /v1/oma/integrations/:id/publications/:pub_id

Section titled “DELETE /v1/oma/integrations/:id/publications/:pub_id”

Delete a publication.

List eval runs.

Start an eval.

Get an eval’s results.

List your keys (the actual key value is not returned).

Create. Body: { "name": "..." }. Returns the key once — store it now.

Revoke.

Starts browser OAuth 2.1 (Authorization Code + PKCE) for an MCP server. JSON body: mcp_server_url and vault_id (required); credential_id (re-authorize an mcp_oauth credential for the same MCP server), redirect_uri (where the browser returns), client_id / client_secret (pin an OAuth client). Returns { "authorization_url": "..." }; open a blank popup during the click, then navigate it to that URL after the POST completes. Secrets must not be sent in query parameters. redirect_uri must use this service’s origin or an origin configured in the comma-separated CONSOLE_ORIGINS setting (same on Cloudflare and Node). The authorization server is discovered from the MCP server’s metadata (RFC 9728, RFC 8414). The client comes from dynamic registration or, for providers that do not support it, from <PROVIDER>_OAUTH_CLIENT_ID / _SECRET (GITHUB, FEISHU, LARK, ASANA, CLICKUP, SLACK); without one the answer is 501 with setup instructions. The in-flight flow travels sealed in the OAuth state (10 minutes), bound to the workspace and authenticated user.

Exchanges the code and stores a managed mcp_oauth credential in the vault, with refresh metadata when the provider issued a refresh token. Older active mcp_oauth credentials for the same MCP server in that vault, and the re-authorized one, are archived. Archival failures return an error instead of reporting success. The popup page notifies only the validated Console origin (postMessage, plus BroadcastChannel("openma-oauth") when same-origin) and closes, or navigates back when no notification transport is available. Error responses contain fixed reasons rather than upstream bodies or internal URLs. The MCP and egress proxies refresh the credential on 401.

oma connect <server|url> --vault <id> uses POST /v1/oma/oauth/cli/authorize with the same required JSON fields, without redirect_uri. The response includes authorization_url, flow_id, claim_token, expires_at and interval_seconds. Only open authorization_url in the browser; never include the API key, client secret or claim token in a URL. The provider still redirects to the service’s registered /v1/oma/oauth/callback, so existing preset clients do not need loopback redirect registration.

Poll POST /v1/oma/oauth/cli/result with { "flow_id": "...", "claim_token": "..." } and the original x-api-key. Results are pending, failed, or ready with only credential_id, never access/refresh tokens. Flows expire after 10 minutes and terminal results are consumed once. Claims are bound to the workspace, initiating user (when the key has one), original API key hash and independent claim secret. The browser does not need a Console cookie: only the sealed CLI discriminator plus the matching pending flow can complete the public callback; Console states continue to require their original authenticated user and allowed origin.

Returns {"ok": true}. Unauthenticated.