⚡ 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 in the console Key Vault (search engines are listed alongside model providers). 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.