# Web search

Allow models to search the web for the latest information before generating a
response.

Web search allows models to access up-to-date information from the internet and
provide answers with sourced citations. To enable this, use the web search tool
in the Responses API or, in some cases, Chat Completions.

There are three main types of web search available with OpenAI models:

1.  Nonâreasoning web search: The non-reasoning model sends the userâs query to
    the web search tool, which returns the response based on top results.
    Thereâs no internal planning and the model simply passes along the search
    toolâs responses. This method is fast and ideal for quick lookups.
2.  Agentic search with reasoning models is an approach where the model actively
    manages the search process. It can perform web searches as part of its chain
    of thought, analyze results, and decide whether to keep searching. This
    flexibility makes agentic search well suited to complex workflows, but it
    also means searches take longer than quick lookups. For example, you can
    adjust GPT-5âs reasoning level to change both the depth and latency of the
    search.
3.  Deep research is a specialized, agent-driven method for in-depth, extended
    investigations by reasoning models. The model conducts web searches as part
    of its chain of thought, often tapping into hundreds of sources. Deep
    research can run for several minutes and is best used with background mode.
    These tasks typically use models like `o3-deep-research`,
    `o4-mini-deep-research`, or `gpt-5` with reasoning level set to `high`.

Using the
[Responses API](https://platform.openai.com/docs/api-reference/responses), you
can enable web search by configuring it in the `tools` array in an API request
to generate content. Like any other tool, the model can choose to search the web
or not based on the content of the input prompt.

```javascript
import OpenAI from "openai";
const client = new OpenAI();

const response = await client.responses.create({
  model: "gpt-5",
  tools: [{ type: "web_search" }],
  input: "What was a positive news story from today?",
});

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

```python
from openai import OpenAI
client = OpenAI()

response = client.responses.create(
    model="gpt-5",
    tools=[{"type": "web_search"}],
    input="What was a positive news story from today?"
)

print(response.output_text)
```

```bash
curl "https://api.openai.com/v1/responses" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $OPENAI_API_KEY" \
    -d '{
        "model": "gpt-5",
        "tools": [{"type": "web_search"}],
        "input": "what was a positive news story from today?"
    }'
