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

# Web Search

> Search the web from the Agent API with filters, search configurations, pricing, parameters, and response fields.

## Overview

The `web_search` tool lets the model search the web during an Agent API request. Use it for current information, recent news, source-grounded research, and questions that need information beyond the model's training data.

Enable the tool by adding it to the `tools` array. The model decides when to call it based on your prompt and instructions.

<CodeGroup>
  ```python Python theme={null}
  from perplexity import Perplexity

  client = Perplexity()

  response = client.responses.create(
      model="openai/gpt-5.5",
      input="What are the latest AI infrastructure announcements this week?",
      tools=[
          {
              "type": "web_search",
              "search_context_size": "medium"
          }
      ],
      instructions="Search for current, source-grounded information before answering.",
  )

  print(response.output_text)
  ```

  ```typescript Typescript theme={null}
  import Perplexity from '@perplexity-ai/perplexity_ai';

  const client = new Perplexity();

  const response = await client.responses.create({
    model: 'openai/gpt-5.5',
    input: 'What are the latest AI infrastructure announcements this week?',
    tools: [
      {
        type: 'web_search' as const,
        search_context_size: 'medium',
      },
    ],
    instructions: 'Search for current, source-grounded information before answering.',
  });

  console.log(response.output_text);
  ```

  ```bash cURL theme={null}
  curl https://api.perplexity.ai/v1/agent \
    -H "Authorization: Bearer $PERPLEXITY_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "openai/gpt-5.5",
      "input": "What are the latest AI infrastructure announcements this week?",
      "tools": [
        {
          "type": "web_search",
          "search_context_size": "medium"
        }
      ],
      "instructions": "Search for current, source-grounded information before answering."
    }' | jq
  ```
</CodeGroup>

## Configuring Search

### Using Recommended Token Budgets

Start with `low`, `medium`, or `high` for search context sizing via `search_context_size`. Each named size maps to a recommended pair of `max_tokens` and `max_tokens_per_page` budgets and is the recommended default for most applications.

| `search_context_size` | `max_tokens` | `max_tokens_per_page` | Best for                                  |
| --------------------- | ------------ | --------------------- | ----------------------------------------- |
| `low`                 | 300          | 300                   | Simple facts and lightweight lookups      |
| `medium`              | 1,000        | 1,000                 | General research and product comparisons  |
| `high`                | 4,000        | 4,000                 | Source-heavy answers and complex research |

<Note>
  These token-budget mappings reflect Perplexity's current recommended defaults and may change as we ship updated configurations based on the latest evaluation results. Calling a named size always resolves to the current recommended budget.
</Note>

<CodeGroup>
  ```python Python theme={null}
  tools = [
      {
          "type": "web_search",
          "search_context_size": "high"
      }
  ]
  ```

  ```typescript Typescript theme={null}
  const tools = [
    {
      type: 'web_search' as const,
      search_context_size: 'high',
    },
  ];
  ```

  ```bash cURL theme={null}
  "tools": [
    {
      "type": "web_search",
      "search_context_size": "high"
    }
  ]
  ```
</CodeGroup>

### Advanced Token Budget Configuration

Use explicit token budgeting when you need to pin exact budgets for cost controls, latency controls, or evaluations. Set `max_tokens` to cap total search context across results, and set `max_tokens_per_page` to cap content extracted from each result page. Explicit budgets override any `search_context_size` value passed in the same request, and you are charged for the exact number of search context tokens consumed, not the requested budget.

<CodeGroup>
  ```python Python theme={null}
  response = client.responses.create(
      model="openai/gpt-5.5",
      input="Find recent government guidance on AI procurement.",
      tools=[
          {
              "type": "web_search",
              "max_tokens": 6000,
              "max_tokens_per_page": 1200,
              "filters": {
                  "search_domain_filter": [".gov"],
                  "search_recency_filter": "month"
              }
          }
      ],
  )
  ```

  ```typescript Typescript theme={null}
  const response = await client.responses.create({
    model: 'openai/gpt-5.5',
    input: 'Find recent government guidance on AI procurement.',
    tools: [
      {
        type: 'web_search' as const,
        max_tokens: 6000,
        max_tokens_per_page: 1200,
        filters: {
          search_domain_filter: ['.gov'],
          search_recency_filter: 'month',
        },
      },
    ],
  });
  ```

  ```bash cURL theme={null}
  curl https://api.perplexity.ai/v1/agent \
    -H "Authorization: Bearer $PERPLEXITY_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "openai/gpt-5.5",
      "input": "Find recent government guidance on AI procurement.",
      "tools": [
        {
          "type": "web_search",
          "max_tokens": 6000,
          "max_tokens_per_page": 1200,
          "filters": {
            "search_domain_filter": [".gov"],
            "search_recency_filter": "month"
          }
        }
      ]
    }' | jq
  ```
