File: search-results.md | Updated: 11/15/2025
Agent Skills are now available! Learn more about extending Claude's capabilities with Agent Skills .
English
Search...
Ctrl K
Search...
Navigation
Capabilities
Search results
Home Developer Guide API Reference Model Context Protocol (MCP) Resources Release Notes
On this page
Search result content blocks enable natural citations with proper source attribution, bringing web search-quality citations to your custom applications. This feature is particularly powerful for RAG (Retrieval-Augmented Generation) applications where you need Claude to cite sources accurately. The search results feature is available on the following models:
claude-opus-4-1-20250805)claude-opus-4-20250514)claude-sonnet-4-5-20250929)claude-sonnet-4-20250514)claude-3-7-sonnet-20250219)claude-3-5-haiku-20241022)Search results can be provided in two ways:
In both cases, Claude can automatically cite information from the search results with proper source attribution.
Search result schema
Search results use the following structure:
Copy
{
"type": "search_result",
"source": "https://example.com/article", // Required: Source URL or identifier
"title": "Article Title", // Required: Title of the result
"content": [ // Required: Array of text blocks\
{\
"type": "text",\
"text": "The actual content of the search result..."\
}\
],
"citations": { // Optional: Citation configuration
"enabled": true // Enable/disable citations for this result
}
}
Required fields
| Field | Type | Description |
| --- | --- | --- |
| type | string | Must be "search_result" |
| source | string | The source URL or identifier for the content |
| title | string | A descriptive title for the search result |
| content | array | An array of text blocks containing the actual content |
Optional fields
| Field | Type | Description |
| --- | --- | --- |
| citations | object | Citation configuration with enabled boolean field |
| cache_control | object | Cache control settings (e.g., {"type": "ephemeral"}) |
Each item in the content array must be a text block with:
type: Must be "text"text: The actual text content (non-empty string)The most powerful use case is returning search results from your custom tools. This enables dynamic RAG applications where tools fetch and return relevant content with automatic citations.
Example: Knowledge base tool
Python
TypeScript
Copy
from anthropic import Anthropic
from anthropic.types import (
MessageParam,
TextBlockParam,
SearchResultBlockParam,
ToolResultBlockParam
)
client = Anthropic()
# Define a knowledge base search tool
knowledge_base_tool = {
"name": "search_knowledge_base",
"description": "Search the company knowledge base for information",
"input_schema": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "The search query"
}
},
"required": ["query"]
}
}
# Function to handle the tool call
def search_knowledge_base(query):
# Your search logic here
# Returns search results in the correct format
return [\
SearchResultBlockParam(\
type="search_result",\
source="https://docs.company.com/product-guide",\
title="Product Configuration Guide",\
content=[\
TextBlockParam(\
type="text",\
text="To configure the product, navigate to Settings > Configuration. The default timeout is 30 seconds, but can be adjusted between 10-120 seconds based on your needs."\
)\
],\
citations={"enabled": True}\
),\
SearchResultBlockParam(\
type="search_result",\
source="https://docs.company.com/troubleshooting",\
title="Troubleshooting Guide",\
content=[\
TextBlockParam(\
type="text",\
text="If you encounter timeout errors, first check the configuration settings. Common causes include network latency and incorrect timeout values."\
)\
],\
citations={"enabled": True}\
)\
]
# Create a message with the tool
response = client.messages.create(
model="claude-sonnet-4-5", # Works with all supported models
max_tokens=1024,
tools=[knowledge_base_tool],
messages=[\
MessageParam(\
role="user",\
content="How do I configure the timeout settings?"\
)\
]
)
# When Claude calls the tool, provide the search results
if response.content[0].type == "tool_use":
tool_result = search_knowledge_base(response.content[0].input["query"])
# Send the tool result back
final_response = client.messages.create(
model="claude-sonnet-4-5", # Works with all supported models
max_tokens=1024,
messages=[\
MessageParam(role="user", content="How do I configure the timeout settings?"),\
MessageParam(role="assistant", content=response.content),\
MessageParam(\
role="user",\
content=[\
ToolResultBlockParam(\
type="tool_result",\
tool_use_id=response.content[0].id,\
content=tool_result # Search results go here\
)\
]\
)\
]
)
You can also provide search results directly in user messages. This is useful for:
Example: Direct search results
Python
TypeScript
Shell
Copy
from anthropic import Anthropic
from anthropic.types import (
MessageParam,
TextBlockParam,
SearchResultBlockParam
)
client = Anthropic()
# Provide search results directly in the user message
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
messages=[\
MessageParam(\
role="user",\
content=[\
SearchResultBlockParam(\
type="search_result",\
source="https://docs.company.com/api-reference",\
title="API Reference - Authentication",\
content=[\
TextBlockParam(\
type="text",\
text="All API requests must include an API key in the Authorization header. Keys can be generated from the dashboard. Rate limits: 1000 requests per hour for standard tier, 10000 for premium."\
)\
],\
citations={"enabled": True}\
),\
SearchResultBlockParam(\
type="search_result",\
source="https://docs.company.com/quickstart",\
title="Getting Started Guide",\
content=[\
TextBlockParam(\
type="text",\
text="To get started: 1) Sign up for an account, 2) Generate an API key from the dashboard, 3) Install our SDK using pip install company-sdk, 4) Initialize the client with your API key."\
)\
],\
citations={"enabled": True}\
),\
TextBlockParam(\
type="text",\
text="Based on these search results, how do I authenticate API requests and what are the rate limits?"\
)\
]\
)\
]
)
print(response.model_dump_json(indent=2))
Regardless of how search results are provided, Claude automatically includes citations when using information from them:
Copy
{
"role": "assistant",
"content": [\
{\
"type": "text",\
"text": "To authenticate API requests, you need to include an API key in the Authorization header",\
"citations": [\
{\
"type": "search_result_location",\
"source": "https://docs.company.com/api-reference",\
"title": "API Reference - Authentication",\
"cited_text": "All API requests must include an API key in the Authorization header",\
"search_result_index": 0,\
"start_block_index": 0,\
"end_block_index": 0\
}\
]\
},\
{\
"type": "text",\
"text": ". You can generate API keys from your dashboard",\
"citations": [\
{\
"type": "search_result_location",\
"source": "https://docs.company.com/api-reference",\
"title": "API Reference - Authentication",\
"cited_text": "Keys can be generated from the dashboard",\
"search_result_index": 0,\
"start_block_index": 0,\
"end_block_index": 0\
}\
]\
},\
{\
"type": "text",\
"text": ". The rate limits are 1,000 requests per hour for the standard tier and 10,000 requests per hour for the premium tier.",\
"citations": [\
{\
"type": "search_result_location",\
"source": "https://docs.company.com/api-reference",\
"title": "API Reference - Authentication",\
"cited_text": "Rate limits: 1000 requests per hour for standard tier, 10000 for premium",\
"search_result_index": 0,\
"start_block_index": 0,\
"end_block_index": 0\
}\
]\
}\
]
}
Citation fields
Each citation includes:
| Field | Type | Description |
| --- | --- | --- |
| type | string | Always "search_result_location" for search result citations |
| source | string | The source from the original search result |
| title | string or null | The title from the original search result |
| cited_text | string | The exact text being cited |
| search_result_index | integer | Index of the search result (0-based) |
| start_block_index | integer | Starting position in the content array |
| end_block_index | integer | Ending position in the content array |
Note: The search_result_index refers to the index of the search result content block (0-based), regardless of how the search results were provided (tool call or top-level content).
Search results can contain multiple text blocks in the content array:
Copy
{
"type": "search_result",
"source": "https://docs.company.com/api-guide",
"title": "API Documentation",
"content": [\
{\
"type": "text",\
"text": "Authentication: All API requests require an API key."\
},\
{\
"type": "text",\
"text": "Rate Limits: The API allows 1000 requests per hour per key."\
},\
{\
"type": "text",\
"text": "Error Handling: The API returns standard HTTP status codes."\
}\
]
}
Claude can cite specific blocks using the start_block_index and end_block_index fields.
Combining both methods
You can use both tool-based and top-level search results in the same conversation:
Copy
# First message with top-level search results
messages = [\
MessageParam(\
role="user",\
content=[\
SearchResultBlockParam(\
type="search_result",\
source="https://docs.company.com/overview",\
title="Product Overview",\
content=[\
TextBlockParam(type="text", text="Our product helps teams collaborate...")\
],\
citations={"enabled": True}\
),\
TextBlockParam(\
type="text",\
text="Tell me about this product and search for pricing information"\
)\
]\
)\
]
# Claude might respond and call a tool to search for pricing
# Then you provide tool results with more search results
Combining with other content types
Both methods support mixing search results with other content:
Copy
# In tool results
tool_result = [\
SearchResultBlockParam(\
type="search_result",\
source="https://docs.company.com/guide",\
title="User Guide",\
content=[TextBlockParam(type="text", text="Configuration details...")],\
citations={"enabled": True}\
),\
TextBlockParam(\
type="text",\
text="Additional context: This applies to version 2.0 and later."\
)\
]
# In top-level content
user_content = [\
SearchResultBlockParam(\
type="search_result",\
source="https://research.com/paper",\
title="Research Paper",\
content=[TextBlockParam(type="text", text="Key findings...")],\
citations={"enabled": True}\
),\
{\
"type": "image",\
"source": {"type": "url", "url": "https://example.com/chart.png"}\
},\
TextBlockParam(\
type="text",\
text="How does the chart relate to the research findings?"\
)\
]
Cache control
Add cache control for better performance:
Copy
{
"type": "search_result",
"source": "https://docs.company.com/guide",
"title": "User Guide",
"content": [{"type": "text", "text": "..."}],
"cache_control": {
"type": "ephemeral"
}
}
Citation control
By default, citations are disabled for search results. You can enable citations by explicitly setting the citations configuration:
Copy
{
"type": "search_result",
"source": "https://docs.company.com/guide",
"title": "User Guide",
"content": [{"type": "text", "text": "Important documentation..."}],
"citations": {
"enabled": true // Enable citations for this result
}
}
When citations.enabled is set to true, Claude will include citation references when using information from the search result. This enables:
If the citations field is omitted, citations are disabled by default.
Citations are all-or-nothing: either all search results in a request must have citations enabled, or all must have them disabled. Mixing search results with different citation settings will result in an error. If you need to disable citations for some sources, you must disable them for all search results in that request.
For tool-based search (Method 1)
For top-level search (Method 2)
General best practices
Structure results effectively
Maintain consistency
Handle errors gracefully
Copy
def search_with_fallback(query):
try:
results = perform_search(query)
if not results:
return {"type": "text", "text": "No results found."}
return format_as_search_results(results)
except Exception as e:
return {"type": "text", "text": f"Search error: {str(e)}"}
content array must contain at least one text blockWas this page helpful?
YesNo
Assistant
Responses are generated using AI and may contain mistakes.