Follow Discord
Sweep 22 Oct 2026 · 21:04Z Build v2.1.309 528 read Stable v2.1.308 Latest v2.1.309 Next v2.1.309 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One capture · api

One read of Claude Developer Platformapi-20261021T193714Z

242 pages moved out of 808 read.

Pages moved 242 significant first
Pages read 808 in this capture
Captured 19:37 UTC
Corpus hash 851c97e9b6f0 corpus-hash

What this read moved

151-175 of 242, page 7 of 10

This capture is too large to show at once. Changes 151-175 of 242 are below, significant first; the rest are on the following screens.

manage-claude/wif-providers/okta Changed · +3 / -3 lines

from line 31
3131The exact navigation depends on your Okta org configuration and admin console version. The following numbered steps walk through one common path:
3232 
33331. **Create a service app integration.** In the Okta Admin Console, create a new app integration of type **API Services** (OIDC, machine-to-machine). Note the generated **Client ID**.
342. **Configure client authentication.** For a keyless setup, choose **Public key / Private key** (`private_key_jwt`) and register your workload's public JWK. Alternatively, use a client secret if your environment can store one securely. For the following example you may need to disable the DPoP requirement on the application; ensure that your production setup adheres to your organization's security requirements.
342. **Configure client authentication.** For a keyless setup, select **Public key / Private key** (`private_key_jwt`) and register your workload's public JWK. Alternatively, use a client secret if your environment can store one securely. For the following example you might need to disable the DPoP requirement on the application; ensure that your production setup adheres to your organization's security requirements.
35353. **Set the audience.** On your custom authorization server, set the audience to `https://api.anthropic.com` so issued access tokens carry that `aud` claim. Anthropic validates `aud` against this fixed value.
36364. **Grant a scope.** On your custom authorization server, ensure at least one scope exists that the service app is allowed to request (for example, `anthropic.access`). Okta rejects `client_credentials` requests that do not include a granted scope.
37375. **Create an access policy.** On your custom authorization server, create an access policy with at least one rule that allows your service app to request the scope you granted in step 4.
from line 509
509509* **Pin the exact Client ID:** Set `subject_prefix` to the service app's full Client ID with no trailing `*`.
510510* **Pin the audience:** Match the `audience` value you configured on the authorization server so tokens minted for a different audience are rejected.
511511* **Match on custom claims:** For finer-grained scoping, add claims in the authorization server's **Claims** tab and match them with the rule's `claims` map or a CEL `condition`.
512* **Use one rule per service app:** Create a separate federation rule for each service app rather than sharing one rule across apps.
512* **Use one rule for each service app:** Create a separate federation rule for each service app rather than sharing one rule across apps.
513513 
514514## Next steps
515515 
516516* Review the [WIF reference](https://platform.claude.com/docs/en/manage-claude/wif-reference) for the full credential resolution order and profile configuration.
517* See the [WIF reference](https://platform.claude.com/docs/en/manage-claude/wif-reference#rule-matching-semantics) to match on custom Okta claims with CEL expressions.
517* See [Rule matching semantics](https://platform.claude.com/docs/en/manage-claude/wif-reference#rule-matching-semantics) to match on custom Okta claims with CEL expressions.
518518 

manage-claude/wif-providers/spiffe Changed · +5 / -5 lines

from line 177
177177 
178178 ACCESS_TOKEN=$(curl -sS https://api.anthropic.com/v1/oauth/token \
179179 -H "content-type: application/json" \
180 --data @- <<JSON | jq -r .access_token
180 -d @- <<JSON | jq -r .access_token
181181 {
182182 "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
183183 "assertion": "$JWT",
from line 342
342342 </Tab>
343343 
344344 <Tab title="Token provider through the SPIFFE Workload API">
345 Except in Java, workloads that link a SPIFFE Workload API client directly can skip spiffe-helper and pass the SDK a token provider that fetches a fresh JWT-SVID from the agent socket. The SDK invokes the provider before each token exchange, so the workload always presents an unexpired SVID. Python ([py-spiffe](https://github.com/HewlettPackard/py-spiffe)) and Go ([go-spiffe](https://github.com/spiffe/go-spiffe)) have mature Workload API clients.
345 Except in Java, workloads that link a SPIFFE Workload API client directly can skip spiffe-helper and pass the SDK a token provider that fetches a fresh JWT-SVID from the agent socket. The SDK calls the provider before each token exchange, so the workload always presents an unexpired SVID. Python ([py-spiffe](https://github.com/HewlettPackard/py-spiffe)) and Go ([go-spiffe](https://github.com/spiffe/go-spiffe)) have mature Workload API clients.
346346 
347347 <CodeGroup exclude="shell, typescript, java, csharp, php, ruby">
348348 ```python Python
from line 445
445445 
446446## Verify the setup
447447 
448Before wiring the SDK in, fetch a JWT-SVID directly from SPIRE Agent and confirm the claims match what your federation rule expects. If you use a different SPIFFE implementation, fetch a JWT-SVID with its CLI or Workload API client and decode the payload the same way.
448Before integrating the SDK, fetch a JWT-SVID directly from SPIRE Agent and confirm the claims match what your federation rule expects. If you use a different SPIFFE implementation, fetch a JWT-SVID with its CLI or Workload API client and decode the payload the same way.
449449 
450450<Note>
451451 The Workload API attests the calling process. For a Kubernetes registration entry, run this command inside a pod that satisfies the entry's selectors and has the agent socket mounted (for example, by using `kubectl exec`). On VMs and bare metal, run it as the user or process that matches the entry's `unix:` selectors. Running from an unattested host shell returns `no identity issued`, which is the most common verify-step failure.
from line 474
474474 
475475* **Pin to one workload:** Set `subject_prefix` to the full SPIFFE ID with no trailing `*`.
476476* **Always set an audience:** Require `audience` on the rule and configure spiffe-helper (or the Workload API call) with the same value so SVIDs minted for other relying parties are rejected.
477* **Scope by path segment:** Use `spiffe://prod.example.com/ns/inference/*` to grant every workload registered under a namespace, and create a separate rule and Anthropic service account per namespace rather than widening one rule.
478* **One issuer per trust domain:** Each SPIRE trust domain has its own signing keys and OIDC Discovery Provider. Register each as a separate federation issuer and bind rules to the issuer that owns the SPIFFE IDs they match.
477* **Scope by path segment:** Use `spiffe://prod.example.com/ns/inference/*` to grant every workload registered under a namespace, and create a separate rule and Anthropic service account for each namespace rather than widening one rule.
478* **One issuer for each trust domain:** Each SPIRE trust domain has its own signing keys and OIDC Discovery Provider. Register each as a separate federation issuer and bind rules to the issuer that owns the SPIFFE IDs they match.
479479 
480480## Next steps
481481 

manage-claude/wif-reference Changed · +15 / -15 lines

from line 126
126126| `workspace:developer` | All non-administrative Claude API endpoints in the rule's workspace: [Messages](https://platform.claude.com/docs/en/api/messages) (including streaming and token counting), [Models](https://platform.claude.com/docs/en/api/models/list), [Managed Agents](https://platform.claude.com/docs/en/managed-agents/overview) and their sessions, [Files](https://platform.claude.com/docs/en/build-with-claude/files), and [Skills](https://platform.claude.com/docs/en/build-with-claude/skills-guide). This matches the access a workspace API key in the same workspace has. |
127127| `workspace:inference` | The inference endpoints in the rule's workspace: [Messages](https://platform.claude.com/docs/en/api/messages) (including streaming and token counting), [Models](https://platform.claude.com/docs/en/api/models/list), and the [OpenAI-compatible chat endpoint](https://platform.claude.com/docs/en/cli-sdks-libraries/libraries/openai-sdk). Use this for workloads that only need to call Claude and never need to manage Files, Skills, or other resources. |
128128| `workspace:manage_tunnels` | The [MCP tunnels API](https://platform.claude.com/docs/en/agents-and-tools/mcp-tunnels/reference#tunnels-api): create, list, and get tunnels, register and archive CA certificates, reveal and rotate the tunnel token, and archive tunnels. The Console's create-tunnel modal window locks this scope when you create a rule from it. |
129| `org:admin` | Full access to the [Admin API](https://platform.claude.com/docs/en/manage-claude/admin-api) (organization members, invites, workspaces, API keys, and the rest). An OAuth `org:admin` token can only create or modify rules scoped to `workspace:developer` or `workspace:inference`, and cannot update an issuer that backs a rule with any other scope; see the [constraints](https://platform.claude.com/docs/en/manage-claude/wif-admin-api#permissions-and-constraints). |
129| `org:admin` | Full access to the [Admin API](https://platform.claude.com/docs/en/manage-claude/admin-api) (organization members, invites, workspaces, API keys, and the rest). An OAuth `org:admin` token can only create or modify rules scoped to `workspace:developer` or `workspace:inference`, and cannot update an issuer that backs a rule with any other scope; see [Permissions and constraints](https://platform.claude.com/docs/en/manage-claude/wif-admin-api#permissions-and-constraints). |
130130 
131131A request to an endpoint outside the token's scope returns HTTP 403. Finer-grained scopes (per resource, or read versus write) are not currently available.
132132 
from line 134
134134 
135135A federation rule's `oauth_scope` is a ceiling: the minted token can never exceed it. The target service account's `organization_role` (`developer` or `admin`) determines which scopes are grantable, so a rule that grants `org:admin` must target a service account with `organization_role=admin`. Effective permissions are the intersection of the rule's scope and the service account's role.
136136 
137| Rule `oauth_scope` | Service account `organization_role` | Effective permissions |
138| --------------------- | ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
139| `workspace:developer` | `admin` | Claude API access in the rule's workspace only. The scope caps the token below the role. |
140| `org:admin` | `admin` | Full Admin API access (organization members, invites, workspaces, API keys, and the rest), minus the OAuth-caller carve-outs; see [constraints](https://platform.claude.com/docs/en/manage-claude/wif-admin-api#permissions-and-constraints). |
137| Rule `oauth_scope` | Service account `organization_role` | Effective permissions |
138| --------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
139| `workspace:developer` | `admin` | Claude API access in the rule's workspace only. The scope caps the token below the role. |
140| `org:admin` | `admin` | Full Admin API access (organization members, invites, workspaces, API keys, and the rest), minus the OAuth-caller exceptions; see [Permissions and constraints](https://platform.claude.com/docs/en/manage-claude/wif-admin-api#permissions-and-constraints). |
141141 
142142## Validation rules
143143 
from line 186
186186 
187187A federation rule's `match` block determines whether an incoming JWT is accepted. All populated fields are evaluated with AND semantics: the JWT must satisfy every populated matcher. At least one of `subject_prefix`, `claims`, or `condition` must be set; a `match` block that contains only `audience` (or no matchers at all) is rejected. This guards against rules that would accept every token from an issuer.
188188 
189| Matcher | Type | Semantics |
190| ---------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
191| `subject_prefix` | string | Exact match against the JWT `sub` claim. A trailing `*` makes it a prefix match (the `sub` value must begin with the characters before the `*`). Case-sensitive. |
192| `audience` | string | The JWT `aud` claim must contain this exact string. When `aud` is an array, any element matching exactly satisfies the check. |
193| `claims` | map\<string, string> | Each key is a top-level claim name and each value is the required exact string value. For nested, numeric, boolean, or complex claims like lists and maps, use `condition` with a CEL expression instead. |
194| `condition` | string (CEL) | A [CEL](https://cel.dev/) expression that must evaluate to `true`. |
189| Matcher | Type | Semantics |
190| ---------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
191| `subject_prefix` | string | Exact match against the JWT `sub` claim. A trailing `*` makes it a prefix match (the `sub` value must start with the characters before the `*`). Case-sensitive. |
192| `audience` | string | The JWT `aud` claim must contain this exact string. When `aud` is an array, any element matching exactly satisfies the check. |
193| `claims` | map\<string, string> | Each key is a top-level claim name and each value is the required exact string value. For nested, numeric, Boolean, or complex claims such as lists and maps, use `condition` with a CEL expression instead. |
194| `condition` | string (CEL) | A [CEL](https://cel.dev/) expression that must evaluate to `true`. |
195195 
196196### CEL evaluation environment
197197 
from line 225
225225| 401 | `authentication_error` | JWKS fetch failed, JWKS is stale, or the JWT was signed with a key not in the JWKS. | For `inline` mode, update the issuer with the rotated keys. For `discovery` and `explicit_url`, confirm the JWKS endpoint is reachable on port 443; if the issuer recently rotated its signing key, see [Key rotation and caching](https://platform.claude.com/docs/en/manage-claude/wif-reference#key-rotation-and-caching). |
226226| 401 | `authentication_error` | The JWT `exp` claim is in the past (beyond the 30-second skew window). | Confirm your identity provider is projecting a fresh token and the SDK is re-reading the token file. |
227227| 401 | `authentication_error` | The JWT was verified but its claims do not satisfy the rule's `match` block. | Decode the JWT and compare each claim against the rule. `subject_prefix` is case-sensitive. `audience` requires an exact element match. |
228| 401 | `authentication_error` | The `federation_rule_id` does not exist, is archived, or the JWT is not authorized for it (consolidated to prevent enumeration). | Confirm the rule ID in the Claude Console and that the rule has not been archived. |
228| 401 | `authentication_error` | The `federation_rule_id` does not exist or is archived, or the JWT is not authorized for it (consolidated to prevent enumeration). | Confirm the rule ID in the Claude Console and that the rule has not been archived. |
229229| 401 | `authentication_error` | The federation rule is enabled for more than one workspace and the request omits `workspace_id`. The authentication history entry shows reason `workspace_id_required`. | Set `ANTHROPIC_WORKSPACE_ID` (or the `workspace_id` body field on a raw request) to the `wrkspc_...` ID you want the token scoped to. See [Token exchange request](https://platform.claude.com/docs/en/manage-claude/wif-reference#token-exchange-request). |
230230 
231Every assertion denial returns the same opaque `401` `authentication_error` with the fixed message `Authentication failed`, regardless of which check failed; a distinguishable error would let a caller probe rule configuration. The deny reason is recorded on the attempt's entry in the [authentication history](https://platform.claude.com/settings/workload-identity-federation?tab=history) in the Claude Console, for example `match_subject_prefix` when the `sub` claim fails the rule's `subject_prefix`, or `workspace_id_required` when the rule spans multiple workspaces and the request names none. Requests rejected before the rule's organization is corroborated (the `400 invalid_request_error` family above) leave no history entry; their response messages name the problem directly. A `401` with no matching history entry usually means the `federation_rule_id` itself was not recognized.
231Every assertion denial returns the same opaque `401` `authentication_error` with the fixed message `Authentication failed`, regardless of which check failed; a distinguishable error would let a caller probe rule configuration. The deny reason is recorded on the attempt's entry in the [authentication history](https://platform.claude.com/settings/workload-identity-federation?tab=history) in the Claude Console, for example `match_subject_prefix` when the `sub` claim fails the rule's `subject_prefix`, or `workspace_id_required` when the rule spans multiple workspaces and the request names none. Requests rejected before the rule's organization is corroborated (the `400 invalid_request_error` family in the previous table) leave no history entry. Their response messages name the problem directly. A `401` with no matching history entry usually means the `federation_rule_id` itself was not recognized.
232232 
233233### Common SDK-side failures
234234 
from line 270
270270 </Step>
271271 
272272 <Step title="Check sub and each claims entry">
273 Compare `sub` against the rule's `subject_prefix` (case-sensitive; a trailing `*` is a prefix match, anything else is exact). Compare every key in the rule's `claims` map against the same-named top-level claim.
273 Compare `sub` against the rule's `subject_prefix` (case-sensitive; a trailing `*` is a prefix match, and anything else is exact). Compare every key in the rule's `claims` map against the same-named top-level claim.
274274 </Step>
275275 
276276 <Step title="Check exp, nbf, and iat">
from line 298
298298 
299299### Key rotation and caching
300300 
301In `discovery` and `explicit_url` modes, Anthropic caches the fetched JWKS. If your identity provider publishes a new signing key and immediately starts signing tokens with it, exchanges that present those tokens may fail with a signature error for up to 1 minute while the cache refreshes.
301In `discovery` and `explicit_url` modes, Anthropic caches the fetched JWKS. If your identity provider publishes a new signing key and immediately starts signing tokens with it, exchanges that present those tokens might fail with a signature error for up to 1 minute while the cache refreshes.
302302 
303303To avoid this window, publish a new signing key in the JWKS at least 15 minutes before your identity provider starts signing tokens with it, and keep the superseded key in the JWKS until tokens it signed have expired. Managed identity providers typically follow this discipline on their own. If you operate your own issuer (a self-managed Kubernetes cluster, a SPIRE OIDC discovery provider, or an Okta custom authorization server with a configured rotation cadence), confirm that your rotation policy publishes new keys ahead of first use.
304304 

manage-claude/workload-identity-federation Changed · +6 / -6 lines

from line 8
88 
99Your workload presents a signed JWT from your identity provider. Anthropic validates it against trust rules you configure in the Claude Console and returns a short-lived Anthropic access token bound to a service account in your organization. There are no static secrets to mint, store in CI, rotate, or leak.
1010 
11Workload Identity Federation strengthens your security posture by replacing static API keys with tokens that expire in minutes rather than never. It is not a complete security story on its own: federated authentication is only as strong as the upstream identity provider that signs the JWT. Pair Workload Identity Federation with the controls your IdP already supports (workload identity binding, conditional access, audit logging) for defense in depth.
11Workload Identity Federation strengthens your security posture by replacing static API keys with tokens that expire in minutes rather than never. It is not a complete security solution on its own: federated authentication is only as strong as the upstream identity provider that signs the JWT. Pair Workload Identity Federation with the controls your IdP already supports (workload identity binding, conditional access, audit logging) for defense in depth.
1212 
1313## Concepts
1414 
from line 18
1818 
1919A **service account** (`svac_...`) is a named, non-human identity inside your Anthropic organization. It is the principal that a [service account key](https://platform.claude.com/docs/en/manage-claude/authentication#key-types) or a federated token acts as. Service accounts live at the organization level and become active in a workspace when you add them as members of that workspace. At exchange time, Anthropic checks that the federation rule's workspace matches one of the service account's workspace memberships; the minted token then follows that workspace's rate limits and usage attribution, the same as an API key. Unlike a human user, a service account has no email, no password, and no Console login. Every service account is implicitly a member of your organization's default workspace; add explicit memberships for any other workspace it should act in. To let an all-workspaces service account key act in a workspace, add the service account to that workspace.
2020 
21The key distinction versus a workspace API key: a workspace API key *is* a credential, while a service account *has* credentials. You can more easily audit which workloads acted as which service account.
21The key distinction versus a workspace API key: a workspace API key *is* a credential, whereas a service account *has* credentials. You can more easily audit which workloads acted as which service account.
2222 
2323### Federation issuers
2424 
from line 31
3131 
3232Issuer and JWKS URLs must be `https`, on port 443, and use a public DNS hostname that resolves to public IP addresses; IP literals are not accepted. These constraints apply only to URLs Anthropic fetches; in `explicit_url` and `inline` modes the `issuer_url` is compared as a string and may reference an internal hostname.
3333 
34You typically register one issuer per environment: your production EKS cluster, your staging cluster, and GitHub Actions are three separate issuers.
34You typically register one issuer for each environment: your production EKS cluster, your staging cluster, and GitHub Actions are three separate issuers.
3535 
3636### Federation rules
3737 
from line 43
4343* **Target:** The service account the matched JWT maps to.
4444* **Authorization:** The OAuth `scope` granted on the minted token. The default is `workspace:developer`, which grants the same access as a workspace API key. Some products lock the scope when you create a rule from their flow; for example, the [MCP tunnels](https://platform.claude.com/docs/en/agents-and-tools/mcp-tunnels/overview) create-tunnel modal creates rules scoped to `workspace:manage_tunnels`. See [OAuth scopes](https://platform.claude.com/docs/en/manage-claude/wif-reference#oauth-scopes). The rule also sets `token_lifetime_seconds` (60 to 86400, default 3600).
4545 
46A single issuer can have many rules: one per team, namespace, or permission level. Rules are evaluated by ID: the client specifies which rule to use in the exchange request, and Anthropic verifies the JWT satisfies that rule's match criteria. There is no implicit rule search.
46A single issuer can have many rules: one for each team, namespace, or permission level. Rules are evaluated by ID: the client specifies which rule to use in the exchange request, and Anthropic verifies the JWT satisfies that rule's match criteria. There is no implicit rule search.
4747 
4848## How it works
4949 
from line 87
8787 
8888### Construct the SDK client
8989 
90You can construct the client with explicit credentials or with no arguments. With no arguments, the SDK resolves credentials from environment variables or the active profile, as described under [Credential precedence](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation#credential-precedence). The zero-argument form is the recommended pattern for production workloads: ship the same container image everywhere and inject `ANTHROPIC_FEDERATION_RULE_ID`, `ANTHROPIC_ORGANIZATION_ID`, `ANTHROPIC_SERVICE_ACCOUNT_ID`, `ANTHROPIC_WORKSPACE_ID`, and `ANTHROPIC_IDENTITY_TOKEN_FILE` per environment.
90You can construct the client with explicit credentials or with no arguments. With no arguments, the SDK resolves credentials from environment variables or the active profile, as described under [Credential precedence](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation#credential-precedence). The zero-argument form is the recommended pattern for production workloads: ship the same container image everywhere and inject `ANTHROPIC_FEDERATION_RULE_ID`, `ANTHROPIC_ORGANIZATION_ID`, `ANTHROPIC_SERVICE_ACCOUNT_ID`, `ANTHROPIC_WORKSPACE_ID`, and `ANTHROPIC_IDENTITY_TOKEN_FILE` for each environment.
9191 
9292<CodeGroup>
9393 ```bash cURL
from line 357
357357 
3583581. **Configure federation in parallel.** Complete the [setup walkthrough](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation#set-up-federation) and confirm the federation rule matches your workload's token. Leave the existing `ANTHROPIC_API_KEY` in place for now.
3593592. **Smoke-test which credential wins.** Run `ant auth status` from inside the workload (or inspect SDK debug logs). Because `ANTHROPIC_API_KEY` sits above the federation tiers in the precedence chain, the API key still wins at this stage.
3603. **Unset `ANTHROPIC_API_KEY` everywhere it is injected.** Remove it from CI secrets, container environment, and shell profiles (see the preceding warning). Re-run `ant auth status` and confirm the federation source is now selected.
3603. **Unset `ANTHROPIC_API_KEY` everywhere it is injected.** Remove it from CI secrets, container environment, and shell profiles (see the preceding warning). Re-run `ant auth status` and confirm the federation source now wins.
3613614. **Delete the API key.** Once the workload is running on the federated token, delete the key on the [API keys](https://platform.claude.com/settings/keys) page (`platform.claude.com/settings/keys`) in the Claude Console.
362362 
363363## Token lifetime and refresh

manage-claude/workspaces Changed · +13 / -13 lines

from line 13
1313Key characteristics:
1414 
1515* **Workspace identifiers** use the `wrkspc_` prefix (for example, `wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ`)
16* **Maximum 100 workspaces** per organization by default (archived workspaces don't count); contact your account team if you need more
16* **Maximum 100 workspaces** for each organization by default (archived workspaces don't count); contact your account team if you need more
1717* **Default Workspace** has a `wrkspc_` ID like any other workspace (returned in the [`anthropic-workspace-id` response header](https://platform.claude.com/docs/en/manage-claude/workspaces#identify-the-workspace-behind-an-api-response) and accepted by [Get Workspace](https://platform.claude.com/docs/en/api/organization/workspaces/retrieve)), but it appears in [List Workspaces](https://platform.claude.com/docs/en/api/organization/workspaces/list) results only when you pass `include_default=true`, and usage reports and cost reports show `null` for its `workspace_id` (an API key's `scope` field carries the real ID for a key bound to the Default Workspace)
18* **API keys** can be scoped to a single workspace. In this case, they can only access resources within that workspace. Some API keys can be granted permissions across multiple workspaces, and provide a [workspace ID header](https://platform.claude.com/docs/en/manage-claude/authentication#select-a-workspace) to access resources within that workspace
18* **API keys** can be scoped to a single workspace. In this case, they can only access resources within that workspace. Other API keys aren't scoped to a workspace. With one of these keys, send a [workspace ID header](https://platform.claude.com/docs/en/manage-claude/authentication#select-a-workspace) on each request to choose the workspace. The key's user or service account must have access to that workspace
1919 
2020### Claude Code workspace
2121 
from line 46
4646 
4747### Role inheritance
4848 
49* **Organization admins** automatically receive Workspace Admin access to all workspaces
50* **Organization billing members** automatically receive Workspace Billing access to all workspaces
51* **Organization users and developers** must be explicitly added to each workspace
49* **Organization admins** automatically receive Workspace Admin access to all workspaces.
50* **Organization billing members** automatically receive Workspace Billing access to all workspaces.
51* **Organization users and developers** must be explicitly added to each workspace.
5252* **Service accounts** are added to workspaces on the [Service accounts](https://platform.claude.com/settings/service-accounts) page (`platform.claude.com/settings/service-accounts`) in the Claude Console: select **Add to workspace** in the account's menu or on its own page. To see the accounts in one workspace, filter the list by workspace.
5353 
5454<Note>
from line 63
6363 
6464### Using the Console
6565 
66Create and manage workspaces in the [Claude Console](https://platform.claude.com/settings/workspaces).
66Create and manage workspaces on the [Workspaces](https://platform.claude.com/settings/workspaces) page in the Claude Console.
6767 
6868#### Create a workspace
6969 
from line 134
134134* Cannot be undone
135135 
136136<Warning>
137 Archiving a workspace archives every API key created for that workspace within seconds (they remain listed in the Admin API as archived), and multi-workspace keys can no longer act in it. This action cannot be undone. If you archive the [Claude Code workspace](https://platform.claude.com/docs/en/manage-claude/workspaces#claude-code-workspace), members of your organization can no longer sign in to Claude Code through Console billing.
137 Archiving a workspace archives every API key created for that workspace within seconds (they remain listed in the Admin API as archived), and keys that aren't scoped to a workspace can no longer act in it. This action cannot be undone. If you archive the [Claude Code workspace](https://platform.claude.com/docs/en/manage-claude/workspaces#claude-code-workspace), members of your organization can no longer sign in to Claude Code through Console billing.
138138</Warning>
139139 
140140### Using the Admin API
from line 145
145145 Admin API endpoints accept an [Admin API key](https://platform.claude.com/docs/en/manage-claude/admin-api-keys), an `org:admin` OAuth token, or a personal or service account key that isn't scoped to a specific workspace. Workspace keys don't work there. See [Authentication](https://platform.claude.com/docs/en/manage-claude/admin-api#authentication).
146146</Note>
147147 
148The following SDK and CLI examples construct the default client, which reads the Admin API key from the `ANTHROPIC_API_KEY` environment variable; the SDKs expose these endpoints under `client.organization.workspaces` (csharp, go: `client.Organization.Workspaces`; java: `client.organization().workspaces()`; php: `$client->organization->workspaces`). SDK list methods fetch further pages on demand, so `limit` sets the page size; the PHP, Ruby, and curl examples return one page.
148The following SDK and CLI examples construct the default client, which reads the Admin API key from the `ANTHROPIC_API_KEY` environment variable; the SDK exposes these endpoints under `client.organization.workspaces` (csharp, go: `client.Organization.Workspaces`; java: `client.organization().workspaces()`; php: `$client->organization->workspaces`). SDK list methods fetch further pages on demand, so `limit` sets the page size; the PHP, Ruby, and curl examples return one page.
149149 
150150Create a workspace:
151151 
from line 825
825825Every request runs in exactly one workspace and can only access resources within that workspace. Which workspace depends on the [key type](https://platform.claude.com/docs/en/manage-claude/authentication#key-types):
826826 
827827* A **workspace key** (a legacy key without an owner) belongs to the workspace it was created in and always runs there.
828* A **personal key** or **service account key** acts as its user or service account. A single-workspace key always runs in the workspace chosen when it was created. A multi-workspace key runs in the workspace named by each request's `anthropic-workspace-id` header. Accounts must have access to the workspace to use it.
828* A **personal key** or **service account key** acts as its user or service account. A single-workspace key always runs in the workspace chosen when it was created. A key that isn't scoped to a workspace runs in the workspace named by each request's `anthropic-workspace-id` header. Accounts must have access to the workspace to use it.
829829 
830830Resources scoped to workspaces include:
831831 
from line 838
838838* **[MCP tunnels](https://platform.claude.com/docs/en/agents-and-tools/mcp-tunnels/overview)** are managed with a `workspace:manage_tunnels` OAuth token obtained through [Workload Identity Federation](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation), not an API key. Tunnels are created in a workspace, and the Console **MCP tunnels** list and the Managed Agent server picker show tunnels in the current workspace only; the cap of 10 active tunnels applies organization-wide. Tunnel management requires a role with tunnel management permissions; organization developers can view but not change them.
839839* **Workspaces** themselves and **organization members** are managed at the organization level through the [Admin API](https://platform.claude.com/docs/en/manage-claude/admin-api), using an Admin API key, an `org:admin` OAuth token, or a personal or service account key that isn't scoped to a specific workspace.
840840 
841To look up your organization's workspace IDs, call the [List Workspaces](https://platform.claude.com/docs/en/api/organization/workspaces/list) endpoint (pass `include_default=true` to include the Default Workspace) or find them in the [Claude Console](https://platform.claude.com/settings/workspaces).
841To look up your organization's workspace IDs, call the [List Workspaces](https://platform.claude.com/docs/en/api/organization/workspaces/list) endpoint (pass `include_default=true` to include the Default Workspace) or find them on the [Workspaces](https://platform.claude.com/settings/workspaces) page in the Claude Console.
842842 
843843<Note>
844844 [Prompt caches](https://platform.claude.com/docs/en/build-with-claude/prompt-caching) are also isolated per workspace on the Claude API, [Claude Platform on AWS](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws), and [Microsoft Foundry](https://platform.claude.com/docs/en/build-with-claude/claude-in-microsoft-foundry). On Amazon Bedrock and Google Cloud, prompt caches are isolated per organization.
from line 1025
10251025* **Rate limits:** Limit requests per minute, input tokens per minute, or output tokens per minute. To set these, go to the [Rate limits](https://platform.claude.com/usage/limits) page in the Claude Console, select the workspace from the **Workspace** dropdown menu, and click **Edit** next to a model.
10261026 
10271027<Note>
1028 - You cannot set spend limits on the Default Workspace
1029 - If not set, workspace limits match the organization's limits
1030 - Organization-wide limits always apply, even if workspace limits add up to more
1028 - You cannot set spend limits on the Default Workspace.
1029 - If not set, workspace limits match the organization's limits.
1030 - Organization-wide limits always apply, even if workspace limits add up to more.
10311031</Note>
10321032 
10331033For detailed information on rate limits and how they work, see [Rate limits](https://platform.claude.com/docs/en/api/rate-limits). You can also read your current organization and workspace rate limits programmatically with the [Rate Limits API](https://platform.claude.com/docs/en/manage-claude/rate-limits-api).

managed-agents/budgets Changed · +5 / -5 lines

from line 10
1010 betaHeader: managed-agents-2026-04-01
1111---
1212 
13A session budget is an optional hard spend ceiling you set when you [create a session](https://platform.claude.com/docs/en/managed-agents/sessions). The platform continuously prices everything the session consumes at public list rates (the session's **list cost**) and stops issuing new model requests once that cost reaches the budget. The request in flight when the cap is crossed still finishes, so the final list cost can land [a fraction past the budget](https://platform.claude.com/docs/en/managed-agents/budgets#when-a-session-reaches-its-budget). A session at its budget pauses and goes [idle](https://platform.claude.com/docs/en/managed-agents/session-operations#session-statuses) rather than terminating; changing or removing the budget resumes the work that the budget paused. Deployments accept the same budget and apply it to each session they start; see [Budgets on deployments](https://platform.claude.com/docs/en/managed-agents/budgets#budgets-on-deployments).
13A session budget is an optional hard spend ceiling you set when you [create a session](https://platform.claude.com/docs/en/managed-agents/sessions). The platform continuously prices everything the session consumes at public list rates (the session's **list cost**) and stops issuing new model requests once that cost reaches the budget. The request in flight when the cap is crossed still completes, so the final list cost can land [a fraction past the budget](https://platform.claude.com/docs/en/managed-agents/budgets#when-a-session-reaches-its-budget). A session at its budget pauses and goes [idle](https://platform.claude.com/docs/en/managed-agents/session-operations#session-statuses) rather than terminating; changing or removing the budget resumes the work that the budget paused. Deployments accept the same budget and apply it to each session they start; see [Budgets on deployments](https://platform.claude.com/docs/en/managed-agents/budgets#budgets-on-deployments).
1414 
1515## Set a budget at session creation
1616 
from line 140
140140The `budget` (csharp, go: `Budget`) object has two fields:
141141 
142142* `type` (csharp, go: `Type`) is always `"limit"`.
143* `max_list_cost` (java, php: `maxListCost`; csharp, go: `MaxListCost`) is the cap itself: `amount` (csharp, go: `Amount`) is a whole number of US cents written as a string with no leading zeros (`"125"` is $1.25 and `"50"` is 50 cents) and must be greater than zero. Decimal forms such as `"25.00"` are rejected. The amount is a string rather than a number so no float rounding is ever applied to it. `currency` (csharp, go: `Currency`) is an uppercase ISO-4217 currency code; `USD` is the only supported currency.
143* `max_list_cost` (java, php: `maxListCost`; csharp, go: `MaxListCost`) is the cap itself: `amount` (csharp, go: `Amount`) is a whole number of US cents written as a string with no leading zeros (`"125"` is $1.25 USD and `"50"` is 50 cents) and must be greater than zero. Decimal forms such as `"25.00"` are rejected. The amount is a string rather than a number so no float rounding is ever applied to it. `currency` (csharp, go: `Currency`) is an uppercase ISO-4217 currency code; `USD` is the only supported currency.
144144 
145145A budget can only be attached when the session is created. Adding a budget to an existing session that doesn't have one is rejected with a 400 error. A budgeted session's cap can be [changed](https://platform.claude.com/docs/en/managed-agents/budgets#change-the-budget) or [removed](https://platform.claude.com/docs/en/managed-agents/budgets#remove-the-budget) at any time.
146146 
from line 183
183183 
184184A `user.interrupt` sent while the session is paused at its budget (all threads paused at the cap) is accepted, and it does not appear in the event list. It stops no thread, because every thread is already paused. Change or remove the budget to continue.
185185 
186If the session has open [workflow runs](https://platform.claude.com/docs/en/managed-agents/workflow-runs#interrupt-a-session-with-runs-open), the interrupt can pause them, as an interrupt at any other time can. A run that an interrupt paused doesn't resume when you change or remove the budget. To continue it, change or remove the budget, then send a `user.message` asking the agent to continue its runs.
186If the session has open workflow runs, the interrupt can pause them, as an interrupt at any other time can. A run that an interrupt paused doesn't resume when you change or remove the budget. To continue it, change or remove the budget, then send a `user.message` asking the agent to continue its runs. See [Interrupt a session with runs open](https://platform.claude.com/docs/en/managed-agents/workflow-runs#interrupt-a-session-with-runs-open).
187187 
188188## Resume a session at its budget
189189 
from line 374
374374 
375375## Monitor spend
376376 
377The session object carries its `budget` (csharp, go: `Budget`) and a `usage` (csharp, go: `Usage`) object with the tracked spend: `usage.list_cost` (java, php: `usage.listCost`; csharp, go: `Usage.ListCost`) is the session's consumed list cost, and `usage.active_seconds` (java, php: `usage.activeSeconds`; csharp, go: `Usage.ActiveSeconds`) is the running time its runtime cost is priced on. On a session paused at `budget_reached`, expect `usage.list_cost` (java, php: `usage.listCost`; csharp, go: `Usage.ListCost`) to read at or a fraction past `max_list_cost` (java, php: `maxListCost`; csharp, go: `MaxListCost`): the [request that crossed the cap](https://platform.claude.com/docs/en/managed-agents/budgets#when-a-session-reaches-its-budget) finished before the pause. Session-level `active_seconds` (java, php: `activeSeconds`; csharp, go: `ActiveSeconds`) counts overlapping activity from concurrent threads once. Thread retrieval responses carry the same two fields on the thread's own `usage` (csharp, go: `Usage`), priced per thread. Per-thread figures are rounded independently and exclude the session's running-time cost, so they don't sum exactly to the session's `list_cost` (java, php: `listCost`; csharp, go: `ListCost`); the session figure is the one the budget is enforced against.
377The session object carries its `budget` (csharp, go: `Budget`) and a `usage` (csharp, go: `Usage`) object with the tracked spend: `usage.list_cost` (java, php: `usage.listCost`; csharp, go: `Usage.ListCost`) is the session's consumed list cost, and `usage.active_seconds` (java, php: `usage.activeSeconds`; csharp, go: `Usage.ActiveSeconds`) is the running time its runtime cost is priced on. On a session paused at `budget_reached`, expect `usage.list_cost` (java, php: `usage.listCost`; csharp, go: `Usage.ListCost`) to read at or a fraction past `max_list_cost` (java, php: `maxListCost`; csharp, go: `MaxListCost`): the [request that crossed the cap](https://platform.claude.com/docs/en/managed-agents/budgets#when-a-session-reaches-its-budget) completed before the pause. Session-level `active_seconds` (java, php: `activeSeconds`; csharp, go: `ActiveSeconds`) counts overlapping activity from concurrent threads once. Thread retrieval responses carry the same two fields on the thread's own `usage` (csharp, go: `Usage`), priced for each thread. Per-thread figures are rounded independently and exclude the session's running-time cost, so they don't sum exactly to the session's `list_cost` (java, php: `listCost`; csharp, go: `ListCost`); the session figure is the one the budget is enforced against.
378378 
379379The `session.usage` event is a snapshot of the session's cumulative usage and tracked list cost. It carries the session's token totals, `list_cost` (java, php: `listCost`; csharp, go: `ListCost`), `active_seconds` (java, php: `activeSeconds`; csharp, go: `ActiveSeconds`), `server_tool_use` (java, php: `serverToolUse`; csharp, go: `ServerToolUse`) request counts (`web_search_requests` (java, php: `webSearchRequests`; csharp, go: `WebSearchRequests`), priced into list cost per request, and `web_fetch_requests` (java, php: `webFetchRequests`; csharp, go: `WebFetchRequests`), which reads `0` because web fetch requests carry no per-request charge and aren't metered), and the session's `budget` (csharp, go: `Budget`) if the session has one. It appears in the events list and the session stream. The session emits one immediately before it goes idle, whatever the stop reason, so a session that reaches its budget always emits one immediately before the budget-reached idle event.
380380 
from line 382
382382 
383383## Budgets in multiagent sessions
384384 
385A [multiagent](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration) session has a single budget shared across all of its threads; there are no per-thread caps. Each thread's consumption is priced at its own served model, and threads pause independently as the shared cap is reached. [Advisor](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#give-the-session-an-advisor) consultations count against the same budget, priced at the advisor model's rates. One thread can pause at `budget_reached` while another finishes its in-flight request.
385A [multiagent](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration) session has a single budget shared across all of its threads; there are no per-thread caps. Each thread's consumption is priced at its own served model, and threads pause independently as the shared cap is reached. [Advisor](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#give-the-session-an-advisor) consultations count against the same budget, priced at the advisor model's rates. One thread can pause at `budget_reached` while another completes its in-flight request.
386386 
387387A pending ask outranks the cap: a session with one thread waiting on `requires_action` and another paused at `budget_reached` reports `requires_action` at the session level. The pending request still needs an answer, and answering it is a [settle event](https://platform.claude.com/docs/en/managed-agents/budgets#events-accepted-at-the-cap) the budget doesn't block.
388388 

managed-agents/define-outcomes Changed · +9 / -9 lines

from line 23
2323<Accordion title="Tips for writing effective rubrics">
2424 Structure the rubric as explicit, gradeable criteria, such as "The CSV contains a price column with numeric values" rather than "The data looks good." The grader scores each criterion independently, so vague criteria produce noisy evaluations.
2525 
26 If you don't have a rubric on hand, try giving Claude an example of a known-good artifact and asking it to analyze what makes that content good, then turn that analysis into a rubric. This middle-ground approach often produces better results than writing criteria from scratch.
26 If you don't have a rubric, try giving Claude an example of a known-good artifact and asking it to analyze what makes that content good, then turn that analysis into a rubric. This middle-ground approach often produces better results than writing criteria with no example to start from.
2727</Accordion>
2828 
2929Example rubric:
from line 285
285285 
286286## Create a session with an outcome
287287 
288The following examples create a [session](https://platform.claude.com/docs/en/managed-agents/sessions) for an existing [agent](https://platform.claude.com/docs/en/managed-agents/agent-setup) and [environment](https://platform.claude.com/docs/en/managed-agents/environments) (both created separately), then send a `user.define_outcome` event. The agent begins work immediately. No additional user message event is required.
288The following examples create a [session](https://platform.claude.com/docs/en/managed-agents/sessions) for an existing [agent](https://platform.claude.com/docs/en/managed-agents/agent-setup) and [environment](https://platform.claude.com/docs/en/managed-agents/environments) (both created separately), then send a `user.define_outcome` event. The agent starts work immediately. No additional user message event is required.
289289 
290290<CodeGroup>
291291 ```bash cURL
from line 347
347347 title="Financial analysis on Costco",
348348 )
349349 
350 # Define the outcome — agent starts working on receipt
350 # Define the outcome. The agent starts working on receipt.
351351 client.beta.sessions.events.send(
352352 session_id=session.id,
353353 events=[
from line 370
370370 title: "Financial analysis on Costco"
371371 });
372372 
373 // Define the outcome — agent starts working on receipt
373 // Define the outcome. The agent starts working on receipt.
374374 await client.beta.sessions.events.send(session.id, {
375375 events: [
376376 {
from line 500
500500 title: "Financial analysis on Costco"
501501 )
502502 
503 # Define the outcome — agent starts working on receipt
503 # Define the outcome. The agent starts working on receipt.
504504 client.beta.sessions.events.send_(
505505 session.id,
506506 events: [
from line 527
527527* `agent.*` events (such as messages and tool use) show progress toward the outcome.
528528* `span.outcome_evaluation_*` events are only emitted for outcome-oriented sessions and show the number of iteration loops and the grader's feedback process.
529529* You can also send `user.message` [events](https://platform.claude.com/docs/en/managed-agents/reference#event-types) to an outcome-oriented session to direct the agent's work as it progresses, but it isn't required: the agent works toward the outcome on its own, iterating until it succeeds or runs out of iterations.
530* A `user.interrupt` event pauses work on the current outcome and marks the `result` (csharp, go: `Result`) of the `span.outcome_evaluation_end` event as `interrupted`, allowing you to kick off a new outcome.
530* A `user.interrupt` event pauses work on the current outcome and marks the `result` (csharp, go: `Result`) of the `span.outcome_evaluation_end` event as `interrupted`, allowing you to start a new outcome.
531531* After the final outcome evaluation, the session can be continued as a conversational session, or a new outcome can be started. The session retains history of the prior outcome.
532532 
533533### Define outcome user event
534534 
535535<Note>
536 Only one outcome is supported at a time, but you may chain outcomes in sequence. To do this, send a new `user.define_outcome` event after the terminal `span.outcome_evaluation_end` event of the previous outcome.
536 Only one outcome is supported at a time, but you can chain outcomes in sequence. To do this, send a new `user.define_outcome` event after the terminal `span.outcome_evaluation_end` event of the previous outcome.
537537</Note>
538538 
539539This is the event you send to initiate an outcome. It is echoed back on receipt, including a `processed_at` (java, php: `processedAt`; csharp, go: `ProcessedAt`) timestamp and `outcome_id` (java: `outcomeId`; php: `outcomeID`; csharp, go: `OutcomeID`).
from line 577
577577 
578578### Outcome evaluation end
579579 
580Emitted when an outcome evaluation cycle ends: after the grader finishes evaluating one iteration, or when the session is interrupted while an outcome is active. The `result` field indicates what happens next.
580Emitted when an outcome evaluation cycle ends: after the grader finishes evaluating one iteration, or when the session is interrupted while an outcome is active. The `result` field indicates what occurs next.
581581 
582582| Result | Next |
583583| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
from line 863
863863 </Card>
864864 
865865 <Card title="Session event stream" icon="lightning" href="https://platform.claude.com/docs/en/managed-agents/events-and-streaming">
866 Send events, stream responses, and interrupt or redirect your session mid-execution.
866 Send events, stream responses, and interrupt or redirect your session while it runs.
867867 </Card>
868868 
869869 <Card title="Adding files" icon="file" href="https://platform.claude.com/docs/en/managed-agents/files">

managed-agents/dreams Changed · +7 / -7 lines

from line 1
11---
22title: Dreams
33url: https://platform.claude.com/docs/en/managed-agents/dreams
4description: Let Claude reflect on past sessions to curate an agent's memory and surface new insights.
4description: Let Claude review past sessions to curate an agent's memory and surface new insights.
55---
66 
77<Tip>
from line 36
3636 -H "anthropic-version: 2023-06-01" \
3737 -H "anthropic-beta: managed-agents-2026-04-01,dreaming-2026-04-21" \
3838 -H "content-type: application/json" \
39 --data '{
39 -d '{
4040 "inputs": [
4141 { "type": "memory_store", "memory_store_id": "'"$store_id"'" },
4242 { "type": "sessions", "session_ids": ["'"$session_a"'", "'"$session_b"'"] }
from line 188
188188 
189189The optional `instructions` (csharp, go: `Instructions`) field steers what the dreaming pipeline synthesizes. It is applied throughout the pipeline: what to read closely, what to merge or drop, and how to structure the output store.
190190 
191Use `instructions` (csharp, go: `Instructions`) for high-level synthesis guidance such as focus areas ("focus on coding-style preferences"), content to preserve unchanged, or output conventions you want applied across the store. The pipeline is a synthesis pass over the inputs, not an editor applied to the text of the store, so imperative directives that target specific lines ("change sentence X to Y", "fix the count in section Z") generally produce no change. To make targeted edits to individual memories, use the [Memory Stores API](https://platform.claude.com/docs/en/managed-agents/memory#view-and-edit-memories) on the output store directly.
191Use `instructions` (csharp, go: `Instructions`) for high-level synthesis guidance such as focus areas ("focus on coding-style preferences"), content to preserve unchanged, or output conventions you want applied across the store. The pipeline is a synthesis pass over the inputs, not an editor applied to the text of the store, so imperative directives that target specific lines ("change sentence X to Y," "fix the count in section Z") generally produce no change. To make targeted edits to individual memories, use the [Memory Stores API](https://platform.claude.com/docs/en/managed-agents/memory#view-and-edit-memories) on the output store directly.
192192 
193193## Track progress
194194 
from line 283
283283 
284284## Use the output
285285 
286When `status` (csharp, go: `Status`) reaches `completed`, the `memory_store` entry in `outputs` (csharp, go: `Outputs`) references a fully populated store. It's an ordinary memory store in your workspace. Review it with the [Memory Stores API](https://platform.claude.com/docs/en/managed-agents/memory#view-and-edit-memories) or in the Console, then either:
286When `status` (csharp, go: `Status`) reaches `completed`, the `memory_store` entry in `outputs` (csharp, go: `Outputs`) references a fully populated store. It's an ordinary memory store in your workspace. Review it with the [Memory Stores API](https://platform.claude.com/docs/en/managed-agents/memory#view-and-edit-memories) or in the Claude Console, then either:
287287 
288* **Leverage it:** attach it to future sessions as a `memory_store` resource in place of (or alongside) the input memory store, or
288* **Use it:** attach it to future sessions as a `memory_store` resource in place of (or alongside) the input memory store, or
289289* **Discard it:** [delete the memory store](https://platform.claude.com/docs/en/api/beta/memory_stores/delete) or [archive the memory store](https://platform.claude.com/docs/en/api/beta/memory_stores/archive).
290290 
291291<CodeGroup>
from line 296
296296 -H "anthropic-version: 2023-06-01" \
297297 -H "anthropic-beta: managed-agents-2026-04-01" \
298298 -H "content-type: application/json" \
299 --data '{
299 -d '{
300300 "agent": "'"$agent_id"'",
301301 "environment_id": "'"$environment_id"'",
302302 "resources": [

managed-agents/environments Changed · +5 / -5 lines

from line 23
2323 -H "anthropic-version: 2023-06-01" \
2424 -H "anthropic-beta: managed-agents-2026-04-01" \
2525 -H "content-type: application/json" \
26 --data '{
26 -d '{
2727 "name": "python-dev",
2828 "config": {
2929 "type": "cloud",
from line 49
4949 ```
5050 </File>
5151 
52 [`ant apply`](https://platform.claude.com/docs/en/cli-sdks-libraries/cli/apply) creates the environment from `environment.yaml`, prints its ID, and records it in `claude-lock.json`. Commit `claude-lock.json` so the next `ant apply` updates this environment instead of trying to create it again.
52 [`ant apply`](https://platform.claude.com/docs/en/cli-sdks-libraries/cli/apply) creates the environment from `environment.yaml`, prints its ID, and records it in `claude-lock.json`. Commit `claude-lock.json` so the next `ant apply` updates this environment instead of attempting to create it again.
5353 </CodeGroupItem>
5454 
5555 ```python Python
from line 161
161161 -H "anthropic-version: 2023-06-01" \
162162 -H "anthropic-beta: managed-agents-2026-04-01" \
163163 -H "content-type: application/json" \
164 --data '{
164 -d '{
165165 "agent": "'"$AGENT_ID"'",
166166 "environment_id": "'"$ENVIRONMENT_ID"'"
167167 }'
from line 240
240240 -H "anthropic-version: 2023-06-01" \
241241 -H "anthropic-beta: managed-agents-2026-04-01" \
242242 -H "content-type: application/json" \
243 --data '{
243 -d '{
244244 "name": "data-analysis",
245245 "config": {
246246 "type": "cloud",
from line 623
623623* **The agent can change things on external sites, not only read them:** The `bash` tool can send any request. The agent can post data, submit forms, call APIs, and run scripts that change data on external sites. Even a request that only fetches a URL can change data on some sites.
624624* **Nothing pauses these requests by default:** The agent toolset's default [permission policy](https://platform.claude.com/docs/en/managed-agents/permission-policies) is `always_allow`, so `bash` commands run without approval.
625625* **Anything in the sandbox can leave it:** This includes files, tool outputs, and any credentials or secrets you put in the sandbox.
626* **Fetched content can steer the agent:** Web pages, API responses, and other content the agent reads can contain instructions (prompt injection) that change what it does next.
626* **Fetched content can steer the agent:** Webpages, API responses, and other content the agent reads can contain instructions (prompt injection) that change what it does next.
627627* **The agent acts on your behalf:** Its actions can violate a site's terms of service, or create accounts and records there.
628628* **Model behavior is not a security control:** The agent can act on external sites in ways you did not ask for, including retrying in a different way after a site blocks a request. Use network settings and permission policies to limit what it can do.
629629* **The safety blocklist is not an allowlist:** It does not limit which other sites the agent reaches, or what the agent does on them.

managed-agents/event-deltas Changed · +10 / -10 lines

from line 10
1010 betaHeader: managed-agents-2026-04-01
1111---
1212 
13By default, the agent's response text reaches the [session event stream](https://platform.claude.com/docs/en/managed-agents/events-and-streaming) as buffered `agent.message` events. Each one is emitted only after the model request that produced it finishes. Event deltas let you render that text incrementally, as a live preview, while the model is still generating it.
13By default, the agent's response text reaches the [session event stream](https://platform.claude.com/docs/en/managed-agents/events-and-streaming) as buffered `agent.message` events. Each one is emitted only after the model request that produced it completes. Event deltas let you render that text incrementally, as a live preview, while the model is still generating it.
1414 
1515Previews are a best-effort display aid, and the buffered `agent.message` is always the authoritative record. A client that ignores previews still receives a complete, correct stream.
1616 
1717## Opt in to previews
1818 
19Previews are opt-in per stream connection. Add the `event_deltas[]` query parameter to the stream you're reading, and repeat it once for each event type you want previewed. The accepted values are `agent.message` and `agent.thinking`. Any other value returns a 400 error, as does a request with more than 100 values.
19Previews are opt-in for each stream connection. Add the `event_deltas[]` query parameter to the stream you're reading, and repeat it once for each event type you want previewed. The accepted values are `agent.message` and `agent.thinking`. Any other value returns a 400 error, as does a request with more than 100 values.
2020 
2121Both stream endpoints accept the parameter:
2222 
from line 29
2929 
3030### Preview events
3131 
32When a previewed event begins, the stream emits an `event_start` carrying the upcoming event's type and `id`:
32When a previewed event starts, the stream emits an `event_start` carrying the upcoming event's type and `id`:
3333 
3434```json
3535{
from line 70
7070 
7171Every SDK that supports event deltas includes an [accumulator helper](https://platform.claude.com/docs/en/managed-agents/event-deltas#sdk-accumulator-helpers) that handles the `index` bookkeeping for you. The manual pattern in this section works in every language when you need custom bookkeeping. Apply it to the generated event types.
7272 
73In the manual pattern, hold preview text in a temporary map keyed by `(event_id, index)`, and treat the buffered event as the record. Reconcile the two per model request.
73In the manual pattern, hold preview text in a temporary map keyed by `(event_id, index)`, and treat the buffered event as the record. Reconcile the two for each model request.
7474 
7575A turn opens with a single `session.status_running` event. On a turn that completes normally, each model request then produces these events, in order:
7676 
from line 78
78782. `event_start`
79793. The `event_delta` events
80804. The buffered `agent.message`
815. [`span.model_request_end`](https://platform.claude.com/docs/en/managed-agents/reference#event-types) (in the Span events tab)
815. [`span.model_request_end`](https://platform.claude.com/docs/en/managed-agents/reference#event-types) (in the **Span events** tab)
8282 
8383On the wire, this is the previewed portion of that sequence, interleaved with the connection's other buffered events:
8484 
from line 89
8989agent.message {"id": "sevt_01abc...", "content": [...]}
9090```
9191 
92The `event_delta` line repeats once per text fragment. Process each event as it arrives:
92The `event_delta` line repeats once for each text fragment. Process each event as it arrives:
9393 
94941. On `event_start`, note the announced `id`. The identifiers always line up: `event_start.event.id`, every `event_delta.event_id`, and the buffered `agent.message`'s `id` are the same value.
95952. On each `event_delta`, append `delta.content.text` to the entry at `(event_id, delta.index)` and render the running text. The first delta for an `index` creates that entry.
from line 99
9999The pattern relies on two guarantees:
100100 
101101* Concatenating a preview's deltas in arrival order, keyed by `(event_id, index)`, gives a prefix of `content[index].text` in the buffered event. It is not necessarily the whole text, because deltas might be [shed under load](https://platform.claude.com/docs/en/managed-agents/event-deltas#limitations).
102* A connection emits at most one `event_start` per `event_id`, and the buffered event is the last thing that connection delivers for that `id`.
102* A connection emits at most one `event_start` for each `event_id`, and the buffered event is the last thing that connection delivers for that `id`.
103103 
104104### SDK accumulator helpers
105105 
from line 564
564564 
565565A thread stream's path ends in `/threads/{thread_id}/stream`. `/events/stream` exists only at the session level, so there is no `/threads/{thread_id}/events/stream` endpoint.
566566 
567`event_start` and `event_delta` have the same shape on a thread stream as on the session-level stream, and the [accumulate and reconcile](https://platform.claude.com/docs/en/managed-agents/event-deltas#accumulate-and-reconcile) pattern applies as written. Run one accumulator instance per stream connection.
567`event_start` and `event_delta` have the same shape on a thread stream as on the session-level stream, and the [accumulate and reconcile](https://platform.claude.com/docs/en/managed-agents/event-deltas#accumulate-and-reconcile) pattern applies as written. Run one accumulator instance for each stream connection.
568568 
569569<CodeGroup>
570570 ```bash cURL
from line 855
855855 ```
856856</CodeGroup>
857857 
858The read loop exits on [`session.thread_status_idle`](https://platform.claude.com/docs/en/managed-agents/reference#event-types), the event emitted when the session thread's turn finishes and the thread goes idle.
858The read loop exits on [`session.thread_status_idle`](https://platform.claude.com/docs/en/managed-agents/reference#event-types), the event emitted when the session thread's turn completes and the thread goes idle.
859859 
860860## Limitations
861861 
from line 877
877877 
878878<CardGroup cols={2}>
879879 <Card title="Session event stream" icon="lightning" href="https://platform.claude.com/docs/en/managed-agents/events-and-streaming">
880 Send events, stream responses, and interrupt or redirect your session mid-execution.
880 Send events, stream responses, and interrupt or redirect your session while it runs.
881881 </Card>
882882 
883883 <Card title="Multiagent orchestration" icon="stack" href="https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration">

managed-agents/events-and-streaming Changed · +8 / -8 lines

from line 1
11---
22title: Session event stream
33url: https://platform.claude.com/docs/en/managed-agents/events-and-streaming
4description: Send events, stream responses, and interrupt or redirect your session mid-execution.
4description: Send events, stream responses, and interrupt or redirect your session while it runs.
55featureMetadata:
66 topic:
77 title: Managed Agents
from line 276
276276 
277277The session reports errors through the `session.error` event. See [Event types](https://platform.claude.com/docs/en/managed-agents/reference#event-types) for its fields.
278278 
279The agent's response text arrives as buffered `agent.message` events, each emitted only after the model request that produced it finishes. To render the text while the model is still generating it, see [Preview responses with event deltas](https://platform.claude.com/docs/en/managed-agents/event-deltas).
279The agent's response text arrives as buffered `agent.message` events, each emitted only after the model request that produced it completes. To render the text while the model is still generating it, see [Preview responses with event deltas](https://platform.claude.com/docs/en/managed-agents/event-deltas).
280280 
281281### Reconnect without missing events
282282 
from line 484
484484 seen_event_ids = Set.new
485485 client.beta.sessions.events.list(session.id).auto_paging_each { seen_event_ids << it.id }
486486 
487 # Tail live events, skipping anything already seen — Set#add? returns nil for duplicates
487 # Tail live events, skipping anything already seen (Set#add? returns nil for duplicates)
488488 stream.each do |event|
489489 next unless seen_event_ids.add?(event.id)
490490 case event
from line 663
663663 
664664## Answer tool calls that pause the session
665665 
666A session pauses when the agent invokes a [custom tool](https://platform.claude.com/docs/en/managed-agents/tools#custom-tools), and when a tool call needs your confirmation under a [permission policy](https://platform.claude.com/docs/en/managed-agents/permission-policies). Both pauses follow the same sequence:
666A session pauses when the agent calls a [custom tool](https://platform.claude.com/docs/en/managed-agents/tools#custom-tools), and when a tool call needs your confirmation under a [permission policy](https://platform.claude.com/docs/en/managed-agents/permission-policies). Both pauses follow the same sequence:
667667 
6686681. The session emits the tool call as an `agent.custom_tool_use`, `agent.tool_use`, or `agent.mcp_tool_use` event.
6696692. The session pauses with a `session.status_idle` event whose `stop_reason.type` is `requires_action`. The blocking event IDs are in the `stop_reason.event_ids` array.
from line 1272
12721272 
12731273## Interrupt the agent
12741274 
1275Send a `user.interrupt` event to stop the agent mid-execution, then follow up with a `user.message` event to redirect it:
1275Send a `user.interrupt` event to stop the agent while it runs, then follow up with a `user.message` event to redirect it:
12761276 
12771277<CodeGroup>
12781278 ```bash cURL
from line 1454
145414542. The `user.interrupt` event appears on the stream, and the interrupted turn ends with a `session.status_idle` event.
145514553. The agent starts its next turn with the `user.message` you sent after the interrupt.
14561456 
1457The idle event's `stop_reason.type` is `end_turn`, the same value as a turn that finishes on its own. If workflow runs are open, the interrupt ends none of them. A run that's running can keep the session `running`, so the `session.status_idle` event in step 2 might not arrive. See [Interrupt a session with runs open](https://platform.claude.com/docs/en/managed-agents/workflow-runs#interrupt-a-session-with-runs-open).
1457The idle event's `stop_reason.type` is `end_turn`, the same value as a turn that completes on its own. If workflow runs are open, the interrupt ends none of them. A run that's running can keep the session `running`, so the `session.status_idle` event in step 2 might not arrive. See [Interrupt a session with runs open](https://platform.claude.com/docs/en/managed-agents/workflow-runs#interrupt-a-session-with-runs-open).
14581458 
14591459## List past events
14601460 
from line 1627
16271627 
16281628On a [supported model](https://platform.claude.com/docs/en/managed-agents/events-and-streaming#supported-models), send a `system.message` event to give the agent privileged system-level context. The context applies to the accompanying turn and all subsequent turns. Use it when the agent needs updated system-level guidance mid-session, for example a different persona, revised constraints, or context fetched at runtime.
16291629 
1630The event's `content` (csharp, go: `Content`) accepts 1–1000 text items. The content is appended to the session's system context as a `role: "system"` turn. It doesn't replace the top-level system prompt, which the `system` (csharp, go: `System`; ruby: `system_`) field on the agent definition sets.
1630The event's `content` (csharp, go: `Content`) accepts 1–1,000 text items. The content is appended to the session's system context as a `role: "system"` turn. It doesn't replace the top-level system prompt, which the `system` (csharp, go: `System`; ruby: `system_`) field on the agent definition sets.
16311631 
16321632<CodeGroup>
16331633 ```bash cURL
from line 1800
18001800 </Card>
18011801 
18021802 <Card title="Subscribe to webhooks" icon="link" href="https://platform.claude.com/docs/en/managed-agents/webhooks">
1803 Get notified when major events happen without polling.
1803 Get notified when major events occur without polling.
18041804 </Card>
18051805 
18061806 <Card title="Event types" icon="book" href="https://platform.claude.com/docs/en/managed-agents/reference#event-types">

managed-agents/files Changed · +6 / -6 lines

from line 349
349349 ```
350350</CodeGroup>
351351 
352A maximum of 500 files is supported per session.
352A maximum of 500 files is supported for each session.
353353 
354354## Managing files on a running session
355355 
from line 715
715715 Files mounted in the sandbox are read-only copies. The agent can read them but cannot modify the original uploaded file. To work with modified versions, the agent writes to new paths within the sandbox.
716716</Note>
717717 
718* The path you specify is rooted under the session's uploads directory: a `mount_path` (java, php: `mountPath`; csharp, go: `MountPath`) of `/data.csv` places the file at `/mnt/session/uploads/data.csv` in the sandbox
719* If you omit `mount_path` (java, php: `mountPath`; csharp, go: `MountPath`), the file is placed at `/mnt/session/uploads/<file_id>`
720* Parent directories are created automatically
721* Paths should be absolute (starting with `/`)
722* Files the agent writes to `/mnt/session/outputs/` become available through the Files API, scoped to the session; see [Listing and downloading session files](https://platform.claude.com/docs/en/managed-agents/files#listing-and-downloading-session-files)
718* The path you specify is rooted under the session's uploads directory: a `mount_path` (java, php: `mountPath`; csharp, go: `MountPath`) of `/data.csv` places the file at `/mnt/session/uploads/data.csv` in the sandbox.
719* If you omit `mount_path` (java, php: `mountPath`; csharp, go: `MountPath`), the file is placed at `/mnt/session/uploads/<file_id>`.
720* Parent directories are created automatically.
721* Paths should be absolute (starting with `/`).
722* Files the agent writes to `/mnt/session/outputs/` become available through the Files API, scoped to the session; see [Listing and downloading session files](https://platform.claude.com/docs/en/managed-agents/files#listing-and-downloading-session-files).
723723 

managed-agents/mcp-connector Changed · +6 / -6 lines

from line 215
215215</CodeGroup>
216216 
217217<Tip>
218 The MCP toolset defaults to a permission policy of `always_ask`, which requires user approval before each tool call. See [permission policies](https://platform.claude.com/docs/en/managed-agents/permission-policies) to configure this behavior.
218 The MCP toolset defaults to a permission policy of `always_ask`, which requires user approval before each tool call. See [Permission policies](https://platform.claude.com/docs/en/managed-agents/permission-policies) to configure this behavior.
219219</Tip>
220220 
221221### `mcp_servers` field reference
from line 366
366366 
367367Session creation does not validate MCP connectivity or credentials. It does check each declared server's host against the environment's networking: with a `limited` environment, session creation fails with a 400 error when a host is not allowed, as described under [Provide authentication at session creation](https://platform.claude.com/docs/en/managed-agents/mcp-connector#provide-authentication-at-session-creation). If an MCP server is unreachable or rejects the supplied credential, the session still starts and interaction remains possible. A [`session.error`](https://platform.claude.com/docs/en/managed-agents/reference#event-types) event is emitted with the `mcp_server_name` (java, php: `mcpServerName`; csharp: `McpServerName`; go: `MCPServerName`) of the affected server and a `retry_status` (java, php: `retryStatus`; csharp, go: `RetryStatus`):
368368 
369| Error type | Meaning |
370| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
371| `mcp_connection_failed_error` | The MCP server could not be reached (network error, timeout, or non-authentication HTTP failure). |
372| `mcp_authentication_failed_error` | Authentication with the MCP server failed: the server rejected the credential from the attached vault, required authentication when no matching credential was configured, or an OAuth token refresh failed. |
369| Error type | Meaning |
370| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
371| `mcp_connection_failed_error` | The MCP server could not be reached (network error, timeout, or non-authentication HTTP failure). |
372| `mcp_authentication_failed_error` | Authentication with the MCP server failed: the server rejected the credential from the attached vault, the server required authentication when no matching credential was configured, or an OAuth token refresh failed. |
373373 
374374You can decide whether to block further interaction on this error, trigger a credential rotation, or let the session continue without the affected server's tools. The connection is retried on the next `session.status_idle` to `session.status_running` transition.
375375 
from line 381
381381 </Card>
382382 
383383 <Card title="Session event stream" icon="lightning" href="https://platform.claude.com/docs/en/managed-agents/events-and-streaming">
384 Send events, stream responses, and interrupt or redirect your session mid-execution.
384 Send events, stream responses, and interrupt or redirect your session while it runs.
385385 </Card>
386386 
387387 <Card title="Supported MCP server types" icon="book" href="https://platform.claude.com/docs/en/managed-agents/reference#supported-mcp-server-types">

managed-agents/memory Changed · +29 / -29 lines

from line 206
206206</CodeGroup>
207207 
208208<Tip>
209 Individual memories within the store are capped at 100 kB (\~25k tokens). A store holds a maximum of 10,000 memories. Structure memory as many small focused files, not a few large ones.
209 Individual memories within the store are capped at 100 kB (\~25k tokens). A store holds a maximum of 10,000 memories. Structure memory as many small focused files, not a few large ones.
210210</Tip>
211211 
212212## Attach a memory store to a session
from line 224
224224 -H "anthropic-version: 2023-06-01" \
225225 -H "anthropic-beta: managed-agents-2026-04-01" \
226226 -H "content-type: application/json" \
227 --data '{
227 -d '{
228228 "agent": "'"$agent_id"'",
229229 "environment_id": "'"$environment_id"'",
230230 "resources": [
from line 368
368368 Memory stores attach with `read_write` access by default. If the agent processes untrusted input (user-supplied prompts, fetched web content, or third-party tool output), a successful prompt injection could write malicious content into the store. Later sessions then read that content as trusted memory. Use `read_only` for reference material, shared lookups, and any store the agent does not need to modify.
369369</Warning>
370370 
371A maximum of **8 memory stores** are supported per session. Attach multiple stores when different parts of memory have different owners or access rules. Common reasons:
371A maximum of **8 memory stores** is supported for each session. Attach multiple stores when different parts of memory have different owners or access rules. Common reasons:
372372 
373373* **Shared reference material:** one read-only store attached to many sessions (standards, conventions, domain knowledge), kept separate from each session's own read-write store.
374* **Mapping to your product's structure:** one store per end user, per team, or per project, while sharing a single agent configuration.
374* **Mapping to your product's structure:** one store for each end user, team, or project, while sharing a single agent configuration.
375375* **Different lifecycles:** a store that outlives any single session, or one you want to archive on its own schedule.
376376 
377377### How the agent accesses memory
378378 
379Each attached store is mounted inside the session's sandbox as a directory under `/mnt/memory/`. The directory name is the store's display name sanitized to a filesystem-safe slug (lowercased; non-alphanumeric runs become a single hyphen), so a store named "Demo Memory" mounts at `/mnt/memory/demo-memory/`. The exact path is returned in the `mount_path` (java, php: `mountPath`; csharp, go: `MountPath`) field on the session's memory-store resource; read it from there rather than constructing it yourself. The agent reads and writes the store with the standard [agent toolset](https://platform.claude.com/docs/en/managed-agents/tools). Writes under the mount path are persisted back to the store and stay in sync across sessions that share it; writes to any other path under `/mnt/memory/` fail, because the sandbox mounts that parent directory read-only. A short description of each mount (display name, mount path, access mode, store `description` (csharp, go: `Description`), and any `instructions` (csharp, go: `Instructions`)) is automatically added to the system prompt.
379Each attached store is mounted inside the session's sandbox as a directory under `/mnt/memory/`. The directory name is the store's display name sanitized to a filesystem-safe slug (lowercased, with each non-alphanumeric run replaced by a single hyphen), so a store named "Demo Memory" mounts at `/mnt/memory/demo-memory/`. The exact path is returned in the `mount_path` (java, php: `mountPath`; csharp, go: `MountPath`) field on the session's memory-store resource; read it from there rather than constructing it yourself. The agent reads and writes the store with the standard [agent toolset](https://platform.claude.com/docs/en/managed-agents/tools). Writes under the mount path are persisted back to the store and stay in sync across sessions that share it; writes to any other path under `/mnt/memory/` fail, because the sandbox mounts that parent directory read-only. A short description of each mount (display name, mount path, access mode, store `description` (csharp, go: `Description`), and any `instructions` (csharp, go: `Instructions`)) is automatically added to the system prompt.
380380 
381`access` (csharp, go: `Access`) is enforced at the filesystem level: a `read_only` mount rejects writes, while writes to a `read_write` mount produce [memory versions](https://platform.claude.com/docs/en/managed-agents/memory#audit-memory-changes) attributed to the session.
381`access` (csharp, go: `Access`) is enforced at the filesystem level: a `read_only` mount rejects writes, whereas writes to a `read_write` mount produce [memory versions](https://platform.claude.com/docs/en/managed-agents/memory#audit-memory-changes) attributed to the session.
382382 
383383<Note>
384384 On [self-hosted sandboxes](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes-memory), each store's directory is a local copy that the worker manages rather than a live mount. The worker reconciles each copy with its store after tool calls, at most once per sync interval (15 seconds by default), and once more when the session ends. The agent's `write` and `edit` tools change only the local copy; the worker uploads those changes at its next sync, so another session running on a self-hosted sandbox sees a change only after both workers have synced. Paths under `/mnt/memory/` outside the store directories are not scratch space there: the worker's file tools refuse to write to them, and anything a shell command writes there is never synced to a store.
from line 397
397397List the memories in a store. Results are returned in a stable, server-defined order.
398398 
399399* `path_prefix` scopes the list to one directory. It must end with `/` and matches whole path segments, so `path_prefix=/notes/` returns `/notes/todo.md` but not `/notes-archive/todo.md`.
400* `depth` controls how deep the listing goes below `path_prefix`: omit it (or pass `0`) to list the whole subtree, or pass `1` to list only the immediate children. Other values return a `400` error.
400* `depth` controls how deep the list goes below `path_prefix`: omit it (or pass `0`) to list the whole subtree, or pass `1` to list only the immediate children. Other values return a `400` error.
401401 
402402<CodeGroup>
403403 ```bash cURL
from line 489
489489 ```
490490</CodeGroup>
491491 
492See the [List memories reference](https://platform.claude.com/docs/en/api/beta/memory_stores/memories/list) for full parameters and response schema.
492See the [List memories](https://platform.claude.com/docs/en/api/beta/memory_stores/memories/list) reference for full parameters and response schema.
493493 
494494### Read a memory
495495 
from line 564
564564 ```
565565</CodeGroup>
566566 
567See the [Retrieve a memory reference](https://platform.claude.com/docs/en/api/beta/memory_stores/memories/retrieve) for full parameters and response schema.
567See the [Retrieve a memory](https://platform.claude.com/docs/en/api/beta/memory_stores/memories/retrieve) reference for full parameters and response schema.
568568 
569569### Create a memory
570570 
571`POST /v1/memory_stores/{memory_store_id}/memories` (python, ruby: `client.beta.memory_stores.memories.create()`; typescript: `client.beta.memoryStores.memories.create()`; go: `client.Beta.MemoryStores.Memories.New()`; java: `client.beta().memoryStores().memories().create()`; csharp: `client.Beta.MemoryStores.Memories.Create()`; php: `$client->beta->memoryStores->memories->create()`; cli: `ant beta:memory-stores:memories create`) creates a memory at a given `path` (csharp, go: `Path`). Create does not overwrite; to change an existing memory, [update it](https://platform.claude.com/docs/en/managed-agents/memory#update-a-memory) with `POST /v1/memory_stores/{memory_store_id}/memories/{memory_id}` (python, ruby: `client.beta.memory_stores.memories.update()`; typescript: `client.beta.memoryStores.memories.update()`; go, csharp: `client.Beta.MemoryStores.Memories.Update()`; java: `client.beta().memoryStores().memories().update()`; php: `$client->beta->memoryStores->memories->update()`; cli: `ant beta:memory-stores:memories update`).
571`POST /v1/memory_stores/{memory_store_id}/memories` (python, ruby: `client.beta.memory_stores.memories.create()`; typescript: `client.beta.memoryStores.memories.create()`; go: `client.Beta.MemoryStores.Memories.New()`; java: `client.beta().memoryStores().memories().create()`; csharp: `client.Beta.MemoryStores.Memories.Create()`; php: `$client->beta->memoryStores->memories->create()`; cli: `ant beta:memory-stores:memories create`) creates a memory at a given `path` (csharp, go: `Path`). Create does not overwrite; to [update an existing memory](https://platform.claude.com/docs/en/managed-agents/memory#update-a-memory), use `POST /v1/memory_stores/{memory_store_id}/memories/{memory_id}` (python, ruby: `client.beta.memory_stores.memories.update()`; typescript: `client.beta.memoryStores.memories.update()`; go, csharp: `client.Beta.MemoryStores.Memories.Update()`; java: `client.beta().memoryStores().memories().update()`; php: `$client->beta->memoryStores->memories->update()`; cli: `ant beta:memory-stores:memories update`).
572572 
573573<CodeGroup>
574574 ```bash cURL
from line 647
647647 ```
648648</CodeGroup>
649649 
650See the [Create a memory reference](https://platform.claude.com/docs/en/api/beta/memory_stores/memories/create) for full parameters and response schema.
650See the [Create a memory](https://platform.claude.com/docs/en/api/beta/memory_stores/memories/create) reference for full parameters and response schema.
651651 
652652### Update a memory
653653 
from line 730
730730 ```
731731</CodeGroup>
732732 
733See the [Update a memory reference](https://platform.claude.com/docs/en/api/beta/memory_stores/memories/update) for full parameters and response schema.
733See the [Update a memory](https://platform.claude.com/docs/en/api/beta/memory_stores/memories/update) reference for full parameters and response schema.
734734 
735735#### Safe content edits (optimistic concurrency)
736736 
737To avoid clobbering a concurrent write, pass a `content_sha256` precondition. The update only applies if the stored content hash still matches the one you read; on mismatch, re-read the memory and retry against the fresh state.
737To avoid overwriting a concurrent write, pass a `content_sha256` precondition. The update only applies if the stored content hash still matches the one you read; on mismatch, re-read the memory and retry against the fresh state.
738738 
739739<CodeGroup>
740740 ```bash cURL
from line 895
895895 ```
896896</CodeGroup>
897897 
898See the [Delete a memory reference](https://platform.claude.com/docs/en/api/beta/memory_stores/memories/delete) for full parameters and response schema.
898See the [Delete a memory](https://platform.claude.com/docs/en/api/beta/memory_stores/memories/delete) reference for full parameters and response schema.
899899 
900900## Audit memory changes
901901 
902902Every mutation to a memory creates an immutable **memory version** (`memver_...`). Use the version endpoints to audit who changed what and when, to inspect or restore a prior snapshot, and to scrub sensitive content out of history with redact.
903903 
904Versions belong to the store (not the individual memory) and are not deleted when the memory itself is deleted, so the audit trail also covers deleted memories, subject to the retention described below. Versions are retained for 30 days after they are written; however, the recent versions of a live memory are always kept regardless of age, so memories that change infrequently might retain history beyond 30 days. The live `GET /v1/memory_stores/{memory_store_id}/memories/{memory_id}` (python, ruby: `client.beta.memory_stores.memories.retrieve()`; typescript: `client.beta.memoryStores.memories.retrieve()`; go: `client.Beta.MemoryStores.Memories.Get()`; java: `client.beta().memoryStores().memories().retrieve()`; csharp: `client.Beta.MemoryStores.Memories.Retrieve()`; php: `$client->beta->memoryStores->memories->retrieve()`; cli: `ant beta:memory-stores:memories retrieve`) call always returns the latest version; the version endpoints give you the retained history.
904Versions belong to the store (not the individual memory) and are not deleted when the memory itself is deleted, so the audit trail also covers deleted memories, subject to the retention described later. Versions are retained for 30 days after they are written; however, the recent versions of a live memory are always kept regardless of age, so memories that change infrequently might retain history beyond 30 days. The live `GET /v1/memory_stores/{memory_store_id}/memories/{memory_id}` (python, ruby: `client.beta.memory_stores.memories.retrieve()`; typescript: `client.beta.memoryStores.memories.retrieve()`; go: `client.Beta.MemoryStores.Memories.Get()`; java: `client.beta().memoryStores().memories().retrieve()`; csharp: `client.Beta.MemoryStores.Memories.Retrieve()`; php: `$client->beta->memoryStores->memories->retrieve()`; cli: `ant beta:memory-stores:memories retrieve`) call always returns the latest version; the version endpoints give you the retained history.
905905 
906906There is no dedicated restore endpoint; to roll back, retrieve the version you want and write its `content` (csharp, go: `Content`) back with `POST /v1/memory_stores/{memory_store_id}/memories/{memory_id}` (python, ruby: `client.beta.memory_stores.memories.update()`; typescript: `client.beta.memoryStores.memories.update()`; go, csharp: `client.Beta.MemoryStores.Memories.Update()`; java: `client.beta().memoryStores().memories().update()`; php: `$client->beta->memoryStores->memories->update()`; cli: `ant beta:memory-stores:memories update`) (or `POST /v1/memory_stores/{memory_store_id}/memories` (python, ruby: `client.beta.memory_stores.memories.create()`; typescript: `client.beta.memoryStores.memories.create()`; go: `client.Beta.MemoryStores.Memories.New()`; java: `client.beta().memoryStores().memories().create()`; csharp: `client.Beta.MemoryStores.Memories.Create()`; php: `$client->beta->memoryStores->memories->create()`; cli: `ant beta:memory-stores:memories create`) if the parent memory has been deleted, provided the version you want is still retained).
907907 
from line 941
941941 const versions = await client.beta.memoryStores.memoryVersions.list(store.id, {
942942 memory_id: mem.id
943943 });
944 for await (const v of versions) {
945 console.log(`${v.id}: ${v.operation}`);
944 for await (const memoryVersion of versions) {
945 console.log(`${memoryVersion.id}: ${memoryVersion.operation}`);
946946 }
947947 
948948 const versionId = versions.data[1].id;
from line 1021
10211021 ```
10221022</CodeGroup>
10231023 
1024See the [List memory versions reference](https://platform.claude.com/docs/en/api/beta/memory_stores/memory_versions/list) for full parameters and response schema.
1024See the [List memory versions](https://platform.claude.com/docs/en/api/beta/memory_stores/memory_versions/list) reference for full parameters and response schema.
10251025 
10261026### Retrieve a version
10271027 
from line 1099
10991099 ```
11001100</CodeGroup>
11011101 
1102See the [Retrieve a memory version reference](https://platform.claude.com/docs/en/api/beta/memory_stores/memory_versions/retrieve) for full parameters and response schema.
1102See the [Retrieve a memory version](https://platform.claude.com/docs/en/api/beta/memory_stores/memory_versions/retrieve) reference for full parameters and response schema.
11031103 
11041104### Redact a version
11051105 
1106Redact scrubs content out of a historical version while preserving the audit trail (who did what, when). Use it for compliance workflows such as removing leaked secrets, PII, or user deletion requests.
1106Redact scrubs content out of a historical version while preserving the audit trail (who did what, when). Use it for compliance workflows such as removing leaked secrets or PII, or fulfilling user deletion requests.
11071107 
11081108A version that is the current head of a live memory cannot be redacted. Write a new version first (or delete the memory), then redact the old one.
11091109 
from line 1174
11741174 ```
11751175</CodeGroup>
11761176 
1177See the [Redact a memory version reference](https://platform.claude.com/docs/en/api/beta/memory_stores/memory_versions/redact) for full parameters and response schema.
1177See the [Redact a memory version](https://platform.claude.com/docs/en/api/beta/memory_stores/memory_versions/redact) reference for full parameters and response schema.
11781178 
11791179## Manage memory stores
11801180 
from line 1202
12021202 ```
12031203 
12041204 ```typescript TypeScript
1205 for await (const s of client.beta.memoryStores.list({ include_archived: true })) {
1206 console.log(s.id, s.name, s.archived_at);
1205 for await (const memoryStore of client.beta.memoryStores.list({ include_archived: true })) {
1206 console.log(memoryStore.id, memoryStore.name, memoryStore.archived_at);
12071207 }
12081208 ```
12091209 
from line 1251
12511251 ```
12521252</CodeGroup>
12531253 
1254See the [List memory stores reference](https://platform.claude.com/docs/en/api/beta/memory_stores/list) for full parameters and response schema.
1254See the [List memory stores](https://platform.claude.com/docs/en/api/beta/memory_stores/list) reference for full parameters and response schema.
12551255 
12561256### Archive a store
12571257 
from line 1301
13011301 ```
13021302</CodeGroup>
13031303 
1304See the [Archive a memory store reference](https://platform.claude.com/docs/en/api/beta/memory_stores/archive) for full parameters and response schema.
1304See the [Archive a memory store](https://platform.claude.com/docs/en/api/beta/memory_stores/archive) reference for full parameters and response schema.
13051305 
1306To [permanently remove a store](https://platform.claude.com/docs/en/api/beta/memory_stores/delete) along with all of its memories and versions, call `DELETE /v1/memory_stores/{memory_store_id}` (python, ruby: `client.beta.memory_stores.delete()`; typescript: `client.beta.memoryStores.delete()`; go, csharp: `client.Beta.MemoryStores.Delete()`; java: `client.beta().memoryStores().delete()`; php: `$client->beta->memoryStores->delete()`; cli: `ant beta:memory-stores delete`).
1306To [permanently delete a store](https://platform.claude.com/docs/en/api/beta/memory_stores/delete) along with all of its memories and versions, call `DELETE /v1/memory_stores/{memory_store_id}` (python, ruby: `client.beta.memory_stores.delete()`; typescript: `client.beta.memoryStores.delete()`; go, csharp: `client.Beta.MemoryStores.Delete()`; java: `client.beta().memoryStores().delete()`; php: `$client->beta->memoryStores->delete()`; cli: `ant beta:memory-stores delete`).
13071307 
13081308## Best practices for memory management
13091309 
13101310When a store reaches its 10,000-memory limit, writes to new memories fail: both direct `POST /v1/memory_stores/{memory_store_id}/memories` (python, ruby: `client.beta.memory_stores.memories.create()`; typescript: `client.beta.memoryStores.memories.create()`; go: `client.Beta.MemoryStores.Memories.New()`; java: `client.beta().memoryStores().memories().create()`; csharp: `client.Beta.MemoryStores.Memories.Create()`; php: `$client->beta->memoryStores->memories->create()`; cli: `ant beta:memory-stores:memories create`) calls and the agent's file writes to unmapped paths. Existing memories remain readable and editable. The following practices help you stay well under the limit and recover gracefully if you reach it.
13111311 
1312* **Use focused stores.** Rather than one large general-purpose store, use smaller purpose-built stores: one per user, one for shared domain knowledge, and one for project-specific context. Each store has its own 10,000-memory limit, so keeping stores scoped reduces the chance any single one fills up.
1312* **Use focused stores.** Rather than one large general-purpose store, use smaller purpose-built stores: one for each user, one for shared domain knowledge, and one for project-specific context. Each store has its own 10,000-memory limit, so keeping stores scoped reduces the chance any single one fills up.
13131313 
13141314* **Condense or prune before the store fills up.** Delete stale or redundant memories with `DELETE /v1/memory_stores/{memory_store_id}/memories/{memory_id}` (python, ruby: `client.beta.memory_stores.memories.delete()`; typescript: `client.beta.memoryStores.memories.delete()`; go, csharp: `client.Beta.MemoryStores.Memories.Delete()`; java: `client.beta().memoryStores().memories().delete()`; php: `$client->beta->memoryStores->memories->delete()`; cli: `ant beta:memory-stores:memories delete`). You can also run a [dreaming session](https://platform.claude.com/docs/en/managed-agents/dreams), which consolidates fragmented content into a separate new output store rather than modifying the original. Switch your sessions over to that output store, then archive or delete the original.
13151315 

managed-agents/migration Changed · +3 / -3 lines

from line 20
2020 
2121| Before | After |
2222| ------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- |
23| You maintain the conversation history array and pass it back on every turn. | The session stores history server-side. Send events, receive events. |
23| You maintain the conversation history array and pass it back on every turn. | The session stores history server-side. You send events and receive events. |
2424| You iterate `tool_use` content blocks, run each tool, and loop back with `tool_result` messages. | Pre-built tools run inside the sandbox automatically. You only handle custom tools through `agent.custom_tool_use` events. |
2525| You provision your own sandbox for running agent-generated code. | The session sandbox handles code execution, file operations, and bash. |
2626| You decide when the loop is done. | The session emits `session.status_idle` when the agent has nothing more to do. |
from line 509
509509 
510510## From the Claude Agent SDK
511511 
512If you built with the [Claude Agent SDK](https://code.claude.com/docs/en/agent-sdk/overview), you're already working with agents, tools, and sessions as concepts. The difference is where they run: the SDK runs in a process you operate, while Managed Agents runs in Anthropic's infrastructure. Most of the migration is mapping SDK configuration objects to their API-side equivalents.
512If you built with the [Claude Agent SDK](https://code.claude.com/docs/en/agent-sdk/overview), you're already working with agents, tools, and sessions as concepts. The difference is where they run: the SDK runs in a process you operate, whereas Managed Agents runs in Anthropic's infrastructure. Most of the migration is mapping SDK configuration objects to their API-side equivalents.
513513 
514514### What changes
515515 
from line 1241
12411241 
12421242## Migrating between model versions
12431243 
1244When a new Claude model is released, migrating a Claude Managed Agents integration is typically a one-field change: update `model` (csharp, go: `Model`) on your [agent definition](https://platform.claude.com/docs/en/managed-agents/agent-setup) and the change takes effect on the next session you create.
1244When a new Claude model is released, migrating a Claude Managed Agents integration is typically a one-field change: update `model` (csharp, go: `Model`) on your [agent definition](https://platform.claude.com/docs/en/managed-agents/agent-setup), and the change takes effect on the next session you create.
12451245 
12461246<CodeGroup defaultLanguage="CLI">
12471247 ```bash cURL

managed-agents/multiagent-orchestration Changed · +11 / -11 lines

from line 22
2222 
2323With subagents, the agent itself determines what happens next. A [subagent's thread](https://platform.claude.com/docs/en/managed-agents/session-threads) stays available until you archive it, so the agent can send it follow-up messages. With dynamic workflows, Claude writes a program to orchestrate agents without Claude's direct involvement. Context and results are passed programmatically from one agent to another, freeing up the main session thread to communicate with the user and check in on one or several running workflows to report on progress. The agent can't send follow-up messages to a run's threads, and the server archives each one by the end of its run.
2424 
25| Approach | What happens | Use it when | Consider |
26| -------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
27| [Subagents](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#delegate-to-subagents) | The agent delegates tasks to its subagents. Each subagent works in its own [session thread](https://platform.claude.com/docs/en/managed-agents/session-threads), which you can list and stream. | The agent should follow up with a subagent after it reports, or it needs specialists that you list, with their own system prompts and tools. | Delegation is one level deep, and a session can have at most 25 child threads at a time, idle ones included. Advisor threads and a workflow run's threads don't count. |
28| [Dynamic workflows](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#dynamic-workflows) | The agent writes a workflow: a program that runs many agents in phases and combines their results. The server runs it in the background as one workflow run, which you can follow. The workflow defines the agents or picks them from a list you give. | Most work that needs more than one agent: work with many pieces, parallel work, or a long task that should finish sooner. Examples are audits, migrations, deep research, and cross-checking. | Every agent in a run uses tokens, so set a [session budget](https://platform.claude.com/docs/en/managed-agents/budgets) to cap the session's spend, runs included. Tell the agent in its system prompt when to use a run. You follow the run by its phases and can read each of its threads. |
29| [Give the session an advisor](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#give-the-session-an-advisor) | The session's [primary thread](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#how-it-works) consults an advisor model mid-turn for guidance, such as planning an approach or reviewing work, and keeps doing the work itself. | One agent should do the work, with an advisor model's judgment at key moments such as planning or a final review. | Only the primary thread can consult the advisor, and consultations are billed at the advisor model's rates. |
25| Approach | What happens | Use it when | Consider |
26| -------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
27| [Delegate to subagents](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#delegate-to-subagents) | The agent delegates tasks to its subagents. Each subagent works in its own [session thread](https://platform.claude.com/docs/en/managed-agents/session-threads), which you can list and stream. | The agent should follow up with a subagent after it reports, or it needs specialists that you list, with their own system prompts and tools. | Delegation is one level deep, and a session can have at most 25 child threads at a time, idle ones included. Advisor threads and a workflow run's threads don't count. |
28| [Dynamic workflows](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#dynamic-workflows) | The agent writes a workflow: a program that runs many agents in phases and combines their results. The server runs it in the background as one workflow run, which you can follow. The workflow defines the agents or picks them from a list you give. | Most work that needs more than one agent: work with many pieces, parallel work, or a long task that should complete sooner. Examples are audits, migrations, deep research, and cross-checking. | Every agent in a run uses tokens, so set a [session budget](https://platform.claude.com/docs/en/managed-agents/budgets) to cap the session's spend, runs included. Tell the agent in its system prompt when to use a run. You follow the run by its phases and can read each of its threads. |
29| [Give the session an advisor](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#give-the-session-an-advisor) | The session's [primary thread](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#how-it-works) consults an advisor model mid-turn for guidance, such as planning an approach or reviewing work, and keeps doing the work itself. | One agent should do the work, with an advisor model's judgment at key moments such as planning or a final review. | Only the primary thread can consult the advisor, and consultations are billed at the advisor model's rates. |
3030 
3131You set these up in the `multiagent` block of the agent's definition, which has a `type`. With the `multiagent_20261001` type, an agent can use all three together, and you can turn each one on or off. By default, `subagents` and `workflows` are both enabled. `subagents` and `workflows` each have `inline_agents` enabled, the setting for [agents that the agent or a workflow defines itself](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#predefined-and-inline-agents):
3232 
from line 89
8989 
9090### What to delegate
9191 
92Multiagent coordination is best suited for complex tasks that either require work across a variety of surfaces, or where multiple well-scoped tasks contribute to an overall goal.
92Multiagent coordination is best suited for complex tasks that either require work across a variety of surfaces or consist of multiple well-scoped tasks that contribute to an overall goal.
9393 
9494Patterns that work well:
9595 
from line 347
347347 
348348* **Pinning:** The agent's configuration, including the `predefined_agents` (java, php: `predefinedAgents`; csharp, go: `PredefinedAgents`) list of `subagents` (csharp, go: `Subagents`), is snapshotted when the agent is created or updated. Referenced agents stay pinned to the versions resolved then and don't pick up later updates to their definitions. An update that doesn't send the list keeps the versions that are already pinned. To delegate to a newer version of a referenced agent, [update the agent](https://platform.claude.com/docs/en/managed-agents/agent-setup#update-an-agent) so the `predefined_agents` (java, php: `predefinedAgents`; csharp, go: `PredefinedAgents`) list of `subagents` (csharp, go: `Subagents`) references that version.
349349* **One level:** The agent can delegate to only one level of agents. Referencing another agent that has `multiagent` (csharp, go: `Multiagent`) set fails the create or update request with a 400 validation error.
350* **Up to 20 agents:** The `predefined_agents` (java, php: `predefinedAgents`; csharp, go: `PredefinedAgents`) list of `subagents` (csharp, go: `Subagents`) can list up to 20 unique agents. The limit is per list: the `predefined_agents` (java, php: `predefinedAgents`; csharp, go: `PredefinedAgents`) list of `workflows` (csharp, go: `Workflows`) can also list up to 20. The agent can call multiple copies of each subagent, within the session's [thread limit](https://platform.claude.com/docs/en/managed-agents/session-threads).
350* **Up to 20 agents:** The `predefined_agents` (java, php: `predefinedAgents`; csharp, go: `PredefinedAgents`) list of `subagents` (csharp, go: `Subagents`) can list up to 20 unique agents. The limit is for each list: the `predefined_agents` (java, php: `predefinedAgents`; csharp, go: `PredefinedAgents`) list of `workflows` (csharp, go: `Workflows`) can also list up to 20. The agent can call multiple copies of each subagent, within the session's [thread limit](https://platform.claude.com/docs/en/managed-agents/session-threads).
351351* **Inference geography:** The agent and every agent that you list, in the `predefined_agents` (java, php: `predefinedAgents`; csharp, go: `PredefinedAgents`) list of `subagents` (csharp, go: `Subagents`) or of `workflows` (csharp, go: `Workflows`), must pin the same [inference geography](https://platform.claude.com/docs/en/manage-claude/data-residency) (`inference_geo` (java, php: `inferenceGeo`; csharp, go: `InferenceGeo`) in the `model` (csharp, go: `Model`) of the [agent definition](https://platform.claude.com/docs/en/managed-agents/agent-setup)), or none of them can pin one. A mismatch in either list is rejected with a 400 validation error. That check runs both when the agent is saved and when a [session-create override](https://platform.claude.com/docs/en/managed-agents/sessions#override-agent-configuration-for-a-session) changes any of the pins.
352352 
353353### Create the session
from line 838
838838 
839839## Dynamic workflows
840840 
841With dynamic workflows, an agent can take on work with many pieces, such as reviewing hundreds of documents or cross-checking many sources. The agent writes a **workflow**: a program that runs many agents in phases and combines what they return. The server runs it in the background as a **workflow run**, while the agent keeps working or ends its turn. You turn dynamic workflows on or off with the `workflows` (csharp, go: `Workflows`) setting in the agent's `multiagent` (csharp, go: `Multiagent`) block. A run's agents can work at the same time, so a long task can finish sooner than if one agent did each piece in turn.
841With dynamic workflows, an agent can take on work with many pieces, such as reviewing hundreds of documents or cross-checking many sources. The agent writes a **workflow:** a program that runs many agents in phases and combines what they return. The server runs it in the background as a **workflow run**, while the agent keeps working or ends its turn. You turn dynamic workflows on or off with the `workflows` (csharp, go: `Workflows`) setting in the agent's `multiagent` (csharp, go: `Multiagent`) block. A run's agents can work at the same time, so a long task can complete sooner than if one agent did each piece in turn.
842842 
843843* **How a run starts:** You describe the work in a `user.message`. From that, the agent determines whether and when to start a run, so there's no additional API call. Instead, you influence the agent's determination by describing when to use a run in `user.message` or in the agent's system prompt. (Permission policies apply to the tools that a run's agents call, not to starting the run.)
844844* **Which agents it uses:** [Inline agents](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#predefined-and-inline-agents) that the workflow defines, predefined agents that you list in the `predefined_agents` (java, php: `predefinedAgents`; csharp, go: `PredefinedAgents`) list of `workflows` (csharp, go: `Workflows`), or both. If you list none, the workflow defines them all. An inline agent uses the model of the agent that the session runs. To let a run use another model for some of its agents, create them as agents and list them in the `predefined_agents` (java, php: `predefinedAgents`; csharp, go: `PredefinedAgents`) list of `workflows` (csharp, go: `Workflows`).
from line 1040
10401040 
10411041### Tell the agent when to use a run
10421042 
1043Turning dynamic workflows on gives the agent the ability to start workflow runs. The agent determines when to start one. To guide that choice, add an instruction like the following to the agent's system prompt. The contract-review agent in [Turn on dynamic workflows](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#turn-on-dynamic-workflows) uses this system prompt:
1043Turning dynamic workflows on gives the agent the ability to start workflow runs. The agent determines when to start one. To guide that choice, add an instruction such as the following to the agent's system prompt. The contract-review agent in [Turn on dynamic workflows](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#turn-on-dynamic-workflows) uses this system prompt:
10441044 
10451045```text wrap
10461046You review contracts. When you're asked to review more than a few contracts, start a workflow run that reads them in parallel and combines the findings. Review one or two contracts yourself, without a run.
from line 1061
10611061 
10621062## Give the session an advisor
10631063 
1064An enabled `advisor` setting in the agent's `multiagent` (csharp, go: `Multiagent`) block gives the session's primary thread an **advisor**: a model it can consult mid-turn for strategic guidance, such as planning an approach, getting unstuck, or reviewing work before finishing. The setting is disabled by default. To enable it, set `advisor` to `{"type": "enabled", "model": "..."}`, which has exactly two fields, `type` and `model`:
1064An enabled `advisor` setting in the agent's `multiagent` (csharp, go: `Multiagent`) block gives the session's primary thread an **advisor:** a model it can consult mid-turn for strategic guidance, such as planning an approach, getting unstuck, or reviewing work before finishing. The setting is disabled by default. To enable it, set `advisor` to `{"type": "enabled", "model": "..."}`, which has exactly two fields, `type` and `model`:
10651065 
10661066<CodeGroup defaultLanguage="CLI">
10671067 ```bash cURL
from line 1212
12121212 
12131213You can't list the advisor in the `predefined_agents` (java, php: `predefinedAgents`; csharp, go: `PredefinedAgents`) list of `subagents` (csharp, go: `Subagents`) or `workflows` (csharp, go: `Workflows`). An enabled `advisor` (csharp, go: `Advisor`) reserves the name `anthropic.advisor`. While it is enabled, neither list can hold an agent literally named `anthropic.advisor`: the request is rejected with a 400 validation error.
12141214 
1215The advisor model must meet a minimum capability bar, and the agent's own model must not be more capable than its advisor; models of equal capability can pair. An invalid pairing is rejected with a 400 validation error when the agent is saved, and again when a session is created. The pairing is also checked when each consultation starts: if it's no longer valid, that consultation fails and the session continues. Valid pairings follow the advisor tool's [model compatibility](https://platform.claude.com/docs/en/agents-and-tools/tool-use/advisor-tool#model-compatibility) table.
1215The advisor model must meet a minimum capability level, and the agent's own model must not be more capable than its advisor; models of equal capability can pair. An invalid pairing is rejected with a 400 validation error when the agent is saved, and again when a session is created. The pairing is also checked when each consultation starts: if it's no longer valid, that consultation fails and the session continues. Valid pairings follow the advisor tool's [model compatibility](https://platform.claude.com/docs/en/agents-and-tools/tool-use/advisor-tool#model-compatibility) table.
12161216 
12171217The advisor is also available as a [server tool on the Messages API](https://platform.claude.com/docs/en/agents-and-tools/tool-use/advisor-tool). The Managed Agents surface differs in configuration and delivery: the `advisor` (csharp, go: `Advisor`) setting has no `max_uses`, `max_tokens`, or `caching` fields, and advice arrives through thread events rather than `advisor_tool_result` blocks.
12181218 

managed-agents/onboarding Changed · +3 / -3 lines

## From Console to your code base ## From Console to your codebase

from line 1
11---
22title: Build in Console
33url: https://platform.claude.com/docs/en/managed-agents/onboarding
4description: Create, test, and iterate on agents visually in Console, then run them from your code with the API.
4description: Create, test, and iterate on agents visually in the Claude Console, then run them from your code with the API.
55featureMetadata:
66 topic:
77 title: Managed Agents
from line 10
1010 betaHeader: managed-agents-2026-04-01
1111---
1212 
13[Console](https://platform.claude.com/workspaces/default/agent-quickstart/) provides a visual interface for creating and configuring agents. It lets you iterate on configuration interactively before writing code.
13The [Claude Console](https://platform.claude.com/workspaces/default/agent-quickstart/) provides a visual interface for creating and configuring agents. It lets you iterate on configuration interactively before writing code.
1414 
1515## How to build an agent
1616 
from line 27
2727 
2828Console includes an inline session runner. After configuring your agent, you can start a test session directly, send messages, and watch the event stream without leaving the page. This is the fastest way to check that your system prompt and tool selection produce the behavior you expect.
2929 
30## From Console to your codebase
30## From Console to your code base
3131 
3232Once your agent works as expected:
3333 

managed-agents/permission-policies Changed · +7 / -7 lines

from line 1
11---
22title: Permission policies
33url: https://platform.claude.com/docs/en/managed-agents/permission-policies
4description: Control when agent and MCP tools execute.
4description: Control when agent and MCP tools run.
55featureMetadata:
66 topic:
77 title: Managed Agents
from line 10
1010 betaHeader: managed-agents-2026-04-01
1111---
1212 
13Permission policies control whether server-executed tools (the pre-built agent toolset and MCP toolset) run automatically, wait for your approval, or have each call evaluated by the server. Custom tools are executed by your application and controlled by you, so they are not governed by permission policies.
13Permission policies control whether server-executed tools (the pre-built agent toolset and MCP toolset) run automatically, wait for your approval, or have each call evaluated by the server. Custom tools are run by your application and controlled by you, so they are not governed by permission policies.
1414 
1515## Permission policy types
1616 
from line 206
206206 
207207### MCP toolset permissions
208208 
209MCP toolsets default to `always_ask`. This ensures that new tools added to an MCP server do not execute in your application without approval. To auto-approve tools from a trusted MCP server, set `default_config.permission_policy` (java, php: `defaultConfig.permissionPolicy`; csharp, go: `DefaultConfig.PermissionPolicy`) on the `mcp_toolset` entry.
209MCP toolsets default to `always_ask`. This ensures that new tools added to an MCP server do not run in your application without approval. To auto-approve tools from a trusted MCP server, set `default_config.permission_policy` (java, php: `defaultConfig.permissionPolicy`; csharp, go: `DefaultConfig.PermissionPolicy`) on the `mcp_toolset` entry.
210210 
211211The `mcp_server_name` (java, php: `mcpServerName`; csharp: `McpServerName`; go: `MCPServerName`) must match the `name` (csharp, go: `Name`) of a server in the `mcp_servers` (java, php: `mcpServers`; csharp: `McpServers`; go: `MCPServers`) array.
212212 
from line 1031
10311031 
10321032## Respond to confirmation requests
10331033 
1034A tool call evaluates to `ask` under an `always_ask` policy, or under `auto` when the server reaches no determination. When that happens:
1034A tool call evaluates to `ask` under an `always_ask` policy, or under `auto` when the server reaches no determination. When that occurs:
10351035 
103610361. The session emits an `agent.tool_use` or `agent.mcp_tool_use` event.
103710372. The session pauses with a `session.status_idle` event whose `stop_reason.type` is `requires_action`. The blocking event IDs are in the `stop_reason.event_ids` array. The session waits indefinitely for a response. A call from a thread of a [workflow run](https://platform.claude.com/docs/en/managed-agents/workflow-runs#while-a-run-is-open) reaches your client on the primary stream. While anything else in the session is working, the session can stay `running` and send no `session.status_idle`, so answer the tool-use event itself. The call waits only until the run finishes with that thread or the run ends. An interrupt might leave it waiting, so allow or deny it yourself.
103810383. Send a `user.tool_confirmation` event for each blocking event, passing the event ID in the `tool_use_id` (java: `toolUseId`; php: `toolUseID`; csharp, go: `ToolUseID`) parameter. Set `result` (csharp, go: `Result`) to `"allow"` or `"deny"`. Use `deny_message` (java, php: `denyMessage`; csharp, go: `DenyMessage`) to explain a denial. You can send several confirmations in a single `events` request.
10394. Once all blocking events are resolved, the session transitions back to `running`. Allowed tools execute. Denied tools do not run, and the agent receives a tool result saying the call was rejected, including your `deny_message` (java, php: `denyMessage`; csharp, go: `DenyMessage`).
10394. Once all blocking events are resolved, the session transitions back to `running`. Allowed tools run. Denied tools do not run, and the agent receives a tool result saying the call was rejected, including your `deny_message` (java, php: `denyMessage`; csharp, go: `DenyMessage`).
10401040 
10411041For example, a `bash` call paused under an `always_ask` policy appears on the stream as follows:
10421042 
from line 1309
13091309 
13101310## Custom tools
13111311 
1312Permission policies do not apply to custom tools. When the agent invokes a custom tool, your application receives an `agent.custom_tool_use` event and is responsible for deciding whether to execute it before sending back a `user.custom_tool_result`. See [Session event stream](https://platform.claude.com/docs/en/managed-agents/events-and-streaming#answer-tool-calls-that-pause-the-session) for the full flow.
1312Permission policies do not apply to custom tools. When the agent invokes a custom tool, your application receives an `agent.custom_tool_use` event and is responsible for deciding whether to run it before sending back a `user.custom_tool_result`. See [Answer tool calls that pause the session](https://platform.claude.com/docs/en/managed-agents/events-and-streaming#answer-tool-calls-that-pause-the-session) for the full flow.
13131313 
13141314## Next steps
13151315 
from line 1319
13191319 </Card>
13201320 
13211321 <Card title="Session event stream" icon="lightning" href="https://platform.claude.com/docs/en/managed-agents/events-and-streaming">
1322 Send events, stream responses, and interrupt or redirect your session mid-execution.
1322 Send events, stream responses, and interrupt or redirect your session while it runs.
13231323 </Card>
13241324</CardGroup>
13251325 

managed-agents/reference Changed · +17 / -17 lines

from line 14
1414 
1515## Event types
1616 
17Persisted event type strings follow a `{domain}.{action}` naming convention; the stream-only event deltas (see the Event deltas tab) are the exception. See [Session event stream](https://platform.claude.com/docs/en/managed-agents/events-and-streaming) for sending, streaming, and listing events. Webhook event types are listed separately in [Subscribe to webhooks](https://platform.claude.com/docs/en/managed-agents/webhooks#supported-event-types), and some of their names differ from the stream's (for example, `session.status_idled` rather than `session.status_idle`).
17Persisted event type strings follow a `{domain}.{action}` naming convention; the stream-only event deltas (see the **Event deltas** tab) are the exception. See [Session event stream](https://platform.claude.com/docs/en/managed-agents/events-and-streaming) for sending, streaming, and listing events. Webhook event types are listed separately in [Subscribe to webhooks](https://platform.claude.com/docs/en/managed-agents/webhooks#supported-event-types), and some of their names differ from the stream's (for example, `session.status_idled` rather than `session.status_idle`).
1818 
1919<Tabs>
2020 <Tab title="User events">
from line 21
2121 | Type | Description |
2222 | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
2323 | `user.message` | A user message with text, image, or document content. |
24 | `user.interrupt` | Stop the agent mid-execution. It ends no [workflow run](https://platform.claude.com/docs/en/managed-agents/workflow-runs#interrupt-a-session-with-runs-open). |
24 | `user.interrupt` | Stop the agent while it runs. It ends no [workflow run](https://platform.claude.com/docs/en/managed-agents/workflow-runs#interrupt-a-session-with-runs-open). |
2525 | `user.custom_tool_result` | Response to a custom tool call from the agent. |
2626 | `user.tool_confirmation` | Approve or deny an agent or MCP tool call when a permission policy requires confirmation. |
2727 | `user.define_outcome` | Define an [outcome](https://platform.claude.com/docs/en/managed-agents/define-outcomes) for the agent to work toward. |
from line 29
2929 </Tab>
3030 
3131 <Tab title="Agent events">
32 | Type | Description |
33 | -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
34 | `agent.message` | Agent response content blocks. |
35 | `agent.thinking` | Signals the agent is making forward progress through extended thinking. This is a progress signal only and does not carry the thinking content. |
36 | `agent.tool_use` | Agent invokes a pre-built agent tool (bash, file operations, and so on). Carries `evaluated_permission` (java, php: `evaluatedPermission`; csharp, go: `EvaluatedPermission`) and, usually, `evaluation` (csharp, go: `Evaluation`) (see [how each call was evaluated](https://platform.claude.com/docs/en/managed-agents/permission-policies#see-how-each-call-was-evaluated)). |
37 | `agent.tool_result` | Result of a pre-built agent tool execution. |
38 | `agent.mcp_tool_use` | Agent invokes an MCP server tool. Carries `evaluated_permission` (java, php: `evaluatedPermission`; csharp, go: `EvaluatedPermission`) and, usually, `evaluation` (csharp, go: `Evaluation`) (see [how each call was evaluated](https://platform.claude.com/docs/en/managed-agents/permission-policies#see-how-each-call-was-evaluated)). |
39 | `agent.mcp_tool_result` | Result of an MCP tool execution. |
40 | `agent.custom_tool_use` | Agent invokes one of your custom tools. Respond with a `user.custom_tool_result` event. |
41 | `agent.thread_context_compacted` | Conversation history was compacted to fit the context window. |
42 | `agent.thread_message_received` | In a [multiagent](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration) session, a message from another thread arrived on the thread whose stream carries this event; on the primary thread, an agent sent a report or question to the agent that the session runs. |
43 | `agent.thread_message_sent` | In a [multiagent](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration) session, the thread whose stream carries this event sent a message to another thread; on the primary thread, the agent that the session runs sent a task or follow-up message to another agent. |
32 | Type | Description |
33 | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
34 | `agent.message` | Agent response content blocks. |
35 | `agent.thinking` | Signals the agent is making forward progress through extended thinking. This is a progress signal only and does not carry the thinking content. |
36 | `agent.tool_use` | Agent calls a pre-built agent tool (bash, file operations, and so on). Carries `evaluated_permission` (java, php: `evaluatedPermission`; csharp, go: `EvaluatedPermission`) and, usually, `evaluation` (csharp, go: `Evaluation`) (see [how each call was evaluated](https://platform.claude.com/docs/en/managed-agents/permission-policies#see-how-each-call-was-evaluated)). |
37 | `agent.tool_result` | Result of a pre-built agent tool execution. |
38 | `agent.mcp_tool_use` | Agent calls an MCP server tool. Carries `evaluated_permission` (java, php: `evaluatedPermission`; csharp, go: `EvaluatedPermission`) and, usually, `evaluation` (csharp, go: `Evaluation`) (see [how each call was evaluated](https://platform.claude.com/docs/en/managed-agents/permission-policies#see-how-each-call-was-evaluated)). |
39 | `agent.mcp_tool_result` | Result of an MCP tool execution. |
40 | `agent.custom_tool_use` | Agent calls one of your custom tools. Respond with a `user.custom_tool_result` event. |
41 | `agent.thread_context_compacted` | Conversation history was compacted to fit the context window. |
42 | `agent.thread_message_received` | In a [multiagent](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration) session, a message from another thread arrived on the thread whose stream carries this event; on the primary thread, an agent sent a report or question to the agent that the session runs. |
43 | `agent.thread_message_sent` | In a [multiagent](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration) session, the thread whose stream carries this event sent a message to another thread; on the primary thread, the agent that the session runs sent a task or follow-up message to another agent. |
4444 
4545 Message content in these events can include a `redacted` content block, `{"type": "redacted"}`: a placeholder for content withheld by Anthropic model policy. The block carries no other fields. Redacted blocks appear only in content the platform emits; a user event that includes one is rejected with a 400 error.
4646 </Tab>
from line 52
5252 | `session.status_idle` | Agent finished its current task and is waiting for input. Includes a `stop_reason` (java, php: `stopReason`; csharp, go: `StopReason`) indicating why the agent stopped. |
5353 | `session.status_rescheduled` | A transient error occurred and the session is retrying automatically. |
5454 | `session.status_terminated` | Session ended, either because of an unrecoverable error or because it was archived. |
55 | `session.deleted` | Session was deleted. Terminates any active event stream; no further events are emitted for this session. |
55 | `session.deleted` | Session was deleted. Ends any active event stream; no further events are emitted for this session. |
5656 | `session.updated` | Session update request changed at least one field. Includes only the fields that changed. Updates apply on the next turn. |
5757 | `session.error` | An error occurred during processing. Includes a typed `error` (csharp, go: `Error`) object with a `retry_status` (java, php: `retryStatus`; csharp, go: `RetryStatus`). |
5858 | `session.usage` | Snapshot of the session's cumulative usage and tracked list cost. Carries the session's usage totals and, if the session has one, its [budget](https://platform.claude.com/docs/en/managed-agents/budgets). |
59 | `session.thread_created` | A [multiagent](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration) thread was created. It includes `workflow_run_id` (java: `workflowRunId`; php: `workflowRunID`; csharp, go: `WorkflowRunID`): the run's ID for a [workflow run](https://platform.claude.com/docs/en/managed-agents/workflow-runs#a-runs-threads)'s thread, and `null` (python: `None`; ruby: `nil`; java: `Optional.empty()`; go: `""`) for any other thread. |
59 | `session.thread_created` | A [multiagent](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration) thread was created. It includes `workflow_run_id` (java: `workflowRunId`; php: `workflowRunID`; csharp, go: `WorkflowRunID`): the run's ID for a [workflow run's thread](https://platform.claude.com/docs/en/managed-agents/workflow-runs#a-runs-threads), and `null` (python: `None`; ruby: `nil`; java: `Optional.empty()`; go: `""`) for any other thread. |
6060 | `session.thread_status_running` | A session thread began executing. Every session emits this for its primary thread; in [multiagent](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration) sessions, child-thread transitions are also cross-posted to the primary stream. |
6161 | `session.thread_status_idle` | A session thread finished its turn and is awaiting input. Includes `stop_reason` (java, php: `stopReason`; csharp, go: `StopReason`). |
6262 | `session.thread_status_rescheduled` | A session thread hit a transient error and is retrying automatically. |
from line 115
115115 
116116## Rate limits
117117 
118Managed Agents endpoints are rate-limited per organization:
118Managed Agents endpoints are rate-limited for each organization:
119119 
120120| Operation | Limit |
121121| ------------------------------------------------------------- | ------------------------- |

managed-agents/scheduled-deployments Changed · +16 / -16 lines

from line 10
1010 betaHeader: managed-agents-2026-04-01
1111---
1212 
13A **scheduled deployment** allows an [agent](https://platform.claude.com/docs/en/managed-agents/agent-setup) to start [sessions](https://platform.claude.com/docs/en/managed-agents/sessions) autonomously, enabling task completion over a predictable cadence. You create and manage deployments with the Deployments API, part of the Claude API.
13A **scheduled deployment** allows an [agent](https://platform.claude.com/docs/en/managed-agents/agent-setup) to start [sessions](https://platform.claude.com/docs/en/managed-agents/sessions) autonomously, so the agent can complete tasks on a predictable cadence. You create and manage deployments with the Deployments API, part of the Claude API.
1414 
1515For the launch context and examples of what teams run on schedules, see [scheduled deployments and vaults in Claude Managed Agents](https://claude.com/blog/whats-new-in-claude-managed-agents) on the blog.
1616 
from line 18
1818 
1919When creating a deployment, you pass the [session configurations](https://platform.claude.com/docs/en/managed-agents/sessions) required for execution, in addition to a `schedule` (csharp, go: `Schedule`).
2020 
21* Deployments require [agent configuration](https://platform.claude.com/docs/en/managed-agents/agent-setup) and [environment configuration](https://platform.claude.com/docs/en/managed-agents/environments), and optionally accept [files](https://platform.claude.com/docs/en/managed-agents/files), [GitHub](https://platform.claude.com/docs/en/managed-agents/github), [memory stores](https://platform.claude.com/docs/en/managed-agents/memory), and [vaults](https://platform.claude.com/docs/en/managed-agents/vaults). A deployment that targets a [self-hosted environment](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes-memory) can attach memory stores; `file` and `github_repository` resources require a cloud environment. The Claude Console deployment form does not currently offer memory stores for self-hosted environments; attach them through the API or an SDK instead.
21* Deployments require [agent configuration](https://platform.claude.com/docs/en/managed-agents/agent-setup) and [environment configuration](https://platform.claude.com/docs/en/managed-agents/environments), and optionally accept [files](https://platform.claude.com/docs/en/managed-agents/files), [GitHub](https://platform.claude.com/docs/en/managed-agents/github), [memory stores](https://platform.claude.com/docs/en/managed-agents/memory), and [vaults](https://platform.claude.com/docs/en/managed-agents/vaults). A deployment that targets a [self-hosted environment](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes-memory) can attach memory stores; `file` and `github_repository` resources require a cloud environment. The Claude Console deployment form does not currently offer memory stores for self-hosted environments; attach them through the API or the SDK instead.
2222* Deployments also require at least one initial event, a `user.message` or `user.define_outcome`, that starts each session's work. In a deployment file for `ant apply`, the text below the frontmatter becomes that `user.message`.
2323* In the `schedule` (csharp, go: `Schedule`), you define a cron `expression` (csharp, go: `Expression`) and a `timezone` (csharp, go: `Timezone`). Maximum granularity supported is at the minute level.
2424 
from line 243
243243}
244244```
245245 
246The upcoming run timestamps reflect the exact schedule configured. However, to distribute load, actual execution applies jitter of up to 15% of the interval between runs, with a minimum of 5 seconds and a maximum of 9 minutes.
246The upcoming run timestamps reflect the exact schedule configured. However, to distribute load, actual execution applies jitter of up to 15 percent of the interval between runs, with a minimum of 5 seconds and a maximum of 9 minutes.
247247 
248A maximum of **1,000 scheduled deployments** is supported per organization. Contact Anthropic support if you need more.
248A maximum of **1,000 scheduled deployments** is supported for each organization. Contact Anthropic support if you need more.
249249 
250See the [Create Deployment reference](https://platform.claude.com/docs/en/api/beta/deployments/create) for full parameters and response schema.
250See the [Create Deployment](https://platform.claude.com/docs/en/api/beta/deployments/create) reference for full parameters and response schema.
251251 
252252### Cron and timezone semantics
253253 
from line 261
261261 
262262### Set a budget on each run
263263 
264Pass the optional `budget` (csharp, go: `Budget`) object when you create or update the deployment. It takes the same shape as a [session budget](https://platform.claude.com/docs/en/managed-agents/budgets). The deployment copies the cap onto each session it starts, so the budget bounds every run separately rather than acting as a cumulative ceiling across runs: a deployment with a `"2000"` cap can spend up to about $20 on every run.
264Pass the optional `budget` (csharp, go: `Budget`) object when you create or update the deployment. It takes the same shape as a [session budget](https://platform.claude.com/docs/en/managed-agents/budgets). The deployment copies the cap onto each session it starts, so the budget bounds every run separately rather than acting as a cumulative ceiling across runs: a deployment with a `"2000"` cap can spend up to about $20 USD on every run.
265265 
266266A session started by the deployment behaves exactly like any other budgeted session: it pauses with `budget_reached` when its own list cost [reaches the cap](https://platform.claude.com/docs/en/managed-agents/budgets#when-a-session-reaches-its-budget). Changing the deployment's budget applies to runs started afterward; a session already running keeps the cap it started with, which you can [change through the session itself](https://platform.claude.com/docs/en/managed-agents/session-operations#updating-the-session-budget). Unlike a session budget, a deployment's budget can be removed with `"budget": null` (python: `budget=None`; typescript: `budget: null`; ruby: `budget: nil`; go: `Budget: param.NullStruct[anthropic.BetaManagedAgentsBudgetLimitParam]()`; java: `.budget(Optional.empty())`; csharp: `Budget = null`; php: `requestOptions: ['extraBodyParams' => ['budget' => null]]`; cli: `--budget null`) and set again later.
267267 
from line 397
397397 
398398## Deployment runs
399399 
400Deployments can fail to trigger for a variety of reasons: for example, if the `environment` resource has been archived, or if session creation is rate-limited. Each attempt at executing a deployment generates a **deployment run** record, allowing you to track successes and failures independent of the session lifecycle.
400Deployments can fail to trigger for a variety of reasons: for example, if the `environment` resource has been archived, or if session creation is rate-limited. Each attempt generates a **deployment run** record, allowing you to track successes and failures independent of the session lifecycle.
401401 
402Successful deployments generate active sessions, and a successful deployment run contains the associated `session_id` (java: `sessionId`; php: `sessionID`; csharp, go: `SessionID`). To follow a session's lifecycle, track the session events through the [event stream](https://platform.claude.com/docs/en/managed-agents/events-and-streaming) or [webhooks](https://platform.claude.com/docs/en/managed-agents/webhooks). Deployment lifecycle changes and the outcome of each scheduled run are also delivered as webhook events, listed in the Deployment events and Deployment run events tabs of [Supported event types](https://platform.claude.com/docs/en/managed-agents/webhooks#supported-event-types).
402Successful deployments generate active sessions, and a successful deployment run contains the associated `session_id` (java: `sessionId`; php: `sessionID`; csharp, go: `SessionID`). To follow a session's lifecycle, track the session events through the [event stream](https://platform.claude.com/docs/en/managed-agents/events-and-streaming) or [webhooks](https://platform.claude.com/docs/en/managed-agents/webhooks). Deployment lifecycle changes and the outcome of each scheduled run are also delivered as webhook events, listed in the **Deployment events** and **Deployment run events** tabs of [Supported event types](https://platform.claude.com/docs/en/managed-agents/webhooks#supported-event-types).
403403 
404404List all deployment runs for a deployment as follows:
405405 
from line 576
576576 ```
577577</CodeGroup>
578578 
579A failed run includes an `error` with a `type` describing why session creation was rejected (for example, `environment_archived_error`, `agent_archived_error`, or `session_rate_limited_error`). See the [List Deployment Runs reference](https://platform.claude.com/docs/en/api/beta/deployment_runs/list) for all filter parameters and the response schema.
579A failed run includes an `error` with a `type` describing why session creation was rejected (for example, `environment_archived_error`, `agent_archived_error`, or `session_rate_limited_error`). See the [List Deployment Runs](https://platform.claude.com/docs/en/api/beta/deployment_runs/list) reference for all filter parameters and the response schema.
580580 
581581```json
582582{
from line 598
598598 
599599## Managing deployment lifecycle
600600 
601Each lifecycle change emits a [webhook event](https://platform.claude.com/docs/en/managed-agents/webhooks#supported-event-types), so you can react to a paused, unpaused, or archived deployment without polling; see the Deployment events tab.
601Each lifecycle change emits a [webhook event](https://platform.claude.com/docs/en/managed-agents/webhooks#supported-event-types), so you can react to a paused, unpaused, or archived deployment without polling; see the **Deployment events** tab.
602602 
603**Pause** suppresses scheduled triggers on a go-forward basis; running sessions from a prior deployment run continue to execute. Manual runs through the `run` endpoint are still allowed while paused. Pausing sets `paused_reason` to `{"type": "manual"}`; unpausing clears it.
603**Pause** suppresses scheduled triggers from that point on; sessions already running from a prior deployment run continue. Manual runs through the `run` endpoint are still allowed while paused. Pausing sets `paused_reason` to `{"type": "manual"}`; unpausing clears it.
604604 
605605<CodeGroup>
606606 ```bash cURL
from line 690
690690 ```
691691</CodeGroup>
692692 
693**Archive**, unlike **pause**, is terminal: the schedule terminates and the deployment cannot be modified.
693**Archive**, unlike **pause**, is terminal: the schedule ends and the deployment cannot be modified.
694694 
695695<CodeGroup>
696696 ```bash cURL

managed-agents/secure-deployment Changed · +62 / -62 lines

from line 40
4040 
4141## Choose where the agent runs
4242 
43Where the agent's tools run decides who secures the sandbox: Anthropic, with a cloud environment, or you, with a self-hosted sandbox. To choose between them and learn what reaches Anthropic with each, see [Choosing an agent environment](https://platform.claude.com/docs/en/managed-agents/choosing-an-environment).
43Where the agent's tools run determines who secures the sandbox: Anthropic, with a cloud environment, or you, with a self-hosted sandbox. To choose between them and learn what reaches Anthropic with each, see [Choosing an agent environment](https://platform.claude.com/docs/en/managed-agents/choosing-an-environment).
4444 
4545If you use a [self-hosted sandbox](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes), keep these four points in mind:
4646 
from line 53
5353 
5454## Limit the network
5555 
56Set `networking.type` to `limited` and list only the hosts the agent needs in `allowed_hosts`. An environment create request that omits `networking` might get `unrestricted`, so set `networking` in every create request. See [Risks of unrestricted networking](https://platform.claude.com/docs/en/managed-agents/environments#risks-of-unrestricted-networking).
56Use `limited` networking and list only the hosts the agent needs in `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`). An environment create request that omits `networking` (csharp, go: `Networking`) might get `unrestricted`, so set `networking` (csharp, go: `Networking`) in every create request. See [Risks of unrestricted networking](https://platform.claude.com/docs/en/managed-agents/environments#risks-of-unrestricted-networking).
5757 
58Files, memory stores, and GitHub repositories that you attach stay available to the agent regardless of `allowed_hosts`.
58Files, memory stores, and GitHub repositories that you attach stay available to the agent regardless of `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`).
5959 
6060The examples on this page use a support agent. It reads a customer's ticket, looks up the order, reads your help center, and drafts a reply. Your application runs the order lookup, which needs no host, so this environment allows one host, the help center, for `web_fetch`:
6161 
from line 201
201201 
202202A `limited` environment has three networking settings:
203203 
204| Setting | What it opens to code in the sandbox | Recommended |
205| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
206| `allowed_hosts` | The hosts you list, for any request | Only the hosts the agent needs, including the host of each MCP server you operate or trust |
207| `allow_package_managers` | The [package manager hosts](https://platform.claude.com/docs/en/managed-agents/environments#package-manager-hosts). They include every repository and path on `github.com`, `gitlab.com`, and `bitbucket.org`, where anyone can publish content and where code in the sandbox can upload files | `false`, unless the environment's `packages` setting lists packages, which requires `true`. If the agent installs packages while it runs, list only the registry hosts it needs in `allowed_hosts` instead |
208| `allow_mcp_servers` | No host. Managed Agents connects to MCP servers from Anthropic's servers | `false`, with the host of each MCP server you operate or trust listed in `allowed_hosts` |
204| Setting | What it opens to code in the sandbox | Recommended |
205| ----------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
206| `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`) | The hosts you list, for any request | Only the hosts the agent needs, including the host of each MCP server you operate or trust |
207| `allow_package_managers` (java, php: `allowPackageManagers`; csharp, go: `AllowPackageManagers`) | The [package manager hosts](https://platform.claude.com/docs/en/managed-agents/environments#package-manager-hosts). They include every repository and path on `github.com`, `gitlab.com`, and `bitbucket.org`, where anyone can publish content and where code in the sandbox can upload files | `false`, unless the environment's `packages` (csharp, go: `Packages`) setting lists packages, which requires `true`. If the agent installs packages while it runs, list only the registry hosts it needs in `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`) instead |
208| `allow_mcp_servers` (java: `allowMcpServers`; php: `allowMCPServers`; csharp: `AllowMcpServers`; go: `AllowMCPServers`) | No host. Managed Agents connects to MCP servers from Anthropic's servers | `false`, with the host of each MCP server you operate or trust listed in `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`) |
209209 
210The `allow_package_managers` and `allow_mcp_servers` settings add no hosts for web search and web fetch.
210The `allow_package_managers` (java, php: `allowPackageManagers`; csharp, go: `AllowPackageManagers`) and `allow_mcp_servers` (java: `allowMcpServers`; php: `allowMCPServers`; csharp: `AllowMcpServers`; go: `AllowMCPServers`) settings add no hosts for web search and web fetch.
211211 
212Leave `allow_mcp_servers` off, which is the default, and list the host of each MCP server you operate or trust in `allowed_hosts`. Each host you list is also open to code in the sandbox. With `allow_mcp_servers` off, a check at session creation rejects the request if an MCP server's host is not listed. See [Provide authentication at session creation](https://platform.claude.com/docs/en/managed-agents/mcp-connector#provide-authentication-at-session-creation). The same check runs when a session update changes `mcp_servers`.
212Leave `allow_mcp_servers` (java: `allowMcpServers`; php: `allowMCPServers`; csharp: `AllowMcpServers`; go: `AllowMCPServers`) off, which is the default, and list the host of each MCP server you operate or trust in `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`). Each host you list is also open to code in the sandbox. With `allow_mcp_servers` (java: `allowMcpServers`; php: `allowMCPServers`; csharp: `AllowMcpServers`; go: `AllowMCPServers`) off, a check at session creation rejects the request if an MCP server's host is not listed. See [Provide authentication at session creation](https://platform.claude.com/docs/en/managed-agents/mcp-connector#provide-authentication-at-session-creation). The same check runs when a session update changes `mcp_servers` (java, php: `mcpServers`; csharp: `McpServers`; go: `MCPServers`).
213213 
214214<Warning>
215215 Network access is granted for each host, not for each operation. The sandbox can send any request to an allowed host, including uploads such as `git push` and package publishing. It can also use any credential the command supplies, even one that someone hid in text the agent reads.
216216</Warning>
217217 
218When you choose hosts for `allowed_hosts`, follow these two rules:
218When you choose hosts for `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`), follow these two rules:
219219 
220220* List only hosts you operate or trust.
221221* Avoid `*.` wildcards and shared-hosting domains where anyone can publish content.
from line 230
230230 
231231## Keep credentials in vaults
232232 
233Store every secret in a vault. For each environment variable credential, set the injection location to request headers only and list only the hosts the secret is for. Code in the sandbox sees a placeholder instead of the secret. Managed Agents swaps in the real secret only in outgoing HTTPS requests to the hosts the credential allows. So the secret stays out of direct reach of the model, unless a service sends it back, such as an endpoint that echoes request headers. If the credential's `networking` is `unrestricted`, Managed Agents swaps in the real secret in requests to any host the environment lets the sandbox reach. To use a vault, pass its ID in `vault_ids` when you create the session or deployment.
233Store every secret in a vault. For each environment variable credential, set the injection location to request headers only and list only the hosts the secret is for. Code in the sandbox sees a placeholder instead of the secret. Managed Agents swaps in the real secret only in outgoing HTTPS requests to the hosts the credential allows. So the secret stays out of direct reach of the model, unless a service sends it back, such as an endpoint that echoes request headers. If the credential's `networking` (csharp, go: `Networking`) is `unrestricted`, Managed Agents swaps in the real secret in requests to any host the environment lets the sandbox reach. To use a vault, pass its ID in `vault_ids` (java: `vaultIds`; php: `vaultIDs`; csharp: `VaultIds`; go: `VaultIDs`) when you create the session or deployment.
234234 
235| Setting | Set it to | Why | What it does not do |
236| --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
237| `injection_location` | `{"header": true, "body": false}`, after you check that the service reads the key from a header | Request bodies are often built from content the agent reads, so a key in a body is more exposed. Name both fields: a create request that omits the object enables both locations, and an update changes only the fields you send | Code can still use the key on every host the credential allows. A service that expects the key in the body receives the placeholder and rejects the request |
238| `networking` on the credential | `limited`, with the exact hosts the key is for | Responses reach the sandbox unredacted, so avoid wildcards, shared-hosting domains, and hosts that echo request headers | It does not open the host. The environment must also allow it |
239| The key's permissions, at the service that issued the key | Only the permissions the agent needs | The agent can do anything the key allows | Not applicable |
240| A mounted repository's GitHub token | A [fine-grained token](https://platform.claude.com/docs/en/managed-agents/github#token-permissions) with the minimum permissions | Code in the sandbox can fetch from and push to the mounted repository with it for the whole session. Grant write access only if the agent must push | Not applicable |
235| Setting | Set it to | Why | What it does not do |
236| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
237| `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) | `{"header": true, "body": false}`, after you check that the service reads the key from a header | Request bodies are often built from content the agent reads, so a key in a body is more exposed. Name both fields: a create request that omits the object enables both locations, and an update changes only the fields you send | Code can still use the key on every host the credential allows. A service that expects the key in the body receives the placeholder and rejects the request |
238| `networking` (csharp, go: `Networking`) on the credential | `limited`, with the exact hosts the key is for | Responses reach the sandbox unredacted, so avoid wildcards, shared-hosting domains, and hosts that echo request headers | It does not open the host. The environment must also allow it |
239| The key's permissions, at the service that issued the key | Only the permissions the agent needs | The agent can do anything the key allows | Not applicable |
240| A mounted repository's GitHub token | A [fine-grained token](https://platform.claude.com/docs/en/managed-agents/github#token-permissions) with the minimum permissions | Code in the sandbox can fetch from and push to the mounted repository with it for the whole session. Grant write access only if the agent must push | Not applicable |
241241 
242242The support agent needs no vault credential, because your application holds the API key for your order API. If your agent does hold a vault credential, see [Add a credential](https://platform.claude.com/docs/en/managed-agents/vaults#add-a-credential) for the request in every language.
243243 
244Keep keys out of system prompts, agent definitions, and messages. Do not give the agent a Claude API key or Claude API access token. Even when one is in a vault, code in the sandbox can use it to call the Claude API directly. It can do anything that credential allows, such as starting or deleting sessions, or using web search and web fetch. The agent's tool settings, approvals, and budget do not apply to those calls. In a `limited` environment, code can make these calls only if `allowed_hosts` lets the sandbox reach `api.anthropic.com`.
244Keep keys out of system prompts, agent definitions, and messages. Do not give the agent a Claude API key or Claude API access token. Even when one is in a vault, code in the sandbox can use it to call the Claude API directly. It can do anything that credential allows, such as starting or deleting sessions, or using web search and web fetch. The agent's tool settings, approvals, and budget do not apply to those calls. In a `limited` environment, code can make these calls only if `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`) lets the sandbox reach `api.anthropic.com`.
245245 
246246Fetch third-party tokens yourself and store them in the vault. A token that code in the sandbox fetches with a stored secret comes back unredacted.
247247 
from line 251
251251 
252252## Restrict web search and web fetch
253253 
254Set `allowed_domains` on `web_fetch` to the sites the agent needs. Any URL the agent fetches can carry data to the site it points to, so this list is a security control. On `web_search`, set `allowed_domains` to the sites you want results from, so that results come only from sites you trust to be accurate. The list does not stop the search query from reaching the search provider. Search results include text from pages, so the list also limits which sites' text reaches the agent. Set `allowed_domains` on both tools for every type of environment.
254Set `allowed_domains` (java, php: `allowedDomains`; csharp, go: `AllowedDomains`) on `web_fetch` to the sites the agent needs. Any URL the agent fetches can carry data to the site it points to, so this list is a security control. On `web_search`, set `allowed_domains` (java, php: `allowedDomains`; csharp, go: `AllowedDomains`) to the sites you want results from, so that results come only from sites you trust to be accurate. The list does not stop the search query from reaching the search provider. Search results include text from pages, so the list also limits which sites' text reaches the agent. Set `allowed_domains` (java, php: `allowedDomains`; csharp, go: `AllowedDomains`) on both tools for every type of environment.
255255 
256A `blocked_domains` list blocks the hosts you list and their subdomains, and no other host. The same content can still reach the agent from web archives, caches, mirrors, or related domains you did not list. Do not rely on `blocked_domains` for security. Use `allowed_domains` and name the hosts you trust.
256A `blocked_domains` (java, php: `blockedDomains`; csharp, go: `BlockedDomains`) list blocks the hosts you list and their subdomains, and no other host. The same content can still reach the agent from web archives, caches, mirrors, or related domains you did not list. Do not rely on `blocked_domains` (java, php: `blockedDomains`; csharp, go: `BlockedDomains`) for security. Use `allowed_domains` (java, php: `allowedDomains`; csharp, go: `AllowedDomains`) and name the hosts you trust.
257257 
258In a `limited` environment, the `allowed_hosts` list from [Limit the network](https://platform.claude.com/docs/en/managed-agents/secure-deployment#limit-the-network) also limits the web tools. An `unrestricted` environment or a self-hosted sandbox does not limit the web tools.
258In a `limited` environment, the `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`) list from [Limit the network](https://platform.claude.com/docs/en/managed-agents/secure-deployment#limit-the-network) also limits the web tools. An `unrestricted` environment or a self-hosted sandbox does not limit the web tools.
259259 
260260| In a `limited` environment | Result |
261261| ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
from line 272
272272| `allowed_hosts` (environment) | `*.example.com` | Every subdomain | `example.com` |
273273| `allowed_domains` (web tool) | `example.com` | `example.com` and every subdomain | Other domains |
274274 
275If the agent needs a site and all of its subdomains, list both `example.com` and `*.example.com` in `allowed_hosts`, and otherwise list exact hosts. If a tool lists `example.com` and `allowed_hosts` lists only `*.example.com`, the session is created. The check at session creation counts `example.com` as within `*.example.com`, but the tool returns nothing from `example.com` itself. See [Set domain lists on an agent](https://platform.claude.com/docs/en/managed-agents/tools-web-restrictions#set-domain-lists-on-an-agent) for how the two lists match.
275If the agent needs a site and all of its subdomains, list both `example.com` and `*.example.com` in `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`), and otherwise list exact hosts. If a tool lists `example.com` and `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`) lists only `*.example.com`, the session is created. The check at session creation counts `example.com` as within `*.example.com`, but the tool returns nothing from `example.com` itself. See [Set domain lists on an agent](https://platform.claude.com/docs/en/managed-agents/tools-web-restrictions#set-domain-lists-on-an-agent) for how the two lists match.
276276 
277277The `web_fetch` tool also opens only URLs that have already appeared in the session:
278278 
from line 292
292292 
293293In a multiagent session, `web_fetch` opens a URL from another agent only if it reached that agent through a source marked Yes. A custom tool's result from a direct call counts as a source marked Yes. This holds even if Claude wrote its text, for example when the tool repeats its input. A URL can count even when it is written without `https://`, such as `example.com/docs`. The `web_fetch` tool cannot always open a link that shows words instead of its URL, such as "Contact support." If the agent must fetch a URL that has not appeared in the session, send it in a user message.
294294 
295This rule reduces the chance that injected text builds a URL that carries private data. End-user text, search results, fetched pages, and custom tool results can still add URLs, so keep `allowed_domains` set. The Messages API applies a similar rule with a different list of sources. See [URL validation](https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-fetch-tool#url-validation).
295This rule reduces the chance that injected text builds a URL that carries private data. End-user text, search results, fetched pages, and custom tool results can still add URLs, so keep `allowed_domains` (java, php: `allowedDomains`; csharp, go: `AllowedDomains`) set. The Messages API applies a similar rule with a different list of sources. See [URL validation](https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-fetch-tool#url-validation).
296296 
297297A domain list on `web_fetch` does not limit the `bash` tool. [Limit the network](https://platform.claude.com/docs/en/managed-agents/secure-deployment#limit-the-network) as well. See [Domain list rules](https://platform.claude.com/docs/en/managed-agents/tools-web-restrictions#domain-list-rules).
298298 
from line 300
300300 
301301Set `auto` on `bash`, `write`, `edit`, and `web_fetch`, and on MCP tools that only read data. Use `always_ask` instead on a tool if you cannot undo its changes outside the sandbox. Also use it on a tool that should not run just because end-user text you relay asks for it. A [permission policy](https://platform.claude.com/docs/en/managed-agents/permission-policies) determines whether a tool call runs, waits for your approval, or is evaluated by the server.
302302 
303| Tool | Recommended policy | Why |
304| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
305| `read`, `glob`, `grep` | `always_allow` | They read files in the sandbox and change nothing |
306| `bash`, `write`, `edit` | `auto`. Use `always_ask` on a tool if you cannot undo its changes outside the sandbox. Use `always_ask` on `bash` if you relay end-user text | The agent toolset default is `always_allow`, which runs every call without approval |
307| `web_fetch` | `auto` | A URL the agent fetches can carry data to the site it points to |
308| `web_search` | `always_ask` if the agent handles data you would not want sent in a search query. Otherwise `always_allow` | `allowed_domains` limits which sites results come from, not what the query contains |
309| MCP tools that only read data | `auto`, set for each tool in the toolset's `configs` | The toolset default stays `always_ask`, so a tool the MCP server adds later still waits for approval |
310| MCP tools that change data | `always_ask` | This is the MCP toolset default. Keep it |
311| Custom tools | Your code decides whether each call runs | Permission policies do not apply |
303| Tool | Recommended policy | Why |
304| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
305| `read`, `glob`, `grep` | `always_allow` | They read files in the sandbox and change nothing |
306| `bash`, `write`, `edit` | `auto`. Use `always_ask` on a tool if you cannot undo its changes outside the sandbox. Use `always_ask` on `bash` if you relay end-user text | The agent toolset default is `always_allow`, which runs every call without approval |
307| `web_fetch` | `auto` | A URL the agent fetches can carry data to the site it points to |
308| `web_search` | `always_ask` if the agent handles data you would not want sent in a search query. Otherwise `always_allow` | `allowed_domains` (java, php: `allowedDomains`; csharp, go: `AllowedDomains`) limits which sites results come from, not what the query contains |
309| MCP tools that only read data | `auto`, set for each tool in the toolset's `configs` (csharp, go: `Configs`) | The toolset default stays `always_ask`, so a tool the MCP server adds later still waits for approval |
310| MCP tools that change data | `always_ask` | This is the MCP toolset default. Keep it |
311| Custom tools | Your code determines whether each call runs | Permission policies do not apply |
312312 
313313The toolset in [Give the agent the smallest tool set](https://platform.claude.com/docs/en/managed-agents/secure-deployment#give-the-agent-the-smallest-tool-set) applies these policies.
314314 
from line 322
322322 
323323## Give the agent the smallest tool set
324324 
325Set `default_config.enabled` to `false` and [enable only the tools the agent needs](https://platform.claude.com/docs/en/managed-agents/tools#enabling-only-specific-tools). The agent toolset enables all eight built-in tools by default.
325Set `default_config.enabled` (java, php: `defaultConfig.enabled`; csharp, go: `DefaultConfig.Enabled`) to `false` and [enable only the tools the agent needs](https://platform.claude.com/docs/en/managed-agents/tools#enabling-only-specific-tools). The agent toolset enables all eight built-in tools by default.
326326 
327327| Tool | What it does |
328328| ------------------------- | ------------------------------------------------------------------------- |
from line 333
333333 
334334The support agent needs three built-in tools: `read` and `write` for its draft, and `web_fetch` for the help center. It looks up orders through a [custom tool](https://platform.claude.com/docs/en/managed-agents/tools#custom-tools), `lookup_order`, that your application runs. Your application holds the API key for your order API, so the agent needs neither `bash` nor a credential.
335335 
336The following sample limits `web_fetch` to `help.example.com` with `allowed_domains`. It sets `auto` on `write` and `web_fetch`, as [Approve risky actions](https://platform.claude.com/docs/en/managed-agents/secure-deployment#approve-risky-actions) recommends. If a customer's ticket leads the agent to use these tools, the agent can only change files in the sandbox or open help center pages. That is why neither tool needs `always_ask`. The sample also sets `always_ask` in `default_config`, so a tool you enable later without its own policy uses `always_ask`:
336The following sample limits `web_fetch` to `help.example.com` with `allowed_domains` (java, php: `allowedDomains`; csharp, go: `AllowedDomains`). It sets `auto` on `write` and `web_fetch`, as [Approve risky actions](https://platform.claude.com/docs/en/managed-agents/secure-deployment#approve-risky-actions) recommends. If a customer's ticket leads the agent to use these tools, the agent can only change files in the sandbox or open help center pages. That is why neither tool needs `always_ask`. The sample also sets `always_ask` in `default_config` (java, php: `defaultConfig`; csharp, go: `DefaultConfig`), so a tool you enable later without its own policy uses `always_ask`:
337337 
338338<CodeGroup defaultLanguage="CLI">
339339 ```bash cURL
from line 763
763763 ```
764764</CodeGroup>
765765 
766An [agent update](https://platform.claude.com/docs/en/managed-agents/agent-setup#update-semantics) replaces the whole `tools` array, so send every entry you want to keep.
766An [agent update](https://platform.claude.com/docs/en/managed-agents/agent-setup#update-semantics) replaces the whole `tools` (csharp, go: `Tools`) array, so send every entry you want to keep.
767767 
768768An agent update reaches only new sessions, so also check deployments, agents that list this agent, and existing sessions:
769769 
770770* A deployment pins an agent version, so point each deployment at the new one.
771* An agent that lists this one in [`subagents.predefined_agents`](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#list-the-subagents) or `workflows.predefined_agents` keeps the version it pinned, so update that agent too.
772* To tighten a session that already exists, [update that session's tools](https://platform.claude.com/docs/en/managed-agents/session-operations#updating-the-agent-configuration). The session must be `idle`, and the update replaces the whole `tools` array. In a multiagent session, new `allowed_domains` and `blocked_domains` lists on the web tools of the agent the session runs also apply to every other agent. They apply from each agent's next turn. Those agents' enabled tools and permission policies do not change. To change those, update each agent, then start a new session.
771* An agent that lists this one in the [`predefined_agents` (java, php: `predefinedAgents`; csharp, go: `PredefinedAgents`) list of `subagents` (csharp, go: `Subagents`)](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#list-the-subagents) or of `workflows` (csharp, go: `Workflows`) keeps the version it pinned. Update that agent too.
772* To tighten a session that already exists, [update that session's tools](https://platform.claude.com/docs/en/managed-agents/session-operations#updating-the-agent-configuration). The session must be `idle`, and the update replaces the whole `tools` (csharp, go: `Tools`) array. In a multiagent session, new `allowed_domains` (java, php: `allowedDomains`; csharp, go: `AllowedDomains`) and `blocked_domains` (java, php: `blockedDomains`; csharp, go: `BlockedDomains`) lists on the web tools of the agent the session runs also apply to every other agent. They apply from each agent's next turn. Those agents' enabled tools and permission policies do not change. To change those, update each agent, then start a new session.
773773 
774774Limit MCP servers and custom tools to what the agent needs, too:
775775 
776* **MCP servers:** An MCP toolset enables every tool the server exposes by default. Set `default_config.enabled` to `false` and enable named tools, so tools a server adds later stay off. Remove servers the agent does not use. See [MCP connector](https://platform.claude.com/docs/en/managed-agents/mcp-connector#configure-which-mcp-tools-are-available).
776* **MCP servers:** An MCP toolset enables every tool the server exposes by default. Set `default_config.enabled` (java, php: `defaultConfig.enabled`; csharp, go: `DefaultConfig.Enabled`) to `false` and enable named tools, so tools a server adds later stay off. Remove servers the agent does not use. See [MCP connector](https://platform.claude.com/docs/en/managed-agents/mcp-connector#configure-which-mcp-tools-are-available).
777777* **Custom tools:** Your application runs them, and permission policies do not apply. Validate each call's input in your application and limit what the tool can touch.
778778 
779779## Keep untrusted input away from powerful tools
from line 780
780780 
781781Check which tools and credentials an agent holds whenever it reads untrusted input, which is text that someone outside your team can write. This section uses two terms:
782782 
783* **Untrusted input:** Web pages, search results, support tickets, emails, repository files, uploads, MCP server results, and end-user messages that you relay.
784* **Powerful tools:** `bash`, `write`, `edit`, `web_fetch`, `web_search`, MCP tools and custom tools that write or send data, and any tool that uses a credential.
783* **Untrusted input:** Webpages, search results, support tickets, emails, repository files, uploads, MCP server results, and end-user messages that you relay
784* **Powerful tools:** `bash`, `write`, `edit`, `web_fetch`, `web_search`, MCP tools and custom tools that write or send data, and any tool that uses a credential
785785 
786786Text in untrusted input can tell the agent to use a powerful tool it holds. The support agent reads tickets, so it reaches your order API only through the custom tool `lookup_order`. Your application checks that the order belongs to the ticket's sender.
787787 
from line 788
788788| Input the agent reads | Power it also has | Do this |
789789| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
790790| Tickets, emails, or uploads | `bash` with a credential | Replace `bash` with a custom tool that does one thing. If the agent must keep `bash`, approve each call with `always_ask` |
791| Web pages or search results | Writing files or changing records | Turn off the web tools, or limit them to sites you operate or trust |
791| Webpages or search results | Writing files or changing records | Turn off the web tools, or limit them to sites you operate or trust |
792792| MCP results or repository files | MCP tools that write | Keep the MCP toolset on `always_ask`, and enable only the tools the agent needs |
793793| A mounted GitHub repository | Any tool | Mount only repositories you trust. An agent with `read` loads skills from the repository's `.claude/skills` directory as agent instructions, with no review step. See [Load skills from a GitHub repository](https://platform.claude.com/docs/en/managed-agents/skills#load-skills-from-a-github-repository) |
794794| Any untrusted input | Writing to a [memory store](https://platform.claude.com/docs/en/managed-agents/memory#attach-a-memory-store-to-a-session) | Attach the store as `read_only` unless the agent must write. The default is `read_write`, and later sessions read saved text as trusted memory |
from line 803
803803 
804804The split uses three agents:
805805 
806| Agent | Reads | Holds | Passes on |
807| -------------------------------------- | ------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
808| Lead (the agent that the session runs) | Your message, and what the other agents send back | No built-in tools. Its `subagents.predefined_agents` list names the fetcher and the writer | A task to each agent |
809| Fetcher | Web pages and search results | `web_fetch` and `web_search` only, each with `allowed_domains` | Short results, in a format you ask for in its system prompt |
810| Writer | The task from the lead | The tools that write files, run commands, or change records, on `auto` or `always_ask`. No web tools | Its result |
806| Agent | Reads | Holds | Passes on |
807| -------------------------------------- | ------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
808| Lead (the agent that the session runs) | Your message, and what the other agents send back | No built-in tools. The `predefined_agents` (java, php: `predefinedAgents`; csharp, go: `PredefinedAgents`) list of its `subagents` (csharp, go: `Subagents`) names the fetcher and the writer | A task to each agent |
809| Fetcher | Web pages and search results | `web_fetch` and `web_search` only, each with `allowed_domains` (java, php: `allowedDomains`; csharp, go: `AllowedDomains`) | Short results, in a format you ask for in its system prompt |
810| Writer | The task from the lead | The tools that write files, run commands, or change records, on `auto` or `always_ask`. No web tools | Its result |
811811 
812812The fetcher's results are built from untrusted pages, and the lead can pass their text on to the writer. Keep `auto` or `always_ask` on the writer's tools. The fetcher can still send some of what it reads to the sites on its `web_fetch` list, and to the search provider in its queries.
813813 
from line 817
817817 
818818Set a budget when you create each session, and decide in advance how you stop an agent.
819819 
820| Control | What it does |
821| --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
822| Session budget | A cap on spend at public list prices. At the cap, the session and each [thread](https://platform.claude.com/docs/en/managed-agents/session-threads) pause. Requests in progress can finish and their tool calls still run, so spend can pass the cap. See [When a session reaches its budget](https://platform.claude.com/docs/en/managed-agents/budgets#when-a-session-reaches-its-budget) |
823| Deployment budget | The same cap, applied to each session a deployment starts |
824| [`user.interrupt` event](https://platform.claude.com/docs/en/managed-agents/events-and-streaming#interrupt-the-agent) | Stops the model response immediately. A running tool call can finish first. The session goes `idle`, unless a workflow run keeps it `running`, and resumes on your next message. An interrupt ends no workflow run |
825| Archive or delete a session | Archiving keeps the history and blocks new events. Deleting removes the record, events, and sandbox |
826| Pause or archive a deployment | Pausing stops new scheduled runs but still allows manual runs. Archiving ends the schedule permanently. Sessions already running keep running |
827| Archive or delete a vault or credential | Removes the secret from running sessions without a restart. Allow for a delay. The sessions keep running, so interrupt them too. A token the agent already fetched with the secret stays in the sandbox |
820| Control | What it does |
821| --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
822| Session budget | A cap on spend at public list prices. At the cap, the session and each [thread](https://platform.claude.com/docs/en/managed-agents/session-threads) pause. Requests in progress can complete and their tool calls still run, so spend can pass the cap. See [When a session reaches its budget](https://platform.claude.com/docs/en/managed-agents/budgets#when-a-session-reaches-its-budget) |
823| Deployment budget | The same cap, applied to each session a deployment starts |
824| [`user.interrupt` event](https://platform.claude.com/docs/en/managed-agents/events-and-streaming#interrupt-the-agent) | Stops the model response immediately. A running tool call can complete first. The session goes `idle`, unless a workflow run keeps it `running`, and resumes on your next message. An interrupt ends no workflow run |
825| Archive or delete a session | Archiving keeps the history and blocks new events. Deleting removes the record, events, and sandbox |
826| Pause or archive a deployment | Pausing stops new scheduled runs but still allows manual runs. Archiving ends the schedule permanently. Sessions already running keep running |
827| Archive or delete a vault or credential | Removes the secret from running sessions without a restart. Allow for a delay. The sessions keep running, so interrupt them too. A token the agent already fetched with the secret stays in the sandbox |
828828 
829829To stop a running agent, follow these steps:
830830 
from line 837
837837 
838838An interrupt does not undo what the agent already did or sent. Archiving an agent does not stop its running sessions.
839839 
840A budget's `max_list_cost.amount` is a whole number of US cents written as a string, so `"125"` means $1.25. See [Set a budget at session creation](https://platform.claude.com/docs/en/managed-agents/budgets#set-a-budget-at-session-creation).
840A budget's `max_list_cost.amount` (java, php: `maxListCost.amount`; csharp, go: `MaxListCost.Amount`) is a whole number of US cents written as a string, so `"125"` means $1.25. See [Set a budget at session creation](https://platform.claude.com/docs/en/managed-agents/budgets#set-a-budget-at-session-creation).
841841 
842842You cannot add a budget to a session created without one. To change or remove a cap, see [Resume a session at its budget](https://platform.claude.com/docs/en/managed-agents/budgets#resume-a-session-at-its-budget). After you remove a session's cap, you cannot set a new one.
843843 

managed-agents/self-hosted-sandboxes-custom-tools Changed · +4 / -4 lines

from line 10
1010 betaHeader: managed-agents-2026-04-01
1111---
1212 
13[Custom tools](https://platform.claude.com/docs/en/managed-agents/tools#custom-tools) are tools your own code executes: the agent emits an `agent.custom_tool_use` event and waits for a matching `user.custom_tool_result`. Your worker can be that code. Because it runs inside your sandbox, the tool reaches the internal services, credentials, and network egress you configured for the sandbox, and nothing more.
13[Custom tools](https://platform.claude.com/docs/en/managed-agents/tools#custom-tools) are tools your own code runs: the agent emits an `agent.custom_tool_use` event and waits for a matching `user.custom_tool_result`. Your worker can be that code. Because it runs inside your sandbox, the tool reaches the internal services, credentials, and network egress you configured for the sandbox, and nothing more.
1414 
1515The environment key authorizes posting custom tool results, so your Claude API key stays off the worker host.
1616 
from line 781
781781Two cases need extra work:
782782 
783783* **Two servers expose the same tool name:** Define the wrapper yourself under a prefixed name and have it call the server's original tool name.
784* **A generator such as pydantic factors schemas into `$defs`:** Inline those schemas before you declare the tool.
784* **A generator such as Pydantic factors schemas into `$defs`:** Inline those schemas before you declare the tool.
785785 
786786### Tool failures surface as error tool results
787787 
788788When the MCP server reports a tool error, the worker posts an error tool result the model can react to. MCP content with no tool result equivalent, such as audio blocks and resource links, also surfaces as an error.
789789 
790Set a timeout on the MCP client for a faster and clearer failure, as the Python worker example does with `read_timeout_seconds`. See [A wrapped MCP tool call hangs](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes-operations#a-wrapped-mcp-tool-call-hangs) for what happens without one.
790Set a timeout on the MCP client for a faster and clearer failure, as the Python worker example does with `read_timeout_seconds`. See [A wrapped MCP tool call hangs](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes-operations#a-wrapped-mcp-tool-call-hangs) for what occurs without one.
791791 
792792### Wrap only servers you operate or trust
793793 
from line 795
795795 
796796### Permission policies do not apply
797797 
798[Permission policies](https://platform.claude.com/docs/en/managed-agents/permission-policies#custom-tools) govern the built-in and MCP toolsets. The worker executes every wrapped tool call the model makes, so put any approval step in your own tool code.
798[Permission policies](https://platform.claude.com/docs/en/managed-agents/permission-policies#custom-tools) govern the built-in and MCP toolsets. The worker runs every wrapped tool call the model makes, so put any approval step in your own tool code.
799799 

managed-agents/self-hosted-sandboxes-operations Changed · +7 / -7 lines

from line 154
154154 
155155Use `POST /v1/environments/{environment_id}/work/{work_id}/stop` (python, typescript, ruby: `client.beta.environments.work.stop()`; go, csharp: `client.Beta.Environments.Work.Stop()`; java: `client.beta().environments().work().stop()`; php: `$client->beta->environments->work->stop()`; cli: `ant beta:environments:work stop`) to ask the worker handling a specific session to shut it down.
156156 
157By default the work item moves to `stopping`. The worker notices on its next lease heartbeat, cancels the session's in-flight tool call, and confirms the shutdown. The work item then becomes `stopped`.
157By default the work item moves to `stopping`. The worker detects this on its next lease heartbeat, cancels the session's in-flight tool call, and confirms the shutdown. The work item then becomes `stopped`.
158158 
159159Pass `force: true` (python: `force=True`; cli: `--force`) to mark the work item `stopped` immediately instead of waiting for the worker's confirmation.
160160 
from line 299
299299 
300300## Stop workers gracefully
301301 
302A worker that is cancelled while a session runs stops its in-flight work before it exits. If the session has [memory stores](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes-memory) attached, the worker skips the final sync but still uploads changed files and removes the store directories.
302A worker that is canceled while a session runs stops its in-flight work before it exits. If the session has [memory stores](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes-memory) attached, the worker skips the final sync but still uploads changed files and removes the store directories.
303303 
304304A killed process runs no teardown. To stop a worker cleanly:
305305 
from line 346
346346 
347347Without a timeout on the MCP client, a hung call to a [wrapped MCP server](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes-custom-tools#wrap-an-mcp-server-as-custom-tools) becomes an error tool result only when a backstop fires:
348348 
349| SDK | Backstop | Fires after |
350| ---------- | -------------------------------------------------------------- | ---------------------------- |
351| Python | The worker's own tool call limit | About two and a half minutes |
352| TypeScript | The MCP SDK's default request timeout | About a minute |
353| Go | The worker cancels a tool call that outlives its default limit | 120 seconds |
349| SDK | Backstop | Fires after |
350| ---------- | -------------------------------------------------------------- | ----------------- |
351| Python | The worker's own tool call limit | About 2.5 minutes |
352| TypeScript | The MCP SDK's default request timeout | About a minute |
353| Go | The worker cancels a tool call that outlives its default limit | 120 seconds |
354354 

managed-agents/self-hosted-sandboxes-workers Changed · +6 / -6 lines

from line 10
1010 betaHeader: managed-agents-2026-04-01
1111---
1212 
13The [quickstart](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes#quickstart) runs one `ant` CLI worker that polls continuously and runs every session in one process. This page covers the other ways to run a worker and how to choose between them.
13The [quickstart](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes#quickstart) runs one `ant` CLI worker that polls continuously and runs every session in one process. This page covers the other ways to run a worker and how to choose among them.
1414 
1515## Choose a deployment pattern
1616 
from line 161
161161 </Step>
162162 
163163 <Step title="Export the webhook signing key">
164 Along with the environment ID and key from the [quickstart](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes#run-your-first-session), export the webhook signing key on your handler host. The handler uses it to verify incoming payloads.
164 Along with the environment ID and key from [Run your first session](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes#run-your-first-session), export the webhook signing key on your handler host. The handler uses it to verify incoming payloads.
165165 
166166 ```bash
167167 export ANTHROPIC_WEBHOOK_SIGNING_KEY="whsec_..."
from line 169
169169 </Step>
170170 
171171 <Step title="Implement the webhook handler">
172 Invoke the worker when `session.status_run_started` fires. The handler drains the queue and hands each claimed work item to `handle_item()` (typescript: `handleItem()`; go: `HandleItem()`), which downloads skills, executes tool calls, posts results back, and returns.
172 Start the worker when `session.status_run_started` fires. The handler drains the queue and hands each claimed work item to `handle_item()` (typescript: `handleItem()`; go: `HandleItem()`), which downloads skills, runs tool calls, posts results back, and returns.
173173 
174174 <CodeGroup exclude="shell, csharp, java, php, ruby">
175175 <CodeGroupItem>
from line 429
429429 
430430## Run one sandbox per session
431431 
432A poller on the host claims work and calls your script once per work item. The script launches a sandbox for that one session.
432A poller on the host claims work and calls your script once for each work item. The script launches a sandbox for that one session.
433433 
434434<Steps>
435435 <Step title="Build the sandbox image">
from line 493
493493 
494494### Launch sandboxes from the SDK poller
495495 
496To claim work from your own code instead of `ant beta:worker poll --on-work`, use `work.poller()` (go: `environments.NewWorkPoller()`). It polls the queue and gives you each claimed session, and you launch the sandbox:
496To claim work from your own code instead of `ant beta:worker poll --on-work`, use `work.poller()` (typescript: `new WorkPoller()`; go: `environments.NewWorkPoller()`). It polls the queue and gives you each claimed session, and you launch the sandbox:
497497 
498498<CodeGroup exclude="shell, csharp, java, php, ruby">
499499 <CodeGroupItem language="cURL">
from line 801
801801 
8028021. Pass file references, such as an S3 path or commit SHA, in the session's `metadata` field.
8038032. In your spawn script or `--on-work` handler, retrieve the session (`GET /v1/sessions/{session_id}`) and read `metadata`. The claimed work item carries the session ID but not the metadata.
8043. Stage the files into the working directory before tool execution begins.
8043. Stage the files into the working directory before any tool runs.
805805 
806806<CodeGroup>
807807 ```bash cURL

managed-agents/session-observability Changed · +3 / -3 lines

from line 18
1818 
1919The session viewer shows:
2020 
21* **Timeline minimap:** A zoomable overview of the session's activity over time, with one lane per thread in [multiagent](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration) sessions. Select a lane to view that thread, or select a mark to jump to its event.
21* **Timeline minimap:** A zoomable overview of the session's activity over time, with one lane for each thread in [multiagent](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration) sessions. Select a lane to view that thread, or select a mark to jump to its event.
2222* **Transcript:** The conversation grouped by model request, including thinking, tool calls with their inputs and results, and message text as it streams. You can filter the events and copy or download them as JSON.
2323* **Inspector:** A resizable side panel with details about the session, in five tabs.
2424 
from line 97
9797## Debugging tips
9898 
9999* **Check session events:** The session reports errors through [`session.error`](https://platform.claude.com/docs/en/managed-agents/reference#event-types) events.
100* **Review tool results:** Tool execution failures often explain unexpected agent behavior. The Inspector's **Tools** tab shows each tool's failures.
100* **Review tool results:** Tool failures often explain unexpected agent behavior. The Inspector's **Tools** tab shows each tool's failures.
101101* **Use system prompts:** Add logging instructions to the system prompt so the agent summarizes what it did and what it found.
102102* **Troubleshoot previews:** If a stream that opts in to event deltas doesn't behave as you expect, see [Troubleshoot previews](https://platform.claude.com/docs/en/managed-agents/event-deltas#troubleshoot-previews).
103103 
from line 105
105105 
106106<CardGroup cols={2}>
107107 <Card title="Session event stream" icon="lightning" href="https://platform.claude.com/docs/en/managed-agents/events-and-streaming">
108 Send events, stream responses, and interrupt or redirect your session mid-execution.
108 Send events, stream responses, and interrupt or redirect your session while it runs.
109109 </Card>
110110 
111111 <Card title="Session budgets" icon="coins" href="https://platform.claude.com/docs/en/managed-agents/budgets">
Feedback