Web Search
Inject web search results into a request with the plugins field. Compatible with OpenRouter's web plugin.
Add {"id": "web"} to the pluginsarray and PleumRouter searches the web with your last user message before calling the model, injecting the results as context. The field shape matches OpenRouter's plugins, so an existing OpenRouter config carries over unchanged.
plugins.web_search_enabled) that is off by default. While the gate is off, the plugins field is silently ignored without an error and the request proceeds normally without search.Request#
| Parameter | Type | Required | Description |
|---|---|---|---|
| plugins | array | Optional | OpenRouter-compatible plugin list. Request web search with a {"id": "web"} entry. |
| plugins[].id | string | Required | Plugin ID. Only "web" is supported today. |
| plugins[].max_results | integer | Optional | Number of search results to inject. Default 3, clamped to 1 – 10. Non-integer values fall back to 3. |
curl https://apirouter.pleum.ai/v1/chat/completions \
-H "Authorization: Bearer plm_..." \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o-mini",
"messages": [
{"role": "user", "content": "What are the latest developments in AI routing?"}
],
"plugins": [{"id": "web", "max_results": 3}]
}'How it works#
The search query is the text of your last user message (for multimodal messages, only the text parts are used). The search backend is the keyless DuckDuckGo Instant Answer API, and the results (a list of titles and URLs) are prepended to the conversation as a system message before the model is called. The response body shape is unchanged — there is no separate citation/annotation field.
If the search fails or returns nothing, the request does not fail — the model is called with your original messages unchanged. The same applies when the last user message has no text.
Billing#
Injected search results become part of the prompt, so they are billed as regular input tokens. The search itself carries no extra fee.