Server-Side Tools
Server-side tools run inside Mixlayer. Add one to a request and the model can call it as needed; Mixlayer executes the call and returns the result to the model automatically. Your application does not need to implement the tool-call loop.
Web search
The web_search tool searches the public web using Exa. It is available over the OpenAI compatible Responses and Chat Completions endpoints.
{
"model": "qwen/qwen3.5-4b-free",
"input": "What changed in Rust this week? Include sources.",
"tools": [
{
"type": "web_search",
"category": "news",
"max_results": 5
}
],
"include": ["web_search_call.action.sources"]
}The model decides whether to search and may search more than once. You are charged for each search it performs, not merely for enabling the tool.
Options
| Option | Type | Default | Description |
|---|---|---|---|
category | string | — | Restricts results to company, people, research paper, news, personal site, or financial report. |
filters.allowed_domains | string[] | [] | Searches only these domains. Cannot be combined with blocked_domains. |
filters.blocked_domains | string[] | [] | Excludes these domains. Cannot be combined with allowed_domains and is not supported with the company or people category. |
user_location | object | — | Approximate user location used to localize the search. Its shape differs by API; see Location. |
max_results | integer | 10 | Maximum results returned by each search. Must be from 1 through 100. |
max_characters | integer | 10000 | Maximum text characters retrieved for each result. Must be greater than zero. |
Each domain list accepts at most 100 unique bare domain names such as example.com. Do not include a scheme, path, port, query, fragment, or wildcard. Domains are normalized to lowercase and a trailing dot is removed.
Location
Use an approximate location with any combination of country, city, region, and timezone. country must be a two-letter country code. timezone must be an IANA-style name such as America/Los_Angeles.
| Field | Type | Required | Description |
|---|---|---|---|
type | "approximate" | Yes | Location type. No other value is supported. |
country | string | No | Two-letter country code, normalized to uppercase. |
city | string | No | Non-empty city name. |
region | string | No | Non-empty region or state name. |
timezone | string | No | IANA-style timezone containing no whitespace. |
Responses uses a flat location object:
{
"type": "web_search",
"user_location": {
"type": "approximate",
"country": "US",
"city": "San Francisco",
"region": "California",
"timezone": "America/Los_Angeles"
}
}Chat Completions nests the location fields under approximate:
{
"web_search_options": {
"user_location": {
"type": "approximate",
"approximate": {
"country": "US",
"city": "San Francisco",
"region": "California",
"timezone": "America/Los_Angeles"
}
}
}
}Results and sources
For Responses, each completed search adds a web_search_call output item:
{
"type": "web_search_call",
"id": "ws_...",
"status": "completed",
"action": {
"type": "search",
"query": "Rust changes this week",
"sources": [
{"type": "url", "url": "https://example.com/article", "title": "Article title"}
]
}
}Pass include: ["web_search_call.action.sources"] to include action.sources; otherwise the source list is omitted. The search call item itself is always returned when a search runs.
For Chat Completions, sources are returned in choices[0].message.sources. Streaming responses send them in a choices[0].delta.sources chunk. Each source has url and title fields.
Both APIs report the number of searches in usage.server_tool_use.web_search_requests.
Responses streaming and WebSocket
Responses streaming emits these events for each search:
| Event | Meaning |
|---|---|
response.output_item.added | An in-progress web_search_call item was added. |
response.web_search_call.in_progress | The search call was initiated. |
response.web_search_call.searching | The search is being executed. |
response.web_search_call.completed | The search completed. |
response.output_item.done | The completed web_search_call item is available. |
The same request options, output items, and lifecycle events work over the Responses WebSocket transport. Put the web search tool in each response.create message where it should be available.
Pricing
| Usage | Price |
|---|---|
| Search request, including up to 10 results | $0.007 per search |
| Results above the first 10 | $0.001 per additional result |
Model input and output tokens are billed separately at the selected model’s rates. For example, one search returning 25 results incurs one search-request unit and 15 additional-result units, plus model token usage.
Combining tools
Web search can be used alongside your own function tools. web_search is reserved for the built-in tool, so custom functions cannot use that name. A request may include the built-in tool only once.