```

## Web search tool versions

The `web_search` tool is generally available with the Responses API, and is
compatible with the models:

- gpt-4o-mini
- gpt-4o
- gpt-4.1-mini
- gpt-4.1
- o4-mini
- o3
- gpt-5 with reasoning levels `low`, `medium` and `high`

The previous version the web search tool, `web_search_preview` , is still
available with both the Chat Completions API and the Responses API; it points to
a dated version`web_search_preview_2025_03_11`. As the tool evolves, future
dated snapshot versions will be documented in the
[API reference](https://platform.openai.com/docs/api-reference/responses/create).

## Output and citations

Model responses that use the web search tool will include two parts:

- A `web_search_call` output item with the ID of the search call, along with the
  action taken in `web_search_call.action`. The action is one of:
  - `search`, which represents a web search. It will usually (but not always)
    includes the search `query` and `domains` which were searched. Search
    actions incur a tool call cost (see
    [pricing](https://platform.openai.com/docs/pricing#built-in-tools)).
  - `open_page`, which represents a page being opened. Only emitted by Deep
    Research models.
  - `find_in_page`, which represents searching within a page. Only emitted by
    Deep Research models.
- A `message` output item containing:
  - The text result in `message.content[0].text`
  - Annotations `message.content[0].annotations` for the cited URLs

By default, the model's response will include inline citations for URLs found in
the web search results. In addition to this, the `url_citation` annotation
object will contain the URL, title and location of the cited source.

When displaying web results or information contained in web results to end
users, inline citations must be made clearly visible and clickable in your user
interface.

```json
[
  {
    "type": "web_search_call",
    "id": "ws_67c9fa0502748190b7dd390736892e100be649c1a5ff9609",
    "status": "completed"
  },
  {
    "id": "msg_67c9fa077e288190af08fdffda2e34f20be649c1a5ff9609",
    "type": "message",
    "status": "completed",
    "role": "assistant",
    "content": [
      {
        "type": "output_text",
        "text": "On March 6, 2025, several news...",
        "annotations": [
          {
            "type": "url_citation",
            "start_index": 2606,
            "end_index": 2758,
            "url": "https://...",
            "title": "Title..."
          }
        ]
      }
    ]
  }
]
```

## Domain filtering

Domain filtering in web search lets you limit results to a specific set of
domains. With the `filters` parameter you can set an allow-list of up to 20
domains. When formatting domain URLs, omit the HTTP or HTTPS prefix. For
example, use openai.com instead of https://openai.com/. This approach also
includes subdomains in the search. Note that domain filtering is only available
in the Responses API with the `web_search` tool.

## Sources

To get greater visibility into the actual domains used by the web search tool,
use `sources`. This returns all the sources the model referenced when forming
its response. The difference between citations and sources is that citations are
optional, and there are often fewer citations than the total number of source
URLs searched. Citations appear inline with the response, while sources provide
developers with the full list of domains. Third-party specialized domains used
during search are labeled as `oai-sports`, `oai-weather`, or `oai-finance`.
Sources are available with both the `web_search` and `web_search_preview` tools.

```bash
curl "https://api.openai.com/v1/responses" -H "Content-Type: application/json" -H "Authorization: Bearer $OPENAI_API_KEY" -d '{
  "model": "gpt-5",
  "reasoning": { "effort": "low" },
  "tools": [
    {
      "type": "web_search",
      "filters": {
        "allowed_domains": [
          "pubmed.ncbi.nlm.nih.gov",
          "clinicaltrials.gov",
          "www.who.int",
          "www.cdc.gov",
          "www.fda.gov"
        ]
      }
    }
  ],
  "tool_choice": "auto",
  "include": ["web_search_call.action.sources"],
  "input": "Please perform a web search on how semaglutide is used in the treatment of diabetes."
}'
```

```javascript
import OpenAI from "openai";
const client = new OpenAI();

const response = await client.responses.create({
  model: "gpt-5",
  reasoning: { effort: "low" },
  tools: [
    {
      type: "web_search",
      filters: {
        allowed_domains: [
          "pubmed.ncbi.nlm.nih.gov",
          "clinicaltrials.gov",
          "www.who.int",
          "www.cdc.gov",
          "www.fda.gov",
        ],
      },
    },
  ],
  tool_choice: "auto",
  include: ["web_search_call.action.sources"],
  input:
    "Please perform a web search on how semaglutide is used in the treatment of diabetes.",
});

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

```python
from openai import OpenAI
client = OpenAI()

response = client.responses.create(
model="gpt-5",
reasoning={"effort": "low"},
tools=[
{
"type": "web_search",
"filters": {
"allowed_domains": [
"pubmed.ncbi.nlm.nih.gov",
"clinicaltrials.gov",
"www.who.int",
"www.cdc.gov",
"www.fda.gov"
]
}
}
],
tool_choice="auto",
include=["web_search_call.action.sources"],
input="Please perform a web search on how semaglutide is used in the treatment of diabetes."
)

print(response.output_text)
```

## User location

To refine search results based on geography, you can specify an approximate user
location using country, city, region, and/or timezone.

- The `city` and `region` fields are free text strings, like `Minneapolis` and
  `Minnesota` respectively.
- The `country` field is a two-letter ISO country code, like `US`.
- The `timezone` field is an IANA timezone like `America/Chicago`.

Note that user location is not supported for deep research models using web
search.

```python
from openai import OpenAI
client = OpenAI()

response = client.responses.create(
    model="o4-mini",
    tools=[{
        "type": "web_search",
        "user_location": {
            "type": "approximate",
            "country": "GB",
            "city": "London",
            "region": "London",
        }
    }],
    input="What are the best restaurants around Granary Square?",
)

print(response.output_text)
```

