← Back to daily report

agents-and-tools/tool-use/web-search-tool.md

Changed on 2026-02-17 13:51:08 EST

+31 lines added
-1 lines removed
Visual Diff
# Web search tool¶

---¶

The web search tool gives Claude direct access to real-time web content, allowing it to answer questions with up-to-date information beyond its knowledge cutoff. Claude automatically cites sources from search results as part of its answer.¶

<Note>¶
Please r
The latest web search tool version (`web_search out through our [feedback form](https://forms.gle/sWjBtsrNEY2oKGuE8) to share your experience with the web search tool_20260209`) supports **dynamic filtering** with Claude Opus 4.6 and Sonnet 4.6. Claude can write and execute code to filter search results before they reach the context window, keeping only relevant information and discarding the rest. This leads to more accurate responses while reducing token consumption. The previous tool version (`web_search_20250305`) remains available without dynamic filtering.¶

<Note>¶
This feature is [Zero Data Retention (ZDR)](/docs/en/build-with-claude/zero-data-retention) eligible. When your organization has a ZDR arrangement, data sent through this feature is not stored after the API response is returned
.¶
</Note>¶

## Supported models¶

Web search is available on:¶

- Claude Opus 4.6 (`claude-opus-4-6`)¶
- Claude Opus 4.5 (`claude-opus-4-5-20251101`)¶
- Claude Opus 4.1 (`claude-opus-4-1-20250805`)¶
- Claude Opus 4 (`claude-opus-4-20250514`)¶
- Claude Sonnet 4.6 (`claude-sonnet-4-6`)¶
- Claude Sonnet 4.5 (`claude-sonnet-4-5-20250929`)¶
- Claude Sonnet 4 (`claude-sonnet-4-20250514`)¶
- Claude Sonnet 3.7 ([deprecated](/docs/en/about-claude/model-deprecations)) (`claude-3-7-sonnet-20250219`)¶
- Claude Haiku 4.5 (`claude-haiku-4-5-20251001`)¶
- Claude Haiku 3.5 ([deprecated](/docs/en/about-claude/model-deprecations)) (`claude-3-5-haiku-latest`)¶

## How web search works¶

When you add the web search tool to your API request:¶

1. Claude decides when to search based on the prompt.¶
2. The API executes the searches and provides Claude with the results. This process may repeat multiple times throughout a single request.¶
3. At the end of its turn, Claude provides a final response with cited sources.¶

### Dynamic filtering with Opus 4.6 and Sonnet 4.6¶

Web search is a token-intensive task. With basic web search, Claude needs to pull search results into context, fetch full HTML from multiple websites, and reason over all of it before arriving at an answer. Often, much of this content is irrelevant, which can degrade response quality.¶

With the `web_search_20260209` tool version, Claude can write and execute code to post-process query results. Instead of reasoning over full HTML files, Claude dynamically filters search results before loading them into context, keeping only what's relevant and discarding the rest.¶

Dynamic filtering is particularly effective for:¶
- Searching through technical documentation¶
- Literature review and citation verification¶
- Technical research¶
- Response grounding and verification¶

<Note>¶
Dynamic filtering requires the [code execution tool](/docs/en/agents-and-tools/tool-use/code-execution-tool) to be enabled. The improved web search tool is available on the Claude API and Microsoft Azure. On Google Vertex AI, the basic web search tool (without dynamic filtering) is available.¶
</Note>¶

To enable dynamic filtering, use the `web_search_20260209` tool version with the `code-execution-web-tools-2026-02-09` beta header:¶

