Skip to content

Search parameters

Everything tunable about a search rides in the request’s search block. The block itself, and the one-line summary of each option, are on Parameters & Configuration; this page is what each one does, what it costs, and where every field in the response came from.

auto_routing · "accuracy" · off by default.

Set auto_routing, and Telem picks the providers for you. Telem finds the topic of each query. Then it sends the query to the three providers that do best on that topic. Each query in a batch gets its own choice.

{
"user_input": { "query": "papers on speculative decoding for LLM inference" },
"search": { "auto_routing": "accuracy" }
}

This query has the topic academic_papers. The routing block in the response names the topic and the providers that Telem chose. accuracy is the only mode at this time.

In the SDKs, the same option is client.search(..., auto_routing="accuracy") in Python and telem.search(..., { autoRouting: "accuracy" }) in JavaScript. The plugins read it from your config file, and the installer can set it for you. See Configuring the plugins and the SDK.

Telem finds these topics without help:

Topic Example query
news “latest news on the EU AI Act vote”
companies “Stripe company overview funding and headquarters”
financial_filings “Apple 10-K risk factors fiscal 2025”
academic_papers “papers on speculative decoding for LLM inference”
people_profiles “who is Jensen Huang”
wikipedia_encyclopedia “history of the Byzantine Empire”

A query that matches none of these topics gets the topic general. A general query runs on the default providers, the same as a search without auto-routing. A finance_markets query also runs on the default providers.

Your request Telem chooses from
No providers block All providers that the deployment runs, except serpapi
providers.include Only the providers in the list. Name serpapi here to let Telem choose it.
providers.exclude All providers that the deployment runs, minus the list and serpapi

serpapi is slow, so Telem does not choose it unless you include it.

With auto_routing, the response has a routing list. It has one entry for each query, in the order of the batch:

"routing": [
{
"topic": "academic_papers",
"score": 0.043288350105285645,
"providers": ["perplexity", "brave", "exa"]
}
]
Field What it is
topic The topic that Telem found, or general. null when Telem cannot find topics.
score How closely the query matched the topic. A higher number is a closer match. null when Telem cannot find topics. Use it for logs only, because the scale can change.
providers The providers that Telem chose, best first.

Without auto_routing, routing is null.

If Telem cannot find topics, every query runs on the default providers. Each run’s warnings then has a routing_unavailable entry.

One of minimalist, default, extended, max. Default "default".

The tier decides how much each result carries and which knobs the adapters send upstream, so it is the price knob as well as the detail knob. The sets are cumulative.

Tier Adds
minimalist url, title, rank, latency_ms, warnings
default summary
extended excerpt, full_content †, publish_date, usage
max thumbnail, favicon, source, enrichments, fetch_meta, answer, entities, related, verticals

† full_content never arrives on the tier alone — see Full page content.

A field in the active set is present on every result — null or [] when the provider cannot supply it. Fields outside the set are absent entirely. latency_ms and warnings are always present.

fields is the explicit alternative: list any of the names above and the tier presets do not apply.

One vocabulary, whoever answered. summary is always the result’s text snippet — whether the provider spells it description (brave), content (tavily), or highlights (exa). Telem aligns every provider’s response into these fields server-side, and never invents a value: a field the provider cannot supply comes back null ([] for list fields), with a capability_gap warning saying so. The original, untouched payload is always one flag away — include_raw.

The tabs below name the raw field behind each normalized one. Three are the same everywhere and omitted: rank is the row’s position in the provider’s own ordering, source.domain comes from the result’s URL, and enrichments carries whatever provider-specific keys normalization did not consume, verbatim.

Normalized Read from
url / title url / title
summary summary, else highlights (below max)
excerpt highlights (10k shape; paid, max/fields mode)
full_content text (paid; max/fields mode)
publish_date publishedDate
usage costDollars
thumbnail / favicon image / favicon
answer output (deep runs via overrides)
source.author author

Cannot supply: entities, related, verticals, fetch_meta — null plus a capability_gap warning. Requesting enrichments on exa buys the paid extras knob.

providers.include replaces the deployment’s default provider set rather than adding to it; providers.exclude subtracts from whatever set would otherwise run. More providers means better recall and a bigger bill, so an explicit list makes a search’s cost a decision rather than an accident.

Provider Notes
brave
ceramic No count knob upstream — num_results is enforced by trimming the results.
exa Embedding-based; matches on meaning. num_results is clamped to 10.
linkup
parallel
perplexity One text field per result feeds both summary and full_content. num_results is sent as-is — no clamp, no trim.
seltz No title by API design — title is always null.
serpapi No count knob upstream — num_results is enforced by trimming the results.
tavily
tinyfish No count knob upstream — every call returns one page of 10, trimmed to num_results; asking for more than 10 adds a capability_gap warning.
you

An unknown name is a 400 listing the known ones, and so is naming the same provider in both halves. Any provider above may be named, whether or not the deployment runs it by default. GET /v1/preprocessors (no auth) is the live roster — each provider’s slug and whether it runs by default.

Normalization covers the portable knobs; provider_overrides is the passthrough for everything native. Keyed by provider, deep-merged into the request Telem builds for that provider — so a knob only one engine has is one line, not a feature request:

{
"search": {
"providers": { "include": ["exa", "tavily"] },
"provider_overrides": {
"exa": { "category": "news" },
"tavily": { "search_depth": "advanced" }
}
}
}

Overrides are explicit intent, so almost nothing is blocked — the guardrails that remain: you can only override providers named in the request (400 otherwise), the whole block caps at 16 KB, and count-type knobs (num_results, max_results, count and friends, at any depth) cap at 20 and still count toward the volume budget. Native knobs are intentionally not portable — keep each one under its provider’s key, and expect paid features (like tavily’s advanced depth) to bill accordingly.

include_raw: true returns each provider run’s original, untouched response under that run’s raw_payload, next to the normalized results — the escape hatch when you need something the envelope does not carry (a provider’s own relevance score, say). Off by default; the payloads are big.

num_results · 1–20 · default 5. Per provider, not per request: five providers at num_results: 10 is fifty rows.

include_full_content: true asks providers for the whole page body rather than a snippet. Slower and more expensive, and off unless set.

It is an intersection, never an addition: the flag keeps the full_content field a tier already has, so at extended and max it fills, and at minimalist and default it is a no-op — those tiers have no full_content field to keep. Naming full_content in fields opts in the same way. It also licenses the paid content knob wherever a provider has one. exa and you supply page text only at tier: "max" (or in fields mode); linkup returns it from extended up and buys its deeper paid mode at max; perplexity returns it from extended up at no extra cost, as the longest form of the same text that fills summary.

Whole pages are rarely the best input for a model, and every one costs money — the cheaper pattern is to search at default and fetch only the URLs you actually keep.

Pass a list of queries and they run concurrently inside a single interaction, each result tagged with the query that produced it — faster and cheaper than calling search repeatedly.

{ "user_input": [ { "query": "istio vs linkerd" }, { "query": "envoy gateway api" } ] }

The Python SDK spells this client.search(["q1", "q2"]).