Browse docs ▾
API reference

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 :online suffix on the model id, e.g. anthropic/claude-sonnet-5:online.
bash
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:

FieldTypeDescription
max_searchesintegerMost searches the model may run, 1 to 20. Default 5. On the web plugin it's max_results.
search_context_sizestringlow, medium or high: how much page content the model reads. OpenAI only.
user_locationobjectOpenAI's shape: { "type": "approximate", "approximate": { "country": "CH", "city": "Bern" } }. Also region and timezone. Used by Claude and GPT; Gemini and Grok ignore it.
allowed_domainsstring[]Only search these domains (up to 20). Not supported by Gemini.
blocked_domainsstring[]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:

json
"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.

ProviderPriceNotes
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.

Search queries are written by the model from your conversation and sent to the provider's search service. Turn on prompt anonymization to keep personal data out of them.