Skip to main content
The web search plugin lets any chat completion pull in current web results before the model responds. You opt in per request; RouteShift queries a search backend, formats the top results as a clearly labeled context block, appends it to the system prompt, and forwards the request to the upstream provider. The model sees titles, URLs, and snippets — but never sees a raw 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:
  1. Model suffix. Append :online to the model name — e.g. gpt-4o:online. The suffix is stripped before the request is dispatched, and a default web plugin is added.
  2. Explicit plugin entry. Add a web object to the top-level plugins array. Use this when you need to tune max_results, pass a custom search_prompt, or mark the plugin as required.
The suffix and the array can be combined; an explicit 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’s system_prompt (creating one if it was empty). The block is deterministic — same query, same results, same ordering:
The 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 PluginWarning is attached to the request log with one of two codes:
    • plugin_backend_not_configured — the backend isn’t wired up (missing EXA_API_KEY, unsupported SEARCH_BACKEND).
    • plugin_backend_failed — the backend was reachable but returned an error or timed out.
Set "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 JSON warnings 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 via WEB_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.