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

# Web Search

> Give models access to real-time web search results

## Overview

Web search is a built-in tool that allows models to search the web during a response. Unlike function tools, you don't need to define a schema or handle execution yourself — the model searches the web automatically and incorporates the results into its answer.

Add `{"type": "web_search"}` to your `tools` array to enable it.

Concentrate can service the search two ways: with the model provider's **native** web search, or with Concentrate's own **Exa**-backed engine. By default it picks the best available for the model, so most models can search the web even when they have no native support. See [Search engines](#search-engines) to control this.

## Prerequisites

Before using web search, ensure you have:

* A Concentrate AI API key ([get one here](https://concentrate.ai))
* A model that supports web search (check the [models endpoint](/docs/api-reference/endpoint/list-models))

## Quick Start

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.concentrate.ai/v1/responses \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -d '{
      "model": "gpt-5.2",
      "input": "What happened in the news today?",
      "tools": [
        {
          "type": "web_search"
        }
      ]
    }'
  ```

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

  response = requests.post(
      "https://api.concentrate.ai/v1/responses",
      headers={
          "Authorization": "Bearer YOUR_API_KEY",
          "Content-Type": "application/json"
      },
      json={
          "model": "gpt-5.2",
          "input": "What happened in the news today?",
          "tools": [{"type": "web_search"}]
      }
  )

  data = response.json()
  print(data)
  ```

  ```typescript TypeScript theme={null}
  const response = await fetch("https://api.concentrate.ai/v1/responses", {
    method: "POST",
    headers: {
      "Authorization": "Bearer YOUR_API_KEY",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      model: "gpt-5.2",
      input: "What happened in the news today?",
      tools: [{ type: "web_search" }]
    })
  });

  const data = await response.json();
  console.log(data);
  ```
</CodeGroup>

## Tool Parameters

| Parameter             | Type   | Required | Description                                                                                                              |
| --------------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------ |
| `type`                | string | Yes      | Must be `"web_search"`                                                                                                   |
| `engine`              | object | No       | Which search backend to use: `{"type": "auto"}` (default), `"native"`, or `"exa"`. See [Search engines](#search-engines) |
| `search_context_size` | string | No       | Amount of search context: `"low"`, `"medium"`, or `"high"`. Defaults to provider behavior                                |
| `filters`             | object | No       | Filter search results by domain                                                                                          |
| `user_location`       | object | No       | Approximate user location for localized results                                                                          |

<Note>
  `search_context_size`, `filters`, and `user_location` are not supported natively by Google Vertex AI (Gemini) or Mistral models, and are silently ignored when those providers run the search themselves. To have them honored on any model, route the search through the [Exa engine](#exa-engine).
</Note>

### Search Context Size

Controls how much search context the model uses. Higher values may return more detailed results but use more tokens.

```json theme={null}
{
  "type": "web_search",
  "search_context_size": "medium"
}
```

### Domain Filtering

Restrict search results to specific domains:

```json theme={null}
{
  "type": "web_search",
  "filters": {
    "allowed_domains": ["wikipedia.org", "bbc.com"]
  }
}
```

### User Location

Provide an approximate location for more relevant local results:

```json theme={null}
{
  "type": "web_search",
  "user_location": {
    "type": "approximate",
    "country": "US",
    "region": "California",
    "city": "San Francisco",
    "timezone": "America/Los_Angeles"
  }
}
```

All `user_location` fields are optional.

## Search engines

The optional `engine` field controls which backend runs the search:

| `engine.type`    | Behavior                                                                                                          |
| ---------------- | ----------------------------------------------------------------------------------------------------------------- |
| `auto` (default) | Use the provider's native web search when the model supports it; otherwise fall back to Concentrate's Exa engine. |
| `native`         | Always use the provider's built-in web search. Requires a model that supports it.                                 |
| `exa`            | Always use Concentrate's [Exa](https://exa.ai)-backed engine, regardless of provider.                             |

```json theme={null}
{
  "type": "web_search",
  "engine": { "type": "exa" }
}
```

### Exa engine

Concentrate runs its own web search through [Exa](https://exa.ai). This is what lets models with **no native web search** still search the web: under `auto`, Concentrate transparently runs the search for them. Set `engine.type` to `"exa"` to force this path even on models that support native search — useful for consistent behavior across providers.

Mechanically, Concentrate exposes an `exa_web_search` function tool to the model in place of the built-in tool. When the model calls it, Concentrate runs the query against Exa, feeds the results back, and repeats until the model stops searching or a turn limit is reached. The response you get back is identical to native search: a `web_search_call` item followed by the model's answer, with the source URLs attached.

Because Concentrate runs these searches itself, `search_context_size`, `filters`, and `user_location` are honored on every model routed through Exa — including Gemini and Mistral, which ignore them natively. `search_context_size` maps to the number of results fetched per query: `low` = 3, `medium` = 5 (default), `high` = 10.

### Pricing

Exa searches are billed separately from tokens, as `exa_web_search` tool calls, at \*\*$7.00 per 1,000 queries** ($0.007 per query). Each query in a search counts as one call. The count is reported in the response `usage`:

```json theme={null}
{
  "usage": {
    "input_tokens": 1234,
    "output_tokens": 567,
    "tool_calls": { "exa_web_search": 2 },
    "total_tokens": 1801
  }
}
```

Provider-native searches are billed by the provider through their normal pricing and appear under `web_search` instead.

## Response Format

When the model performs a web search, the response `output` array includes a `web_search_call` item:

```json theme={null}
{
  "output": [
    {
      "type": "web_search_call",
      "id": "ws_abc123",
      "status": "completed",
      "action": {
        "type": "search",
        "query": "latest news today",
        "sources": [
          {
            "type": "url",
            "url": "https://example.com/article"
          }
        ]
      }
    },
    {
      "type": "message",
      "role": "assistant",
      "content": [
        {
          "type": "output_text",
          "text": "Here's what's happening today..."
        }
      ]
    }
  ]
}
```

The `sources` array contains the URLs the model referenced. Use these to provide citations in your application.

## Combining with Function Tools

Web search works alongside function tools in the same request:

```json theme={null}
{
  "model": "gpt-5.2",
  "input": "Search for the latest Tesla stock price and convert it to EUR",
  "tools": [
    {
      "type": "web_search"
    },
    {
      "type": "function",
      "name": "convert_currency",
      "description": "Convert between currencies",
      "parameters": {
        "type": "object",
        "properties": {
          "amount": { "type": "number" },
          "from": { "type": "string" },
          "to": { "type": "string" }
        },
        "required": ["amount", "from", "to"]
      }
    }
  ]
}
```

### Provider Limitations

Google Vertex AI (Gemini) and Mistral models do not support using web search and function tools together in the same request. When both are provided, function tool calling takes priority and web search is ignored.

To use web search with these providers, use `tool_choice` to explicitly select it:

```json theme={null}
{
  "model": "gemini-2.5-pro",
  "input": "What happened in the news today?",
  "tools": [
    { "type": "web_search" },
    {
      "type": "function",
      "name": "convert_currency",
      "description": "Convert between currencies",
      "parameters": {
        "type": "object",
        "properties": {
          "amount": { "type": "number" },
          "from": { "type": "string" },
          "to": { "type": "string" }
        },
        "required": ["amount", "from", "to"]
      }
    }
  ],
  "tool_choice": {
    "type": "allowed_tools",
    "mode": "auto",
    "tools": [{ "type": "web_search" }]
  }
}
```

## Provider Support

Web search is supported across multiple providers:

| Provider         | Supported | Notes                                                                                                            |
| ---------------- | --------- | ---------------------------------------------------------------------------------------------------------------- |
| OpenAI           | Yes       | GPT-4o, GPT-4.1, GPT-5 family                                                                                    |
| Anthropic        | Yes       | Claude Sonnet, Opus, Haiku models                                                                                |
| xAI              | Yes       | Grok-4 family                                                                                                    |
| Google Vertex AI | Yes       | Gemini models. No `search_context_size`/`filters` support. Cannot combine with function tools                    |
| Mistral          | Yes       | Mistral Small, Medium, Magistral. No `search_context_size`/`filters` support. Cannot combine with function tools |

<Note>
  The table above reflects **native** support only. Through the [Exa engine](#exa-engine), web search also works on models with no native support, as long as they support [function tool calling](/docs/api-reference/endpoint/tool-calling).
</Note>

Check specific model support using the [List Models](/docs/api-reference/endpoint/list-models) endpoint.

***

## Related Pages

<CardGroup cols={2}>
  <Card title="Tool Calling" icon="wrench" href="/docs/api-reference/endpoint/tool-calling">
    Define custom function tools
  </Card>

  <Card title="Create Response" icon="code" href="/docs/api-reference/endpoint/create-response">
    Main API endpoint reference
  </Card>
</CardGroup>
