# Responses > POST /responses reference: parameter support status, stream events, where usage.cost appears, errors and examples. Responses are not stored; previous_response_id is rejected. Source: https://kiln.bricksum.com/docs/en/api-reference/responses `POST https://api.bricksum.com/v1/responses` Generates a model response in the OpenAI Responses format. The gateway forwards the request body and the stream events to the model server unchanged, and meters the tokens. Responses are not stored on the gateway, so each request must carry the full conversation in input. Codex CLI talks to Kiln over this endpoint. The provider block is on the [Integrations page, under Codex CLI](https://kiln.bricksum.com/docs/en/integrations#codex). ## Authentication Authentication is the same on every endpoint the gateway fronts, and is documented on the [API Reference](https://kiln.bricksum.com/docs/en/api-reference) page. ## Request body | Status | Description | | --- | --- | | supported | The gateway handles it, or a published measurement shows it works. | | passed through | Forwarded to the model server; not verified by Kiln. | | ignored | Accepted with 200, but not applied. The rest of the response is normal. | | not supported | Rejected with an error, or not working on the models named in the description. | ### Common parameters These are documented once on the [API Reference](https://kiln.bricksum.com/docs/en/api-reference) page. Listed here with what this endpoint does differently. | Field | Type | required | Default | Status | Description | | --- | --- | --- | --- | --- | --- | | `model` | string | required | | supported | Same as the shared definition. | | `stream` | boolean | | `false` | supported | The gateway also reads the string "true" and the number 1 as true, and rewrites the field to a boolean before forwarding. It does not add stream_options to a Responses request. | | `tools` | array | | | passed through | Forwarded to the model server; not verified by Kiln. | | `tool_choice` | string \| object | | | passed through | Forwarded to the model server; not verified by Kiln. On qwen3-32b (measured 2026-09-26), forced tool choice fails without a clear error: tool_choice "required" returns HTTP 500 with a plain-text "Internal Server Error" body, and naming a function returns 200 with empty arguments (finish_reason "stop"). Neither is a 4xx, so do not retry it — send tool_choice "auto" only. | ### Only on this endpoint | Field | Type | required | Default | Status | Description | | --- | --- | --- | --- | --- | --- | | `input` | string \| array | required | | supported | A text prompt, or an array of input items (messages, function calls and function call outputs). Send the whole conversation each time. The gateway forwards the value unchanged and does not validate it. | | `previous_response_id` | string | | | not supported | Rejected with 400 (unsupported_parameter) before the request reaches the model, and not billed. Responses are not stored on the gateway, so there is no earlier response to continue. A null value is accepted. | | `store` | boolean | | | passed through | Forwarded to the model server as sent. Whatever the value, a response cannot be read back through Kiln: GET /responses/{id}, DELETE /responses/{id} and GET /responses/{id}/input_items answer 404 (not_found). | | `instructions` | string | | | passed through | System-level instructions for this request. Forwarded to the model server; not verified by Kiln. | | `max_output_tokens` | integer | | | passed through | Maximum number of tokens to generate. Forwarded to the model server; not verified by Kiln. A generation that the model server ends early closes with response.incomplete, and its tokens are billed. | | `parallel_tool_calls` | boolean | | | passed through | Forwarded to the model server; not verified by Kiln. On qwen3-32b the parallel_tool_calls setting is not applied, which is not the same as replies holding one call: even with parallel_tool_calls: false, one reply can carry several tool calls. Answer every entry in tool_calls with its own tool message. | | `reasoning` | object | | | passed through | Forwarded to the model server; not verified by Kiln. | | `text` | object | | | passed through | Forwarded to the model server; not verified by Kiln. | | `temperature` | number | | | passed through | Forwarded to the model server; not verified by Kiln. Range: 0–2 | | `top_p` | number | | | passed through | Forwarded to the model server; not verified by Kiln. Range: 0–1 | | `truncation` | string | | | passed through | Forwarded to the model server; not verified by Kiln. | | `include` | array | | | passed through | Forwarded to the model server; not verified by Kiln. | | `metadata` | object | | | passed through | Forwarded to the model server; not verified by Kiln. | | `user` | string | | | passed through | Forwarded to the model server; not verified by Kiln. | OpenAI Responses parameters that are not listed here are forwarded to the model server in the same way. Kiln has not verified them. ## Response body | Field | Type | Description | | --- | --- | --- | | `id` | string | ID of the response. It cannot be used to fetch the response later. | | `object` | string | "response". | | `status` | string | "completed", or "incomplete" when generation was cut short. | | `output` | array | Output items from the model server: messages with output_text parts, and function calls. Forwarded unchanged. | | `usage.input_tokens` | integer | Input tokens. | | `usage.output_tokens` | integer | Output tokens. | | `usage.total_tokens` | integer | Input plus output tokens. | | `usage.input_tokens_details.cached_tokens` | integer | Input tokens served from the prefix cache. Present only when the model server reports it. | | `usage.cost` | number | Amount in USD deducted from credits for this request. The gateway adds it to non-streaming responses only. | | `X-Neocloud-Generation-Id` | header | Response header with the ID of the usage event for this request. It is sent on streaming responses too. Store it with your logs. | ## Stream events With stream: true, the model server sends typed events: an event: line with the type, then a data: line whose JSON repeats it in type. The gateway forwards every event unchanged and reads the token counts from the last one. It does not add usage.cost to streamed events, because usage sits inside response there. To get the cost of a streamed request, compute it from response.usage and the model's prices, or look the request up in Console → Usage. | Event | Description | | --- | --- | | `response.created` | Forwarded from the model server unchanged. | | `response.output_text.delta` | Forwarded from the model server unchanged. delta holds the new text. | | `response.completed` | Last event of a finished generation. response.usage holds the token counts that are billed. | | `response.incomplete` | Last event of a generation that was cut short, for example by max_output_tokens. response.usage holds the token counts, and they are billed. | | `response.failed` | The generation failed. The request is not billed, even when the event reports usage. | | `error` | An error event from the model server. The request is not billed. | | Field | Type | Description | | --- | --- | --- | | `type` | string | The event type, one of the values above. The model server can send other response.* events; they are forwarded unchanged. | | `delta` | string | On response.output_text.delta: the new text. | | `response` | object | On response.created and the last event: the response object. Its usage is null until the last event. | | `response.usage` | object | On response.completed and response.incomplete: input_tokens, output_tokens and total_tokens. The gateway never removes it and adds no cost field to it. | Keepalive comments and disconnects are described on the [Streaming](https://kiln.bricksum.com/docs/en/streaming) page. ## Errors | Status | error.code | Cause | What to do | | --- | --- | --- | --- | | 400 | `unsupported_parameter` | The request carries previous_response_id. | Remove it and send the full conversation in input. | | 400 | | The model server rejected the request: malformed JSON, invalid parameters, or more than the model's context window (the Models page lists it per model). | Fix the payload. Do not retry as sent. | | 404 | `model_not_found` | The model ID is not in the catalog. | Check the ID against GET /models. | | 404 | `not_found` | GET /responses/{id}, DELETE /responses/{id} or GET /responses/{id}/input_items was called. Responses are not stored on the gateway. | Keep the conversation in your client and send it in input. | | 429 | `rate_limit_exceeded` | The organization already has 8 requests in flight. No rate-limit headers are sent. | Back off exponentially and retry. | | 502 | | The model backend returned an error or was unreachable. The body is plain text. | Retry with exponential backoff. | | 503 | | The service is in maintenance mode, or no model backend is available. | During maintenance, wait until the Retry-After date. Otherwise retry with exponential backoff. | 401, 402, 403 and 429 come from the gateway before the request reaches this endpoint. They are listed once on the [API Reference](https://kiln.bricksum.com/docs/en/api-reference) page. Branch on the HTTP status and error.code, not on the message text. An empty error.code cell means the body carries no code. Every status code is listed on the [Errors](https://kiln.bricksum.com/docs/en/errors) page. ## Limits Context length, request body size, timeouts and the per-organization rate limits apply here as well; they are listed once on the [API Reference](https://kiln.bricksum.com/docs/en/api-reference) page. Headers and retry guidance for 429 are on the [Rate limits](https://kiln.bricksum.com/docs/en/rate-limits) page. ## Examples ### Request **cURL** ```bash curl https://api.bricksum.com/v1/responses \ -H "Authorization: Bearer $KILN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "qwen3-32b", "instructions": "Answer briefly.", "input": "Hello!" }' ``` **Python** ```python import os from openai import OpenAI client = OpenAI( base_url="https://api.bricksum.com/v1", api_key=os.environ["KILN_API_KEY"], ) resp = client.responses.create( model="qwen3-32b", instructions="Answer briefly.", input="Hello!", ) print(resp.output_text) print(resp.usage) ``` **JavaScript** ```javascript import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://api.bricksum.com/v1", apiKey: process.env.KILN_API_KEY, }); const resp = await client.responses.create({ model: "qwen3-32b", instructions: "Answer briefly.", input: "Hello!", }); console.log(resp.output_text); console.log(resp.usage); ``` ### Response **200 OK** ```json { "id": "resp_...", "object": "response", "created_at": 1710000000, "model": "qwen3-32b", "status": "completed", "output": [ { "type": "message", "role": "assistant", "content": [{ "type": "output_text", "text": "Hello! How can I help?" }] } ], "usage": { "input_tokens": 9, "output_tokens": 12, "total_tokens": 21, "cost": 0.000001155 } } ``` **text/event-stream** ```text event: response.created data: {"type":"response.created","response":{"id":"resp_...","status":"in_progress","usage":null}} event: response.output_text.delta data: {"type":"response.output_text.delta","delta":"Hello"} event: response.completed data: {"type":"response.completed","response":{"id":"resp_...","status":"completed","usage":{"input_tokens":9,"output_tokens":12,"total_tokens":21}}} ``` **400 Bad Request** ```json { "error": { "message": "'previous_response_id' is not supported: responses are not stored on this gateway. Send the full conversation in 'input'.", "type": "invalid_request_error", "param": "previous_response_id", "code": "unsupported_parameter" } } ```