> ## Documentation Index
> Fetch the complete documentation index at: https://docs.abliteration.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenAI Responses API

> Use web search with the Responses API, select tools, restrict domains, and handle streamed results.

`POST /v1/responses`

Add a `web_search` entry to the `tools` array. The model requests a search, and the results are returned to the model so it can use them in its answer.

## Request

```python theme={"system"}
import os

from openai import OpenAI

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

resp = client.responses.create(
    model="abliterated-model-large-v2",
    input=(
        "Use web search to find IANA documentation describing what example.com is "
        "reserved for. Cite the official source and answer in one sentence."
    ),
    tools=[{"type": "web_search"}],
    tool_choice="required",
    reasoning={"effort": "low"},
    max_output_tokens=6000,
)

print(resp.output_text)
```

Accepted type aliases: `web_search`, `web_search_preview`, `web_search_2025_08_26`, `web_search_preview_2025_03_11`.

## Select a tool

| `tool_choice` | Behavior |
| - | - |
| `"auto"` | The model decides whether to use a tool. This is the default. |
| `"required"` | Requires tool use. With only `web_search` available, this requires a search. |
| `{"type": "web_search"}` | Selects web search specifically when other tools are also available. |
| `"none"` | Disables tool use for the request. |

Use string values for `"auto"`, `"required"`, and `"none"`. To select web search specifically, set:

```python theme={"system"}
tool_choice={"type": "web_search"}
```

Requiring a search does not run it before the model starts. The model first generates the search request, then uses the results to continue its response.

## Restrict search domains

Set `filters.allowed_domains` on the web-search tool:

```python theme={"system"}
resp = client.responses.create(
    model="abliterated-model-large-v2",
    input="Find IANA documentation explaining what example.com is reserved for.",
    tools=[{
        "type": "web_search",
        "filters": {"allowed_domains": ["iana.org"]},
    }],
    tool_choice="required",
    reasoning={"effort": "low"},
    max_output_tokens=6000,
)
```

Use domain names such as `iana.org`, without `http://` or `https://` prefixes.

Project domain policies also apply:

* If both the project and request specify allowed domains, searches use their intersection. A request with no permitted overlap returns `400`.
* If the request omits allowed domains, the project's allow list still applies.
* Project blocked domains apply to every search. The request filter supports only `allowed_domains`.

## Streaming

Set `stream=True` to receive server-sent events. Search results appear as `web_search_call` output items, and the answer arrives as text deltas.

| Event | What to handle |
| - | - |
| `response.created` | Starts the response lifecycle. |
| `response.output_item.added` | Adds an output item. Check `item.type` to distinguish `web_search_call` from other items. |
| `response.output_item.done` | Provides the finished output item. Match it to the added item by ID. |
| `response.output_text.delta` | Adds text to the answer. |
| `response.completed` | Provides the completed response and its output. |
| `response.incomplete` | Ends the response with partial output. Check `incomplete_details`. |
| `error` | Reports a failed request. Read its `code`, `message`, and `param` when provided. |

These are the main events to handle, not an exhaustive sequence. A search item can already have `status: "completed"` when it is added. Do not depend on receiving separate `response.web_search_call.in_progress`, `response.web_search_call.searching`, or `response.web_search_call.completed` events.

Use item IDs to reconcile streamed items with the final response. The final output contains the same items; appending it to the streamed output can duplicate the answer.

## Streaming errors

HTTP `200` means the stream opened. The request can still fail with an `error` event, including when a request parameter is invalid. An error is not a completed response, and the stream can end without `response.completed`.

Handle errors as you read the stream. If it closes without `response.completed`, `response.incomplete`, or an error, treat the response as interrupted. See [API errors](/api/errors) for general error handling.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.