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

# Responses.

> The OpenAI Responses dialect on the Sideren catalog — the wire protocol the Codex CLI uses. Send input, receive typed output items, stream with SSE.

## Endpoint

```http theme={null}
POST /v1/responses
```

Authenticate with `Authorization: Bearer sdn_...`. This is the surface a Codex provider
block with `wire_api = "responses"` talks to — see the
[Codex CLI guide](/guides/codex).

## Request parameters

| Parameter | Type | Notes |
| - | - | - |
| `model` | string · required | Any catalog id. |
| `input` | string \| array · required | A plain string, or a list of input items (messages, tool results). |
| `instructions` | string | System-level guidance for the run. |
| `max_output_tokens` | integer | Output ceiling. On reasoning models, hidden reasoning counts against it. |
| `temperature` | number | Sampling temperature. |
| `tools` | array | Function, custom and namespaced tools, carried exactly as sent. See [Tool calling](/guides/tool-calling). |
| `stream` | boolean | SSE event stream when true. |
| `reasoning` | object | Opt into visible reasoning; `reasoning.effort` sets the level. See [Reasoning](/guides/reasoning). |
| `store` | boolean | Persist this response so it can be chained on or re-read. Defaults to `true`, the OpenAI default; send `store: false` to opt out. See [Stateful conversations](#stateful-conversations). |
| `previous_response_id` | string | Continue from a stored response, sending only the new input items. |
| `prompt_cache_key` | string | A conversation-stable identity hint that keeps a session on a warm cache; `safety_identifier` and `user` are accepted as fallbacks. See [Prompt caching](/guides/prompt-caching). |

<Note>
  On reasoning models a very small `max_output_tokens` can be consumed entirely by hidden
  reasoning, leaving an empty `output_text`. If you see empty outputs, raise the budget —
  4,000+ is a safe floor for reasoning models.
</Note>

## Example

<CodeGroup>
  ```sh curl theme={null}
  curl https://api.sideren.io/v1/responses \
    -H "authorization: Bearer $SIDEREN_API_KEY" \
    -H "content-type: application/json" \
    -d '{
      "model": "@sdn/gpt-oss-120b",
      "input": "Say hi."
    }'
  ```

  ```python Python theme={null}
  from openai import OpenAI

  client = OpenAI(
      base_url="https://api.sideren.io/v1",
      api_key="sdn_your_key",
  )

  r = client.responses.create(
      model="@sdn/gpt-oss-120b",
      input="Say hi.",
  )
  print(r.output_text)
  ```

  ```ts TypeScript theme={null}
  import OpenAI from "openai";

  const client = new OpenAI({
    baseURL: "https://api.sideren.io/v1",
    apiKey: process.env.SIDEREN_API_KEY,
  });

  const r = await client.responses.create({
    model: "@sdn/gpt-oss-120b",
    input: "Say hi.",
  });
  console.log(r.output_text);
  ```
</CodeGroup>

```json title="Response (shape)" theme={null}
{
  "id": "resp_...",
  "object": "response",
  "model": "@sdn/gpt-oss-120b",
  "output": [{
    "type": "message",
    "role": "assistant",
    "content": [{ "type": "output_text", "text": "Hi." }]
  }],
  "usage": { "input_tokens": 14, "output_tokens": 3 }
}
```

## Streaming

With `stream: true` the response is an SSE event stream — typed events such as
`response.output_text.delta` as text generates, closed by `response.completed`. The
OpenAI SDKs' `responses.stream(...)` helpers consume it unchanged. See
[Streaming](/guides/streaming).

## Stateful conversations

Responses is the one chat dialect that can hold the conversation for you. A response is
persisted under your key by default (`store` defaults to `true`); a later turn then chains
on it by id and sends **only the new input**, instead of re-uploading the whole transcript.
This is the OpenAI SDK's default conversation pattern, and it works here unchanged.

```sh title="Turn 1" theme={null}
curl https://api.sideren.io/v1/responses \
  -H "authorization: Bearer $SIDEREN_API_KEY" \
  -H "content-type: application/json" \
  -d '{"model":"@sdn/gpt-oss-120b","input":"Remember the number 42.","store":true}'
```

```sh title="Turn 2 — chain on it" theme={null}
curl https://api.sideren.io/v1/responses \
  -H "authorization: Bearer $SIDEREN_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "model": "@sdn/gpt-oss-120b",
    "previous_response_id": "resp_...",
    "input": "What number did I ask you to remember?"
  }'
```

Both fields are echoed back on every envelope, so a client can always see what it is
chained to.

### Reading a stored response back

```http theme={null}
GET /v1/responses/{id}
```

Returns the exact envelope you already received — the same bytes, replayed. Authenticated
like every other data route, and scoped to your key: an id belonging to someone else is a
`404`, never their response.

```sh theme={null}
curl https://api.sideren.io/v1/responses/resp_123 \
  -H "authorization: Bearer $SIDEREN_API_KEY"
```

<Note>
  Chaining on an unknown or expired id is a `404` with an `invalid_request_error` body,
  naming only the id you sent. That is deliberate: a loud failure beats a conversation that
  silently lost its history and answers as if the earlier turns never happened.
</Note>

Stored responses are kept for **24 hours** — a session store for live conversations, not an
archive — and are scoped to the key that created them. Envelopes larger than **512 KB** are
not stored; chaining on one then fails with the same loud `404`, so send the full
transcript for very large turns instead.

## Errors

Standard status codes, OpenAI-shaped bodies. Retry on `429`/`5xx` with backoff and honor
`retry-after`. Full reference: [Errors](/errors).


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