ground/router

One endpoint · every grounding provider

Search routing for agents.

Point your agent at one API. Switch between Exa, Tavily, Brave and Ozone — or query them all at once — by changing configuration, not code. Every result says which provider found it and whether the content is licensed.

request
curl https://api.groundrouter.ai/v1/search \
  -H "Authorization: Bearer $GROUNDROUTER_KEY" \
  -d '{
    "query": "who won the 2026 UK general election",
    "top_k": 3
  }'

No provider named. Routing comes from your config.

response 200 · 1.6s
{
  "results": [
    {
      "rank": 3,
      "domain": "bbc.com",
      "title": "Election 2026: results in full",
      "provenance": {
        "provider": "ozone",
        "found_by": ["tavily", "ozone"],
        "licensed": true,
        "publisher_name": "BBC",
        "promoted": "ozone_precedence"
      }
    }
  ]
}

Tavily found it. Ozone licenses it. You get both facts.

Quickstart

Built for agents, not dashboards.

GroundRouter speaks MCP, so most harnesses need one line and no SDK. Pick yours.

terminal
claude mcp add --transport http groundrouter \
  https://api.groundrouter.ai/mcp \
  --header "Authorization: Bearer $GROUNDROUTER_KEY"

# Your agent now has `search` and `list_providers`.

Providers

Not every provider can answer every question.

Filters are not universally supported, so GroundRouter refuses a filter a provider cannot honour rather than returning unfiltered results that look filtered. This table is served live from GET /v1/providers.

Provider Domain Date Publisher Full text Similar Index
Ozonelicensed Licensed publisher corpus
Exa Embeddings, open web
Tavily LLM-tuned, open web
Brave Independent index
Binginactive Pending API availability

Publisher, article-type and temporal filters describe a licensed corpus. They are meaningless on the open web, so only Ozone declares them.

How it works

Four decisions the router makes for you.

01 · DISPATCHPick the providers

Four policies, set per API key: single, failover, rotate (weighted, to spread spend across quotas) and fanout (all at once, merged).

Failover distinguishes whose fault a failure is. A missing key moves to the next provider; a rejected key does not — continuing would spend another provider's quota to hide a configuration error you need to fix.

02 · DEDUPLICATECollapse the same page

Providers return the same document under different URLs: tracking parameters, www. and m. hosts, AMP variants, trailing slashes. Those are canonicalised to one result.

Unknown query parameters are deliberately kept. For many sites ?id=123 is the document identity, and merging those would serve one article in place of two.

03 · RANKFuse on rank, not score

Provider scores are not comparable — Tavily's 0.48 and Exa's 0.48 come from different models over different corpora. Sorting on raw score across providers would assert a comparability that does not exist.

So results are fused by rank using Reciprocal Rank Fusion. A document several providers rank highly beats one only a single provider liked.

04 · ATTRIBUTESay what is licensed

Ozone holds content licences the commodity providers do not. When any provider returns a URL on an Ozone publisher domain, Ozone's record is served for it and the result is marked licensed: true.

Licensed content gets no ranking advantage over content it does not own — it ranks where the evidence puts it. An agent that cannot trust the ordering stops using the router.

Configuration, not code

Change providers without touching your agent.

One PUT, and the next request routes differently. No redeploy, no client release, no code change.

before
{
  "routing": {
    "policy": "single",
    "provider": "tavily"
  }
}
after
{
  "routing": {
    "policy": "fanout",
    "providers": ["ozone", "exa", "tavily"],
    "timeout_ms": 6000
  },
  "merge": { "strategy": "precedence" }
}

Same API key. Same request. Three providers, deduplicated, with licence provenance.