Web Fetch

Beta
Give any model the ability to fetch content from URLs
Beta

Server tools are currently in beta. The API and behavior may change.

The openrouter:web_fetch server tool gives any model the ability to fetch content from a specific URL. When the model needs to read a web page or PDF document, it calls the tool with the URL. OpenRouter fetches and extracts the content, returning text that the model can use in its response.

How It Works

  1. You include { "type": "openrouter:web_fetch" } in your tools array.
  2. Based on the user’s prompt, the model decides whether it needs to fetch a URL and generates the request.
  3. OpenRouter fetches the URL using the configured engine (defaults to auto, which uses native provider fetch when available or falls back to Exa).
  4. The page content (text, title, and URL) is returned to the model.
  5. The model incorporates the fetched content into its response. It may fetch multiple URLs in a single request if needed.

Quick Start

1const response = await fetch('https://openrouter.ai/api/v1/chat/completions', {
2 method: 'POST',
3 headers: {
4 Authorization: 'Bearer {{API_KEY_REF}}',
5 'Content-Type': 'application/json',
6 },
7 body: JSON.stringify({
8 model: '{{MODEL}}',
9 messages: [
10 {
11 role: 'user',
12 content: 'Summarize the content at https://example.com/article'
13 }
14 ],
15 tools: [
16 { type: 'openrouter:web_fetch' }
17 ]
18 }),
19});
20
21const data = await response.json();
22console.log(data.choices[0].message.content);

Configuration

The web fetch tool accepts optional parameters to customize behavior:

1{
2 "type": "openrouter:web_fetch",
3 "parameters": {
4 "engine": "exa",
5 "max_uses": 10,
6 "max_content_tokens": 100000,
7 "allowed_domains": ["docs.example.com"],
8 "blocked_domains": ["private.example.com"]
9 }
10}
ParameterTypeDefaultDescription
enginestringautoFetch engine to use: auto, native, exa, openrouter, or firecrawl
max_usesintegerMaximum fetches per request. Once exceeded, the tool returns an error
max_content_tokensintegerMaximum content length in approximate tokens. Content exceeding this is truncated
allowed_domainsstring[]Only fetch from these domains
blocked_domainsstring[]Never fetch from these domains

Engine Selection

The web fetch server tool supports multiple fetch engines:

  • auto (default): Uses native fetch if the provider supports it, otherwise falls back to Exa
  • native: Forces the provider’s built-in web fetch
  • exa: Uses Exa’s Contents API to extract page content (supports BYOK)
  • openrouter: Uses direct HTTP fetch with content extraction
  • firecrawl: Uses Firecrawl’s scrape API (BYOK — bring your own key)

Engine Capabilities

FeatureExaFirecrawlOpenRouterNative
Domain filteringYesYesYesVaries
Token truncationYesYesYesNo
API keyServer-side or BYOKBYOK (your key)Server-sideProvider-handled
Hard limitNoneNone50/request50/request

Firecrawl (BYOK)

Firecrawl uses your own API key. To set it up:

  1. Go to your OpenRouter plugin settings and configure your Firecrawl API key
  2. Your Firecrawl account is billed separately from OpenRouter

Hard Limits

To prevent runaway costs:

  • Exa engine: No hard limit (billed via API credits)
  • Firecrawl engine: No hard limit (uses your Firecrawl credits)
  • OpenRouter/native engines: Hard limit of 50 fetches per request

Domain Filtering

Restrict which domains can be fetched using allowed_domains and blocked_domains:

1{
2 "type": "openrouter:web_fetch",
3 "parameters": {
4 "allowed_domains": ["docs.example.com", "api.example.com"],
5 "blocked_domains": ["internal.example.com"]
6 }
7}

When allowed_domains is set, only URLs from those domains will be fetched. When blocked_domains is set, URLs from those domains will be rejected.

Content Truncation

Use max_content_tokens to limit the amount of content returned:

1{
2 "type": "openrouter:web_fetch",
3 "parameters": {
4 "max_content_tokens": 50000
5 }
6}

Content exceeding this limit is truncated. This is useful for controlling context window usage when fetching large pages.

Works with the Responses API

The web fetch server tool also works with the Responses API:

1const response = await fetch('https://openrouter.ai/api/v1/responses', {
2 method: 'POST',
3 headers: {
4 Authorization: 'Bearer {{API_KEY_REF}}',
5 'Content-Type': 'application/json',
6 },
7 body: JSON.stringify({
8 model: '{{MODEL}}',
9 input: 'What does the documentation at https://example.com/docs say?',
10 tools: [
11 { type: 'openrouter:web_fetch', parameters: { max_content_tokens: 50000 } }
12 ]
13 }),
14});
15
16const data = await response.json();
17console.log(data);

Response Format

When the model calls the web fetch tool, it receives a response like:

1{
2 "url": "https://example.com/article",
3 "title": "Article Title",
4 "content": "The full text content of the page...",
5 "status": "completed",
6 "retrieved_at": "2025-07-15T14:30:00.000Z"
7}

If the fetch fails, the response includes an error:

1{
2 "url": "https://example.com/404",
3 "status": "failed",
4 "error": "HTTP 404: Page not found"
5}

Pricing

EnginePricing
Exa$1 per 1,000 fetches (free with BYOK)
FirecrawlUses your Firecrawl credits directly — no OpenRouter charge
OpenRouterFree
NativePassed through from the provider

All pricing is in addition to standard LLM token costs for processing the fetched content.

Exa BYOK

If you configure your own Exa API key in your provider settings, web fetches using the Exa engine are free through OpenRouter — you pay Exa directly.

Next Steps