Web search
Let the model look things up before it answers. One switch works for Claude, GPT, Gemini and Grok: boldrouter turns it into each provider's own search tool and returns the sources the answer cites, in OpenAI's url_citation format.
Turning it on
Any one of these on POST /v1/chat/completions turns web search on:
web_search_options, as in OpenAI's API. An empty object{}is enough.plugins: [{ "id": "web" }], as on OpenRouter.- A
:onlinesuffix on the model id, e.g.anthropic/claude-sonnet-5:online.
curl https://boldrouter.com/v1/chat/completions \
-H "Authorization: Bearer $BOLD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-sonnet-5",
"messages": [{"role": "user", "content": "What changed in the EU AI Act this month?"}],
"web_search_options": {"max_searches": 3}
}'Options
All optional, inside web_search_options:
| Field | Type | Description |
|---|---|---|
| max_searches | integer | Most searches the model may run, 1 to 20. Default 5. On the web plugin it's max_results. |
| search_context_size | string | low, medium or high: how much page content the model reads. OpenAI only. |
| user_location | object | OpenAI's shape: { "type": "approximate", "approximate": { "country": "CH", "city": "Bern" } }. Also region and timezone. Used by Claude and GPT; Gemini and Grok ignore it. |
| allowed_domains | string[] | Only search these domains (up to 20). Not supported by Gemini. |
| blocked_domains | string[] | Never search these domains. Use this or allowed_domains, not both. |
Models
A search request only goes to models that can search, and failover stays among them: boldrouter won't fall back to a model that would answer without searching. If none of the models you named can search, the request fails with a 400 that says so. GET /v1/models lists web_search in a model's capabilities, with its price in pricing.per_web_search.
Sources in the response
The answer's sources come back as annotations on the message. start_index and end_index mark the part of the answer each source supports, when the provider gives one:
"message": {
"role": "assistant",
"content": "The Commission published its guidelines on ...",
"annotations": [
{
"type": "url_citation",
"url_citation": {
"url": "https://digital-strategy.ec.europa.eu/...",
"title": "Guidelines on general-purpose AI models",
"start_index": 0,
"end_index": 64
}
}
]
}- When streaming, the annotations arrive in one delta just before the final chunk.
- Claude marks whole passages, not single sentences.
- Gemini's URLs are Google redirect links that lead to the source, and its titles are the site's domain.
- Grok also writes its sources into the text as numbered markdown links.
Pricing
Each search is billed on top of tokens, at the provider's list price. Search results the model reads count as input tokens. The response's usage.server_tool_use.web_search_requests shows how many searches ran, and usage.cost includes them. With your own provider key, the provider bills you for the searches and boldrouter charges its 5.5% fee on them.
| Provider | Price | Notes |
|---|---|---|
Anthropic (Claude) Claude's web search tool | $10.00 / 1,000 per search | Every current Claude model. |
OpenAI (GPT) OpenAI's web search tool | $10.00 / 1,000 per search | GPT-4o, GPT-4.1, GPT-5 and later. Not gpt-4o-mini, gpt-4.1-mini or gpt-4.1-nano. Retrieved pages count as input tokens. |
Google (Gemini 3 and later) Grounding with Google Search | $14.00 / 1,000 per search query | Not with function tools or domain filters. |
Google (Gemini 2.5) Grounding with Google Search | $35.00 / 1,000 per request that searched | Billed once per request, however many queries it ran. |
xAI (Grok) Grok's web search tool | $5.00 / 1,000 per search | Up to 5 allowed or blocked domains. Sources also appear as numbered links in the text. |
Before the request runs, your balance holds enough for max_searches searches; what doesn't get used is released when it finishes.
Workspaces
Workspace admins can turn web search off for their members under Models. Requests that ask for it are then refused with a 403.