<CodeGroup>¶
```bash Shell¶
curl https://api.anthropic.com/v1/messages \¶
--header "x-api-key: $ANTHROPIC_API_KEY" \¶
--header "anthropic-version: 2023-06-01" \¶
--header "anthropic-beta: code-execution-web-tools-2026-02-09" \¶
--header "content-type: application/json" \¶
--data '{¶
"model": "claude-opus-4-6",¶
"max_tokens": 4096,¶
"messages": [¶
{¶
"role": "user",¶
"content": "Search for the current prices of AAPL and GOOGL, then calculate which has a better P/E ratio."¶
}¶
],¶
"tools": [{¶
"type": "web_search_20260209",¶
"name": "web_search"¶
}]¶
}'¶
```¶

```python Python¶
import anthropic¶

client = anthropic.Anthropic()¶

response = client.beta.messages.create(¶
model="claude-opus-4-6",¶
max_tokens=4096,¶
betas=["code-execution-web-tools-2026-02-09"],¶
messages=[¶
{¶
"role": "user",¶
"content": "Search for the current prices of AAPL and GOOGL, then calculate which has a better P/E ratio.",¶
}¶
],¶
tools=[{"type": "web_search_20260209", "name": "web_search"}],¶
)¶
print(response)¶
```¶

```typescript TypeScript¶
import { Anthropic } from "@anthropic-ai/sdk";¶

const anthropic = new Anthropic();¶

async function main() {¶
const response = await anthropic.beta.messages.create({¶
model: "claude-opus-4-6",¶
max_tokens: 4096,¶
betas: ["code-execution-web-tools-2026-02-09"],¶
messages: [¶
{¶
role: "user",¶
content:¶
"Search for the current prices of AAPL and GOOGL, then calculate which has a better P/E ratio."¶
}¶
],¶
tools: [{ type: "web_search_20260209", name: "web_search" }]¶
});¶

console.log(response);¶
}¶

main().catch(console.error);¶
```¶
</CodeGroup>¶

## How to use web search¶

<Note>¶
Your organization's administrator must enable web search in [Console](/settings/privacy).¶
</Note>¶

Provide the web search tool in your API request:¶

<CodeGroup>¶
```bash Shell¶
curl https://api.anthropic.com/v1/messages \¶
--header "x-api-key: $ANTHROPIC_API_KEY" \¶
--header "anthropic-version: 2023-06-01" \¶
--header "content-type: application/json" \¶
--data '{¶
"model": "claude-opus-4-6",¶
"max_tokens": 1024,¶
"messages": [¶
{¶
"role": "user",¶
"content": "What is the weather in NYC?"¶
}¶
],¶
"tools": [{¶
"type": "web_search_20250305",¶
"name": "web_search",¶
"max_uses": 5¶
}]¶
}'¶
```¶

```python Python¶
import anthropic¶

client = anthropic.Anthropic()¶

response = client.messages.create(¶
model="claude-opus-4-6",¶
max_tokens=1024,¶
messages=[{"role": "user", "content": "What's the weather in NYC?"}],¶
tools=[{"type": "web_search_20250305", "name": "web_search", "max_uses": 5}],¶
)¶
print(response)¶
```¶

```typescript TypeScript¶
import { Anthropic } from "@anthropic-ai/sdk";¶

const anthropic = new Anthropic();¶

async function main() {¶
const response = await anthropic.messages.create({¶
model: "claude-opus-4-6",¶
max_tokens: 1024,¶
messages: [¶
{¶
role: "user",¶
content: "What's the weather in NYC?"¶
}¶
],¶
tools: [{¶
type: "web_search_20250305",¶
name: "web_search",¶
max_uses: 5¶
}]¶
});¶

console.log(response);¶
}¶

main().catch(console.error);¶
```¶
</CodeGroup>¶

### Tool definition¶

The web search tool supports the following parameters:¶

```json JSON¶
{¶
"type": "web_search_20250305",¶
"name": "web_search",¶

// Optional: Limit the number of searches per request¶
"max_uses": 5,¶

// Optional: Only include results from these domains¶
"allowed_domains": ["example.com", "trusteddomain.org"],¶

// Optional: Never include results from these domains¶
"blocked_domains": ["untrustedsource.com"],¶

// Optional: Localize search results¶
"user_location": {¶
"type": "approximate",¶
"city": "San Francisco",¶
"region": "California",¶
"country": "US",¶
"timezone": "America/Los_Angeles"¶
}¶
}¶
```¶

