# Responses

> POST /v1/responses and its persisted-state siblings — the OpenAI Responses contract.

URL: https://boelabs.com/en/docs/ai-gateway/responses
Language: English

Generate responses, continue conversations, and use tools through the OpenAI Responses contract.
Use a public model configured for text generation and a virtual key allowed to call it.

## Example request

Set `GATEWAY` to the gateway origin and `API_KEY` to your virtual key. Replace the example
public model with one from [Model discovery](https://boelabs.com/docs/ai-gateway/models-discovery).

```bash
curl -X POST "$GATEWAY/v1/responses" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "model": "general", "input": "Say hi" }'
```

Same canonical core as [Chat completions](https://boelabs.com/docs/ai-gateway/chat-completions), rendered through the Responses
shape: `input` instead of `messages`, `text.format` instead of `response_format`,
`reasoning: { effort, summary }` instead of `reasoning_effort`, plus multi-turn state the client doesn't
have to resend by hand.

`input_file` accepts provider file IDs, HTTPS URLs, and base64 data. Native transports receive the
original file form when possible; Gemini URLs are materialized to inline data, and text-only
deployments receive an explicit parser fallback. See [Content inputs](https://boelabs.com/docs/ai-gateway/file-inputs).

`input_image` likewise accepts HTTPS or base64 data URLs. The same candidate-aware resolver preserves
native URLs where supported and securely materializes them for inline-only transports, so historical
images remain portable when a Responses conversation is replayed through another provider.

The router prefers the native Responses transport when a deployment supports it. Inputs that only
exist on this wire, such as built-in tools or native item types, are preserved verbatim and require a
native deployment; they are never silently erased during conversion to another text protocol.

## Persisted state

Unlike Chat Completions, a Response can be **stored** and referenced later:

- **`store`** (boolean) — whether to persist this response. Defaults to `RESPONSES_STORE_DEFAULT`
  (gateway-wide, `true` by default; set `false` gateway-wide for a privacy-first deployment) when the
  client omits it.
- **`previous_response_id`** — chains a new request onto a previously stored one: the gateway
  reconstructs the full input (the previous request's input + its output) and prepends it, so the
  client only sends the new turn. Returns `400 previous_response_not_found` if the referenced id
  doesn't exist **or belongs to a different virtual key** — stored state is scoped per key, the same
  way rate limits and budgets are.
- **`GET /v1/responses/:id`** — retrieve a previously stored response.
- **`GET /v1/responses/:id/input_items`** — list the resolved input items (including anything
  inherited via `previous_response_id`).
- **`DELETE /v1/responses/:id`** — delete stored state early, before its retention window
  (`RESPONSES_STATE_RETENTION_DAYS`) expires it automatically.

Stored state lives in Postgres (`response_states`), separate from observability tables — it exists to
reconstruct conversation state, not for observability. See
[Environment variables](https://boelabs.com/docs/ai-gateway/reference-environment#requests-logging-and-limits) for the retention
variable and [Operations → `response_states` GC](https://boelabs.com/docs/ai-gateway/operations#response_states-gc) for how expiry
actually runs.

When `store: false`, the client owns the full conversation state. Echo output items back as they were
returned: opaque provider state rides inside function calls and reasoning items, so clients that replay
ids and items verbatim need no provider-specific handling. Encrypted reasoning content is included in
the public response only when `include` requests it; internal persisted state retains it for faithful
continuation. See
[Provider-specific fields](https://boelabs.com/docs/ai-gateway/provider-specific-fields).

## Compaction

`POST /v1/responses/compact` accepts `model` plus `input`, `previous_response_id`, `instructions`, and
`prompt_cache_key`. It returns a `response.compaction` resource whose opaque output item can be sent
back in a later Responses request. The capsule is encrypted locally, contains a concise continuation
summary rather than the full transcript, and is expanded only by the same gateway instance.

## `text.format`

Maps to the same canonical `responseFormat` as Chat Completions' `response_format` — `text`,
`json_object`, or `json_schema`. See [Chat completions → Structured outputs](https://boelabs.com/docs/ai-gateway/chat-completions#structured-outputs).

## Reasoning

`reasoning: { "effort": "high", "summary": "auto" }` — the object form of the same canonical knob
described in [Reasoning](https://boelabs.com/docs/ai-gateway/reasoning). `summary` controls whether the model's reasoning is
surfaced back (`auto`, `none`, `concise`, `detailed`).

Providers may surface visible reasoning as either `summary[].summary_text` or
`content[].reasoning_text`. When one representation is empty or absent, AI Gateway mirrors the other
into it on the same reasoning item. Streams expose the corresponding summary and content delta/done
events together; this applies equally to SSE and Responses WebSocket turns.

Mirroring shapes what AI Gateway **returns**. A `reasoning` item replayed on input is sent upstream
with only what the provider produced — its id, `encrypted_content`, and summary — because request
schemas accept `content` on a reasoning item solely as an empty array. Clients may send the mirrored
item back untouched; the extra half is dropped for them.

## `responsesTransport` passthrough

Fields specific to the Responses wire contract that don't have a Chat Completions equivalent —
`include`, `metadata`, `service_tier`, `safety_identifier`, `prompt_cache_key`, `top_logprobs`,
`max_tool_calls`, `truncation`, `context_management`, and `user` — are threaded through as-is to
providers that support the Responses transport natively. Response resources include the complete
nullable and defaulted field set required by the current OpenResponses resource schema.

## Streaming

Same SSE mechanics as every other endpoint. Terminal upstream failure events are surfaced as errors,
and a stored stream is committed before its terminal success event is emitted. See
[Streaming](https://boelabs.com/docs/ai-gateway/streaming).

## WebSocket mode

Open a persistent connection to `wss://YOUR_GATEWAY/v1/responses` using the same bearer key as HTTP.
Each turn starts with a top-level `response.create` object:

```json
{
  "type": "response.create",
  "model": "general",
  "store": false,
  "input": "Find the bug"
}
```

Do not send the HTTP-only `stream`, `stream_options`, or `background` fields. Server messages are the
normal JSON `response.*` streaming event objects, without SSE framing. A connection processes one
turn at a time; additional `response.create` messages are queued in arrival order. Open another
connection for parallel runs.

The connection keeps the most recent response state in memory. Continue with only new items and its
public id:

```json
{
  "type": "response.create",
  "model": "general",
  "store": false,
  "previous_response_id": "resp_...",
  "input": [
    {
      "type": "function_call_output",
      "call_id": "call_...",
      "output": "tool result"
    }
  ]
}
```

This works with `store: false` while the socket remains open. After reconnecting, only `store: true`
responses can be hydrated from Postgres; otherwise send the complete context or a compacted window.
Connections close after 60 minutes with `websocket_connection_limit_reached`.

`generate: false` performs an OpenAI-compatible warmup. Providers without native Responses
WebSockets receive a gateway-local semantic warmup. When the selected OpenAI deployment supports
the native transport, the gateway maintains a separate upstream socket and private upstream response
id. Public ids and events are still regenerated through the canonical core; provider traffic is
never passed directly to the client.

## Next steps

- [Chat completions](https://boelabs.com/docs/ai-gateway/chat-completions) — the fields shared between both contracts.
- [Reasoning](https://boelabs.com/docs/ai-gateway/reasoning) — the `reasoning` object in full.
- [Security](https://boelabs.com/docs/ai-gateway/security) — why stored responses are scoped per virtual key.

