> ## Documentation Index
> Fetch the complete documentation index at: https://exa.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> The Exa API is served at https://api.exa.ai. Authenticate with `Authorization: Bearer $EXA_API_KEY` (or `x-api-key: $EXA_API_KEY`); create keys at https://dashboard.exa.ai/api-keys?utm_source=docs&utm_medium=docs&utm_campaign=markdown_instructions. Every way an agent can get access to Exa is described at https://exa.ai/auth.md.
> Prefer the official SDKs, `exa-py` (`pip install exa-py`) and `exa-js` (`npm install exa-js`); both read `EXA_API_KEY` from the environment.
> Tool-using agents can call Exa without writing code through the hosted MCP server at https://mcp.exa.ai/mcp, or install the Exa agent skill with `npx skills add exa-labs/agent-skills` (skill file: https://exa.ai/docs/skill.md).
> The OpenAPI specs at https://exa.ai/docs/exa-spec.yaml and https://exa.ai/docs/team-management-spec.yaml are the source of truth for request and response schemas.

# OpenRouter

> Ground any OpenRouter model with Exa web search through the openrouter:web_search server tool.

Exa is the search engine behind [OpenRouter](https://openrouter.ai)'s web search. OpenRouter gives you one API for hundreds of models, and Exa gives those models live web access: any model without native search grounds through Exa by default, and any model can be pointed at Exa explicitly. No Exa API key is needed. OpenRouter runs the searches server-side and bills them to your OpenRouter credits.

## Use the web search server tool

Add `openrouter:web_search` to your `tools` array and the model decides when to search, what to search for, and whether to search again within the same request. [Server tools](https://openrouter.ai/docs/guides/features/server-tools/web-search) are in beta on OpenRouter, and they replace the deprecated `web` plugin and `:online` model variants; see OpenRouter's [migration guide](https://openrouter.ai/docs/guides/features/server-tools/web-search#migrating-from-the-web-search-plugin) if you use either.

```javascript JavaScript theme={null}
const response = await fetch("https://openrouter.ai/api/v1/chat/completions", {
  method: "POST",
  headers: {
    Authorization: "Bearer <OPENROUTER_API_KEY>",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "openai/gpt-5.2",
    messages: [
      { role: "user", content: "What were the major AI announcements this week?" },
    ],
    tools: [{ type: "openrouter:web_search" }],
  }),
});

const data = await response.json();
console.log(data.choices[0].message.content);
```

```python Python theme={null}
import requests

response = requests.post(
    "https://openrouter.ai/api/v1/chat/completions",
    headers={
        "Authorization": "Bearer <OPENROUTER_API_KEY>",
        "Content-Type": "application/json",
    },
    json={
        "model": "openai/gpt-5.2",
        "messages": [
            {"role": "user", "content": "What were the major AI announcements this week?"}
        ],
        "tools": [{"type": "openrouter:web_search"}],
    },
)

print(response.json()["choices"][0]["message"]["content"])
```

```bash cURL theme={null}
curl https://openrouter.ai/api/v1/chat/completions \
  -H "Authorization: Bearer <OPENROUTER_API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.2",
    "messages": [
      { "role": "user", "content": "What were the major AI announcements this week?" }
    ],
    "tools": [{ "type": "openrouter:web_search" }]
  }'
```

With the default `engine: "auto"`, OpenRouter uses the provider's native search where a model has one and Exa everywhere else. Set `engine: "exa"` to keep one search behavior across every model:

```json theme={null}
{
  "type": "openrouter:web_search",
  "parameters": {
    "engine": "exa",
    "mode": "auto",
    "max_results": 5,
    "max_total_results": 20,
    "allowed_domains": ["arxiv.org"],
    "excluded_domains": ["reddit.com"]
  }
}
```

| Parameter | Use it to |
| - | - |
| `mode` | Trade latency for depth: `instant`, `fast`, `auto` (default), `deep-lite`, `deep`, or `deep-reasoning`. The modes map to Exa's [search types](https://exa.ai/docs/search/quickstart.md). |
| `max_results` | Cap results per search call (default 5) |
| `max_uses` | Cap how many times the model may search in one request |
| `max_total_results` | Cap cumulative results across all searches in one request |
| `max_characters` | Set an exact per-result character budget for highlights |
| `search_context_size` | Use a preset budget instead: `low`, `medium`, or `high` |
| `allowed_domains`, `excluded_domains` | Filter result domains. Exa supports both filters in the same request. |

`instant`, `fast`, and `deep-reasoning` are [legacy search types](https://exa.ai/docs/search/quickstart.md#legacy-search-types).

## How results come back

OpenRouter requests [Exa highlights](https://exa.ai/docs/search/highlights.md) for each result rather than full page text: extractive excerpts sized adaptively, typically 2,000 to 4,000 characters per result, unless you set `max_characters` or `search_context_size`. The model reads the excerpts, and API callers receive them in standardized `url_citation` annotations on the response message. Within one result, `[...]` markers separate excerpts drawn from different parts of the page.

## Pricing

Exa searches bill to your OpenRouter credits, in addition to the model's token costs for reading the results. The `instant` mode costs \$0.004 per search, `fast` and `auto` cost \$0.007, `deep-lite` and `deep` cost \$0.012, and `deep-reasoning` costs \$0.015. Each search includes up to 10 results, and additional results cost \$0.001 each. See [OpenRouter's web search docs](https://openrouter.ai/docs/guides/features/server-tools/web-search) for current rates.

The response's `usage` object reports how many searches the model ran in `server_tool_use.web_search_requests`.

## Resources

> [card] [Server tool docs](https://openrouter.ai/docs/guides/features/server-tools/web-search)
>
> Full configuration reference for `openrouter:web_search`.

> [card] [Customer story](https://exa.ai/customers/openrouter)
>
> How OpenRouter gives hundreds of models web search with Exa.