#### Max uses¶

The `max_uses` parameter limits the number of searches performed. If Claude attempts more searches than allowed, the `web_search_tool_result` will be an error with the `max_uses_exceeded` error code.¶

#### Domain filtering¶

When using domain filters:¶

- Domains should not include the HTTP/HTTPS scheme (use `example.com` instead of `https://example.com`)¶
- Subdomains are automatically included (`example.com` covers `docs.example.com`)¶
- Specific subdomains restrict results to only that subdomain (`docs.example.com` returns only results from that subdomain, not from `example.com` or `api.example.com`)¶
- Subpaths are supported and match anything after the path (`example.com/blog` matches `example.com/blog/post-1`)¶
- You can use either `allowed_domains` or `blocked_domains`, but not both in the same request.¶

**Wildcard support:**¶

- Only one wildcard (`*`) is allowed per domain entry, and it must appear after the domain part (in the path)¶
- Valid: `example.com/*`, `example.com/*/articles`¶
- Invalid: `*.example.com`, `ex*.com`, `example.com/*/news/*`¶

Invalid domain formats will return an `invalid_tool_input` tool error.¶

<Note>¶
Request-level domain restrictions must be compatible with organization-level domain restrictions configured in the Console. Request-level domains can only further restrict domains, not override or expand beyond the organization-level list. If your request includes domains that conflict with organization settings, the API will return a validation error.¶
</Note>¶

#### Localization¶

The `user_location` parameter allows you to localize search results based on a user's location.¶

- `type`: The type of location (must be `approximate`)¶
- `city`: The city name¶
- `region`: The region or state¶
- `country`: The country¶
- `timezone`: The [IANA timezone ID](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).¶

### Response¶

Here's an example response structure:¶

```json¶
{¶
"role": "assistant",¶
"content": [¶
// 1. Claude's decision to search¶
{¶
"type": "text",¶
"text": "I'll search for when Claude Shannon was born."¶
},¶
// 2. The search query used¶
{¶
"type": "server_tool_use",¶
"id": "srvtoolu_01WYG3ziw53XMcoyKL4XcZmE",¶
"name": "web_search",¶
"input": {¶
"query": "claude shannon birth date"¶
}¶
},¶
// 3. Search results¶
{¶
"type": "web_search_tool_result",¶
"tool_use_id": "srvtoolu_01WYG3ziw53XMcoyKL4XcZmE",¶
"content": [¶
{¶
"type": "web_search_result",¶
"url": "https://en.wikipedia.org/wiki/Claude_Shannon",¶
"title": "Claude Shannon - Wikipedia",¶
"encrypted_content": "EqgfCioIARgBIiQ3YTAwMjY1Mi1mZjM5LTQ1NGUtODgxNC1kNjNjNTk1ZWI3Y...",¶
"page_age": "April 30, 2025"¶
}¶
]¶
},¶
{¶
"text": "Based on the search results, ",¶
"type": "text"¶
},¶
// 4. Claude's response with citations¶
{¶
"text": "Claude Shannon was born on April 30, 1916, in Petoskey, Michigan",¶
"type": "text",¶
"citations": [¶
{¶
"type": "web_search_result_location",¶
"url": "https://en.wikipedia.org/wiki/Claude_Shannon",¶
"title": "Claude Shannon - Wikipedia",¶
"encrypted_index": "Eo8BCioIAhgBIiQyYjQ0OWJmZi1lNm..",¶
"cited_text": "Claude Elwood Shannon (April 30, 1916 – February 24, 2001) was an American mathematician, electrical engineer, computer scientist, cryptographer and i..."¶
}¶
]¶
}¶
],¶
"id": "msg_a930390d3a",¶
"usage": {¶
"input_tokens": 6039,¶
"output_tokens": 931,¶
"server_tool_use": {¶
"web_search_requests": 1¶
}¶
},¶
"stop_reason": "end_turn"¶
}¶
```¶

