Web search
Add the built-in web_search tool and the platform handles retrieval: models with a native search index use it, and models without one search through MindsHub's own loop. There is no search provider to configure and no separate key.
Works with
Models whose catalog entry declares search. On a model without search the web tools are dropped without warning, so the call looks like it worked while the model answered from its own knowledge; check the per-model column on the capability matrix before relying on it.
Request
- Chat Completions
- Responses
- Messages
- Chat Completions
- Responses
- Messages
response = client.chat.completions.create(
model="sonnet",
messages=[{"role": "user", "content": "What shipped in Python 3.14?"}],
tools=[{"type": "web_search"}, {"type": "fetch"}],
)
print(response.choices[0].message.content)
response = client.responses.create(
model="sonnet",
input="What shipped in Python 3.14?",
tools=[{"type": "web_search"}],
)
print(response.output_text)
message = client.messages.create(
model="sonnet",
max_tokens=1024,
messages=[{"role": "user", "content": "What shipped in Python 3.14?"}],
tools=[{"type": "web_search_20250305", "name": "web_search"}],
)
print(message.content[-1].text)
const response = await client.chat.completions.create({
model: "sonnet",
messages: [{ role: "user", content: "What shipped in Python 3.14?" }],
tools: [{ type: "web_search" }, { type: "fetch" }] as any,
});
console.log(response.choices[0].message.content);
const response = await client.responses.create({
model: "sonnet",
input: "What shipped in Python 3.14?",
tools: [{ type: "web_search" }],
});
console.log(response.output_text);
const message = await client.messages.create({
model: "sonnet",
max_tokens: 1024,
messages: [{ role: "user", content: "What shipped in Python 3.14?" }],
tools: [{ type: "web_search_20250305", name: "web_search" }],
});
console.log(message.content.at(-1));
These samples use sonnet, which searches natively and draws the prepaid wallet.
web_searchlets the model run web searches;fetch(Chat Completions) lets it retrieve a URL. On Messages, Anthropic's hostedweb_search*andweb_fetch*tool types map onto the same platform search.- OpenAI's
web_search_optionsparameter on Chat Completions does the same thing as a{"type": "web_search"}tool entry. Itssearch_context_sizeanduser_locationsub-options have no cross-provider equivalent and are dropped. - When your
toolsarray contains only web tools, anytool_choiceyou send is ignored: forced tool choice can't be applied to server-side search. - Searches carry a per-search charge on top of tokens; see Billing.
Response
A turn that searched reports its sources where each API puts them:
- Chat Completions
- Responses
- Messages
{"type": "url_citation",
"url_citation": {"start_index": 42, "end_index": 118,
"title": "EU AI Act — Article 6", "url": "https://example.eu/ai-act"}}
{"type": "web_search_call", "id": "ws_1a2b", "status": "completed"}
{"type": "web_search_result_location", "url": "https://example.eu/ai-act",
"title": "EU AI Act — Article 6", "cited_text": "…", "encrypted_index": "mindshub:…"}
- Chat Completions:
message.annotationsin OpenAI'surl_citationshape; the offsets index intomessage.content. - Responses:
web_search_callitems inoutput, andurl_citationannotations on theoutput_textpart. Models that don't attribute sources returnannotations: [].includedoesn't gate any of this:web_search_call.resultsandweb_search_call.action.sourcesare accepted and ignored; the items and annotations are returned either way. - Messages:
citationson thetextblock they apply to, in Anthropic'sweb_search_result_locationshape, including when the target model is a GPT or Grok one, whose offset citations are converted to the quoted span this wire format uses.encrypted_indexis Anthropic's own opaque replay cursor, so a citation relayed from a non-Anthropic model carries a synthesizedmindshub:-prefixed value there.
Only some models report sources: the GPT/Grok and Claude families tell us which sentence used which page, while Kimi's builtin search, the external search loop (Fireworks, Meta), and Gemini's own grounding hand results to the model without marking which sentences drew on them. Those answers omit citations entirely rather than guessing. Gemini's grounding is invisible entirely: it runs and bills like any other provider's search but produces neither a web_search_call item nor citations, so the only signal a search happened is the charge for it.
Streaming
Streaming does not narrate searches yet: a streamed Responses turn runs the same searches and returns the same annotations on its terminal response.completed event, but emits no response.web_search_call.* events along the way. Native-search models otherwise stream normally. Models that search through the external loop (deepseek, qwen, glm, muse-spark, and kimi when routed externally) run the loop first and replay the finished answer as a stream, so the first token arrives late. See Streaming.
Per-model differences
| Provider | How it searches |
|---|---|
| Anthropic (Claude family) | Native web_search and web_fetch tools |
| OpenAI and xAI (GPT and Grok families) | Native web_search tool |
| Gemini | Google Search grounding; fetch is always dropped, and no search items or citations are reported |
Moonshot (kimi) | Its $web_search builtin, or the external loop, per policy |
Fireworks and Meta (deepseek, qwen, glm, muse-spark) | External loop (Exa) only |
Which mode each alias uses today is on the capability matrix; it can change by policy without a release.
Errors you can hit
None specific to this feature. Search charges are refused up front like any other paid usage when the wallet is empty (402 wallet_empty). See Errors.