Quickstart

Get a key and run your first search, embeddings, and rerank requests in a few minutes.

1. Get an API key

Create an account and generate a key from your dashboard. Keys look like sk-sr-... and are passed as a Bearer token on every request.

Get your API key →

Export it so the examples below work as-is. For local development the base URL is http://localhost:8000/api/v1.

bash
export SR_API_KEY="sk-sr-..."

2. Make your first search request

Send a query and get back a normalized, ranked list of results:

bash
curl https://searchrouter.ai/api/v1/search \
  -H "Authorization: Bearer $SR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "exa/neural",
    "query": "best vector databases for RAG 2026",
    "num_results": 5
  }'

The response is the same canonical shape no matter which provider served it:

json
{
  "id": "sr-gen-abc123",
  "model": "exa/neural",
  "provider": "exa",
  "search_type": "neural",
  "results": [
    {
      "title": "Comparing Vector Databases",
      "url": "https://example.com/vdb",
      "snippet": "A short extract...",
      "content": null,
      "score": 0.87,
      "published_date": "2025-11-02"
    }
  ],
  "usage": { "requests": 1, "results": 5, "cost": 0.005 }
}

3. Try embeddings and rerank

The same key and base URL power every primitive. Generate embeddings - use input_type to tell asymmetric models whether the text is a query or a document (SearchRouter maps it to each provider's native vocabulary):

bash
curl https://searchrouter.ai/api/v1/embeddings \
  -H "Authorization: Bearer $SR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/text-embedding-3-small",
    "input": "hybrid search combines keyword and vector retrieval",
    "input_type": "document"
  }'

Then rerank a candidate set by relevance to a query:

bash
curl https://searchrouter.ai/api/v1/rerank \
  -H "Authorization: Bearer $SR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "cohere/rerank-v3.5",
    "query": "what is hybrid search?",
    "documents": [
      "Hybrid search blends BM25 and vector similarity.",
      "Cats are small domesticated mammals.",
      "Reranking reorders candidates by relevance."
    ],
    "top_n": 2
  }'

4. Switch providers by changing the model string

Because the schema is shared, swapping engines is a one-line change. The request body stays identical:

json
# Same request body - only the model string changes.

# Tavily web search:
{ "model": "tavily/search", "query": "...", "num_results": 5 }

# Serper (Google SERP):
{ "model": "serper/google", "query": "...", "num_results": 5 }

# Or let SearchRouter pick the best provider per query:
{ "model": "searchrouter/auto-search", "query": "..." }

5. Mix and match - search several providers at once

You aren't limited to one engine per query. Set mode: "fanout" to query multiple search providers concurrently and get back a single, deduped, fused ranking. List the providers to combine in models, or omit it to fan out across all of them:

bash
curl https://searchrouter.ai/api/v1/search \
  -H "Authorization: Bearer $SR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "searchrouter/auto-search",
    "query": "best vector databases for RAG 2026",
    "mode": "fanout",
    "models": ["exa/neural", "tavily/search", "brave/web"]
  }'

Results are deduped by URL and combined with Reciprocal Rank Fusion, so results multiple engines agree on rank highest. Each result carries a sources array showing which providers returned it. See Fan-out & fusion.

6. Add routing preferences

Use the provider object to control routing - try providers in order, optimize for price, and fall back automatically if one fails:

bash
curl https://searchrouter.ai/api/v1/search \
  -H "Authorization: Bearer $SR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "searchrouter/auto-search",
    "query": "best vector databases for RAG 2026",
    "num_results": 5,
    "provider": {
      "order": ["exa", "tavily"],
      "sort": "price",
      "allow_fallbacks": true
    }
  }'
Routing See Routing & Fallback for order, only, ignore, sort, the auto router, and the :nitro / :floor / :free variants.

Use it from your code

Python

python
import os, requests

resp = requests.post(
    "https://searchrouter.ai/api/v1/search",
    headers={"Authorization": f"Bearer {os.environ['SR_API_KEY']}"},
    json={
        "model": "exa/neural",
        "query": "best vector databases for RAG 2026",
        "num_results": 5,
    },
)
data = resp.json()
for r in data["results"]:
    print(r["score"], r["title"], r["url"])

JavaScript

javascript
const resp = await fetch("https://searchrouter.ai/api/v1/search", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.SR_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "exa/neural",
    query: "best vector databases for RAG 2026",
    num_results: 5,
  }),
});
const data = await resp.json();
data.results.forEach((r) => console.log(r.score, r.title, r.url));