Responses (OpenAI)
POST /v1/responses — OpenAI Responses API, with complete examples by scenario
OpenAI's newer Responses API (/v1/responses). For requests whose upstream natively supports Responses, the request and response are passed through almost unchanged; for the rest, the platform converts to Chat Completions, runs the same routing pipeline, and converts the response back to Responses format. It suits code that uses the responses interface of the new OpenAI SDK.
This page is organized by scenario: start with the scenario overview, then go to the section for request, response and caveats. Every example carries an evidence label. Tested means it was called for real with a live test account (2026-10-19); response fields come from the real reply, with id, timestamps and text replaced by placeholders. Per official docs (not tested) means it was written from the OpenAI documentation and we did not verify it with a real call.
The same model can return different response shapes: a model may have both native and converted upstreams, and routing decides which one each request lands on. In testing, two requests to glm-5.3-flash got the two shapes: the native shape has many echo fields (background, tools, top_p and so on) and upstream-specific fields; the converted shape has no upstream-specific fields. The converted shape is aligned with the official one: every event carries sequence_number, id starts with resp_, the response object echoes the request parameters, thinking uses summary, and thinking comes first in output. Read both shapes the same way: use output[] and usage, and do not depend on the exact values of echo fields. Each example on this page says which shape it is.
Scenario overview
Scenarios follow OpenAI's Text generation, Streaming, Function calling, Structured outputs, Reasoning, Images and vision, Conversation state and Tools guides.
| Scenario | Offered officially | Our status | Example |
|---|---|---|---|
Basic chat (string input, instructions) | Yes | Supported | Basic chat |
Multi-turn (array input with history, developer / user roles) | Yes | Supported | Multi-turn |
| Streaming | Yes | Supported | Streaming |
Function calling (function_call / function_call_output) | Yes | Supported | Function calling |
Structured output (json_schema in text.format) | Yes | Supported | Structured output |
Reasoning (reasoning) | Yes | Supported | Reasoning |
Image input (input_image) | Yes | Partial: needs a vision model; base64 tested, public URL not tested, file_id not supported | Image input |
Stateful continuation (previous_response_id, conversation) | Yes | Not supported: the platform does not store responses. In testing, a request with previous_response_id could not see the previous turn; send the full input yourself | — |
Built-in tools (web_search, file_search, code_interpreter, computer_use, mcp, image_generation) | Yes | Not supported: the converted path keeps only function / custom and drops the other built-in tools; web_search is converted to web_search_options, which had no search effect on live models in testing | — |
Custom tools and grammar constraints (custom tools, CFG) | Yes | Partial: custom is converted to a function with a single string parameter; grammar constraints are not supported; not tested | — |
Background tasks and webhooks (background) | Yes | Not supported: forwarded to the upstream with no Responses semantics; it does not run in the background | — |
Conversation compaction (/v1/responses/compact) | Yes | Partial: the endpoint exists; not tested | — |
Retrieve / delete / cancel (GET, DELETE, cancel) | Yes | Partial: only valid for responses created by native upstreams, see "Other methods" | — |
Basic chat
When to use: one question, one answer; use instructions to set role and tone.
Evidence: tested (live test account, 2026-10-19). The response is the native shape.
Request
curl https://api.modelsite.ai/v1/responses \
-H "Authorization: Bearer $MODELSITE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "glm-5.3-flash",
"input": "Explain quantum entanglement in one sentence",
"instructions": "Answer briefly",
"max_output_tokens": 1500
}'Response
The reply text is content[].text of the output[] item whose type is message (the SDK's output_text already joins it); status is status (completed / incomplete; when truncated incomplete_details.reason is max_output_tokens, when blocked by content safety it is content_filter); usage is usage. The reply text below is real output for a Chinese prompt (the real request was written in Chinese).
{
"background": false,
"created_at": 1760000000,
"ec_transfer_params": null,
"error": null,
"frequency_penalty": 0.0,
"id": "resp_xxxx",
"incomplete_details": null,
"input_messages": null,
"instructions": "Answer briefly",
"max_output_tokens": 1500,
"max_tool_calls": null,
"metadata": null,
"model": "glm-5.3-flash",
"object": "response",
"output": [
{
"id": "msg_xxxx",
"content": [
{
"annotations": [],
"text": "# 量子纠缠\n\n量子纠缠是指两个或多个粒子形成一种特殊的量子关联状态,无论相距多远,测量其中一个粒子的状态会瞬间确定另一个粒子的状态。……",
"type": "output_text",
"logprobs": null
}
],
"role": "assistant",
"status": "completed",
"type": "message",
"phase": null
}
],
"output_messages": null,
"parallel_tool_calls": true,
"presence_penalty": 0.0,
"previous_response_id": null,
"prompt": null,
"reasoning": null,
"service_tier": "auto",
"status": "completed",
"temperature": 1,
"text": null,
"tool_choice": "none",
"tools": [],
"top_logprobs": null,
"top_p": 0.95,
"truncation": "disabled",
"usage": {
"input_tokens": 23,
"input_tokens_details": { "cached_tokens": 0 },
"output_tokens": 91,
"output_tokens_details": { "reasoning_tokens": 0 },
"total_tokens": 114
},
"user": null
}Notes
temperature,top_p,tool_choiceand so on are the upstream's echo of your request or its defaults (for exampletool_choiceshowsnonewhen no tools were sent); they do not mean the platform rewrote your request.- The
modelin the response is the model name you requested, andidis a platform-encodedresp_ID. - The API card below is rendered from the OpenAPI spec (request-body parameter table, response schema).
Authorization
BearerAuth Authorization: Bearer $MODELSITE_API_KEY
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/responses" \ -H "Content-Type: application/json" \ -d '{ "model": "string", "input": "string" }'取回复:output[] 里 type 为 message 的项。上游原生支持 Responses 时是这种带回显字段的形态;取自线上真实响应(glm-5.3-flash,2026-10-19),取值为占位。
{ "background": false, "created_at": 1760000000, "ec_transfer_params": null, "error": null, "frequency_penalty": 0, "id": "resp_xxxx", "incomplete_details": null, "input_messages": null, "instructions": "用中文回答,简洁", "max_output_tokens": 1500, "max_tool_calls": null, "metadata": null, "model": "glm-5.3-flash", "object": "response", "output": [ { "id": "msg_xxxx", "content": [ { "annotations": [], "text": "# 量子纠缠\n\n量子纠缠是指两个或多个粒子形成一种特殊的量子关联状态,无论相距多远,测量其中一个粒子的状态会瞬间确定另一个粒子的状态。\n\n**通俗类比**:就像一双“魔法手套”分别寄到地球两端,你打开盒子看到左手套的瞬间,就知道另一端是右手套——但量子纠缠更神奇,手套在被打开前连“左右”都还没确定。", "type": "output_text", "logprobs": null } ], "role": "assistant", "status": "completed", "type": "message", "phase": null } ], "output_messages": null, "parallel_tool_calls": true, "presence_penalty": 0, "previous_response_id": null, "prompt": null, "reasoning": null, "service_tier": "auto", "status": "completed", "temperature": 1, "text": null, "tool_choice": "none", "tools": [], "top_logprobs": null, "top_p": 0.95, "truncation": "disabled", "usage": { "input_tokens": 23, "input_tokens_details": { "cached_tokens": 0 }, "output_tokens": 91, "output_tokens_details": { "reasoning_tokens": 0 }, "total_tokens": 114 }, "user": null}Multi-turn
When to use: conversations that need context. The platform does not store responses; put the full history in the input array on every request. You can also use the developer role for instructions.
Evidence: per official docs (not tested). Multi-turn with tools (function_call returned) was tested, see Function calling.
Request
curl https://api.modelsite.ai/v1/responses \
-H "Authorization: Bearer $MODELSITE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "glm-5.3-flash",
"input": [
{"role": "developer", "content": "Answer briefly"},
{"role": "user", "content": "What is quantum entanglement?"},
{"role": "assistant", "content": "Two particles share a state regardless of distance."},
{"role": "user", "content": "Can it be used for faster-than-light communication?"}
],
"max_output_tokens": 1500
}'Response: same structure as Basic chat.
Notes
- On the converted path the
inputarray only convertsmessage(including the short form with justrole+content),function_call,function_call_output,custom_tool_callandcustom_tool_call_output;reasoningitems are skipped, and other types such asitem_referenceandimage_generation_callare dropped. - Do not rely on
previous_response_idfor continuation; see the scenario overview.
Streaming
When to use: show output token by token and lower time to first token.
Evidence: tested (live test account, 2026-10-19). The event sequence is the native shape.
Request
curl -N https://api.modelsite.ai/v1/responses \
-H "Authorization: Bearer $MODELSITE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "glm-5.3-flash",
"input": "Reply with one character: 好",
"stream": true,
"reasoning": {"effort": "low"},
"max_output_tokens": 600
}'Response
Each event is an event: line plus a data: line; concatenate the delta of response.output_text.delta for the text; the stream ends with response.completed, whose response.usage holds usage. There is no [DONE]. Every event carries an increasing sequence_number.
event: response.created
data: {"response":{"id":"resp_xxxx","created_at":1760000000,"model":"glm-5.3-flash","object":"response","output":[],"status":"in_progress","usage":null, ...echo fields as in the basic response...},"sequence_number":0,"type":"response.created"}
event: response.in_progress
data: {"response":{ ...same as above... },"sequence_number":1,"type":"response.in_progress"}
event: response.output_item.added
data: {"item":{"id":"rs_xxxx","summary":[],"type":"reasoning","content":null,"encrypted_content":null,"status":"in_progress"},"output_index":0,"sequence_number":2,"type":"response.output_item.added"}
event: response.reasoning_part.added
data: {"content_index":0,"item_id":"rs_xxxx","output_index":0,"part":{"text":"","type":"reasoning_text"},"sequence_number":3,"type":"response.reasoning_part.added"}
event: response.reasoning_text.delta
data: {"content_index":0,"delta":"User wants exactly one character: \"好\".","item_id":"rs_xxxx","output_index":0,"sequence_number":4,"type":"response.reasoning_text.delta"}
event: response.reasoning_text.done
data: {"content_index":0,"item_id":"rs_xxxx","output_index":0,"sequence_number":8,"text":"User wants exactly one character: \"好\".","type":"response.reasoning_text.done"}
event: response.reasoning_part.done
data: {"content_index":0,"item_id":"rs_xxxx","output_index":0,"part":{"text":"User wants exactly one character: \"好\".","type":"reasoning_text"},"sequence_number":9,"type":"response.reasoning_part.done"}
event: response.output_item.done
data: {"item":{"id":"rs_xxxx","summary":[],"type":"reasoning","content":[{"text":"User wants exactly one character: \"好\".","type":"reasoning_text"}],"encrypted_content":null,"status":"completed"},"output_index":0,"sequence_number":10,"type":"response.output_item.done"}
event: response.output_item.added
data: {"item":{"id":"msg_xxxx","content":[],"role":"assistant","status":"in_progress","type":"message","phase":null},"output_index":1,"sequence_number":11,"type":"response.output_item.added"}
event: response.content_part.added
data: {"content_index":0,"item_id":"msg_xxxx","output_index":1,"part":{"annotations":[],"text":"","type":"output_text","logprobs":[]},"sequence_number":12,"type":"response.content_part.added"}
event: response.output_text.delta
data: {"content_index":0,"delta":"好","item_id":"msg_xxxx","logprobs":[],"output_index":1,"sequence_number":13,"type":"response.output_text.delta"}
event: response.output_text.done
data: {"content_index":0,"item_id":"msg_xxxx","logprobs":[],"output_index":1,"sequence_number":14,"text":"好","type":"response.output_text.done"}
event: response.content_part.done
data: {"content_index":0,"item_id":"msg_xxxx","output_index":1,"part":{"annotations":[],"text":"好","type":"output_text","logprobs":null},"sequence_number":15,"type":"response.content_part.done"}
event: response.output_item.done
data: {"item":{"id":"msg_xxxx","content":[{"annotations":[],"text":"好","type":"output_text","logprobs":null}],"role":"assistant","status":"completed","type":"message","phase":null,"summary":[]},"output_index":1,"sequence_number":16,"type":"response.output_item.done"}
event: response.completed
data: {"response":{"id":"resp_xxxx","status":"completed","model":"glm-5.3-flash","output":[ ...the two items from output_item.done... ],"usage":{"input_tokens":18,"input_tokens_details":{"cached_tokens":0,"input_tokens_per_turn":[],"cached_tokens_per_turn":[]},"output_tokens":12,"output_tokens_details":{"reasoning_tokens":9,"tool_output_tokens":0,"output_tokens_per_turn":[],"tool_output_tokens_per_turn":[]},"total_tokens":30}, ...},"sequence_number":17,"type":"response.completed"}Notes
- In the native shape, thinking arrives as
response.reasoning_text.*events atoutput_index: 0and the answer atoutput_index: 1. On the converted path thinking arrives as the officialresponse.reasoning_summary_part.added,response.reasoning_summary_text.delta,response.reasoning_summary_text.doneandresponse.reasoning_summary_part.doneevents (per code and unit tests, not tested online). The two shapes place thinking differently; read by event type and do not hard-code indexes. - On the converted path
output_indexincreases in order of appearance starting at 0: with thinking, thinking is 0; a turn that only calls tools has no message item; each item getsoutput_item.donebefore the next item starts. - On the converted path, streaming requests turn on
include_usageautomatically, and usage is inresponse.completed. - If a stream fails after output has started, the error is sent as an in-stream event; see "Errors" below.
Function calling
When to use: let the model decide to call functions you define. The flow: declare tools → the model returns a function_call item → you run it → in the next request's input put back that function_call item and a function_call_output item (matched by call_id) → the model gives the final answer.
Evidence: tested (live test account, 2026-10-19): a single call and returning the result (native shape). tool_choice values, parallel calls and the streaming function_call_arguments events are per official docs (not tested).
Request (first turn)
curl https://api.modelsite.ai/v1/responses \
-H "Authorization: Bearer $MODELSITE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "glm-5.3-flash",
"input": "What is the weather in Hangzhou tomorrow?",
"tools": [{
"type": "function",
"name": "get_weather",
"description": "Get the current weather for a city",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"]
}
}],
"max_output_tokens": 1500
}'Response (first turn)
A tool call is an output[] item with type function_call; arguments is a JSON string. Only output and usage are shown; the other fields are as in Basic chat (tools echoes the tools you declared and tool_choice is auto).
{
"id": "resp_xxxx",
"object": "response",
"status": "completed",
"model": "glm-5.3-flash",
"output": [
{
"id": "rs_xxxx",
"summary": [],
"type": "reasoning",
"content": [
{ "text": "The user is asking about the weather in Hangzhou… (omitted)", "type": "reasoning_text" }
],
"encrypted_content": null,
"status": null
},
{
"arguments": "{\"city\": \"杭州\"}",
"call_id": "chatcmpl-tool-xxxxxxxx",
"name": "get_weather",
"type": "function_call",
"id": "fc_xxxx",
"caller": null,
"namespace": null,
"status": "completed"
}
],
"usage": {
"input_tokens": 160,
"output_tokens": 95,
"total_tokens": 255,
"input_tokens_details": { "cached_tokens": 0 },
"output_tokens_details": { "reasoning_tokens": 83 }
}
}Returning the tool result (second turn)
curl https://api.modelsite.ai/v1/responses \
-H "Authorization: Bearer $MODELSITE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "glm-5.3-flash",
"input": [
{"role": "user", "content": "What is the weather in Hangzhou tomorrow?"},
{"type": "function_call", "call_id": "chatcmpl-tool-xxxxxxxx", "name": "get_weather", "arguments": "{\"city\": \"杭州\"}"},
{"type": "function_call_output", "call_id": "chatcmpl-tool-xxxxxxxx", "output": "Cloudy, 7-13°C"}
],
"tools": [ ... same as the first turn ... ],
"reasoning": {"effort": "low"},
"max_output_tokens": 1500
}'Second-turn response (tested; output has a single message):
{
"id": "resp_xxxx",
"object": "response",
"status": "completed",
"model": "glm-5.3-flash",
"output": [
{
"id": "msg_xxxx",
"content": [
{ "annotations": [], "text": "杭州明天天气:多云,气温 7~13°C。早晚偏凉,建议适当添衣保暖。", "type": "output_text", "logprobs": null }
],
"role": "assistant",
"status": "completed",
"type": "message",
"phase": null
}
],
"usage": {
"input_tokens": 182,
"input_tokens_details": { "cached_tokens": 0 },
"output_tokens": 25,
"output_tokens_details": { "reasoning_tokens": 0 },
"total_tokens": 207
}
}Notes
- On the converted path a
customtool is converted to a function with a single string parameter and restored in the response;allowed_toolsintool_choiceis approximated asrequired(whenmodeisrequired) orauto, and hosted-tool forms degrade toauto. - The format of
call_iddepends on the upstream; send it back unchanged. - When streaming, the event sequence for tool calls follows the official docs:
response.output_item.added(function_call) → severalresponse.function_call_arguments.delta→response.function_call_arguments.done→response.output_item.done.
Structured output (text.format)
When to use: the reply must strictly match a JSON Schema you provide (in Responses this is text.format, not response_format).
Evidence: tested (live test account, 2026-10-19, native shape).
Request
curl https://api.modelsite.ai/v1/responses \
-H "Authorization: Bearer $MODELSITE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "glm-5.3-flash",
"input": "Extract: Zhang San, 28 years old, lives in Shanghai",
"reasoning": {"effort": "low"},
"max_output_tokens": 1500,
"text": {
"format": {
"type": "json_schema",
"name": "person",
"strict": true,
"schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"},
"city": {"type": "string"}
},
"required": ["name", "age", "city"],
"additionalProperties": false
}
}
}
}'Response (output only; text.format is echoed in the response)
"output": [
{
"id": "rs_xxxx",
"summary": [],
"type": "reasoning",
"content": [ { "text": "Simple extraction task.", "type": "reasoning_text" } ]
},
{
"id": "msg_xxxx",
"content": [
{ "annotations": [], "text": "{\n \"age\": 28,\n \"city\": \"上海\",\n \"name\": \"张三\"\n}", "type": "output_text", "logprobs": null }
],
"role": "assistant",
"status": "completed",
"type": "message"
}
]Notes
- In this run the output matched the schema; key order is not guaranteed. The platform does not validate output server-side, so still validate the result yourself; when
statusisincompletethe output may be truncated. - On the converted path,
text.formatofjson_schema/json_objectis converted toresponse_format,verbosityis converted toverbosity, and other sub-fields are dropped.
Reasoning
When to use: you want the model to reason before answering, or you want to control reasoning effort.
Evidence: tested (live test account, 2026-10-19): reasoning.effort: "low", streaming and non-streaming (native shape).
Request
curl https://api.modelsite.ai/v1/responses \
-H "Authorization: Bearer $MODELSITE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "glm-5.3-flash",
"input": "What is the weather in Hangzhou tomorrow?",
"reasoning": {"effort": "low"},
"max_output_tokens": 1500
}'Response: thinking is the output[] item with type reasoning (before the message); non-streaming it is in content[].text (type reasoning_text); the thinking token count is usage.output_tokens_details.reasoning_tokens; cache hits are usage.input_tokens_details.cached_tokens. Real reasoning items are in the responses under Function calling and Structured output; streaming events are under Streaming.
Notes
- Without
reasoning,glm-5.3-flashin the native shape returned noreasoningitem in testing (reasoning_tokenswas 0); whether it thinks and the strength values are decided by the model and upstream; see the vendor pages for per-model values. - On the converted path
reasoning.effortis converted toreasoning_effort, andmax_tokens,enabled,excludeare normalized by the thinking rules of Chat Completions;summaryandgenerate_summaryhave no counterpart and do nothing (thereasoningin the response only echoes what you sent). On the converted path thinking is always returned assummary(summary_text), identically for streaming and non-streaming.
Image input
When to use: have a vision model answer questions about an image. Choose a model that accepts image input (such as qwen3-vl-plus).
Evidence: base64 images tested (live test account, 2026-10-19, qwen3-vl-plus, converted shape); public URL per official docs (not tested).
Request
curl https://api.modelsite.ai/v1/responses \
-H "Authorization: Bearer $MODELSITE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3-vl-plus",
"max_output_tokens": 300,
"input": [{
"role": "user",
"content": [
{"type": "input_text", "text": "What is in this image? One sentence."},
{"type": "input_image", "image_url": "data:image/png;base64,iVBORw0KGgo..."}
]
}]
}'Response (converted shape; only the main fields are listed, the other echo fields are described under "Unsupported or different parameters" above)
{
"id": "resp_xxxx",
"object": "response",
"created_at": 1760000000,
"status": "completed",
"max_output_tokens": 300,
"model": "qwen3-vl-plus",
"output": [
{
"type": "message",
"id": "msg_xxxx",
"status": "completed",
"role": "assistant",
"content": [
{ "type": "output_text", "text": "图中是一个红色的实心圆,背景为白色。" }
]
}
],
"usage": {
"input_tokens": 82,
"input_tokens_details": { "cached_tokens": 0 },
"output_tokens": 14,
"output_tokens_details": { "reasoning_tokens": 0 },
"total_tokens": 96
}
}Notes
- Images are billed as input tokens. Per-model limits on image size and count are on the vendor pages.
- OpenAI's
file_id(Files API) is not supported.
Errors
401 invalid or missing key
{"error":{"type":"authentication_error","message":"invalid API key"}}When the Authorization header is missing, message is missing or invalid authorization header.
402 insufficient balance
{"error":{"type":"insufficient_quota","message":"insufficient balance"}}429 rate limited
{"error":{"type":"rate_limit_error","message":"too many requests"}}The response carries Retry-After (seconds); back off accordingly.
403 no access to this model
{"error":{"type":"model_access_error","message":"model 'glm-5.3-flash' is not allowed for this API key"}}503 gateway at capacity
{"error":{"type":"overloaded_error","message":"gateway at capacity, retry later"}}Also carries Retry-After: 5.
400 unknown model
{"error":{"type":"invalid_request_error","message":"unknown model: not-a-model"}}A wrong or not-yet-live model is a 400 (not 404).
400 invalid parameters
{"error":{"message":"<validation message>","type":"invalid_request_error","code":"invalid_request_error"}}Errors from the routing layer have an extra code field (same value as type).
When an upstream is temporarily unavailable the response may be 502 (server_error) or 503 (error.code is no_upstream_available); retry shortly. If a streaming request fails after output has started, the HTTP status is already 200 and the error is sent as an in-stream event. Full error codes and handling advice: Errors.
Other methods
| Method | Path | Notes |
|---|---|---|
| GET | /v1/responses | List endpoint; the platform does not store responses and always returns an empty list |
| GET | /v1/responses/:id | Get response details (only valid for responses created through upstreams that natively support Responses) |
| DELETE | /v1/responses/:id | Delete a response (same as above) |
| POST | /v1/responses/:id/cancel | Cancel an in-progress response (same as above) |
| POST | /v1/responses/compact | Compact response context |
None of these methods was tested.
previous_response_id or built-in tools (file_search, code_interpreter, mcp and so on); for multi-turn conversations put the full history in input yourself.Unsupported or different parameters
This endpoint has two paths, and parameter behavior differs between them. The platform does not drop parameters against a parameter allowlist and does not clamp values: apart from the hard-coded behavior listed below, parameters go to the upstream as-is, and whether they take effect, are ignored or are rejected (4xx) is up to the upstream.
- Requests to upstreams that natively support Responses: the request body is forwarded as-is and all official fields are kept, including fields the platform has not modeled. When the upstream returns 4xx pointing at a top-level parameter it does not support, the platform removes that parameter and retries, up to 2 rounds (
input,model,instructions,stream,tools,tool_choice,previous_response_idare never removed); if it still fails it may fall back to the converted path below. - Requests converted by the platform: the request is converted to Chat Completions and the response is converted back to Responses format. The table below is this path's behavior. Which path a model uses is decided by the upstream, and one model can have both.
| Parameter | Behavior on the converted path | Notes |
|---|---|---|
instructions | Rewritten | Converted to a leading system message |
input | Partial | A string, or an array of message (including the short form with only role + content), function_call, function_call_output, custom_tool_call, custom_tool_call_output. reasoning items are skipped; other types such as item_reference and image_generation_call are dropped |
max_output_tokens | Rewritten | Converted to max_tokens |
tools | Partial | function as usual; custom is converted to a function with a single string parameter and restored in the response; web_search / web_search_preview is converted to web_search_options (no search effect on live models in testing); other built-in tools such as file_search, computer_use, mcp, code_interpreter, image_generation are dropped |
tool_choice | Rewritten | auto / none / required as-is; a specific function / custom becomes a specific function; allowed_tools is approximated as required (when mode is required) or auto; other built-in tool forms degrade to auto |
reasoning | Partial | effort is converted to reasoning_effort; max_tokens, enabled, exclude are normalized by the thinking rules of Chat Completions; summary and generate_summary have no counterpart and do nothing (echoed only) |
text | Partial | When format.type is json_schema / json_object it is converted to response_format and text itself is no longer forwarded; verbosity is converted to verbosity; other sub-fields are dropped |
previous_response_id | Dropped | The platform does not store responses, so it cannot continue; send the full input for multi-turn; the response object only echoes the value you sent |
truncation include max_tool_calls | Dropped | No Chat Completions counterpart |
store service_tier user metadata parallel_tool_calls | Mapped | Mapped to the same-named Chat fields and forwarded; metadata keeps only string values |
stream | Usage added automatically | With stream: true, include_usage is turned on automatically and usage is in response.completed |
background conversation prompt top_logprobs stream_options context_management safety_identifier prompt_cache_key prompt_cache_retention moderation | No Responses semantics | Forwarded to the upstream as unknown top-level fields and do not produce Responses behavior (for example background does not make the request run in the background) |
Common to both paths: the model in the response is the model name you requested, and id is a platform-encoded resp_ ID (identical for streaming and non-streaming on the converted path).
On the converted path the response object echoes the request parameters in the official shape: instructions, tools, tool_choice, temperature, top_p, max_output_tokens, parallel_tool_calls, metadata, reasoning, store, text, truncation, user, previous_response_id, max_tool_calls. Parameters you did not send are echoed with the official defaults (tool_choice auto, tools [], parallel_tool_calls true, store true, truncation disabled, metadata {}); temperature and top_p are null when not sent. These are request echoes and do not mean the upstream used those values (for example store, truncation and previous_response_id are dropped on the converted path, see the table above). Converted responses carry no upstream-specific fields (ec_transfer_params, input_messages, output_messages and so on).
Platform extensions
What follows is defined by the platform and does not exist in the official OpenAI API.
Request headers: the gateway only lets Authorization, Content-Type, Accept, Accept-Encoding, Origin, User-Agent, Anthropic-Beta, OpenAI-Beta through and drops all others. A value you send in X-Request-ID is kept and echoed; if absent, the platform generates one.
Response headers
| Header | Notes |
|---|---|
X-Request-ID | Request ID; give it to us when troubleshooting |
Retry-After | Suggested back-off seconds on 429; at gateway capacity it returns 503 with Retry-After: 5 |
Content-Type: text/event-stream, Cache-Control: no-cache | Streaming responses; when a stream is idle the gateway sends a : heartbeat comment frame every 15 seconds, which SSE clients ignore automatically |
The platform does not return X-RateLimit-* quota headers.
Response fields
| Field | Notes |
|---|---|
usage.cost, usage.cost_details | Cost fields on non-streaming responses. Not returned by default; they appear only when your organization is set to total or detailed, and callers cannot turn them on with a request parameter. Amounts are exact decimal strings; requests that cannot be priced omit them. The component names differ from Chat Completions: input_cost, output_cost, reasoning_cost, prompt_cache_read_cost and so on, only components greater than 0 |
output[].content[].reasoning_text (non-streaming), response.reasoning_text.* / reasoning_summary_* events (streaming) | Thinking; the location depends on path and mode, see each scenario |
Automatic behavior
- When the balance runs out during streaming, the stream is cut and you then receive a
data: {"error":{"type":"insufficient_quota","message":"balance exhausted"}}frame anddata: [DONE]. - Automatic retry and upstream switching on upstream failure follow the same rules as Chat Completions.
GET /v1/responses/:id,DELETEandcancelare only valid for responses created on the native path; see "Other methods" above.