#### Search results¶

Search results include:¶

- `url`: The URL of the source page¶
- `title`: The title of the source page¶
- `page_age`: When the site was last updated¶
- `encrypted_content`: Encrypted content that must be passed back in multi-turn conversations for citations¶

#### Citations¶

Citations are always enabled for web search, and each `web_search_result_location` includes:¶

- `url`: The URL of the cited source¶
- `title`: The title of the cited source¶
- `encrypted_index`: A reference that must be passed back for multi-turn conversations.¶
- `cited_text`: Up to 150 characters of the cited content¶

The web search citation fields `cited_text`, `title`, and `url` do not count towards input or output token usage.¶

<Note>¶
When displaying API outputs directly to end users, citations must be included to the original source. If you are making modifications to API outputs, including by reprocessing and/or combining them with your own material before displaying them to end users, display citations as appropriate based on consultation with your legal team.¶
</Note>¶

#### Errors¶

When the web search tool encounters an error (such as hitting rate limits), the Claude API still returns a 200 (success) response. The error is represented within the response body using the following structure:¶

```json¶
{¶
"type": "web_search_tool_result",¶
"tool_use_id": "servertoolu_a93jad",¶
"content": {¶
"type": "web_search_tool_result_error",¶
"error_code": "max_uses_exceeded"¶
}¶
}¶
```¶

These are the possible error codes:¶

- `too_many_requests`: Rate limit exceeded¶
- `invalid_input`: Invalid search query parameter¶
- `max_uses_exceeded`: Maximum web search tool uses exceeded¶
- `query_too_long`: Query exceeds maximum length¶
- `unavailable`: An internal error occurred¶

#### `pause_turn` stop reason¶

The response may include a `pause_turn` stop reason, which indicates that the API paused a long-running turn. You may provide the response back as-is in a subsequent request to let Claude continue its turn, or modify the content if you wish to interrupt the conversation.¶

## Prompt caching¶

Web search works with [prompt caching](/docs/en/build-with-claude/prompt-caching). To enable prompt caching, add at least one `cache_control` breakpoint in your request. The system will automatically cache up until the last `web_search_tool_result` block when executing the tool.¶

For multi-turn conversations, set a `cache_control` breakpoint on or after the last `web_search_tool_result` block to reuse cached content.¶

For example, to use prompt caching with web search for a multi-turn conversation:¶

<CodeGroup>¶
```python¶
import anthropic¶

client = anthropic.Anthropic()¶

# First request with web search and cache breakpoint¶
messages = [¶
{"role": "user", "content": "What's the current weather in San Francisco today?"}¶
]¶

response1 = client.messages.create(¶
model="claude-opus-4-6",¶
max_tokens=1024,¶
messages=messages,¶
tools=[¶
{¶
"type": "web_search_20250305",¶
"name": "web_search",¶
"user_location": {¶
"type": "approximate",¶
"city": "San Francisco",¶
"region": "California",¶
"country": "US",¶
"timezone": "America/Los_Angeles",¶
},¶
}¶
],¶
)¶

# Add Claude's response to the conversation¶
messages.append({"role": "assistant", "content": response1.content})¶

# Second request with cache breakpoint after the search results¶
messages.append(¶
{¶
"role": "user",¶
"content": "Should I expect rain later this week?",¶
"cache_control": {"type": "ephemeral"}, # Cache up to this point¶
}¶
)¶

response2 = client.messages.create(¶
model="claude-opus-4-6",¶
max_tokens=1024,¶
messages=messages,¶
tools=[¶
{¶
"type": "web_search_20250305",¶
"name": "web_search",¶
"user_location": {¶
"type": "approximate",¶
"city": "San Francisco",¶
"region": "California",¶
"country": "US",¶
"timezone": "America/Los_Angeles",¶
},¶
}¶
],¶
)¶
# The second response will benefit from cached search results¶
# while still being able to perform new searches if needed¶
print(f"Cache read tokens: {response2.usage.get('cache_read_input_tokens', 0)}")¶
```¶

