# Web search

> Enable web search with the web_search tool or OpenAI web_search_options on models marked web-search capable; search fees and token fees are billed separately.

Web search lets a chat model look up current information before answering instead of relying only on its training data. MirAPI exposes it through the `web_search` tool (plus `web_search_options` on the OpenAI protocol), and only on models marked web-search capable in the catalogue.

## How web search works

Web search runs as a tool call inside an ordinary chat request:

1. You add the web search tool to the request.
2. The model decides whether it needs fresh information and, if so, issues a search query.
3. MirAPI executes the search and returns the results into the conversation.
4. The model composes an answer from those results, citing sources where the model supports them.

## OpenAI protocol

On the OpenAI-compatible Responses API, enable search with the `web_search` tool or the `web_search_options` field:

```python
import os
from openai import OpenAI

client = OpenAI(base_url="https://api.mirapi.ai/v1", api_key=os.environ["MIRAPI_API_KEY"])

response = client.responses.create(
    model="deepseek-chat",
    input="What did MirAPI announce this week?",
    tools=[{"type": "web_search"}],
)

print(response.output_text)
```

Both forms turn on search; use whichever your client makes easier.

## Anthropic protocol

On the Anthropic Messages API, pass the `web_search` tool in the `tools` array:

```json
{
  "model": "deepseek-chat",
  "max_tokens": 1024,
  "tools": [
    {
      "type": "web_search"
    }
  ],
  "messages": [
    {
      "role": "user",
      "content": "What is the latest release of Claude Code?"
    }
  ]
}
```

The model calls the tool when it decides a search is needed, and MirAPI returns the results as tool content for the model to synthesize.

## Billing

Web search is billed on two lines:

- **Per search** — each executed search is charged as a search event.
- **Tokens** — the search results are fed back into the context and billed as ordinary input tokens; the model's final answer is billed as output tokens.

Both lines appear separately in the console billing log and in `GET /api/log/token`, so you can tell how much of a request's cost was search versus model tokens.

:::note
A non-streaming response's `usage` reports token counts only, not a dollar amount. Reconcile costs in the console usage log at https://console.mirapi.ai or with `GET /api/log/token`.
:::

## Model support

Web search is not universal. It works only on models whose catalogue entry lists the **web search** capability:

- Check the catalogue at https://console.mirapi.ai or with `GET /v1/models`, and look at each model's `supported_parameters` before relying on search.
- Send one test request and inspect the response for search citations or sources.
- Do not assume a model can search just because it supports tool calling; web search is a distinct capability.
- MirAPI never silently swaps in a different model. If the model cannot search, the request fails — pick a capable model instead.

## Errors and troubleshooting

- **401** — the API key is missing, invalid, or unknown. Fix your credentials.
- **403** — the key is valid but rejected (for example, an empty balance). Resolve the cause and retry; balance-based rejections recover immediately after top-up.
- **429** — rate limited. Retry with jittered exponential backoff (1s → 2s → 4s, capped at ~30s). MirAPI sends no `Retry-After` header.
- **5xx** — the model's channels are unavailable. Retry; idempotent requests are safe to retry.

Every error message ends with a request ID — include it when you open a support ticket.

## Related links

- [Models & pricing](/docs/models) — check which models advertise web search
- [Billing & top-ups](/docs/billing) — how token billing and top-ups work
- [Prompt caching](/docs/guides/prompt-caching) — reduce the cost of repeated context
- [Errors](/docs/api-reference/errors) — status codes and error envelopes