⚡ New — Kimi K3 is live: bring your own Moonshot key →
Documentation

Ground any model in live web results

← Cookbook

Append :online to any chat model and BharatRouter searches the web first, then answers with cited sources — OpenRouter-compatible, on your own Exa / Brave / Tavily key.

:online web search (BYOK engine)AdvancedIntermediate8 min

Models go stale the day they finish training. Append :online to any chat model and BharatRouter runs a web search first, injects the ranked results as context, and returns the answer with url_citation annotations — the same shape OpenRouter uses, so existing clients read it unchanged.

You'll use: the :online model suffix (or the OpenRouter web plugin) backed by your own search-engine key. Reference: Web search.

Save a search-engine key (BYOK)

Search runs on your own engine key — save an Exa, Brave or Tavily key once under BYOK → Web search on the dashboard. It lives in the same encrypted vault as your model keys and is used only in-flight. Exa is the default engine (OpenRouter parity).

Ask a question that needs today's web

from openai import OpenAI

client = OpenAI(base_url="https://api.bharatrouter.com/v1", api_key="br-...")

r = client.chat.completions.create(
    model="gemma-4-e4b-it:online",   # any chat model + :online
    messages=[{"role": "user", "content": "What did the RBI decide at its latest policy meeting?"}],
)
print(r.choices[0].message.content)

# Sources come back as OpenRouter-shaped url_citation annotations:
for a in getattr(r.choices[0].message, "annotations", None) or []:
    print(a["url_citation"]["title"], "-", a["url_citation"]["url"])

Tune the search — the web plugin

For control over the engine, result count and domain scope, pass the OpenRouter-compatible web plugin instead of (or alongside) the suffix:

curl https://api.bharatrouter.com/v1/chat/completions \
  -H "Authorization: Bearer br-..." -H "Content-Type: application/json" \
  -d '{
    "model": "gemma-4-e4b-it",
    "messages": [{"role": "user", "content": "Summarise this week's GST council news"}],
    "plugins": [{
      "id": "web",
      "engine": "exa",
      "max_results": 5,
      "include_domains": ["pib.gov.in", "cbic.gov.in"]
    }]
  }'

How it works

  • BR searches your last user turn, prepends the results as a system context block, then routes the now-grounded request to the model you asked for — search and model are independent, so you can pair live web with any catalog model.
  • The response carries url_citation annotations and an x-br-web-search: <engine>:<count> header, so you can see exactly what was fetched.
  • Fail-open: with no saved key for the engine, the request still answers (from the model's own knowledge) and the header reads <engine>:no-key — a diagnosable signal, never a hard error.

Residency: every current search engine is US-hosted, so the query text leaves India when :online is on — a :online request can't also be india_only. Because it's BYOK, the search itself bills to your engine account, not to BR.

More recipes in the Cookbook, or see the fullAPI reference.