</CodeGroup>

## Filters

Use filters to constrain the sources, dates, and location context used by `web_search`.

| Filter                       | Type             | Description                                                                           |
| ---------------------------- | ---------------- | ------------------------------------------------------------------------------------- |
| `search_domain_filter`       | array of strings | Include or exclude up to 20 domains or URLs. Prefix entries with `-` to exclude them. |
| `search_recency_filter`      | string           | Restrict results to `"hour"`, `"day"`, `"week"`, `"month"`, or `"year"`.              |
| `search_after_date_filter`   | string           | Include results published after a date in MM/DD/YYYY format.                          |
| `search_before_date_filter`  | string           | Include results published before a date in MM/DD/YYYY format.                         |
| `last_updated_after_filter`  | string           | Include results last updated after a date in MM/DD/YYYY format.                       |
| `last_updated_before_filter` | string           | Include results last updated before a date in MM/DD/YYYY format.                      |
| `user_location`              | object           | Personalize search by country, region, city, latitude, and longitude.                 |

### Domain filter

<Warning>
  Use `search_domain_filter` in either allowlist mode or denylist mode, not both. The domain filter accepts up to 20 domains or URLs. For example, `["nasa.gov", "wikipedia.org"]` includes only those domains, while `["-reddit.com", "-pinterest.com"]` excludes those domains.
</Warning>

Entries can be at the domain level (e.g., `wikipedia.org`) or at the URL level (e.g., `https://en.wikipedia.org/wiki/Chess`) for more granular control.

### Recency filter

`search_recency_filter` maps each value to a relative window:

| Value   | Window                                                                  |
| ------- | ----------------------------------------------------------------------- |
| `hour`  | Past hour — use for real-time data such as breaking news or live events |
| `day`   | Past 24 hours                                                           |
| `week`  | Past 7 days                                                             |
| `month` | Past 30 days                                                            |
| `year`  | Past 365 days                                                           |

For exact ranges, use `search_after_date_filter` / `search_before_date_filter` (publication date) or `last_updated_after_filter` / `last_updated_before_filter` (last update). Date filter values must use the `MM/DD/YYYY` format (e.g., `"03/01/2026"`).

### Location filter

`user_location` accepts any combination of the following fields:

* `country` — Two-letter [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) code (for example, `"US"`, `"FR"`).
* `region` — Region or state name (for example, `"California"`).
* `city` — City name (for example, `"San Francisco"`).
* `latitude` and `longitude` — Coordinates for precise targeting.

<Tip>
  `city` and `region` significantly improve location accuracy. Include them alongside `country` whenever possible.
</Tip>

<Warning>
  `latitude` and `longitude` must be provided together with `country`. They cannot be supplied on their own.
</Warning>

### Filter Usage Cheatsheet

Copy any of these snippets into a `web_search` tool object. `user_location` sits alongside `filters`, while the other controls sit inside `filters`.

| Filter               | Example                                                                                                          |
| -------------------- | ---------------------------------------------------------------------------------------------------------------- |
| Domain allowlist     | `filters: { search_domain_filter: ["docs.perplexity.ai", "developer.mozilla.org"] }`                             |
| Domain denylist      | `filters: { search_domain_filter: ["-reddit.com", "-pinterest.com"] }`                                           |
| Recency              | `filters: { search_recency_filter: "week" }`                                                                     |
| Published date range | `filters: { search_after_date_filter: "01/01/2026", search_before_date_filter: "05/01/2026" }`                   |
| Last updated range   | `filters: { last_updated_after_filter: "01/01/2026", last_updated_before_filter: "05/01/2026" }`                 |
| User location        | `user_location: { country: "US", region: "CA", city: "San Francisco", latitude: 37.7749, longitude: -122.4194 }` |

<Tip>
  Filters compose freely. Combine any of the source, date, recency, and location filters above in a single `web_search` tool object — there's no per-request limit on filter combinations.
</Tip>

<CodeGroup>
  ```python Python theme={null}
  response = client.responses.create(
      model="openai/gpt-5.5",
      input="What changed in US AI policy this month?",
      tools=[
          {
              "type": "web_search",
              "search_context_size": "medium",
              "filters": {
                  "search_domain_filter": [".gov"],
                  "search_recency_filter": "month"
              },
              "user_location": {
                  "country": "US"
              }
          }
      ],
  )
  ```

  ```typescript Typescript theme={null}
  const response = await client.responses.create({
    model: 'openai/gpt-5.5',
    input: 'What changed in US AI policy this month?',
    tools: [
      {
        type: 'web_search' as const,
        search_context_size: 'medium',
        filters: {
          search_domain_filter: ['.gov'],
          search_recency_filter: 'month',
        },
        user_location: {
          country: 'US',
        },
      },
    ],
  });
  ```

  ```bash cURL theme={null}
  curl https://api.perplexity.ai/v1/agent \
    -H "Authorization: Bearer $PERPLEXITY_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "openai/gpt-5.5",
      "input": "What changed in US AI policy this month?",
      "tools": [
        {
          "type": "web_search",
          "search_context_size": "medium",
          "filters": {
            "search_domain_filter": [".gov"],
            "search_recency_filter": "month"
          },
          "user_location": {
            "country": "US"
          }
        }
      ]
    }' | jq
  ```
