> For clean Markdown of any page, append `.md` to the page URL.
> Documentation index: https://you.com/docs/llms.txt (section indexes: append `/llms.txt` to any section URL).
> Search these docs: Docs MCP at https://you.com/docs/_mcp/server (`searchDocs`, no API key).
> Call live You.com APIs: Product MCP at https://api.you.com/mcp (keyless `?profile=free` exposes `you-search` and `you-discover`. Research and finance use `/mcp/research`, `/mcp/finance`, or `?tools=` on `/mcp`). To pick an API or integration path, call `you-discover` on that server instead of guessing.
> OpenAPI: https://you.com/docs/openapi.json—auth header `X-API-Key`, env `YDC_API_KEY`.

# Web Tools

Add a web tool to a request and the router runs the searches and page fetches the model asks for, using the [Web Search API](/docs/guides/search) and [Contents API](/docs/guides/contents). The model sees the results with citation numbers and writes its answer. The response lists every source in `web_results`.

---

## Tool Types

Declare these in `tools` on `/v1/chat/completions`.

| `type`              | Who runs it | What it does                                                                                  |
| ------------------- | ----------- | --------------------------------------------------------------------------------------------- |
| `web_search`        | The router  | Searches the web with the Web Search API.                                                     |
| `web_extract`       | The router  | Fetches page content with the Contents API.                                                   |
| `client:web_search` | Your code   | Declares a `web_search` function. The model's call comes back in `tool_calls` for you to run. |

A request can declare one `web_search` and one `web_extract`. A duplicate returns `400`.

```bash
curl https://api.you.com/v1/chat/completions \
  -H "Authorization: Bearer $YDC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "kimi-k3",
    "messages": [{"role": "user", "content": "What changed in the latest Python release?"}],
    "tools": [
      {"type": "web_search", "freshness": "month", "count": 5},
      {"type": "web_extract", "formats": ["markdown"]}
    ]
  }'
```

---

## `web_search` Parameters

All fields are optional and sit flat on the tool object. A value you set overrides the same parameter when the model supplies one. Search parameters match the [Web Search API](/docs/api-reference/search/v1-search).

| Parameter           | Type      | Description                                                                                                                                                   |
| ------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `max_search_rounds` | integer   | Maximum search rounds, 1 or more. Defaults to 30. Each round is one model call plus every search the model issued in it. At the limit, the model must answer. |
| `count`             | integer   | Results per search. The router uses 10 when unset and caps the value at 20.                                                                                   |
| `offset`            | integer   | Page offset, 0 through 9.                                                                                                                                     |
| `freshness`         | string    | `day`, `week`, `month`, `year`, or a date range in `YYYY-MM-DDtoYYYY-MM-DD` format.                                                                           |
| `country`           | string    | Two-letter ISO 3166-1 alpha-2 country code, such as `US`.                                                                                                     |
| `language`          | string    | BCP 47 language tag, such as `en` or `en-US`.                                                                                                                 |
| `safesearch`        | string    | `off`, `moderate`, or `strict`.                                                                                                                               |
| `exclude_domains`   | string\[] | Domains to leave out. Up to 500.                                                                                                                              |
| `boost_domains`     | string\[] | Domains to rank higher. Up to 500.                                                                                                                            |
| `crawl_timeout`     | integer   | Seconds to wait for page content, 1 through 60.                                                                                                               |

Other fields return `400`. Each search times out after 15 seconds.

## `web_extract` Parameters

The model chooses the URLs. You set how pages are fetched.

| Parameter       | Type      | Description                                                        |
| --------------- | --------- | ------------------------------------------------------------------ |
| `formats`       | string\[] | Any of `markdown`, `html`, and `metadata`. Defaults to `markdown`. |
| `crawl_timeout` | integer   | Seconds to wait for page content, 1 through 60.                    |
| `max_age`       | integer   | Maximum age of cached content in seconds. `0` ignores the cache.   |

The router fetches at most 5 distinct `http` or `https` URLs per call and bills each extracted page. A fetch times out after 30 seconds.

---

## Response

When a web tool runs, the response carries a `web_results` object next to `choices`. Citation numbers are shared across searches and extractions, so the model cites a fetched page the same way it cites a search result.

```json maxLines=30
{
  "choices": [{"message": {"role": "assistant", "content": "<answer text> [1]"}, "finish_reason": "stop"}],
  "web_results": {
    "searches": [
      {
        "query": "<search query>",
        "results": [
          {
            "citation": 1,
            "title": "<page title>",
            "url": "https://example.com/page",
            "snippet": "<extracted highlight>",
            "published_at": "<publication date>"
          }
        ]
      }
    ],
    "extracts": []
  }
}
```

`web_results` is absent when no search or fetch ran. In a stream, it arrives on the final chunk. Before it, the router sends named `web_search` and `web_extract` events that report each step with fields such as `status`, `round`, `query`, `result_count`, and `duration_ms`.

---

## Unsupported Shapes

The router returns `400` for other web-search shapes instead of grounding them silently:

* The `web_search_options` field.
* Tool types `web_search_preview` and any `web_search_*` type on `/v1/chat/completions`.
* A tool named `WebSearch` with no `input_schema`.
* Function tools named `litellm_web_search`, `you_web_search`, or `you_web_extract`.

---

## Anthropic Web Search on Messages

On `/v1/messages`, declare Anthropic's versioned `web_search_*` server tool, such as `web_search_20250305`. The router answers it with You.com search and returns `server_tool_use` and `web_search_tool_result` blocks for every search it ran.

```bash
curl https://api.you.com/v1/messages \
  -H "Authorization: Bearer $YDC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "kimi-k3",
    "max_tokens": 1024,
    "messages": [{"role": "user", "content": "What changed in the latest Python release?"}],
    "tools": [{"type": "web_search_20250305", "name": "web_search", "max_uses": 3}]
  }'
```

| Anthropic field         | Router behavior                                                                                                             |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `max_uses`              | Sets `max_search_rounds`. A round can run several searches in parallel, so a request can search more than `max_uses` times. |
| `blocked_domains`       | Maps to `exclude_domains`.                                                                                                  |
| `user_location.country` | Maps to `country`.                                                                                                          |
| `allowed_domains`       | Returns `400`. Use `blocked_domains`.                                                                                       |

Only one web search tool is allowed per request. The `web_search` and `web_extract` tool types are not documented for `/v1/messages`.