Follow Discord
Sweep 08 Oct 2026 · 18:53Z Build v2.1.295 516 read Stable v2.1.286 Latest v2.1.295 Next v2.1.295 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One capture · api

One read of Claude Developer Platformapi-20261006T220745Z

24 pages moved out of 754 read.

Pages moved 24 significant first
Pages read 754 in this capture
Captured 22:07 UTC
Corpus hash 923988329fff corpus-hash

What this read moved

1-24 of 24

agents-and-tools/tool-use/web-search-tool Changed · +3 / -3 lines

from line 237
237237 Web search is enabled for your organization unless an administrator has disabled it in the [Claude Console](https://platform.claude.com/settings/capabilities), where they can also restrict which domains it searches. If it's disabled, a request that includes the tool fails with a 400 `invalid_request_error` that says web search is not enabled, rather than an [error code](https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-search-tool#errors) inside a search result.
238238</Note>
239239 
240These organization-level settings in the Claude Console apply to Messages API requests only. [Claude Managed Agents](https://platform.claude.com/docs/en/managed-agents/overview) sessions use only the per-tool `allowed_domains` and `blocked_domains` lists on the agent toolset; see [Restrict web search and web fetch domains](https://platform.claude.com/docs/en/managed-agents/tools#restrict-web-search-and-web-fetch-domains).
240These organization-level settings in the Claude Console apply to Messages API requests only. [Claude Managed Agents](https://platform.claude.com/docs/en/managed-agents/overview) sessions use only the per-tool `allowed_domains` and `blocked_domains` lists on the agent toolset; see [Restrict web search and web fetch domains](https://platform.claude.com/docs/en/managed-agents/tools-web-restrictions).
241241 
242242Provide the web search tool in your API request:
243243 
from line 448
448448 
449449For the full domain filtering rules, see [Domain filtering](https://platform.claude.com/docs/en/agents-and-tools/tool-use/server-tools#domain-filtering) in the Server tools guide.
450450 
451On [Claude Managed Agents](https://platform.claude.com/docs/en/managed-agents/overview), set these fields on the `web_search` entry of the agent toolset; see [Restrict web search and web fetch domains](https://platform.claude.com/docs/en/managed-agents/tools#restrict-web-search-and-web-fetch-domains).
451On [Claude Managed Agents](https://platform.claude.com/docs/en/managed-agents/overview), set these fields on the `web_search` entry of the agent toolset; see [Restrict web search and web fetch domains](https://platform.claude.com/docs/en/managed-agents/tools-web-restrictions).
452452 
453453### Localization
454454 
from line 460
460460* `country`: The two-letter [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code. The API rejects unsupported country codes with a 400 error.
461461* `timezone`: The [IANA timezone ID](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
462462 
463On Claude Managed Agents, the `web_search` entry of the agent toolset accepts a `user_location` object with the same fields. The API rejects an unsupported `country` code with a 400 error when you create or update the agent, or when you create or update a session that supplies the setting. See [Restrict web search and web fetch domains](https://platform.claude.com/docs/en/managed-agents/tools#restrict-web-search-and-web-fetch-domains).
463On Claude Managed Agents, the `web_search` entry of the agent toolset accepts a `user_location` object with the same fields. The API rejects an unsupported `country` code with a 400 error when you create or update the agent, or when you create or update a session that supplies the setting. See the [web tool settings](https://platform.claude.com/docs/en/managed-agents/tools-web-restrictions#settings).
464464 
465465### Response inclusion
466466 

manage-claude/compliance-errors Changed · +40 / -4 lines

### Transcript page too large ### Server busy reading large transcripts

from line 23
2323 
2424On this page, local sessions run on users' machines and remote sessions run in the cloud; see [Retrieve session transcripts](https://platform.claude.com/docs/en/manage-claude/compliance-sessions).
2525 
26Match on the HTTP status code and `error.type`, not on the message string. Messages are stable enough to copy into runbooks but might be reworded over time; the status codes and type values are part of the API contract. A few responses that share a status code and type are told apart by their message; each is called out where it applies.
26Match on the HTTP status code and `error.type`, not on the message string. Messages are stable enough to copy into runbooks but might be reworded over time; the status codes and type values are part of the API contract. A few responses that share a status code and type are told apart by an error code in `error.details.error_code` when the response carries one, and otherwise by their message; each is called out where it applies.
2727 
2828The following table tells you at a glance whether to retry. Each section that follows shows the verbatim error body and the fix.
2929 
3030| Status | Retry? | When |
3131| -------------------------------------------------------------------------------------------------------------------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
32| [400 Bad Request](https://platform.claude.com/docs/en/manage-claude/compliance-errors#400-bad-request) | No | Fix the request, or enable the Compliance API if the message says it is not enabled, then resend. |
32| [400 Bad Request](https://platform.claude.com/docs/en/manage-claude/compliance-errors#400-bad-request) | No | Fix the request, or enable the Compliance API if the message says it is not enabled, then resend. If `error.details.error_code` is `transcript_page_read_limit_exceeded` (the message says a page of a session's transcript is too large to read), do not resend the same request; [Transcript page too large](https://platform.claude.com/docs/en/manage-claude/compliance-errors#transcript-page-too-large) says what to do instead. |
3333| [401 Unauthorized](https://platform.claude.com/docs/en/manage-claude/compliance-errors#401-unauthorized) | No | The key is not recognized, has been deactivated, or has expired; re-enable or replace it, then resend. |
3434| [403 Forbidden](https://platform.claude.com/docs/en/manage-claude/compliance-errors#403-forbidden) | No | Add the missing scope or use the right key type, then resend. |
3535| [404 Not Found](https://platform.claude.com/docs/en/manage-claude/compliance-errors#404-not-found) | Usually no | A message that names a resource means it was deleted or never existed; remove it from your queue. The bare message `Not found` means the request did not authenticate (or the path does not exist), not that a resource is gone; see [Request not authenticated](https://platform.claude.com/docs/en/manage-claude/compliance-errors#request-not-authenticated). The session endpoints add two more cases: on the local session endpoints, the message `Local sessions are not available.` (returned on every call, including the list) means the endpoints are currently unavailable to your parent organization, not that a session is gone; keep your queued IDs and see [Local session not found](https://platform.claude.com/docs/en/manage-claude/compliance-errors#local-session-not-found). A remote session still in `pending` status 404s on its messages endpoint until it starts; see [Remote session not found](https://platform.claude.com/docs/en/manage-claude/compliance-errors#remote-session-not-found). |
from line 40
4040 
4141## 400 Bad Request
4242 
43The request was syntactically valid, but the server rejected a parameter or the Compliance API is not enabled for the organization. Fix the cause named in the message and resend.
43The request was syntactically valid, but the server rejected a parameter or the Compliance API is not enabled for the organization. Fix the cause named in the message and resend. One 400 is different: [Transcript page too large](https://platform.claude.com/docs/en/manage-claude/compliance-errors#transcript-page-too-large), which the local session messages endpoint can return for a page of a very large session even when every parameter is valid; its entry says what to do instead of resending.
4444 
4545### Compliance API not enabled
4646 
from line 128
128128 
129129For the first body, resend the unmodified `next_page` value from the previous response to the endpoint and session that issued it. For an expired cursor, restart without a `page` parameter; the new walk reflects the retention boundary in effect when it starts, so messages that aged out of the retention period in the meantime are no longer returned (see [Retrieve a local session transcript](https://platform.claude.com/docs/en/manage-claude/compliance-sessions#retrieve-a-local-session-transcript)).
130130 
131### Transcript page too large
132 
133**Type:** `invalid_request_error`
134 
135**Error code:** `transcript_page_read_limit_exceeded`, returned in `error.details.error_code`
136 
137```text wrap
138This page of the session's transcript is too large to read, and retrying will not help. If you are reading newest first (order=desc), read this session oldest first instead: omit the order and page parameters, then follow next_page.
139```
140 
141**Cause:** `GET /v1/compliance/apps/sessions/local/{session_id}/messages` can return this error for a page of a very large session. Only this endpoint returns this error. It shares the `invalid_request_error` type with the other 400s, so identify it by its error code, not by the message text, which might be reworded.
142 
143**Fix:** Do not retry the request. If it used `order=desc`, read that session oldest first instead:
144 
145* Restart the session's walk (one pass through its pages; see [Retrieve a local session transcript](https://platform.claude.com/docs/en/manage-claude/compliance-sessions#retrieve-a-local-session-transcript)) without `order` (or with `order=asc`) and without `page`, and follow `next_page` until it is `null`. Messages you already stored from the newest-first read keep the same `id`, so deduplicate on `id`.
146* Set your client's request timeout to at least 5 minutes for this walk.
147* Lowering `limit` is not a reliable way to avoid this error.
148 
149If an oldest-first request returns this error, do not retry it either. Keep the pages you have already read, record the session as incomplete, continue with the rest of your export, and contact your Anthropic representative with the `request-id` response header.
150 
131151## 401 Unauthorized
132152 
133153The request carried a Compliance Access Key (`sk-ant-api01-...`) or Admin API key (`sk-ant-admin01-...`) that does not authenticate. A request that carries no key, or a key of another type, returns [404 Not Found](https://platform.claude.com/docs/en/manage-claude/compliance-errors#request-not-authenticated) instead on every endpoint except organization settings, and a valid key with the wrong scopes returns [403 Forbidden](https://platform.claude.com/docs/en/manage-claude/compliance-errors#403-forbidden).
from line 409
389409 
390410Requests to the Compliance API are limited to **600 requests per minute per [parent organization](https://platform.claude.com/docs/en/manage-claude/compliance-api#how-the-compliance-api-works)**. The limit is one budget shared across every key under the parent (Compliance Access Keys and the Admin API keys of all linked organizations) and across every `/v1/compliance/*` endpoint; the remote session endpoints carry a second request budget on top. For a standalone Claude Console organization, which has no parent organization, the same budget applies to the organization itself and is shared across its Admin API keys. Contact your Anthropic representative if your integration needs a higher limit.
391411 
412One 429 is different: on a very large session, the local session messages endpoint might return [Server busy reading large transcripts](https://platform.claude.com/docs/en/manage-claude/compliance-errors#server-busy-reading-large-transcripts), which is not a rate limit and not a limit on your organization. Its entry, at the end of this section, says how to identify it and what to do.
413 
392414Once your API key authenticates, Compliance API responses report the shared budget through the standard [rate-limit response headers](https://platform.claude.com/docs/en/api/rate-limits#response-headers) so your client can throttle proactively instead of waiting for a 429:
393415 
394416* `anthropic-ratelimit-requests-limit` is the per-minute request budget.
from line 443
421443 
422444Requests that fail authentication (a missing or unrecognized key, or a Claude API key rather than a Compliance Access Key or Admin API key) are rejected before the rate limiter and do not consume quota. A valid key that lacks the endpoint's required scope consumes one quota unit before the 403 is returned.
423445 
424The [local session endpoints](https://platform.claude.com/docs/en/manage-claude/compliance-sessions#retrieve-local-sessions) count only against the shared limit. The [remote session endpoints](https://platform.claude.com/docs/en/manage-claude/compliance-sessions#retrieve-remote-sessions) also carry a second request budget, keyed to your parent organization like the shared limit, on top of it. A 429 from that budget carries a `retry-after` header that is always `1` (a minimum wait, not the actual reset time); any `anthropic-ratelimit-*` headers on that response describe the shared limit rather than this budget, so back off exponentially if the 429 repeats.
446The [local session endpoints](https://platform.claude.com/docs/en/manage-claude/compliance-sessions#retrieve-local-sessions) count only against the shared limit. The [remote session endpoints](https://platform.claude.com/docs/en/manage-claude/compliance-sessions#retrieve-remote-sessions) also carry a second request budget, keyed to your parent organization like the shared limit, on top of it. A 429 from that budget carries a `retry-after` header that is always `1` (a minimum wait, not the actual reset time); any `anthropic-ratelimit-*` headers on that response describe the shared limit rather than this budget, so back off exponentially if the 429 repeats. One 429 comes from no request budget: [Server busy reading large transcripts](https://platform.claude.com/docs/en/manage-claude/compliance-errors#server-busy-reading-large-transcripts), which only the local session messages endpoint returns.
425447 
426448If you poll the [Activity Feed](https://platform.claude.com/docs/en/manage-claude/compliance-activity-feed) on a schedule, budget your aggregate request rate (across all keys, linked organizations, and concurrent workers) below the shared limit. Watch `anthropic-ratelimit-requests-remaining` to slow down before you reach it. See [Design your compliance integration](https://platform.claude.com/docs/en/manage-claude/compliance-integration-patterns#choose-a-feed-consumption-pattern) for choosing between window-polling and cursor-driven ingestion.
449 
450### Server busy reading large transcripts
451 
452**Type:** `rate_limit_error`
453 
454**Error code:** `transcript_read_server_busy`, returned in `error.details.error_code`
455 
456```text wrap
457Too many large session transcripts are being read at once. This is not a limit on your organization. Retry this request after the number of seconds in the retry-after header.
458```
459 
460**Cause:** `GET /v1/compliance/apps/sessions/local/{session_id}/messages` might return this 429 for a page of a very large session. Only this endpoint returns this error, and it might occur with either `order` value. It is not a rate limit and not a limit on your organization: it does not mean you exceeded the shared limit or any other request budget. This error shares the 429 status code and the `rate_limit_error` type with the rate-limit responses, so identify it by its error code, not by the message text, which might be reworded.
461 
462**Fix:** Wait the number of seconds in the `retry-after` header, then send the same request again, unchanged: keep the same `page` value, or none if the request had none. If the retry returns this error again, wait and retry in the same way. If the `retry-after` header is absent, fall back to exponential backoff (start at 1 second, double up to 60 seconds). If this error keeps recurring across runs, contact your Anthropic representative and include the `request-id` response header.
427463 
428464## 500 Internal Server Error
429465 

manage-claude/inference-hooks Changed · +3 / -5 lines

from line 12
1212 
1313Because the hook runs on Anthropic's servers, after the request leaves the client and before the model runs, it applies to every governed request uniformly, with nothing to install or deploy on user devices.
1414 
15There are two hook events. `prompt` fires once per governed inference request, before inference begins. `tool_call` fires when Claude's response contains tool calls, before any of them runs, in organizations that have turned on **Validate tool calls**.
15There are two hook events. `prompt` fires once per governed inference request, before inference begins. `tool_call` fires when Claude's response contains tool calls, before any of them runs, in organizations that have **Validate tool calls** on.
1616 
1717***
1818 
from line 23
23233. Your AI security server evaluates the content and responds with a verdict within the verdict timeout your organization configures (5 seconds by default).
24244. On `allow`, inference proceeds normally. On `deny`, the request is rejected and the user sees a blocked-by-policy message assembled from two parts: the per-request reason your AI security server supplied in the verdict's `deny_reason` field, followed by a standing message your administrators configure (for example, who to contact or where to request an exception). If your administrators haven't configured one, a built-in default directs the user to contact them. Each denial is also recorded in your organization's [Activity Feed](https://platform.claude.com/docs/en/manage-claude/compliance-activity-feed).
2525 
26The following diagram traces one example (a Cowork request where Claude also calls an O365 tool) to illustrate which parts of the flow are hooked. The hooked points are the diagram's steps 1 and 6, where the prompt arrives and the tool result returns; each results in the validation exchange with your AI security server shown in steps 2–3 and 7–8.
26The following diagram traces one example (a Cowork request where Claude also calls an O365 tool) to illustrate which parts of the flow are hooked. The hooked points are the diagram's steps 1, 2, and 3, where the prompt arrives, Claude calls the tool, and the tool result returns. At each one, your AI security server returns a verdict before the flow continues. Step 2 is hooked only with **Validate tool calls** on, and its one verdict covers all the tool calls in a response.
2727 
28![Flow diagram: the AI security server validates both the prompt and the tool result before inference proceeds](https://platform.claude.com/docs/images/inference-hooks-flow.png)
29 
30With **Validate tool calls** on, Claude's tool calls are a third hooked point, which the diagram doesn't show: your AI security server returns one verdict for all the tool calls in a response before any of them runs.
28![Flow diagram: the prompt, the tool call, and the tool result are each checked by the AI security server; the response is not](https://platform.claude.com/docs/images/inference-hooks-flow-2.svg)
3129 
3230A verdict is a small JSON object: `{"action": "allow"}` lets the request proceed, and a deny carries the user-facing reason. For the full verdict schema, see [Return a verdict](https://platform.claude.com/docs/en/manage-claude/inference-hooks-endpoint#return-a-verdict).
3331 

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

from line 416
416416 
417417### Networking
418418 
419The `networking` field controls the sandbox's outbound network access. It does not affect the `web_search` or `web_fetch` tools, which run on Anthropic's servers; to restrict the sites those tools can reach, set `allowed_domains` or `blocked_domains` on the tool's entry in the agent toolset. See [Restrict web search and web fetch domains](https://platform.claude.com/docs/en/managed-agents/tools#restrict-web-search-and-web-fetch-domains).
419The `networking` field controls the sandbox's outbound network access. It does not affect the `web_search` or `web_fetch` tools, which run on Anthropic's servers; to restrict the sites those tools can reach, set `allowed_domains` or `blocked_domains` on the tool's entry in the agent toolset. See [Restrict web search and web fetch domains](https://platform.claude.com/docs/en/managed-agents/tools-web-restrictions).
420420 
421421| Mode | Description |
422422| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
from line 595
595595 
596596When using `limited` networking:
597597 
598* `allowed_hosts` specifies domains the sandbox can reach. Specify bare hostnames or wildcard patterns (such as `*.example.com`). Do not include a URL scheme, port, or path.
598* `allowed_hosts` specifies domains the sandbox can reach. Specify bare hostnames or wildcard patterns (such as `*.example.com`). Do not include a URL scheme, port, or path. A bare hostname matches that exact host: `example.com` does not match `www.example.com`. `*.example.com` matches every subdomain of `example.com`, but not `example.com` itself.
599599* `allow_mcp_servers` allows outbound access to MCP server endpoints configured on the agent, beyond those listed in the `allowed_hosts` array. Defaults to `false`. While it is `false`, session creation fails with a 400 error if the agent declares an MCP server whose host is not in `allowed_hosts`. The same applies to [an agent it can delegate to](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration). To fix it, add the host to `allowed_hosts` or set `allow_mcp_servers` to `true`.
600600* `allow_package_managers` allows outbound access to a set of public package registries and code hosts beyond those listed in the `allowed_hosts` array. See [Package manager hosts](https://platform.claude.com/docs/en/managed-agents/environments#package-manager-hosts) for the list. Defaults to `false`. Set it to `true` whenever the environment specifies `packages`; otherwise the request is rejected with a 400 error, even if the registry hosts are listed in `allowed_hosts`.
601601 
from line 642
642642}
643643```
644644 
645An agent that only uses the `web_search` and `web_fetch` tools does not need `unrestricted` networking if you can list the sites it needs. [Networking](https://platform.claude.com/docs/en/managed-agents/environments#networking) says when `allowed_hosts` applies to those tools. Where it does, list those sites in `allowed_hosts`. Listing them in `web_search`'s `allowed_domains` too makes it search those sites. A host that you add to `allowed_hosts` is also open to the sandbox. To restrict the tools further, see [Restrict web search and web fetch domains](https://platform.claude.com/docs/en/managed-agents/tools#restrict-web-search-and-web-fetch-domains).
645An agent that only uses the `web_search` and `web_fetch` tools does not need `unrestricted` networking if you can list the sites it needs. [Networking](https://platform.claude.com/docs/en/managed-agents/environments#networking) says when `allowed_hosts` applies to those tools. Where it does, list those sites in `allowed_hosts`. Listing them in `web_search`'s `allowed_domains` too makes it search those sites. A host that you add to `allowed_hosts` is also open to the sandbox. To restrict the tools further, see [Restrict web search and web fetch domains](https://platform.claude.com/docs/en/managed-agents/tools-web-restrictions).
646646 
647647Use `unrestricted` only when the agent must reach sites you cannot list in advance. In that case, keep secrets and sensitive files out of the sandbox, and give the agent only the credentials the task needs. Consider setting the `bash` tool's permission policy to `always_ask` or `auto`, and [watch the session's events](https://platform.claude.com/docs/en/managed-agents/events-and-streaming).
648648 

managed-agents/tools Changed · +41 / -452 lines

### Restricting web search and web fetch ### Config entry types in the SDKs ### Restrict web search and web fetch domains #### Domain list rules #### When settings are validated #### Multiagent sessions, outcomes, and mid-session updates #### Differences from the Messages API tools

The two sides of this change are more than 400 edits apart, too far apart to line up, so this is the differ's own diff of it and the words inside a line are not marked.

from line 16
1616 
1717## Available tools
1818 
19The agent toolset includes the following tools. All are enabled by default when you include the toolset in your agent configuration. Each entry in the `configs` array is identified by its `name`, using the values in the Name column, and accepts an optional `type` field with the same value. The `web_search` and `web_fetch` entries accept additional settings; see [Restrict web search and web fetch domains](https://platform.claude.com/docs/en/managed-agents/tools#restrict-web-search-and-web-fetch-domains).
19The agent toolset includes the following tools. All are enabled by default when you include the toolset in the agent configuration.
2020 
2121| Tool | Name | Description |
2222| ---------- | ------------ | ---------------------------------------------- |
from line 33
3333 
3434## Configuring the toolset
3535 
36Enable the full toolset with `agent_toolset_20260401` when creating an agent. Use the `configs` array to disable specific tools or override their settings. Each config entry can also set a `permission_policy` that controls whether the tool's calls run without confirmation, require confirmation, or are evaluated individually by the server. See [Permission policies](https://platform.claude.com/docs/en/managed-agents/permission-policies) for the available policy types.
37 
38Config entries for `web_search` and `web_fetch` also accept domain filters and other web settings; see [Restrict web search and web fetch domains](https://platform.claude.com/docs/en/managed-agents/tools#restrict-web-search-and-web-fetch-domains).
36Enable the full toolset with `agent_toolset_20260401` when creating an agent. Use the `configs` array to disable specific tools or override their settings. Each entry is identified by its `name`, which takes a value from the Name column in [Available tools](https://platform.claude.com/docs/en/managed-agents/tools#available-tools). An entry also accepts an optional `type` field with the same value.
37 
38Each config entry can also set a `permission_policy`. The policy controls whether the tool's calls run without confirmation, require confirmation, or are evaluated individually by the server. See [Permission policies](https://platform.claude.com/docs/en/managed-agents/permission-policies) for the available policy types.
39 
40The following example enables the toolset and disables `web_fetch`:
3941 
4042<CodeGroup defaultLanguage="CLI">
4143 ```bash cURL
from line 206
204206 
205207### Disabling specific tools
206208 
207To disable a tool, set `enabled: false` in its config entry in the toolset object of your agent's `tools` array:
209To disable a tool, set `enabled: false` in its `configs` entry:
208210 
209211```json
210212{
from line 234
232234}
233235```
234236 
235### Restrict web search and web fetch domains
236 
237To control which sites the agent's web tools can reach, set `allowed_domains` (the tool can reach only these hosts) or `blocked_domains` (the tool can never reach these hosts) on the `web_search` and `web_fetch` entries of the toolset's `configs` array. Each tool carries its own list, so `web_search` and `web_fetch` can have different restrictions. A listed domain covers that host and all of its subdomains. At runtime, a `web_fetch` call for a URL that its lists do not permit returns an error result to the agent (`is_error: true` on the `agent.tool_result` event, with content that names the error code `url_not_allowed`), and `web_search` omits results that its lists do not permit.
238 
239The following toolset limits `web_search` to two sites and localizes its results, and blocks one host for `web_fetch` while capping how much fetched content enters the context:
240 
241```json
242{
243 "type": "agent_toolset_20260401",
244 "configs": [
245 {
246 "type": "web_search",
247 "name": "web_search",
248 "allowed_domains": ["docs.example.com", "arxiv.org"],
249 "user_location": {
250 "type": "approximate",
251 "country": "US",
252 "timezone": "America/Los_Angeles"
253 }
254 },
255 {
256 "type": "web_fetch",
257 "name": "web_fetch",
258 "blocked_domains": ["ads.example.com"],
259 "max_content_tokens": 50000
260 }
261 ]
262}
263```
264 
265<Note>
266 In the Python, TypeScript, Go, Java, C#, Ruby, and PHP SDKs, each `configs` entry is typed per tool: a union with one member per built-in tool, discriminated by `type`. `type` is optional when you construct an entry (the server infers it from `name`) and always present on responses. This typing does not change the JSON that an entry serializes to, so a request whose entries set only `name`, `enabled`, and `permission_policy` is valid with or without `type`. In SDKs where you construct entries from typed values rather than plain dictionaries or hashes (Go, Java, C#, and PHP), the element type of `configs` is the union itself: build each entry from its per-tool member type.
267</Note>
268 
269The following request creates an agent with this toolset and prints the `configs` array from the response:
270 
271<CodeGroup defaultLanguage="CLI">
272 ```bash cURL
273 agent=$(curl -fsSL https://api.anthropic.com/v1/agents \
274 -H "x-api-key: $ANTHROPIC_API_KEY" \
275 -H "anthropic-version: 2023-06-01" \
276 -H "anthropic-beta: managed-agents-2026-04-01" \
277 -H "content-type: application/json" \
278 -d @- <<'EOF'
279 {
280 "name": "Research Agent",
281 "model": "claude-opus-5-5",
282 "tools": [
283 {
284 "type": "agent_toolset_20260401",
285 "configs": [
286 {
287 "type": "web_search",
288 "name": "web_search",
289 "allowed_domains": ["docs.example.com", "arxiv.org"],
290 "user_location": {
291 "type": "approximate",
292 "country": "US",
293 "timezone": "America/Los_Angeles"
294 }
295 },
296 {
297 "type": "web_fetch",
298 "name": "web_fetch",
299 "blocked_domains": ["ads.example.com"],
300 "max_content_tokens": 50000
301 }
302 ]
303 }
304 ]
305 }
306 EOF
307 )
308 jq '.tools[0].configs' <<< "$agent"
309 ```
310 
311 <CodeGroupItem>
312 ```bash CLI
313 ant apply agent.md
314 ```
315 
316 <File filename="agent.md">
317 ```markdown
318 ---
319 name: Research Agent
320 model: claude-opus-5-5
321 tools:
322 - type: agent_toolset_20260401
323 configs:
324 - type: web_search
325 name: web_search
326 allowed_domains: [docs.example.com, arxiv.org]
327 user_location:
328 type: approximate
329 country: US
330 timezone: America/Los_Angeles
331 - type: web_fetch
332 name: web_fetch
333 blocked_domains: [ads.example.com]
334 max_content_tokens: 50000
335 ---
336 ```
337 </File>
338 
339 [`ant apply`](https://platform.claude.com/docs/en/cli-sdks-libraries/cli/apply) creates the agent and prints its ID, not the `configs` array.
340 </CodeGroupItem>
341 
342 ```python Python
343 client = Anthropic()
344 
345 agent = client.beta.agents.create(
346 name="Research Agent",
347 model="claude-opus-5-5",
348 tools=[
349 {
350 "type": "agent_toolset_20260401",
351 "configs": [
352 {
353 "name": "web_search",
354 "allowed_domains": ["docs.example.com", "arxiv.org"],
355 "user_location": {
356 "type": "approximate",
357 "country": "US",
358 "timezone": "America/Los_Angeles",
359 },
360 },
361 {
362 "name": "web_fetch",
363 "blocked_domains": ["ads.example.com"],
364 "max_content_tokens": 50_000,
365 },
366 ],
367 }
368 ],
369 )
370 
371 for tool in agent.tools:
372 if tool.type == "agent_toolset_20260401":
373 print(json.dumps([config.to_dict() for config in tool.configs], indent=2))
374 ```
375 
376 ```typescript TypeScript
377 const client = new Anthropic();
378 
379 const agent = await client.beta.agents.create({
380 name: "Research Agent",
381 model: "claude-opus-5-5",
382 tools: [
383 {
384 type: "agent_toolset_20260401",
385 configs: [
386 {
387 name: "web_search",
388 allowed_domains: ["docs.example.com", "arxiv.org"],
389 user_location: {
390 type: "approximate",
391 country: "US",
392 timezone: "America/Los_Angeles"
393 }
394 },
395 {
396 name: "web_fetch",
397 blocked_domains: ["ads.example.com"],
398 max_content_tokens: 50_000
399 }
400 ]
401 }
402 ]
403 });
404 
405 for (const tool of agent.tools) {
406 if (tool.type === "agent_toolset_20260401") {
407 console.log(JSON.stringify(tool.configs, null, 2));
408 }
409 }
410 ```
411 
412 ```csharp C#
413 using Anthropic.Models.Beta.Agents;
414 
415 AnthropicClient client = new();
416 
417 var agent = await client.Beta.Agents.Create(new()
418 {
419 Name = "Research Agent",
420 Model = BetaManagedAgentsModel.ClaudeOpus5_5,
421 Tools =
422 [
423 new BetaManagedAgentsAgentToolset20260401Params
424 {
425 Type = BetaManagedAgentsAgentToolset20260401ParamsType.AgentToolset20260401,
426 Configs =
427 [
428 new BetaManagedAgentsWebSearchToolConfigParams
429 {
430 AllowedDomains = ["docs.example.com", "arxiv.org"],
431 UserLocation = new()
432 {
433 Country = "US",
434 Timezone = "America/Los_Angeles",
435 },
436 },
437 new BetaManagedAgentsWebFetchToolConfigParams
438 {
439 BlockedDomains = ["ads.example.com"],
440 MaxContentTokens = 50_000,
441 },
442 ],
443 },
444 ],
445 });
446 
447 JsonSerializerOptions jsonOptions = new() { WriteIndented = true };
448 foreach (var tool in agent.Tools)
449 {
450 if (tool.TryPickBetaManagedAgentsAgentToolset20260401(out var toolset))
451 {
452 Console.WriteLine(JsonSerializer.Serialize(toolset.Configs, jsonOptions));
453 }
454 }
455 ```
456 
457 ```go Go
458 client := anthropic.NewClient()
459 ctx := context.Background()
460 
461 agent, err := client.Beta.Agents.New(ctx, anthropic.BetaAgentNewParams{
462 Name: "Research Agent",
463 Model: anthropic.BetaManagedAgentsModelConfigParams{
464 ID: anthropic.BetaManagedAgentsModelClaudeOpus5_5,
465 },
466 Tools: []anthropic.BetaAgentNewParamsToolUnion{{
467 OfAgentToolset20260401: &anthropic.BetaManagedAgentsAgentToolset20260401Params{
468 Type: anthropic.BetaManagedAgentsAgentToolset20260401ParamsTypeAgentToolset20260401,
469 Configs: []anthropic.BetaManagedAgentsAgentToolConfigParamsUnion{
470 {OfWebSearch: &anthropic.BetaManagedAgentsWebSearchToolConfigParams{
471 AllowedDomains: []string{"docs.example.com", "arxiv.org"},
472 UserLocation: anthropic.BetaManagedAgentsUserLocationParam{
473 Country: anthropic.String("US"),
474 Timezone: anthropic.String("America/Los_Angeles"),
475 },
476 }},
477 {OfWebFetch: &anthropic.BetaManagedAgentsWebFetchToolConfigParams{
478 BlockedDomains: []string{"ads.example.com"},
479 MaxContentTokens: anthropic.Int(50000),
480 }},
481 },
482 },
483 }},
484 })
485 if err != nil {
486 panic(err)
487 }
488 
489 for _, tool := range agent.Tools {
490 switch toolset := tool.AsAny().(type) {
491 case anthropic.BetaManagedAgentsAgentToolset20260401:
492 configs := make([]json.RawMessage, len(toolset.Configs))
493 for i, config := range toolset.Configs {
494 configs[i] = json.RawMessage(config.RawJSON())
495 }
496 output, err := json.MarshalIndent(configs, "", " ")
497 if err != nil {
498 panic(err)
499 }
500 fmt.Println(string(output))
501 }
502 }
503 ```
504 
505 ```java Java
506 import com.anthropic.models.beta.agents.AgentCreateParams;
507 import com.anthropic.models.beta.agents.BetaManagedAgentsAgentToolset20260401Params;
508 import com.anthropic.models.beta.agents.BetaManagedAgentsModel;
509 import com.anthropic.models.beta.agents.BetaManagedAgentsUserLocation;
510 import com.anthropic.models.beta.agents.BetaManagedAgentsWebFetchToolConfigParams;
511 import com.anthropic.models.beta.agents.BetaManagedAgentsWebSearchToolConfigParams;
512 
513 void main() {
514 var client = AnthropicOkHttpClient.fromEnv();
515 
516 var agent = client.beta().agents().create(AgentCreateParams.builder()
517 .name("Research Agent")
518 .model(BetaManagedAgentsModel.CLAUDE_OPUS_5_5)
519 .addTool(BetaManagedAgentsAgentToolset20260401Params.builder()
520 .type(BetaManagedAgentsAgentToolset20260401Params.Type.AGENT_TOOLSET_20260401)
521 .addConfig(BetaManagedAgentsWebSearchToolConfigParams.builder()
522 .allowedDomains(List.of("docs.example.com", "arxiv.org"))
523 .userLocation(BetaManagedAgentsUserLocation.builder()
524 .country("US")
525 .timezone("America/Los_Angeles")
526 .build())
527 .build())
528 .addConfig(BetaManagedAgentsWebFetchToolConfigParams.builder()
529 .blockedDomains(List.of("ads.example.com"))
530 .maxContentTokens(50_000)
531 .build())
532 .build())
533 .build());
534 
535 for (var tool : agent.tools()) {
536 if (tool.isAgentToolset20260401()) {
537 var configs = tool.asAgentToolset20260401().configs();
538 IO.println(ObjectMappers.jsonMapper().valueToTree(configs));
539 }
540 }
541 }
542 ```
543 
544 ```php PHP
545 use Anthropic\Beta\Agents\BetaManagedAgentsAgentToolset20260401;
546 use Anthropic\Beta\Agents\BetaManagedAgentsAgentToolset20260401Params;
547 use Anthropic\Beta\Agents\BetaManagedAgentsUserLocation;
548 use Anthropic\Beta\Agents\BetaManagedAgentsWebFetchToolConfigParams;
549 use Anthropic\Beta\Agents\BetaManagedAgentsWebSearchToolConfigParams;
550 // ...
551 
552 $client = new Client();
553 
554 $agent = $client->beta->agents->create(
555 name: 'Research Agent',
556 model: 'claude-opus-5-5',
557 tools: [
558 BetaManagedAgentsAgentToolset20260401Params::with(
559 type: 'agent_toolset_20260401',
560 configs: [
561 BetaManagedAgentsWebSearchToolConfigParams::with(
562 allowedDomains: ['docs.example.com', 'arxiv.org'],
563 userLocation: BetaManagedAgentsUserLocation::with(
564 country: 'US',
565 timezone: 'America/Los_Angeles',
566 ),
567 ),
568 BetaManagedAgentsWebFetchToolConfigParams::with(
569 blockedDomains: ['ads.example.com'],
570 maxContentTokens: 50_000,
571 ),
572 ],
573 ),
574 ],
575 );
576 
577 foreach ($agent->tools as $tool) {
578 if ($tool instanceof BetaManagedAgentsAgentToolset20260401) {
579 echo json_encode($tool->configs, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES), PHP_EOL;
580 }
581 }
582 ```
583 
584 ```ruby Ruby
585 client = Anthropic::Client.new
586 
587 agent = client.beta.agents.create(
588 name: "Research Agent",
589 model: "claude-opus-5-5",
590 tools: [
591 {
592 type: :agent_toolset_20260401,
593 configs: [
594 {
595 name: :web_search,
596 allowed_domains: ["docs.example.com", "arxiv.org"],
597 user_location: {type: :approximate, country: "US", timezone: "America/Los_Angeles"}
598 },
599 {
600 name: :web_fetch,
601 blocked_domains: ["ads.example.com"],
602 max_content_tokens: 50_000
603 }
604 ]
605 }
606 ]
607 )
608 
609 case agent.tools.first
610 in Anthropic::Models::Beta::BetaManagedAgentsAgentToolset20260401 => toolset
611 puts JSON.pretty_generate(toolset.configs.map(&:to_h))
612 end
613 ```
614</CodeGroup>
615 
616In the Claude Console, set allowed or blocked domains from the `web_search` and `web_fetch` rows of the **Built-in tools** card on the agent form; set `max_content_tokens` and `user_location` in the **Raw** view of the agent's configuration.
617 
618In addition to `enabled` and `permission_policy`, the web tool entries accept the following settings:
619 
620| Setting | Applies to | Description |
621| -------------------- | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
622| `allowed_domains` | `web_search`, `web_fetch` | The only hosts the tool can reach. Cannot be combined with `blocked_domains` on the same entry. |
623| `blocked_domains` | `web_search`, `web_fetch` | Hosts the tool cannot reach. |
624| `max_content_tokens` | `web_fetch` | Caps the amount of fetched page content included in the context. Must be a positive integer. See [content limits](https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-fetch-tool#content-limits). |
625| `user_location` | `web_search` | Localizes search results. An object with the same fields as the Messages API [`user_location`](https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-search-tool#localization) parameter. |
626 
627<Note>
628 An environment's [`networking`](https://platform.claude.com/docs/en/managed-agents/environments#networking) settings control the sandbox's own outbound traffic. They do not affect `web_search` or `web_fetch`, which run on Anthropic's servers whether the environment is a cloud or self-hosted sandbox. The per-tool `allowed_domains` and `blocked_domains` lists are the way to restrict what these tools can reach.
629</Note>
630 
631<Note>
632 Organization-level web search and web fetch settings in the Claude Console apply to the Messages API and do not apply to Managed Agents sessions. To restrict an agent's web tools, configure `allowed_domains` or `blocked_domains` on its toolset instead.
633</Note>
634 
635#### Domain list rules
636 
637* Set either `allowed_domains` or `blocked_domains` on an entry, not both. An entry that sets both is rejected.
638* Each list holds 1 to 64 domains, each 1 to 255 characters. An empty list is rejected: to apply no restriction, omit the field or send `null`.
639* Each domain is a registrable domain name, or a subdomain of one, written as a plain hostname: ASCII letters, digits, hyphens, underscores, and dots, with no scheme, port, credentials, wildcard, or whitespace, no label that begins or ends with a hyphen, and no path other than the optional `web_search` path suffix described later in this list. Use `example.com`, not `https://example.com`, `example.com:443`, or `*.example.com`. Hostnames are compared without regard to case, and a single trailing `/` is ignored.
640* A listed domain matches that host and its subdomains: `example.com` covers `docs.example.com`, but `docs.example.com` does not cover `example.com` or `api.example.com`. A leading `www.` is a subdomain like any other, so `www.example.com` does not cover `example.com`; list the bare domain to cover both.
641* IP addresses are not accepted in any form, whether IPv4, IPv6, bracketed, or numeric shorthand such as `127.1`. List the site's domain name instead.
642* A bare top-level domain or registry suffix such as `com`, `co.uk`, or `gov.uk` is rejected, and so is a single-label name such as `intranet`. List a full domain such as `example.co.uk`.
643* `localhost` and hosts ending in `.localhost`, `.local`, `.internal`, `.localdomain`, or `.invalid` are rejected.
644* Use the `xn--` (Punycode) form for internationalized domain names; a domain that contains non-ASCII characters is rejected.
645* A `web_fetch` domain cannot include a path: use `example.com`, not `example.com/*`. A `web_search` domain can carry a path suffix such as `example.com/blog`, in which the path cannot contain spaces, `?`, `#`, or any of the characters `$ , | ^ !`. Prefer plain hostnames for `web_search` too, because the search provider matches path suffixes as URL patterns rather than as strict host rules.
646* Duplicate domains within a list are rejected. `www.example.com` and `example.com` count as different domains; see the earlier matching rule for what each covers.
647 
648#### When settings are validated
649 
650Format and limit violations are rejected with a 400 `invalid_request_error` when you [create an agent](https://platform.claude.com/docs/en/managed-agents/agent-setup#create-an-agent) or [update an agent](https://platform.claude.com/docs/en/managed-agents/agent-setup#update-an-agent), and when you create or update a session that supplies `tools`. For example, the message for an entry that sets both lists includes `Only one of allowed_domains or blocked_domains may be set.`, and the message for an empty list includes `allowed_domains: Empty list of domains is ambiguous. Provide at least one domain or null.` The message for a domain that breaks a format rule names its list and zero-based position, for example `allowed_domains.0: IP addresses are not supported; provide a plain hostname like "example.com"`.
651 
652The same requests also reject three settings that depend on the search and fetch providers: a domain in `allowed_domains` that Anthropic's crawler is not permitted to access, a `user_location.country` that the search provider does not support (the message ends in `user_location.country: not a country the search provider supports`), and a `user_location.timezone` that is not a valid IANA name. The session checks the configuration again when it first initializes the tool; if a setting that was accepted earlier is no longer valid at that point, the session emits a [`session.error`](https://platform.claude.com/docs/en/managed-agents/events-and-streaming) event and returns to `idle` without retrying. Fix the setting by [updating the session's tools](https://platform.claude.com/docs/en/managed-agents/session-operations#updating-the-agent-configuration), update the agent as well so that new sessions start with the corrected configuration, then send a new `user.message` to continue.
653 
654#### Multiagent sessions, outcomes, and mid-session updates
655 
656In a [multiagent session](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration), every domain list that applies to a thread is enforced at the same time: an agent in the roster of the coordinator is bound by its own `allowed_domains` and `blocked_domains`, by those of any agent that called it, and by the coordinator's current lists.
657 
658* Allowlists combine to the domains that all of them cover, and blocklists add together, so a roster agent can narrow what a tool reaches but never widen it. For example, a roster agent that sets `blocked_domains` keeps the coordinator's `allowed_domains` and blocks those hosts within it, and a roster agent that sets its own `allowed_domains` can reach only the hosts that both its list and the coordinator's list cover.
659* If the combined allowlists have no domain in common, the tool stays available to that agent but every call fails with a `url_not_allowed` error stating that no domain is permitted, and the tool description tells the model so. Keep each roster agent's allowlist inside the coordinator's to avoid this.
660* `max_content_tokens` and `user_location` are not combined: a thread uses the value from its own tool configuration if set, otherwise from the agent that called it, otherwise from the coordinator's current configuration.
661* A `{"type": "self"}` roster entry has no web settings of its own and follows the coordinator's current settings.
662* The grader in [outcome-driven sessions](https://platform.claude.com/docs/en/managed-agents/define-outcomes) runs without `web_search` and `web_fetch`, regardless of these settings.
663* You can change the lists on an idle session by [updating its tools](https://platform.claude.com/docs/en/managed-agents/session-operations#updating-the-agent-configuration). The new lists apply to the rest of the session; in a multiagent session, every thread applies them from its next turn, while a roster agent's own lists stay as its agent definition set them when the session was created.
664 
665#### Differences from the Messages API tools
666 
667These settings use the same `allowed_domains` and `blocked_domains` vocabulary as [domain filtering](https://platform.claude.com/docs/en/agents-and-tools/tool-use/server-tools#domain-filtering) on the Messages API server tools, with the following differences on Managed Agents:
668 
669* Each list is capped at 64 domains.
670* Domains listed for `web_fetch` cannot include a path.
671* Domains must be ASCII: use the `xn--` (Punycode) form for internationalized domain names. The Messages API accepts Unicode entries, though it recommends against them.
672* `max_uses`, `citations`, and `cache_control` are not available on the toolset.
237### Restricting web search and web fetch
238 
239The `web_search` and `web_fetch` entries also accept domain lists, a cap on fetched content, and a search location. See [Restrict web search and web fetch domains](https://platform.claude.com/docs/en/managed-agents/tools-web-restrictions).
240 
241### Config entry types in the SDKs
242 
243The Python, TypeScript, Go, Java, C#, Ruby, and PHP SDKs type each `configs` entry per tool. The type is a union with one member per built-in tool, discriminated by `type`.
244 
245In Go, Java, C#, and PHP, you construct entries from typed values rather than plain dictionaries or hashes. In those SDKs, the element type of `configs` is the union itself, so build each entry from its per-tool member type.
246 
247You can omit `type` when you construct an entry, because the server infers it from `name`. Responses always include it. This typing does not change the JSON that an entry serializes to. A request whose entries set only `name`, `enabled`, and `permission_policy` is valid with or without `type`.
673248 
674249## Custom tools
675250 
676In addition to built-in tools, you can define custom tools. Custom tools are analogous to [user-defined client tools](https://platform.claude.com/docs/en/agents-and-tools/tool-use/how-tool-use-works#user-defined-tools-client-executed) in the Messages API.
677 
678Each custom tool defines a contract: you specify what operations are available and what they return, and Claude determines when and how to call them. The model never executes anything on its own. It emits a structured request, your code runs the operation, and the result flows back into the conversation. See [Session event stream](https://platform.claude.com/docs/en/managed-agents/events-and-streaming#handling-custom-tool-calls) for how to receive custom tool calls and return results during a session.
679 
680If your sessions run in a self-hosted sandbox, the environment worker can [serve custom tools from your sandbox](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes-custom-tools), including tools that wrap an MCP server inside your network.
251Custom tools are analogous to [user-defined client tools](https://platform.claude.com/docs/en/agents-and-tools/tool-use/how-tool-use-works#user-defined-tools-client-executed) in the Messages API. You specify what operations are available and what they return, and Claude determines when and how to call them.
252 
253Claude does not run a custom tool itself. It emits a structured request, your code runs the operation, and you return the result to the session.
254 
255The following example creates an agent with the built-in toolset and one custom tool, `get_weather`:
681256 
682257<CodeGroup defaultLanguage="CLI">
683258 ```bash cURL
from line 498
923498 ```
924499</CodeGroup>
925500 
926Once you've defined custom tools on the agent, the agent invokes them during a session.
501The agent calls its custom tools during a session. To receive the calls and return results, see [Session event stream](https://platform.claude.com/docs/en/managed-agents/events-and-streaming#handling-custom-tool-calls).
502 
503For sessions that run in a self-hosted sandbox, the environment worker can [serve custom tools from the sandbox](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes-custom-tools). These can include tools that wrap an MCP server inside your network.
927504 
928505### Best practices for custom tool definitions
929506 
930* **Provide extremely detailed descriptions.** This is by far the most important factor in tool performance. Your descriptions should explain what the tool does and when to use it (and when not to). Explain what each parameter means and how it affects the tool's behavior. Call out any important caveats or limitations. The more context you can give Claude about your tools, the better it is at determining when and how to use them. Aim for three to four sentences for each tool description, more if the tool is complex.
931* **Consolidate related operations into fewer tools.** Rather than creating a separate tool for every action (`create_pr`, `review_pr`, `merge_pr`), group them into a single tool with an `action` parameter. Fewer, more capable tools reduce selection ambiguity and make your tool surface easier for Claude to navigate.
507* **Provide extremely detailed descriptions.** This is by far the most important factor in tool performance. The more context you can give Claude about your tools, the better it is at determining when and how to use them. Aim for three to four sentences for each tool description, more if the tool is complex. Your descriptions should cover:
508 
509 * What the tool does
510 * When to use it, and when not to
511 * What each parameter means and how it affects the tool's behavior
512 * Any important caveats or limitations
513 
514* **Consolidate related operations into fewer tools.** Group actions such as `create_pr`, `review_pr`, and `merge_pr` into a single tool with an `action` parameter. Fewer, more capable tools reduce selection ambiguity and make your tool surface easier for Claude to navigate.
515 
932516* **Use meaningful namespacing in tool names.** When your tools span multiple services or resources, prefix names with the resource (for example, `db_query` or `storage_read`). This makes tool selection unambiguous as your library grows.
933* **Design tool responses to return only high-signal information.** Return semantic, stable identifiers (for example, slugs or UUIDs) rather than opaque internal references, and include only the fields Claude needs to determine its next step. Bloated responses waste context and make it harder for Claude to extract what matters.
517 
518* **Design tool responses to return only high-signal information.** Return semantic, stable identifiers (for example, slugs or UUIDs) rather than opaque internal references. Include only the fields Claude needs to determine its next step. Bloated responses waste context and make it harder for Claude to extract what matters.
934519 
935520## Next steps
936521 
937522<CardGroup cols={2}>
523 <Card title="Restrict web search and web fetch domains" icon="shield" href="https://platform.claude.com/docs/en/managed-agents/tools-web-restrictions">
524 Control which sites the web tools can reach, cap fetched content, and localize search results.
525 </Card>
526 
938527 <Card title="MCP connector" icon="link" href="https://platform.claude.com/docs/en/managed-agents/mcp-connector">
939528 Connect MCP servers to your agents for access to external tools and data sources.
940529 </Card>
941530 

managed-agents/tools-web-restrictions New page · 523 lines, new page

## Set domain lists on an agent ## Settings ## When a domain is not permitted ## Domain list rules ### What a listed domain matches ### Domain format ### Path suffixes on web search domains ## Validation errors ### When an accepted setting is no longer valid ## Multiagent and outcome-driven sessions ## Change the lists mid-session ## Differences from the Messages API tools ## Next steps

A whole new page. There's nothing to diff it against, so here is what it says.

---
title: Restrict web search and web fetch domains
url: https://platform.claude.com/docs/en/managed-agents/tools-web-restrictions
description: Control which sites an agent's web search and web fetch tools can reach, cap fetched content, and localize search results.
featureMetadata:
  topic:
    title: Managed Agents
    url: https://platform.claude.com/docs/en/managed-agents/overview
  status: beta
  betaHeader: managed-agents-2026-04-01
---

To control which sites the agent's web tools can reach, set a domain list on the `web_search` and `web_fetch` entries of the [agent toolset](https://platform.claude.com/docs/en/managed-agents/tools#configuring-the-toolset). Each of these `configs` entries takes one of two lists:

* **`allowed_domains`:** The tool can reach only these hosts.
* **`blocked_domains`:** The tool can never reach these hosts.

Each tool carries its own list, so `web_search` and `web_fetch` can have different restrictions.

<Note>
  These per-tool lists are the way to restrict what the web tools can reach. Two other settings do not affect these tools:

  * **Environment networking:** An environment's [`networking`](https://platform.claude.com/docs/en/managed-agents/environments#networking) settings control the sandbox's own outbound traffic. `web_search` and `web_fetch` run on Anthropic's servers, whether the environment is a cloud or self-hosted sandbox.
  * **Organization settings:** Organization-level web search and web fetch settings in the Claude Console apply to the Messages API. They do not apply to Managed Agents sessions.
</Note>

## Set domain lists on an agent

The following example creates an agent that limits `web_search` to two sites and blocks one host for `web_fetch`. It also sets `user_location` and `max_content_tokens`, which [Settings](https://platform.claude.com/docs/en/managed-agents/tools-web-restrictions#settings) describes. The example then prints the `configs` array from the response.

<CodeGroup defaultLanguage="CLI">
  ```bash cURL
  agent=$(curl -fsSL https://api.anthropic.com/v1/agents \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: managed-agents-2026-04-01" \
    -H "content-type: application/json" \
    -d @- <<'EOF'
  {
    "name": "Research Agent",
    "model": "claude-opus-5-5",
    "tools": [
      {
        "type": "agent_toolset_20260401",
        "configs": [
          {
            "type": "web_search",
            "name": "web_search",
            "allowed_domains": ["docs.example.com", "arxiv.org"],
            "user_location": {
              "type": "approximate",
              "country": "US",
              "timezone": "America/Los_Angeles"
            }
          },
          {
            "type": "web_fetch",
            "name": "web_fetch",
            "blocked_domains": ["ads.example.com"],
            "max_content_tokens": 50000
          }
        ]
      }
    ]
  }
  EOF
  )
  jq '.tools[0].configs' <<< "$agent"
  ```

  <CodeGroupItem>
    ```bash CLI
    ant apply agent.md
    ```

    <File filename="agent.md">
      ```markdown
      ---
      name: Research Agent
      model: claude-opus-5-5
      tools:
        - type: agent_toolset_20260401
          configs:
            - type: web_search
              name: web_search
              allowed_domains: [docs.example.com, arxiv.org]
              user_location:
                type: approximate
                country: US
                timezone: America/Los_Angeles
            - type: web_fetch
              name: web_fetch
              blocked_domains: [ads.example.com]
              max_content_tokens: 50000
      ---
      ```
    </File>

    [`ant apply`](https://platform.claude.com/docs/en/cli-sdks-libraries/cli/apply) creates the agent and prints its ID, not the `configs` array.
  </CodeGroupItem>

  ```python Python
  client = Anthropic()

  agent = client.beta.agents.create(
      name="Research Agent",
      model="claude-opus-5-5",
      tools=[
          {
              "type": "agent_toolset_20260401",
              "configs": [
                  {
                      "name": "web_search",
                      "allowed_domains": ["docs.example.com", "arxiv.org"],
                      "user_location": {
                          "type": "approximate",
                          "country": "US",
                          "timezone": "America/Los_Angeles",
                      },
                  },
                  {
                      "name": "web_fetch",
                      "blocked_domains": ["ads.example.com"],
                      "max_content_tokens": 50_000,
                  },
              ],
          }
      ],
  )

  for tool in agent.tools:
      if tool.type == "agent_toolset_20260401":
          print(json.dumps([config.to_dict() for config in tool.configs], indent=2))
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const agent = await client.beta.agents.create({
    name: "Research Agent",
    model: "claude-opus-5-5",
    tools: [
      {
        type: "agent_toolset_20260401",
        configs: [
          {
            name: "web_search",
            allowed_domains: ["docs.example.com", "arxiv.org"],
            user_location: {
              type: "approximate",
              country: "US",
              timezone: "America/Los_Angeles"
            }
          },
          {
            name: "web_fetch",
            blocked_domains: ["ads.example.com"],
            max_content_tokens: 50_000
          }
        ]
      }
    ]
  });

  for (const tool of agent.tools) {
    if (tool.type === "agent_toolset_20260401") {
      console.log(JSON.stringify(tool.configs, null, 2));
    }
  }
  ```

  ```csharp C#
  using Anthropic.Models.Beta.Agents;

  AnthropicClient client = new();

  var agent = await client.Beta.Agents.Create(new()
  {
      Name = "Research Agent",
      Model = BetaManagedAgentsModel.ClaudeOpus5_5,
      Tools =
      [
          new BetaManagedAgentsAgentToolset20260401Params
          {
              Type = BetaManagedAgentsAgentToolset20260401ParamsType.AgentToolset20260401,
              Configs =
              [
                  new BetaManagedAgentsWebSearchToolConfigParams
                  {
                      AllowedDomains = ["docs.example.com", "arxiv.org"],
                      UserLocation = new()
                      {
                          Country = "US",
                          Timezone = "America/Los_Angeles",
                      },
                  },
                  new BetaManagedAgentsWebFetchToolConfigParams
                  {
                      BlockedDomains = ["ads.example.com"],
                      MaxContentTokens = 50_000,
                  },
              ],
          },
      ],
  });

  JsonSerializerOptions jsonOptions = new() { WriteIndented = true };
  foreach (var tool in agent.Tools)
  {
      if (tool.TryPickBetaManagedAgentsAgentToolset20260401(out var toolset))
      {
          Console.WriteLine(JsonSerializer.Serialize(toolset.Configs, jsonOptions));
      }
  }
  ```

  ```go Go
  client := anthropic.NewClient()
  ctx := context.Background()

  agent, err := client.Beta.Agents.New(ctx, anthropic.BetaAgentNewParams{
  	Name: "Research Agent",
  	Model: anthropic.BetaManagedAgentsModelConfigParams{
  		ID: anthropic.BetaManagedAgentsModelClaudeOpus5_5,
  	},
  	Tools: []anthropic.BetaAgentNewParamsToolUnion{{
  		OfAgentToolset20260401: &anthropic.BetaManagedAgentsAgentToolset20260401Params{
  			Type: anthropic.BetaManagedAgentsAgentToolset20260401ParamsTypeAgentToolset20260401,
  			Configs: []anthropic.BetaManagedAgentsAgentToolConfigParamsUnion{
  				{OfWebSearch: &anthropic.BetaManagedAgentsWebSearchToolConfigParams{
  					AllowedDomains: []string{"docs.example.com", "arxiv.org"},
  					UserLocation: anthropic.BetaManagedAgentsUserLocationParam{
  						Country:  anthropic.String("US"),
  						Timezone: anthropic.String("America/Los_Angeles"),
  					},
  				}},
  				{OfWebFetch: &anthropic.BetaManagedAgentsWebFetchToolConfigParams{
  					BlockedDomains:   []string{"ads.example.com"},
  					MaxContentTokens: anthropic.Int(50000),
  				}},
  			},
  		},
  	}},
  })
  if err != nil {
  	panic(err)
  }

  for _, tool := range agent.Tools {
  	switch toolset := tool.AsAny().(type) {
  	case anthropic.BetaManagedAgentsAgentToolset20260401:
  		configs := make([]json.RawMessage, len(toolset.Configs))
  		for i, config := range toolset.Configs {
  			configs[i] = json.RawMessage(config.RawJSON())
  		}
  		output, err := json.MarshalIndent(configs, "", "  ")
  		if err != nil {
  			panic(err)
  		}
  		fmt.Println(string(output))
  	}
  }
  ```

  ```java Java
  import com.anthropic.models.beta.agents.AgentCreateParams;
  import com.anthropic.models.beta.agents.BetaManagedAgentsAgentToolset20260401Params;
  import com.anthropic.models.beta.agents.BetaManagedAgentsModel;
  import com.anthropic.models.beta.agents.BetaManagedAgentsUserLocation;
  import com.anthropic.models.beta.agents.BetaManagedAgentsWebFetchToolConfigParams;
  import com.anthropic.models.beta.agents.BetaManagedAgentsWebSearchToolConfigParams;

  void main() {
      var client = AnthropicOkHttpClient.fromEnv();

      var agent = client.beta().agents().create(AgentCreateParams.builder()
          .name("Research Agent")
          .model(BetaManagedAgentsModel.CLAUDE_OPUS_5_5)
          .addTool(BetaManagedAgentsAgentToolset20260401Params.builder()
              .type(BetaManagedAgentsAgentToolset20260401Params.Type.AGENT_TOOLSET_20260401)
              .addConfig(BetaManagedAgentsWebSearchToolConfigParams.builder()
                  .allowedDomains(List.of("docs.example.com", "arxiv.org"))
                  .userLocation(BetaManagedAgentsUserLocation.builder()
                      .country("US")
                      .timezone("America/Los_Angeles")
                      .build())
                  .build())
              .addConfig(BetaManagedAgentsWebFetchToolConfigParams.builder()
                  .blockedDomains(List.of("ads.example.com"))
                  .maxContentTokens(50_000)
                  .build())
              .build())
          .build());

      for (var tool : agent.tools()) {
          if (tool.isAgentToolset20260401()) {
              var configs = tool.asAgentToolset20260401().configs();
              IO.println(ObjectMappers.jsonMapper().valueToTree(configs));
          }
      }

Cut at 300 lines. The page has the rest.

release-notes/overview Changed · +5 / -1 lines

### October 5, 2026

from line 12
1212 For updates to Claude Code, see the [complete CHANGELOG.md](https://github.com/anthropics/claude-code/blob/main/CHANGELOG.md) in the `claude-code` repository.
1313</Tip>
1414 
15### October 5, 2026
16 
17* We've added `capabilities.thinking.types.disabled` to the [Models API](https://platform.claude.com/docs/en/api/models/list). `GET /v1/models` and `GET /v1/models/{model_id}` now report whether each model accepts `thinking: {type: "disabled"}`, which turns thinking off. See [Using the Models API](https://platform.claude.com/docs/en/models/overview#using-the-models-api).
18 
1519### October 1, 2026
1620 
1721* We've added a `line` field to the [Models API](https://platform.claude.com/docs/en/api/models/list). `GET /v1/models` and `GET /v1/models/{model_id}` now return the model line each model belongs to. Claude Opus 4.5 and Claude Opus 4.6 both report `opus`, for example. Use `line` to group models without parsing their IDs. `line` is `null` for a model that belongs to no line. See [Using the Models API](https://platform.claude.com/docs/en/models/overview#using-the-models-api).
from line 109
105109* The [Files API](https://platform.claude.com/docs/en/build-with-claude/files) is out of beta on the Claude API. Requests to the `/v1/files` endpoints, and Messages API requests that reference an uploaded file, no longer require the `files-api-2025-04-14` beta header. Requests sent without the header use the current response format: [file expiration](https://platform.claude.com/docs/en/build-with-claude/files#file-expiration) (set `expires_in_seconds` when you upload a file; file objects report `expires_at`), and `page` and `next_page` [pagination](https://platform.claude.com/docs/en/api/overview#pagination) plus an `ids[]` filter when you [list files](https://platform.claude.com/docs/en/build-with-claude/files#list-files). `/v1/files` requests that still send the beta header keep working and return the previous response format. To move an existing integration off the header, see [Migrate from `files-api-2025-04-14`](https://platform.claude.com/docs/en/build-with-claude/files#migrate-from-files-api-2025-04-14).
106110* [Agent Skills](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/overview) and the Skills API (`/v1/skills`) are out of beta on the Claude API. Requests no longer require the `skills-2025-10-02` beta header, including Messages API requests that load Skills through the `container` parameter. Requests that still send the header continue to work unchanged. See [Using Agent Skills with the API](https://platform.claude.com/docs/en/build-with-claude/skills-guide). To move an existing integration off the header, see [Migrate from `skills-2025-10-02`](https://platform.claude.com/docs/en/build-with-claude/skills-guide#migrate-from-skills-2025-10-02).
107111* The [Admin API](https://platform.claude.com/docs/en/api/beta/organization) user-management endpoints for **Claude Enterprise** (claude.ai) organizations (members, invites, groups, and custom roles) are out of beta. The `anthropic-beta: ce-user-management-2026-07-13` header is no longer required on group and custom-role requests; requests that still send it are accepted unchanged. See [User management](https://platform.claude.com/docs/en/manage-claude/user-management).
108* You can now restrict which sites a Claude Managed Agents agent's `web_search` and `web_fetch` tools can reach. Set `allowed_domains` or `blocked_domains` on the tool's entry in the `agent_toolset_20260401` `configs` array; `web_fetch` also accepts `max_content_tokens` and `web_search` accepts `user_location`. Each `configs` entry is identified by its `name` and typed by an optional `type`, and requests that pass only `name`, `enabled`, and `permission_policy` continue to work; in the typed SDKs, `configs` entries become per-tool types. See [Restrict web search and web fetch domains](https://platform.claude.com/docs/en/managed-agents/tools#restrict-web-search-and-web-fetch-domains).
112* You can now restrict which sites a Claude Managed Agents agent's `web_search` and `web_fetch` tools can reach. Set `allowed_domains` or `blocked_domains` on the tool's entry in the `agent_toolset_20260401` `configs` array; `web_fetch` also accepts `max_content_tokens` and `web_search` accepts `user_location`. Each `configs` entry is identified by its `name` and typed by an optional `type`, and requests that pass only `name`, `enabled`, and `permission_policy` continue to work; in the typed SDKs, `configs` entries become [per-tool types](https://platform.claude.com/docs/en/managed-agents/tools#config-entry-types-in-the-sdks). See [Restrict web search and web fetch domains](https://platform.claude.com/docs/en/managed-agents/tools-web-restrictions).
109113* Claude Managed Agents sessions that run in a [self-hosted sandbox](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes) can now attach [memory stores](https://platform.claude.com/docs/en/managed-agents/memory). The Python, TypeScript, and Go SDK workers download each attached store into the sandbox at its `mount_path` and sync the agent's changes back to the store. See [Memory stores in self-hosted sandboxes](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes-memory).
110114* The session viewer in the Claude Console has been redesigned with a timeline minimap, a transcript grouped by model request, and an Inspector panel for session details and cost, raw events, per-tool statistics, mounted resources, and per-thread activity. See [Console observability](https://platform.claude.com/docs/en/managed-agents/events-and-streaming#console-observability).
111115 

agents-and-tools/mcp-tunnels/concepts Changed · +2 / -0 lines

from line 46
4646 
4747```mermaid
4848sequenceDiagram
49 accTitle: How a request reaches an MCP server through a tunnel
50 accDescr: cloudflared, the proxy, and the upstream MCP server run inside your network. cloudflared opens an outbound connection on port 7844 to the tunnel edge on the Cloudflare network. The connection stays open, and no inbound port is opened. The Anthropic backend sends an MCP request to the tunnel edge over outer mTLS. The edge carries it over the open connection to cloudflared, which passes it to the proxy on localhost:8080. Inner TLS spans the Anthropic backend to the proxy and terminates at the proxy. The proxy routes the request by hostname to the upstream MCP server. The response returns along the same path, reversed.
4951 participant A as Anthropic<br/>backend
5052 participant E as Tunnel edge<br/>(Cloudflare network)
5153 participant C as cloudflared

agents-and-tools/tool-use/advisor-tool Changed · +2 / -0 lines

from line 10
1010 
1111```mermaid
1212sequenceDiagram
13 accTitle: How the executor model consults the advisor model
14 accDescr: Your application sends a request with the advisor tool to the executor model, which begins the task. The executor emits a server_tool_use block, and Anthropic runs the advisor model server-side. The advisor reads the full transcript and returns strategic guidance in an advisor_tool_result. The executor continues, informed by the advice, and returns the response to your application.
1315 participant U as Your application
1416 participant E as Executor model
1517 participant A as Advisor model

agents-and-tools/tool-use/define-tools Changed · +1 / -1 lines

from line 856
856856This diagram illustrates how each option works:
857857 
858858<Frame>
859 ![Diagram showing the four tool_choice options: auto, any, tool, and none](https://platform.claude.com/docs/images/tool_choice.png)
859 ![Diagram showing the four tool\_choice options: auto, any, tool, and none](https://platform.claude.com/docs/images/tool_choice.png)
860860</Frame>
861861 
862862Note that when you have `tool_choice` as `any` or `tool`, the API prefills the assistant message to force a tool to be used. This means that the models will not emit a natural language response or explanation before `tool_use` content blocks, even if explicitly asked to do so.

agents-and-tools/tool-use/server-tools Changed · +1 / -1 lines

from line 1071
10711071 Unicode characters in domain names can bypass domain filters through homograph attacks: `аmazon.com` (with a Cyrillic `а`) looks identical to `amazon.com` but is a different domain. Use ASCII-only domain names in allow and block lists, and audit existing entries for non-ASCII characters.
10721072</Warning>
10731073 
1074[Claude Managed Agents](https://platform.claude.com/docs/en/managed-agents/overview) uses the same `allowed_domains` and `blocked_domains` fields on the `web_search` and `web_fetch` entries of the agent toolset. On Managed Agents, each list holds at most 64 entries, domains listed for `web_fetch` cannot include a path, and fields specific to the Messages API tools, such as `max_uses`, `citations`, and `cache_control`, are not available. See [Restrict web search and web fetch domains](https://platform.claude.com/docs/en/managed-agents/tools#restrict-web-search-and-web-fetch-domains) for the full rules.
1074[Claude Managed Agents](https://platform.claude.com/docs/en/managed-agents/overview) uses the same `allowed_domains` and `blocked_domains` fields on the `web_search` and `web_fetch` entries of the agent toolset. On Managed Agents, each list holds at most 64 entries, domains listed for `web_fetch` cannot include a path, and fields specific to the Messages API tools, such as `max_uses`, `citations`, and `cache_control`, are not available. See [Domain list rules](https://platform.claude.com/docs/en/managed-agents/tools-web-restrictions#domain-list-rules) for the full rules.
10751075 
10761076Organization-level web search and web fetch settings in the Claude Console apply to Messages API requests only; they do not apply to Managed Agents sessions, which use only the per-tool lists on the agent toolset.
10771077 

agents-and-tools/tool-use/tool-runner Changed · +2 / -0 lines

from line 797
797797 
798798```mermaid
799799sequenceDiagram
800 accTitle: The tool runner loop
801 accDescr: In each iteration, the tool runner sends a request with the current state to the Messages API. It receives the response message and yields it to your code. Your loop body runs, then the tool runner resumes. If the message history is unchanged and there are tool calls, it appends the assistant message and the tool results and continues. If there are none, it exits the loop. If the message history changed, it uses your state unchanged.
800802 participant U as Your code
801803 participant TR as ToolRunner
802804 participant API as Messages API

agents-and-tools/tool-use/web-fetch-tool Changed · +2 / -2 lines

from line 448
448448 
449449For domain filtering with `allowed_domains` and `blocked_domains`, see [Server tools](https://platform.claude.com/docs/en/agents-and-tools/tool-use/server-tools#domain-filtering).
450450 
451On [Claude Managed Agents](https://platform.claude.com/docs/en/managed-agents/overview), set these fields on the `web_fetch` entry of the agent toolset, where each listed domain must be a plain hostname with no path; see [Restrict web search and web fetch domains](https://platform.claude.com/docs/en/managed-agents/tools#restrict-web-search-and-web-fetch-domains).
451On [Claude Managed Agents](https://platform.claude.com/docs/en/managed-agents/overview), set these fields on the `web_fetch` entry of the agent toolset, where each listed domain must be a plain hostname with no path; see [Restrict web search and web fetch domains](https://platform.claude.com/docs/en/managed-agents/tools-web-restrictions).
452452 
453453### Content limits
454454 
from line 458
458458 The `max_content_tokens` parameter limit is approximate. The actual number of input tokens used can vary by a small amount.
459459</Note>
460460 
461On Claude Managed Agents, the `web_fetch` entry of the agent toolset also accepts `max_content_tokens`; see [Restrict web search and web fetch domains](https://platform.claude.com/docs/en/managed-agents/tools#restrict-web-search-and-web-fetch-domains).
461On Claude Managed Agents, the `web_fetch` entry of the agent toolset also accepts `max_content_tokens`; see the [web tool settings](https://platform.claude.com/docs/en/managed-agents/tools-web-restrictions#settings).
462462 
463463### Cache bypass
464464 

build-with-claude/fallback-credit Changed · +1 / -1 lines

from line 14
1414 
1515<Steps>
1616 <Step title="Opt in with the beta header">
17 Send the request that may be refused with the `anthropic-beta: fallback-credit-2026-07-01` header. The `server-side-fallback-2026-07-01` header also grants the same fields, and the earlier `fallback-credit-2026-06-01` header remains accepted and grants the same fields.
17 Send the request that may be refused with the `anthropic-beta: fallback-credit-2026-07-01` header. The `server-side-fallback-2026-07-01` header also grants the same fields, except on Amazon Bedrock and Google Cloud, which return a 400 error for that header. The earlier `fallback-credit-2026-06-01` header remains accepted and grants the same fields.
1818 </Step>
1919 
2020 <Step title="Read two fields from the refusal">

build-with-claude/thinking Changed · +2 / -0 lines

from line 470
470470 
471471Claude Fable 5.1, Claude Mythos 5.1, Claude Fable 5, Claude Mythos 5, Claude Opus 5.5, and Claude Mythos Preview reject `thinking: {type: "disabled"}`. Thinking can't be turned off on these models.
472472 
473To check whether a model accepts `"disabled"` before you send a request, read its `capabilities.thinking.types.disabled.supported` value from the Models API. [Using the Models API](https://platform.claude.com/docs/en/models/overview#using-the-models-api) describes the field.
474 
473475If your model supports only extended thinking (see the [per-model configuration table](https://platform.claude.com/docs/en/build-with-claude/thinking-troubleshooting#supported-models)), configure it with `type: "enabled"` and a `budget_tokens` value instead. The [Extended thinking](https://platform.claude.com/docs/en/build-with-claude/extended-thinking) page covers that configuration. And if any thinking configuration comes back with a 400 error, [Troubleshooting thinking](https://platform.claude.com/docs/en/build-with-claude/thinking-troubleshooting) matches each error message to its fix.
474476 
475477## Reading thinking output

cli-sdks-libraries/middleware Changed · +2 / -0 lines

from line 8
88 
99```mermaid
1010sequenceDiagram
11 accTitle: How a request and its response pass through middleware
12 accDescr: Your code sends the request to Middleware A. Middleware A calls next(request) to pass it to Middleware B, and Middleware B calls next(request) to pass it to the SDK core. The SDK core sends the HTTP request to the Claude API and receives the HTTP response. The response returns through Middleware B, then Middleware A, to your code.
1113 autonumber
1214 participant App as Your code
1315 participant M1 as Middleware A

manage-claude/compliance-sessions Changed · +4 / -0 lines

from line 266
266266 
267267Messages are returned oldest first by default; pass `order=desc` to reverse. Pagination uses the same `page`/`next_page` scheme as the list endpoint, with a `limit` default of 100 and a max of 1,000. A page can end early when the response reaches its size limit, so a page with fewer than `limit` messages does not mean you have reached the end; keep paginating until `next_page` is `null`. Page cursors are bound to the session and sort order they were issued under, and a walk's cursors expire 24 hours after its first page: an expired cursor returns [400 Bad Request](https://platform.claude.com/docs/en/manage-claude/compliance-errors#400-bad-request) telling you to restart without the `page` parameter, and the restarted walk reflects the current retention boundary. A cursor issued for a different session or `order` also returns 400, as an invalid cursor.
268268 
269On a very large session, the messages endpoint can return a 400 for a page, with a message saying that the page is too large to read; see [Transcript page too large](https://platform.claude.com/docs/en/manage-claude/compliance-errors#transcript-page-too-large). Do not retry that request. If it used `order=desc`, read that session oldest first from its first page instead, with no `order` and no `page`, and set your client's request timeout to at least 5 minutes. If an oldest-first page returns the same error, that errors guide entry says what to do.
270 
271On a very large session, the messages endpoint might also return a 429 whose `error.details.error_code` is `transcript_read_server_busy`. It does not mean that your organization exceeded a rate limit. Unlike the 400, retry it: wait the number of seconds in the `retry-after` header, then send the same request again, unchanged (with the same `page` value, if it had one). See [Server busy reading large transcripts](https://platform.claude.com/docs/en/manage-claude/compliance-errors#server-busy-reading-large-transcripts).
272 
269273Each message carries a `role` (`user` or `assistant`) and a `content` array of `text`, `tool_use`, and `tool_result` blocks. It also carries a `model`: on an assistant turn captured from the Claude API this is the model that served the turn, and it is `null` on user messages and on any assistant message whose `provenance` is set, because client-asserted history and synthetic markers were not produced by a model and the serving model is unknown for unavailable content. A `text` block carries `text` and `truncated`. A `tool_use` block carries `id`, `name`, `input`, and `truncated`, where `input` is a JSON-encoded string rather than an object. A `tool_result` block carries `tool_use_id`, `name`, `is_error`, a `content` array of `text` entries, and `truncated`. MCP tool calls and results, and most server tool calls and results, are normalized into these same `tool_use` and `tool_result` shapes; any other block type appears as a `[<block type> content not shown]` placeholder. A message `id` is stable while the turn is retained. Every message reconstructed from the same inference call carries that call's timestamp, so consecutive messages often share a `created_at` value; preserve the returned order rather than re-sorting by timestamp.
270274 
271275Each message also carries a `provenance` field describing how its content was captured. `provenance` is `null` for verified content captured by the Claude API, which is the common case. Otherwise it is an object whose `type` marks the exception:

manage-claude/inference-hooks-configuration Changed · +1 / -1 lines

from line 89
8989 
9090 Turn on **Enforce verdicts** to gate Claude on your AI security server's verdict for every governed prompt, then confirm in the dialog, which restates your failure handling choice. Allow about a minute for the change to reach every Anthropic server; requests already in flight finish under the old setting. Turning it off stops prompts from being sent to your AI security server, again within about a minute; your configuration is kept.
9191 
92 Turn on **Validate tool calls**, below **Enforce verdicts**, and confirm in the dialog, to also send the tool calls in each of Claude's responses to your AI security server and wait for its verdict before they run; see [The tool call frame](https://platform.claude.com/docs/en/manage-claude/inference-hooks-endpoint#the-tool-call-frame). It is off by default. It has no effect while **Enforce verdicts** is off, and a change to it takes about a minute to reach every Anthropic server, as with **Enforce verdicts**. Confirm that your AI security server handles tool call frames before you turn it on.
92 **Validate tool calls**, below **Enforce verdicts**, also sends the tool calls in each of Claude's responses to your AI security server and waits for its verdict before they run; see [The tool call frame](https://platform.claude.com/docs/en/manage-claude/inference-hooks-endpoint#the-tool-call-frame). It is on by default in a new configuration. It has no effect while **Enforce verdicts** is off, and a change to it takes about a minute to reach every Anthropic server, as with **Enforce verdicts**.
9393 </Step>
9494</Steps>
9595 

manage-claude/inference-hooks-endpoint Changed · +1 / -1 lines

from line 158
158158| `User-Agent` | `anthropic-dlp/1` |
159159| `Accept-Encoding` | `identity` |
160160 
161There are two hook events, told apart by the top-level `type` field. The prompt frame is sent once per governed inference request, before inference begins. The tool call frame is sent when a model response contains tool calls, before any of them runs, in organizations that have turned on **Validate tool calls**. Either way, Anthropic waits until your AI security server responds or the verdict timeout elapses.
161There are two hook events, told apart by the top-level `type` field. The prompt frame is sent once per governed inference request, before inference begins. The tool call frame is sent when a model response contains tool calls, before any of them runs, in organizations that have **Validate tool calls** on. Either way, Anthropic waits until your AI security server responds or the verdict timeout elapses.
162162 
163163## The prompt frame
164164 

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

from line 252
252252 
253253## Configure which MCP tools are available
254254 
255The `mcp_toolset` entry supports a `default_config` object and a `configs` array, applied to the tools the MCP server exposes. Each `configs` entry accepts only `name`, `enabled`, and `permission_policy`. Unlike entries in the built-in agent toolset, MCP tool entries do not take a `type` field, and the [web settings](https://platform.claude.com/docs/en/managed-agents/tools#restrict-web-search-and-web-fetch-domains) available on `web_search` and `web_fetch` do not apply to MCP tools. The `name` in each `configs` entry is the bare tool name as reported by the server.
255The `mcp_toolset` entry supports a `default_config` object and a `configs` array, applied to the tools the MCP server exposes. Each `configs` entry accepts only `name`, `enabled`, and `permission_policy`. Unlike entries in the built-in agent toolset, MCP tool entries do not take a `type` field, and the [web settings](https://platform.claude.com/docs/en/managed-agents/tools-web-restrictions#settings) available on `web_search` and `web_fetch` do not apply to MCP tools. The `name` in each `configs` entry is the bare tool name as reported by the server.
256256 
257257By default all tools exposed by the MCP server are enabled. To enable only specific tools, set `default_config.enabled` to `false` and explicitly enable the tools you want:
258258 

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

from line 609
609609 
610610* **System prompt and model:** Same fields, now on the agent definition.
611611* **Custom tools:** Still declared with JSON Schema. Execution moves from inline handling to responding to `agent.custom_tool_use` events. See [Session event stream](https://platform.claude.com/docs/en/managed-agents/events-and-streaming).
612* **Web search and web fetch settings:** Same `allowed_domains`, `blocked_domains`, `max_content_tokens`, and `user_location` fields, now set once on the `web_search` and `web_fetch` entries of the agent toolset's `configs` array instead of on every request. The `max_uses`, `citations`, and `cache_control` fields are not available. See [Restrict web search and web fetch domains](https://platform.claude.com/docs/en/managed-agents/tools#restrict-web-search-and-web-fetch-domains).
612* **Web search and web fetch settings:** Same `allowed_domains`, `blocked_domains`, `max_content_tokens`, and `user_location` fields, now set once on the `web_search` and `web_fetch` entries of the agent toolset's `configs` array instead of on every request. The `max_uses`, `citations`, and `cache_control` fields are not available. See [Differences from the Messages API tools](https://platform.claude.com/docs/en/managed-agents/tools-web-restrictions#differences-from-the-messages-api-tools).
613613* **Context:** You can still inject context through the system prompt, [file resources](https://platform.claude.com/docs/en/managed-agents/files), or [skills](https://platform.claude.com/docs/en/managed-agents/skills).
614614 
615615## From the Claude Agent SDK

managed-agents/session-operations Changed · +1 / -1 lines

from line 25
2525 
2626## Updating the agent configuration
2727 
28You can update a session's `agent.tools` and `agent.mcp_servers`, including permission policies and per-tool web settings such as [domain filters](https://platform.claude.com/docs/en/managed-agents/tools#restrict-web-search-and-web-fetch-domains), mid-session without creating a new agent version. Updates are session-local and do not propagate back to the underlying agent. Updated `allowed_domains` and `blocked_domains` apply to the rest of the session.
28You can update a session's `agent.tools` and `agent.mcp_servers`, including permission policies and per-tool web settings such as [domain filters](https://platform.claude.com/docs/en/managed-agents/tools-web-restrictions#change-the-lists-mid-session), mid-session without creating a new agent version. Updates are session-local and do not propagate back to the underlying agent. Updated `allowed_domains` and `blocked_domains` apply to the rest of the session.
2929 
3030Only the agent's `tools` and `mcp_servers` can change after a session is created. To run a session with `model`, `system`, or `skills` values other than the agent's, use [agent configuration overrides](https://platform.claude.com/docs/en/managed-agents/sessions#override-agent-configuration-for-a-session) when you create the session. The agent's model configuration, including its [`inference_geo`](https://platform.claude.com/docs/en/manage-claude/data-residency) pin, also can't change mid-session: set the pin when you save the agent, or set or clear it for a single session with a `model` override when you create it. The agent's configured `system` field is fixed for the session's lifetime. On models that support it, you can still append system-level guidance mid-session by sending a [`system.message` event](https://platform.claude.com/docs/en/managed-agents/events-and-streaming#sending-system-messages).
3131 

models/fable-5-1/migration-guide Changed · +1 / -1 lines

from line 1506
15061506 
150715072. **Change instructions and tools with mid-conversation system messages:** To change instructions or tools partway through a session, append a [`role: "system"` message](https://platform.claude.com/docs/en/build-with-claude/mid-conversation-system-messages), with `tool_addition` and `tool_removal` blocks for tool changes (beta header `inline-tools-2026-09-15` on the Claude API). A `tool_addition` block can name a tool declared in `tools` at session start or [carry the tool's full definition](https://platform.claude.com/docs/en/build-with-claude/mid-conversation-system-messages#define-tools-in-a-message-beta), so a tool that is unknown at session start doesn't need to be in `tools`. This preserves prompt cache hits on earlier turns and keeps the conversation history append-only. The older `mid-conversation-tool-changes-2026-07-01` header still works for changes that name a tool by reference, on the Claude API, Amazon Bedrock, and Google Cloud. The same message replaces forced `tool_choice` when a specific tool must run on the current turn (see [Breaking changes](https://platform.claude.com/docs/en/models/fable-5-1/migration-guide#fable-5-1-breaking-changes)). For a reminder that applies to one turn only, send it as a separate text-only `role: "system"` message with `clear_at: "next_user_message"` ([turn-scoped system messages](https://platform.claude.com/docs/en/build-with-claude/mid-conversation-system-messages#turn-scoped-system-messages), beta header `mid-conversation-system-clear-at-2026-08-21`) and leave it in the history: it stops rendering after the next user message and costs no tokens once cleared. A message that carries `tool_addition` or `tool_removal` blocks can't be turn-scoped.
15081508 
15093. **Use `fallbacks: "default"` for refusals:** Keep handling `stop_reason: "refusal"` and reading `stop_details.category` before response content. To re-run refused requests on another model automatically, set `fallbacks: "default"` (beta, `server-side-fallback-2026-07-01` header). `"default"` retries a declined request on the model Anthropic recommends for that category. The permitted fallback targets for Claude Fable 5.1 are Claude Opus 4.8 (`claude-opus-4-8`) and Claude Opus 5 (`claude-opus-5`). An explicit `fallbacks` list may name either. The fallback model doesn't receive Claude Fable 5.1's thinking blocks. If you build the retry yourself, [fallback credit](https://platform.claude.com/docs/en/build-with-claude/fallback-credit) applies on the same terms as Claude Fable 5. See [Refusals and fallback](https://platform.claude.com/docs/en/build-with-claude/refusals-and-fallback).
15093. **Use `fallbacks: "default"` for refusals:** Keep handling `stop_reason: "refusal"` and reading `stop_details.category` before response content. To re-run refused requests on another model automatically, set `fallbacks: "default"` (beta, `server-side-fallback-2026-07-01` header). `"default"` retries a declined request on the model Anthropic recommends for that category. The permitted fallback targets for Claude Fable 5.1 are Claude Opus 4.8 (`claude-opus-4-8`) and Claude Opus 5 (`claude-opus-5`). An explicit `fallbacks` list may name either. The fallback model doesn't receive Claude Fable 5.1's thinking blocks. The `fallbacks` parameter isn't available on Amazon Bedrock, Google Cloud, or Microsoft Foundry. On those platforms, use [client-side fallback](https://platform.claude.com/docs/en/build-with-claude/refusals-and-fallback#client-side-fallback) instead. If you build the retry yourself, [fallback credit](https://platform.claude.com/docs/en/build-with-claude/fallback-credit) applies on the same terms as Claude Fable 5. See [Refusals and fallback](https://platform.claude.com/docs/en/build-with-claude/refusals-and-fallback).
15101510 
151115114. **Start at `high` effort and sweep:** The [effort parameter](https://platform.claude.com/docs/en/build-with-claude/effort) default is `high`, and all five levels are supported. Keep the Claude Fable 5 guidance: `high` for most work, and `medium` as a cost control worth testing. Claude Fable 5.1's gains over Claude Fable 5 are largest at `xhigh` and `max`, but those levels also add thinking time and time-to-first-response, so step up to them for the most capability-sensitive tasks and where your evals show the gain. Run a fresh sweep on your own evals rather than carrying over a setting tuned for Claude Fable 5. See [Recommended effort levels for Claude Fable 5.1](https://platform.claude.com/docs/en/build-with-claude/effort#recommended-effort-levels-for-claude-fable-5-1).
15121512 

models/overview Changed · +2 / -0 lines

from line 71
7171 
7272Each model in the response also has a `line` field, which names the model line it belongs to. Claude Opus 4.5 and Claude Opus 4.6 both report `opus`. Use `line` to group models, for example, in a model picker. `line` is `null` when a model belongs to no line. Read `line` instead of inferring it from the model's `id`. Anthropic might add more lines, so don't treat the set of values as fixed.
7373 
74Each model's `capabilities` object includes `thinking.types.disabled`, which reports whether the model accepts `thinking: {type: "disabled"}`, the setting that [turns thinking off](https://platform.claude.com/docs/en/build-with-claude/thinking#turning-thinking-off). `supported` is `false` when the model rejects `"disabled"` with a 400 error, and `true` on a model that doesn't support thinking. Even when `supported` is `true`, the API can still reject a `"disabled"` request for another reason. One such reason is an [effort](https://platform.claude.com/docs/en/build-with-claude/effort) level that the model doesn't allow with thinking off.
75 
7476## Prompt and output performance
7577 
7678Current Claude models excel in:
Feedback