</CodeGroup>

## Parameters

| Parameter             | Type    | Required | Description                                                                                                                          |
| --------------------- | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `type`                | string  | Yes      | Must be `"web_search"`.                                                                                                              |
| `search_context_size` | string  | No       | Recommended token budget: `"low"`, `"medium"`, or `"high"`. See [Using Recommended Token Budgets](#using-recommended-token-budgets). |
| `filters`             | object  | No       | Domain, date, recency, and location filters. See [Filters](#filters).                                                                |
| `user_location`       | object  | No       | Location context for search personalization.                                                                                         |
| `max_tokens`          | integer | No       | Maximum total tokens for search context.                                                                                             |
| `max_tokens_per_page` | integer | No       | Maximum tokens extracted from each search result page.                                                                               |

## Response Shape

When `web_search` runs, the response can include a `search_results` output item before the final assistant message. The final `usage` object includes token counts, cost details, and `tool_calls_details.web_search.invocation` when tool-call usage is reported.

```json theme={null}
{
  "output": [
    {
      "type": "search_results",
      "queries": ["AI infrastructure announcements"],
      "results": [
        {
          "id": 1,
          "url": "https://example.com/news",
          "title": "Example AI infrastructure announcement",
          "snippet": "A short snippet from the search result.",
          "date": "2026-05-01",
          "last_updated": "2026-05-01",
          "source": "web"
        }
      ]
    },
    {
      "type": "message",
      "role": "assistant",
      "content": [
        {
          "type": "output_text",
          "text": "The answer generated from the search results."
        }
      ]
    }
  ],
  "usage": {
    "input_tokens": 1200,
    "output_tokens": 300,
    "total_tokens": 1500,
    "tool_calls_details": {
      "web_search": {
        "invocation": 1
      }
    }
  }
}
```

Each entry in `results` includes the following fields:

| Field          | Type    | Description                                                     |
| -------------- | ------- | --------------------------------------------------------------- |
| `id`           | integer | Stable index used to reference the result in citations.         |
| `url`          | string  | Canonical URL of the source page.                               |
| `title`        | string  | Page title as returned by the source.                           |
| `snippet`      | string  | Excerpted text extracted from the page during search.           |
| `date`         | string  | Date the page was originally published, in `YYYY-MM-DD` format. |
| `last_updated` | string  | Date the page was last updated, in `YYYY-MM-DD` format.         |
| `source`       | string  | Origin of the result (for example, `"web"`).                    |

## Pricing

`web_search` is billed at **\$5 per 1,000 invocations**. Model token usage is billed separately according to Agent API token pricing.

<Note>
  Pricing follows the same pattern as other tool calls: pay for tool invocations plus model tokens. See [Pricing](/docs/getting-started/pricing).
</Note>

## Limits / Quotas

`web_search` runs inside Agent API requests and is governed by Agent API request rate limits. See [Rate Limits & Usage Tiers](/docs/admin/rate-limits-usage-tiers#agent-api-rate-limits) for the current tier-based Agent API limits.

| Limit                 | Applies to                                                 | Guidance                                                                                                                            |
| --------------------- | ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| Rate limits           | Agent API requests that include `web_search`               | Agent API tier limits apply to the request. Add retry and backoff handling for production traffic.                                  |
| Domain entries        | `search_domain_filter`                                     | Up to 20 domains or URLs per request. Use either allowlist or denylist mode as described in the [Filters](#filters) warning.        |
| Search context budget | `search_context_size`, `max_tokens`, `max_tokens_per_page` | `search_context_size` presets manage context automatically. Use explicit token caps when you need tighter cost or latency controls. |
| Tool-call billing     | `web_search` invocations                                   | Each search invocation counts toward tool-call usage and pricing, separate from model token usage.                                  |

## Next Steps

<CardGroup cols={2}>
  <Card title="Fetch URL Content" icon="file-text" href="/docs/agent-api/tools/fetch-url-content">
    Fetch full content from known URLs.
  </Card>

  <Card title="People Search" icon="users" href="/docs/agent-api/tools/people-search">
    Search for professionals, employees, and people.
  </Card>

  <Card title="Agent API Presets" icon="settings" href="/docs/agent-api/presets">
    Use optimized presets for common Agent API workloads.
  </Card>

  <Card title="API Reference" icon="code-circle" href="/api-reference/agent-post">
    View complete endpoint documentation.
  </Card>
</CardGroup>