```javascript
import OpenAI from "openai";
const openai = new OpenAI();

const response = await openai.responses.create({
  model: "o4-mini",
  tools: [
    {
      type: "web_search",
      user_location: {
        type: "approximate",
        country: "GB",
        city: "London",
        region: "London",
      },
    },
  ],
  input: "What are the best restaurants around Granary Square?",
});
console.log(response.output_text);
```

```bash
curl "https://api.openai.com/v1/responses" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $OPENAI_API_KEY" \
    -d '{
        "model": "o4-mini",
        "tools": [{
            "type": "web_search",
            "user_location": {
                "type": "approximate",
                "country": "GB",
                "city": "London",
                "region": "London"
            }
        }],
        "input": "What are the best restaurants around Granary Square?"
    }'
```

## Search context size

When using this tool, the `search_context_size` parameter controls how much
context is retrieved from the web to help the tool formulate a response. The
tokens used by the search tool do **not** affect the context window of the main
model specified in the `model` parameter in your response creation request.
These tokens are also **not** carried over from one turn to another â they're
simply used to formulate the tool response and then discarded.

Choosing a context size impacts:

- **Cost**: Search content tokens are free for some models, but may be billed at
  a model's text token rates for others. Refer to
  [pricing](https://platform.openai.com/docs/pricing#built-in-tools) for
  details.
- **Quality**: Higher search context sizes generally provide richer context,
  resulting in more accurate, comprehensive answers.
- **Latency**: Higher context sizes require processing more tokens, which can
  slow down the tool's response time.

Available values:

- **`high`**: Most comprehensive context, slower response.
- **`medium`** (default): Balanced context and latency.
- **`low`**: Least context, fastest response, but potentially lower answer
  quality.

Context size configuration is not supported for o3, o3-pro, o4-mini, and deep
research models.

```python
from openai import OpenAI
client = OpenAI()

response = client.responses.create(
    model="gpt-4.1",
    tools=[{
        "type": "web_search_preview",
        "search_context_size": "low",
    }],
    input="What movie won best picture in 2025?",
)

print(response.output_text)
```

```javascript
import OpenAI from "openai";
const openai = new OpenAI();

const response = await openai.responses.create({
  model: "gpt-4.1",
  tools: [
    {
      type: "web_search_preview",
      search_context_size: "low",
    },
  ],
  input: "What movie won best picture in 2025?",
});
console.log(response.output_text);
```

```bash
curl "https://api.openai.com/v1/responses" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $OPENAI_API_KEY" \
    -d '{
        "model": "gpt-4.1",
        "tools": [{
            "type": "web_search_preview",
            "search_context_size": "low"
        }],
        "input": "What movie won best picture in 2025?"
    }'
```

## Usage notes

| API Availability | Rate limits | Notes |
| ---------------- | ----------- | ----- |

| [Responses](https://platform.openai.com/docs/api-reference/responses)

[Chat Completions](https://platform.openai.com/docs/api-reference/chat)

[Assistants](https://platform.openai.com/docs/api-reference/assistants)

|

Same as tiered rate limits for underlying
[model](https://platform.openai.com/docs/models) used with the tool.

|

[Pricing](https://platform.openai.com/docs/pricing#built-in-tools)  
[ZDR and data residency](https://platform.openai.com/docs/guides/your-data)

|

#### Limitations

- Web search is currently not supported in
  [gpt-5](https://platform.openai.com/docs/models/gpt-5) with `minimal`
  [gpt-4.1-nano](https://platform.openai.com/docs/models/gpt-4.1-nano) model.
- When used as a tool in the
  [Responses API](https://platform.openai.com/docs/api-reference/responses), web
  search has the same tiered rate limits as the models above.
- Web search is limited to a context window size of 128000 (even with
  [gpt-4.1](https://platform.openai.com/docs/models/gpt-4.1) and
  [gpt-4.1-mini](https://platform.openai.com/docs/models/gpt-4.1-mini) models).
- [Refer to this guide](https://platform.openai.com/docs/guides/your-data) for
  data handling, residency, and retention information.