Native web search providers: Vertex AI (Google), Azure OpenAI, OpenAI, Anthropic, xAI, Perplexity
Browse models with web search in the Requesty Console. Look for
supports_web_search: true in the List Models response.How It Works
Each provider implements web search differently. Requesty normalizes these differences behind a single tool definition that works across all three inference endpoints:| Endpoint | Format | Tool definition |
|---|---|---|
/v1/chat/completions | OpenAI Chat Completions | "tools": [{ "type": "web_search" }] |
/v1/responses | OpenAI Responses API | "tools": [{ "type": "web_search" }] |
/v1/messages | Anthropic Messages | "tools": [{ "type": "web_search_20250305", "name": "web_search", "max_uses": 5 }] |
"stream": true) for all web search requests. Streaming delivers citations and content in real time, and avoids the extra latency of waiting for the full search to finish.
Usage
- Chat Completions
- Responses API
- Messages API
POST /v1/chat/completions - Add { "type": "web_search" } to the tools array.curl https://router.requesty.ai/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_REQUESTY_API_KEY" \
-d '{
"model": "anthropic/claude-sonnet-4-20250514",
"messages": [
{ "role": "user", "content": "What are the latest news in London today?" }
],
"tools": [{ "type": "web_search" }],
"stream": true
}'
from openai import OpenAI
client = OpenAI(
api_key="YOUR_REQUESTY_API_KEY",
base_url="https://router.requesty.ai/v1",
)
stream = client.chat.completions.create(
model="anthropic/claude-sonnet-4-20250514",
messages=[
{"role": "user", "content": "What are the latest news in London today?"}
],
tools=[{"type": "web_search"}],
stream=True,
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")
import OpenAI from 'openai';
const client = new OpenAI({
apiKey: 'YOUR_REQUESTY_API_KEY',
baseURL: 'https://router.requesty.ai/v1',
});
const stream = await client.chat.completions.create({
model: 'anthropic/claude-sonnet-4-20250514',
messages: [
{ role: 'user', content: 'What are the latest news in London today?' }
],
tools: [{ type: 'web_search' }],
stream: true,
});
for await (const chunk of stream) {
const content = chunk.choices[0]?.delta?.content;
if (content) process.stdout.write(content);
}
model to switch providers:# Vertex / Gemini
model="vertex/google/gemini-2.5-pro"
# xAI / Grok
model="xai/grok-3"
# Perplexity
model="perplexity/sonar-pro"
web_search metadata on streamed chunks with citation URLs and titles:{
"choices": [{
"delta": {
"content": "Based on the search results...",
"web_search": {
"content": [
{ "url": "https://example.com/news", "title": "London News" }
]
}
}
}]
}
POST /v1/responses - Add { "type": "web_search" } to the tools array.curl https://router.requesty.ai/v1/responses \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_REQUESTY_API_KEY" \
-d '{
"model": "openai-responses/gpt-4.1",
"input": "What are the latest developments in artificial intelligence?",
"tools": [{ "type": "web_search" }],
"stream": true
}'
from openai import OpenAI
client = OpenAI(
api_key="YOUR_REQUESTY_API_KEY",
base_url="https://router.requesty.ai/v1",
)
response = client.responses.create(
model="openai-responses/gpt-4.1",
input="What are the latest developments in artificial intelligence?",
tools=[{"type": "web_search"}],
stream=True,
)
for event in response:
if hasattr(event, 'type') and event.type == 'response.completed':
for item in event.response.output:
if item.type == 'message':
for content in item.content:
if content.type == 'output_text':
print(content.text)
import OpenAI from 'openai';
const client = new OpenAI({
apiKey: 'YOUR_REQUESTY_API_KEY',
baseURL: 'https://router.requesty.ai/v1',
});
const response = await client.responses.create({
model: 'openai-responses/gpt-4.1',
input: 'What are the latest developments in artificial intelligence?',
tools: [{ type: 'web_search' }],
});
for (const item of response.output) {
if (item.type === 'message') {
for (const content of item.content) {
if (content.type === 'output_text') {
console.log(content.text);
}
}
}
}
web_search_call items and url_citation annotations on text content:{
"output": [
{
"type": "web_search_call",
"id": "ws_abc123",
"status": "completed"
},
{
"type": "message",
"role": "assistant",
"content": [{
"type": "output_text",
"text": "Recent AI developments include...",
"annotations": [{
"type": "url_citation",
"url": "https://example.com/ai-news",
"title": "AI News Today",
"start_index": 0,
"end_index": 35
}]
}]
}
]
}
POST /v1/messages - Uses Anthropic’s native web_search_20250305 tool type.curl https://router.requesty.ai/v1/messages \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_REQUESTY_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "anthropic/claude-sonnet-4-20250514",
"max_tokens": 4096,
"messages": [
{ "role": "user", "content": "What are the latest developments in artificial intelligence?" }
],
"tools": [{
"type": "web_search_20250305",
"name": "web_search",
"max_uses": 5
}],
"stream": true
}'
import anthropic
client = anthropic.Anthropic(
api_key="YOUR_REQUESTY_API_KEY",
base_url="https://router.requesty.ai",
)
with client.messages.stream(
model="anthropic/claude-sonnet-4-20250514",
max_tokens=4096,
messages=[
{"role": "user", "content": "What are the latest developments in artificial intelligence?"}
],
tools=[{
"type": "web_search_20250305",
"name": "web_search",
"max_uses": 5,
}],
) as stream:
response = stream.get_final_message()
for block in response.content:
if block.type == "text":
print(block.text)
import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic({
apiKey: 'YOUR_REQUESTY_API_KEY',
baseURL: 'https://router.requesty.ai',
});
const stream = client.messages.stream({
model: 'anthropic/claude-sonnet-4-20250514',
max_tokens: 4096,
messages: [
{ role: 'user', content: 'What are the latest developments in artificial intelligence?' }
],
tools: [{
type: 'web_search_20250305',
name: 'web_search',
max_uses: 5,
}],
});
const response = await stream.finalMessage();
for (const block of response.content) {
if (block.type === 'text') {
console.log(block.text);
}
}
server_tool_use, web_search_tool_result, and text blocks with citations:{
"content": [
{
"type": "server_tool_use",
"id": "srvtoolu_abc123",
"name": "web_search",
"input": { "query": "latest AI developments" }
},
{
"type": "web_search_tool_result",
"tool_use_id": "srvtoolu_abc123",
"content": [{
"type": "web_search_result",
"url": "https://example.com/ai-news",
"title": "AI News Today",
"encrypted_content": "..."
}]
},
{
"type": "text",
"text": "Recent AI developments include...",
"citations": [{
"type": "web_search_result_location",
"url": "https://example.com/ai-news",
"title": "AI News Today",
"cited_text": "Recent breakthroughs in..."
}]
}
]
}
Web search requires models with tool use support. Check the Model Library to confirm web search support for specific models.