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.

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

OptionTypeDefaultDescription
categorystringRestricts results to company, people, research paper, news, personal site, or financial report.
filters.allowed_domainsstring[][]Searches only these domains. Cannot be combined with blocked_domains.
filters.blocked_domainsstring[][]Excludes these domains. Cannot be combined with allowed_domains and is not supported with the company or people category.
user_locationobjectApproximate user location used to localize the search. Its shape differs by API; see Location.
max_resultsinteger10Maximum results returned by each search. Must be from 1 through 100.
max_charactersinteger10000Maximum 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.

FieldTypeRequiredDescription
type"approximate"YesLocation type. No other value is supported.
countrystringNoTwo-letter country code, normalized to uppercase.
citystringNoNon-empty city name.
regionstringNoNon-empty region or state name.
timezonestringNoIANA-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:

EventMeaning
response.output_item.addedAn in-progress web_search_call item was added.
response.web_search_call.in_progressThe search call was initiated.
response.web_search_call.searchingThe search is being executed.
response.web_search_call.completedThe search completed.
response.output_item.doneThe 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

UsagePrice
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.