Skip to main content
Web research is always on. You do not need to pass a web_search tool to get a grounded answer. The tool still matters in two ways. Its filters restrict which domains are searched and cited, and every response reports the searches the model ran and the pages it read as web_search_call output items, in the same shape OpenAI returns them.

Domain filters

Pass the OpenAI web_search tool with filters to gate research to specific domains. The filters map onto Parallel’s Source Policy:
Entries follow the Source Policy rules. An apex domain such as sec.gov matches all of its subdomains, example.com/blog scopes the filter to a path prefix, and a bare extension such as .gov matches every domain with that extension. Schemes, ports, query strings, and fragments are not allowed, and a request may carry at most 200 entries across both lists. Invalid entries return a 400 with the same error message the Task API returns for the same source_policy.
Set one list per request. When both allowed_domains and blocked_domains are present, only the allow list applies. If any entry appears in both lists, including a subdomain of an allowed domain, the request is rejected with a 400. A request may contain at most one web_search tool. search_context_size and user_location are accepted and ignored.
The response echoes your web_search tool on tools. Every other tool type is accepted and ignored, and is not echoed.

Search trail

A completed response contains one web_search_call item per web action the model took, ahead of the message item. action.type says which kind:
Items appear in the order the model started them. Every item closes completed when research finishes; a page that could not be fetched is still reported as read. Read output by item type, or use the output_text accessor. Do not assume the first item is the message.
A run that answers without searching or reading a page returns no web_search_call items. Pages your domain filters exclude are never read and do not appear. A search whose results are all excluded by your filters still appears as a search item; the answer then states what it could not confirm instead of citing an excluded source. action.sources is always null, and include: ["web_search_call.action.sources"] is accepted and ignored. These searches and page reads are what surface the sources returned as url_citation annotations on the answer. See Citations for how to read them. With streaming enabled, each search and page read is announced as it starts, so web_search_call events are the first sign of progress on longer requests. The items close together once research finishes, after the answer’s text delta.