plugins field.
Web search runs entirely proxy-side, so you don’t need to change providers or wire up your own search integration. Any model you can call through RouteShift can be augmented this way.
When to use it
Turn on web search when the answer depends on information that may be newer than the model’s training cutoff — release notes, current prices, breaking news, regulatory changes, or anything else that’s genuinely time-sensitive. Skip it for evergreen prompts (code generation, summarization of user-supplied text, math). Each augmented request adds a search-backend round trip and a per-request surcharge, and cache reuse is disabled for the augmented turn.Opt in per request
There are two equivalent ways to enable web search on a single call:- Model suffix. Append
:onlineto the model name — e.g.gpt-4o:online. The suffix is stripped before the request is dispatched, and a defaultwebplugin is added. - Explicit plugin entry. Add a
webobject to the top-levelpluginsarray. Use this when you need to tunemax_results, pass a customsearch_prompt, or mark the plugin as required.
web entry wins over the suffix’s defaults.
Suffix form
Explicit form
Plugin fields
The
plugins array is stripped from the payload before dispatch — upstream providers never see it. The :online suffix is stripped from the model name for the same reason.
What the model sees
When the backend returns results, RouteShift appends a fenced context block to the request’ssystem_prompt (creating one if it was empty). The block is deterministic — same query, same results, same ordering:
Untrusted wrapper is intentional — it primes the model to treat retrieved text as supplemental context rather than authoritative instructions, which limits the blast radius of prompt-injection payloads in scraped pages.
If the backend returns zero results, the request is dispatched unchanged rather than adding an empty context block.
Optional vs. required plugins
RouteShift treats web search as optional by default. A backend timeout,EXA_API_KEY misconfiguration, or non-2xx response degrades gracefully:
- The upstream call still runs against the un-augmented request.
- A
PluginWarningis attached to the request log with one of two codes:plugin_backend_not_configured— the backend isn’t wired up (missingEXA_API_KEY, unsupportedSEARCH_BACKEND).plugin_backend_failed— the backend was reachable but returned an error or timed out.
"required": true when a stale answer is worse than a failed request — e.g. a compliance workflow that must cite fresh sources. A required-plugin failure short-circuits the request with:
Read warnings from the SDK
@routeshift/sdk exposes the wire types (PluginId, PluginSpec, PluginWarning) directly, so you can attach plugins to a request and inspect what the proxy did with them without hand-typing the shape.
Non-streaming responses
client.chat(...) returns a ChatCompletionResponse whose warnings array carries every optional-plugin degradation the proxy reported. The array is absent when nothing was skipped.
Streaming responses
SSE bodies don’t carry the JSONwarnings envelope, so the proxy reports the same information through response headers. client.chatStream(...) returns a ChatCompletionStream that exposes a metadata promise; it resolves to ChatCompletionStreamMetadata with the raw header values.
If the request fails before headers arrive (e.g. the proxy returns
503), stream.metadata resolves to an empty object rather than rejecting — iterating the stream is what throws the underlying error.
Billing
Every augmented request adds a fixed surcharge on top of the underlying model spend, applied by the Track D billing pipeline. The default surcharge is 500,000 microcents ($0.005) per request; deployments can tune it viaWEB_SEARCH_SURCHARGE_MICROCENTS. Failed and warning-only requests are not surcharged. Augmented requests are also marked non-cacheable — the same prompt run twice will make two search-backend calls and pay the surcharge twice.
Deployment configuration
Self-hosted proxies configure web search with four environment variables:
Managed RouteShift tenants ship with the Exa backend enabled out of the box; you only need to opt in per request.
Errors
Warnings are attached to the request log’s
plugin_warnings column so you can spot silent degradation from the dashboard without parsing every response.