</CodeGroup>¶

## Streaming¶

With streaming enabled, you'll receive search events as part of the stream. There will be a pause while the search executes:¶

```json¶
event: message_start¶
data: {"type": "message_start", "message": {"id": "msg_abc123", "type": "message"}}¶

event: content_block_start¶
data: {"type": "content_block_start", "index": 0, "content_block": {"type": "text", "text": ""}}¶

// Claude's decision to search¶

event: content_block_start¶
data: {"type": "content_block_start", "index": 1, "content_block": {"type": "server_tool_use", "id": "srvtoolu_xyz789", "name": "web_search"}}¶

// Search query streamed¶
event: content_block_delta¶
data: {"type": "content_block_delta", "index": 1, "delta": {"type": "input_json_delta", "partial_json": "{\"query\":\"latest quantum computing breakthroughs 2025\"}"}}¶

// Pause while search executes¶

// Search results streamed¶
event: content_block_start¶
data: {"type": "content_block_start", "index": 2, "content_block": {"type": "web_search_tool_result", "tool_use_id": "srvtoolu_xyz789", "content": [{"type": "web_search_result", "title": "Quantum Computing Breakthroughs in 2025", "url": "https://example.com"}]}}¶

// Claude's response with citations (omitted in this example)¶
```¶

## Batch requests¶

You can include the web search tool in the [Messages Batches API](/docs/en/build-with-claude/batch-processing). Web search tool calls through the Messages Batches API are priced the same as those in regular Messages API requests.¶

## Usage and pricing¶

Web search usage is charged in addition to token usage:¶

```json¶
"usage": {¶
"input_tokens": 105,¶
"output_tokens": 6039,¶
"cache_read_input_tokens": 7123,¶
"cache_creation_input_tokens": 7345,¶
"server_tool_use": {¶
"web_search_requests": 1¶
}¶
}¶
```¶

Web search is available on the Claude API for **$10 per 1,000 searches**, plus standard token costs for search-generated content. Web search results retrieved throughout a conversation are counted as input tokens, in search iterations executed during a single turn and in subsequent conversation turns.¶

Each web search counts as one use, regardless of the number of results returned. If an error occurs during web search, the web search will not be billed.

Unified Diff

--- a/agents-and-tools/tool-use/web-search-tool.md
+++ b/agents-and-tools/tool-use/web-search-tool.md
@@ -4,8 +4,10 @@
 
 The web search tool gives Claude direct access to real-time web content, allowing it to answer questions with up-to-date information beyond its knowledge cutoff. Claude automatically cites sources from search results as part of its answer.
 
+The latest web search tool version (`web_search_20260209`) supports **dynamic filtering** with Claude Opus 4.6 and Sonnet 4.6. Claude can write and execute code to filter search results before they reach the context window, keeping only relevant information and discarding the rest. This leads to more accurate responses while reducing token consumption. The previous tool version (`web_search_20250305`) remains available without dynamic filtering.
+
 <Note>
-Please reach out through our [feedback form](https://forms.gle/sWjBtsrNEY2oKGuE8) to share your experience with the web search tool.
+This feature is [Zero Data Retention (ZDR)](/docs/en/build-with-claude/zero-data-retention) eligible. When your organization has a ZDR arrangement, data sent through this feature is not stored after the API response is returned.
 </Note>
 
 ## Supported models
@@ -16,6 +18,7 @@
 - Claude Opus 4.5 (`claude-opus-4-5-20251101`)
 - Claude Opus 4.1 (`claude-opus-4-1-20250805`)
 - Claude Opus 4 (`claude-opus-4-20250514`)
+- Claude Sonnet 4.6 (`claude-sonnet-4-6`)
 - Claude Sonnet 4.5 (`claude-sonnet-4-5-20250929`)
 - Claude Sonnet 4 (`claude-sonnet-4-20250514`)
 - Claude Sonnet 3.7 ([deprecated](/docs/en/about-claude/model-deprecations)) (`claude-3-7-sonnet-20250219`)
@@ -29,6 +32,94 @@
 1. Claude decides when to search based on the prompt.
 2. The API executes the searches and provides Claude with the results. This process may repeat multiple times throughout a single request.
 3. At the end of its turn, Claude provides a final response with cited sources.
+
+### Dynamic filtering with Opus 4.6 and Sonnet 4.6
+
+Web search is a token-intensive task. With basic web search, Claude needs to pull search results into context, fetch full HTML from multiple websites, and reason over all of it before arriving at an answer. Often, much of this content is irrelevant, which can degrade response quality.
+
+With the `web_search_20260209` tool version, Claude can write and execute code to post-process query results. Instead of reasoning over full HTML files, Claude dynamically filters search results before loading them into context, keeping only what's relevant and discarding the rest.
+
+Dynamic filtering is particularly effective for:
+- Searching through technical documentation
+- Literature review and citation verification
+- Technical research
+- Response grounding and verification
+
+<Note>
+Dynamic filtering requires the [code execution tool](/docs/en/agents-and-tools/tool-use/code-execution-tool) to be enabled. The improved web search tool is available on the Claude API and Microsoft Azure. On Google Vertex AI, the basic web search tool (without dynamic filtering) is available.
+</Note>
+
+To enable dynamic filtering, use the `web_search_20260209` tool version with the `code-execution-web-tools-2026-02-09` beta header:
+
+<CodeGroup>
+```bash Shell
+curl https://api.anthropic.com/v1/messages \
+    --header "x-api-key: $ANTHROPIC_API_KEY" \
+    --header "anthropic-version: 2023-06-01" \
+    --header "anthropic-beta: code-execution-web-tools-2026-02-09" \
+    --header "content-type: application/json" \
+    --data '{
+        "model": "claude-opus-4-6",
+        "max_tokens": 4096,
+        "messages": [
+            {
+                "role": "user",
+                "content": "Search for the current prices of AAPL and GOOGL, then calculate which has a better P/E ratio."
+            }
+        ],
+        "tools": [{
+            "type": "web_search_20260209",
+            "name": "web_search"
+        }]
+    }'
+```
+
+```python Python
+import anthropic
+
+client = anthropic.Anthropic()
+
+response = client.beta.messages.create(
+    model="claude-opus-4-6",
+    max_tokens=4096,
+    betas=["code-execution-web-tools-2026-02-09"],
+    messages=[
+        {
+            "role": "user",
+            "content": "Search for the current prices of AAPL and GOOGL, then calculate which has a better P/E ratio.",
+        }
+    ],
+    tools=[{"type": "web_search_20260209", "name": "web_search"}],
+)
+print(response)
+```
+
+```typescript TypeScript
+import { Anthropic } from "@anthropic-ai/sdk";
+
+const anthropic = new Anthropic();
+
+async function main() {
+  const response = await anthropic.beta.messages.create({
+    model: "claude-opus-4-6",
+    max_tokens: 4096,
+    betas: ["code-execution-web-tools-2026-02-09"],
+    messages: [
+      {
+        role: "user",
+        content:
+          "Search for the current prices of AAPL and GOOGL, then calculate which has a better P/E ratio."
+      }
+    ],
+    tools: [{ type: "web_search_20260209", name: "web_search" }]
+  });
+
+  console.log(response);
+}
+
+main().catch(console.error);
+```
+</CodeGroup>
 
 ## How to use web search