Responses API

POST /v1/responses: the OpenAI Responses format with stored state, background runs and enforced tool rules.

Responses API compatibility

POST /v1/responses follows the OpenAI Responses API: the same request fields, output items, streaming events, error shapes and stored state, so OpenAI SDKs (responses.create, responses.stream, responses.parse, responses.retrieve, conversations) and the Agents SDKs work by changing the base URL. As on OpenAI, responses are stored by default, so you can continue a conversation with previous_response_id or a conversation, run a response in the background and retrieve it later. Send store: false to store nothing and send the whole conversation as input each turn instead. What is stored, for how long, and how to turn storage off for your account: see Data retention below.

Tool rules are guaranteed. When a request sets strict: true on a function tool, uses tool_choice (required, a named tool or allowed_tools) or sets parallel_tool_calls: false, OpenScale checks every tool call before you see it: arguments match the JSON schema (types, required, additionalProperties: false, enum, format, pattern), only allowed tools are called, and at most one call comes back when parallel calls are off. A reply that breaks a rule is stopped and retried, and never returned; if no valid reply arrives within three attempts the request fails with 500 and code: tool_call_validation_failed (in a stream: an error event, then response.failed). Failed attempts are not billed. Streams with tool rules send reasoning as it is generated, and text and tool calls once they have been checked. A strict: true schema must follow the Structured Outputs rules (every object sets additionalProperties: false and lists all properties in required; no allOf, not or if), or the request is refused with 400 naming the parameter. Function tools without strict are not checked and read back as strict: false.

Field or toolStatus
input (messages, function, custom, shell, local shell, apply patch and tool search items, reasoning items), instructions, stream, temperature, top_p, max_output_tokens (16 to the model limit), text.format, reasoningSupported
tools: function (with strict), custom, namespace, shell, local_shell, apply_patch, tool_search with execution: "client", defer_loadingSupported (all run by your client)
tool_choice: auto, none, required, a named tool, allowed_tools; parallel_tool_callsSupported and enforced
top_logprobs, include: ["message.output_text.logprobs"]Supported
phase on assistant messagesSupported: every assistant message in the output has phase: commentary for text the model wrote before a tool call in the same response (always, when tool_choice forces a call), final_answer otherwise. In a stream it is on response.output_item.done (and already on response.output_item.added when tool_choice forces a call). Assistant messages you send back in input may keep it
include: ["reasoning.encrypted_content"]Supported (reasoning always comes back with encrypted_content, readable reasoning_text content, and a summary when reasoning.summary is set)
Images (input_image with a URL or data URL, detail), including images returned in function_call_outputSupported
POST /v1/responses/input_tokensSupported (exact counts for text and tools; images and models whose tokenizer we do not carry are estimated)
prompt_cache_options.prewarmSupported (fills the prompt cache and returns a completed response with no output)
metadata, user, safety_identifier, prompt_cache_key, max_tool_callsAccepted and echoed in the response
service_tierpriority runs the request in fast mode when it is available (see Fast mode); any other value runs at the standard tier. The response reports the tier that served it
storeSupported. Defaults to true: the response is stored for 30 days. false stores nothing
previous_response_idSupported: the earlier responses' input and output items come before your input (their instructions do not carry over). An id that is unknown, deleted, past its 30 days or another account's is a 400 with code: previous_response_not_found
conversation and the Conversations API (/v1/conversations and its items)Supported: the conversation's items come before your input, and the input and output are added to it when the response finishes. Cannot be combined with previous_response_id
background: trueSupported: answered at once with a queued response that runs to the end whether or not you stay connected (up to 29 minutes). Poll GET /v1/responses/{id}, resume its stream with ?stream=true&starting_after=, or cancel it with POST /v1/responses/{id}/cancel
item_reference itemsSupported for items of your stored responses and conversations
GET and DELETE /v1/responses/{id}, GET /v1/responses/{id}/input_itemsSupported
web_search, web_search_preview, a hosted tool_searchLeft out of the request and named in the x-openscale-ignored-tools response header (deferred tools are then loaded directly)
file_search, code_interpreter, image_generation, computer, computer_use_preview, mcp, programmatic_tool_callingRefused with 400 (param: tools[i].type); define the capability as a function tool instead
input_file with file_data (a base64 data URL) or file_url (public https URLs)Supported for PDFs (their text, page by page), images (read as input_image) and text files (txt, md, csv, json, html, xml, yaml, code). Up to 20 MB and 500 pages a file, 20 files and 50 MB a request. Other types (Word, Excel, audio) are a 400 naming the parameter. Stored responses keep the text read from a file, not the file
prompt (id, version, variables)Supported with prompts you save through /v1/prompts (see Prompts below). Variables fill {{name}} placeholders with text, or with an input_image or input_file in user messages. An unknown prompt or version, a missing variable or one the prompt does not use is a 400
POST /v1/responses/compact, compaction itemsSupported: returns response.compaction with your user messages and a compaction item that stands for the rest; send that output as the next input. A compaction item that OpenScale did not create, or that was changed, is a 400
context_management: [{"type": "compaction", "compact_threshold": n}], compaction_trigger itemsSupported: past n input tokens the conversation is summarized first; the response starts with a compaction item (streamed with response.compaction.compacting) that replaces everything before it in later turns, and its usage includes the summary. A final compaction_trigger item returns just the compaction
truncation: "auto"Supported: when the input does not fit the context window, the oldest items are dropped (a tool call is always dropped with its output, reasoning with its turn); your instructions and newest item are kept. disabled (the default) answers 400 with code: context_length_exceeded
WebSocket mode (response.create over wss://)Not available yet; use HTTP streaming (stream: true)
Images and files by file_idRefused with 400 naming the parameter; send them by URL or as data

Every refusal uses the OpenAI error shape {"error": {"message", "type", "param", "code"}} with param set to the field at fault.

Endpoints

Count input tokens

POST https://api.openscale.so/v1/responses/input_tokens

Count the input tokens a Responses request would use, without running the model. Takes the same body as Create a response and counts it with the model tokenizer: exact for text and tools, estimated for images and for models whose tokenizer we do not carry. Free.

Example request

bash
curl https://api.openscale.so/v1/responses/input_tokens \
  -H "Authorization: Bearer $OPENSCALE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "deepseek/deepseek-v4.1-flash",
  "input": "Hello from OpenScale"
}'

Response

200: The input token count.

FieldTypeDescription
objectstringAlways response.input_tokens.
input_tokensinteger

Errors

StatusMeaning
400The request cannot be served; param names the field.
401Missing or invalid API key.

Create a response

POST https://api.openscale.so/v1/responses

Create a response from a string or an array of input items (messages, tool call and tool output items, and reasoning items from an earlier turn). Function, custom, namespace, shell, local shell, apply patch and client tool search tools are supported, and strict, tool_choice (including allowed_tools) and parallel_tool_calls: false are enforced. Reasoning comes back as a reasoning item with encrypted_content you can send back unchanged, readable reasoning_text content, and a summary when reasoning.summary is set. Responses are stored for 30 days by default (store), so a later request can continue from one with previous_response_id, or keep its turns in a conversation; with background: true the response runs on its own and is retrieved later. See the Responses API compatibility table and Data retention in the introduction.

Request body

FieldTypeRequiredDescription
modelstringYesOne of deepseek/deepseek-v4.1-flash, z-ai/glm-5.3-flash, deepseek/deepseek-v4.1-flash-1017, deepseek/deepseek-v4.1-flash-0910, z-ai/glm-5.3-flash-0828, deepseek/deepseek-v4.1-flash:fast, deepseek/deepseek-v4.1-flash-1017:fast, deepseek/deepseek-v4.1-flash-0910:fast.
inputstring or array of objectYes
instructionsstringNo
toolsarray of objectNofunction (with strict), custom, namespace, shell, local_shell, apply_patch and client tool_search tools. Web search is left out (see x-openscale-ignored-tools); other hosted tools are refused.
tool_choiceanyNoauto, none, required, a named tool, or allowed_tools. Enforced: a reply that breaks it is retried and never returned.
parallel_tool_callsbooleanNo
textobjectNoStructured outputs: { "format": { "type": "json_schema", ... } } or json_object. json_object works whether or not your prompt mentions JSON.
max_output_tokensintegerNo
temperaturenumberNoFrom 0 to 2.
top_pnumberNoFrom 0 to 1.
streambooleanNoDefault false.
metadataobjectNo
storebooleanNoStore the response for 30 days, for previous_response_id, retrieval and input_items. false stores nothing. Always false when the account has zero data retention on. Default true.
previous_response_idstringNoContinue from a stored response: its input and output (and those of the responses before it) come before input. Its instructions do not carry over.
conversationstring or objectNoA conversation id (or { "id": ... }): its items come before input, and the input and output are added to it when the response finishes.
backgroundbooleanNoRun the response on its own: answered at once with a queued response; retrieve it, stream it, or cancel it by id. Default false.
userstringNo
reasoningobjectNoReasoning control: effort (none to xhigh) and summary (auto, concise or detailed returns a readable summary).

Example request

bash
curl https://api.openscale.so/v1/responses \
  -H "Authorization: Bearer $OPENSCALE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "deepseek/deepseek-v4.1-flash",
  "input": "Hello from OpenScale",
  "store": false
}'

Response

200: The response, or a typed SSE stream when stream is true.

FieldTypeDescription
idstringExample: resp_example.
objectstringAlways response.
created_atinteger
statusstringOne of completed, incomplete, failed, in_progress, queued, cancelled.
modelstringOne of deepseek/deepseek-v4.1-flash, z-ai/glm-5.3-flash, deepseek/deepseek-v4.1-flash-1017, deepseek/deepseek-v4.1-flash-0910, z-ai/glm-5.3-flash-0828, deepseek/deepseek-v4.1-flash:fast, deepseek/deepseek-v4.1-flash-1017:fast, deepseek/deepseek-v4.1-flash-0910:fast.
outputarray of object
output[].typestringAlways message.
output[].idstringExample: msg_example.
output[].rolestringAlways assistant.
output[].statusstringAlways completed.
output[].contentarray of object
output[].phasestringcommentary: text written before a tool call in the same response. final_answer: the reply. Assistant messages sent back in input may keep it. One of commentary, final_answer.
usageobject
usage.input_tokensinteger
usage.input_tokens_detailsobject
usage.output_tokensinteger
usage.output_tokens_detailsobject
usage.total_tokensinteger
service_tierstringThe tier that served the response: priority in fast mode. One of default, priority.
json
{
  "id": "resp_example",
  "object": "response",
  "created_at": 1790078324,
  "status": "completed",
  "model": "deepseek/deepseek-v4.1-flash",
  "output": [
    {
      "type": "message",
      "id": "msg_example",
      "role": "assistant",
      "status": "completed",
      "content": [
        {
          "type": "output_text",
          "text": "Hello!",
          "annotations": []
        }
      ],
      "phase": "final_answer"
    }
  ],
  "usage": {
    "input_tokens": 5,
    "input_tokens_details": {
      "cached_tokens": 0
    },
    "output_tokens": 2,
    "output_tokens_details": {
      "reasoning_tokens": 0
    },
    "total_tokens": 7
  }
}

With stream: true: Typed events: response.created, response.in_progress, response.output_item.added and .done, response.content_part.added and .done, response.output_text.delta and .done, response.reasoning_summary_part and response.reasoning_summary_text events, response.function_call_arguments.delta and .done, response.custom_tool_call_input.done, and response.completed, response.incomplete or response.failed.

Errors

StatusMeaning
400Invalid request; param names the field. previous_response_not_found when the previous response is unknown, deleted or past its 30 days.
401Missing or invalid API key.
402Empty balance, or the key reached its spend limit.
404Unknown model id.
429Rate limit crossed or model at capacity.
502The model is temporarily unavailable.
504The model did not respond in time.

Retrieve a response

GET https://api.openscale.so/v1/responses/{response_id}

A stored response, as it was returned (status queued or in_progress while a background response runs). With stream=true (background responses only), its stream events from the start, or after starting_after, then each new one as it happens.

Path parameters

FieldTypeRequiredDescription
response_idstringYes

Query parameters

FieldTypeRequiredDescription
streambooleanNoStream a background response as SSE events.
starting_afterintegerNoWith stream: the sequence number to resume after.

Example request

bash
curl https://api.openscale.so/v1/responses/$RESPONSE_ID \
  -H "Authorization: Bearer $OPENSCALE_API_KEY"

Response

200: The response, or its events when stream is true.

FieldTypeDescription
idstringExample: resp_example.
objectstringAlways response.
created_atinteger
statusstringOne of completed, incomplete, failed, in_progress, queued, cancelled.
modelstringOne of deepseek/deepseek-v4.1-flash, z-ai/glm-5.3-flash, deepseek/deepseek-v4.1-flash-1017, deepseek/deepseek-v4.1-flash-0910, z-ai/glm-5.3-flash-0828, deepseek/deepseek-v4.1-flash:fast, deepseek/deepseek-v4.1-flash-1017:fast, deepseek/deepseek-v4.1-flash-0910:fast.
outputarray of object
output[].typestringAlways message.
output[].idstringExample: msg_example.
output[].rolestringAlways assistant.
output[].statusstringAlways completed.
output[].contentarray of object
output[].phasestringcommentary: text written before a tool call in the same response. final_answer: the reply. Assistant messages sent back in input may keep it. One of commentary, final_answer.
usageobject
usage.input_tokensinteger
usage.input_tokens_detailsobject
usage.output_tokensinteger
usage.output_tokens_detailsobject
usage.total_tokensinteger
service_tierstringThe tier that served the response: priority in fast mode. One of default, priority.

Errors

StatusMeaning
404No stored response with this id in your account (never stored, deleted or past its 30 days).

Delete a response

DELETE https://api.openscale.so/v1/responses/{response_id}

Delete a stored response, its input and its output at once. A running background response is cancelled.

Path parameters

FieldTypeRequiredDescription
response_idstringYes

Example request

bash
curl -X DELETE https://api.openscale.so/v1/responses/$RESPONSE_ID \
  -H "Authorization: Bearer $OPENSCALE_API_KEY"

Response

200: Deleted.

json
{
  "id": "resp_example",
  "object": "response.deleted",
  "deleted": true
}

Errors

StatusMeaning
404No stored response with this id.

Cancel a background response

POST https://api.openscale.so/v1/responses/{response_id}/cancel

Stop a queued or running background response; it ends with status cancelled and is not billed for unfinished work. Cancelling again, or cancelling a finished response, returns it unchanged.

Path parameters

FieldTypeRequiredDescription
response_idstringYes

Example request

bash
curl -X POST https://api.openscale.so/v1/responses/$RESPONSE_ID/cancel \
  -H "Authorization: Bearer $OPENSCALE_API_KEY"

Response

200: The response.

FieldTypeDescription
idstringExample: resp_example.
objectstringAlways response.
created_atinteger
statusstringOne of completed, incomplete, failed, in_progress, queued, cancelled.
modelstringOne of deepseek/deepseek-v4.1-flash, z-ai/glm-5.3-flash, deepseek/deepseek-v4.1-flash-1017, deepseek/deepseek-v4.1-flash-0910, z-ai/glm-5.3-flash-0828, deepseek/deepseek-v4.1-flash:fast, deepseek/deepseek-v4.1-flash-1017:fast, deepseek/deepseek-v4.1-flash-0910:fast.
outputarray of object
output[].typestringAlways message.
output[].idstringExample: msg_example.
output[].rolestringAlways assistant.
output[].statusstringAlways completed.
output[].contentarray of object
output[].phasestringcommentary: text written before a tool call in the same response. final_answer: the reply. Assistant messages sent back in input may keep it. One of commentary, final_answer.
usageobject
usage.input_tokensinteger
usage.input_tokens_detailsobject
usage.output_tokensinteger
usage.output_tokens_detailsobject
usage.total_tokensinteger
service_tierstringThe tier that served the response: priority in fast mode. One of default, priority.

Errors

StatusMeaning
400The response was not created in the background.
404No stored response with this id.

List input items

GET https://api.openscale.so/v1/responses/{response_id}/input_items

The input items of a stored response, each with its id. Paged with limit (1 to 100, default 20), order (desc by default) and after (an item id).

Path parameters

FieldTypeRequiredDescription
response_idstringYes

Query parameters

FieldTypeRequiredDescription
limitintegerNoFrom 1 to 100. Default 20.
orderstringNoOne of asc, desc. Default "desc".
afterstringNo

Example request

bash
curl https://api.openscale.so/v1/responses/$RESPONSE_ID/input_items \
  -H "Authorization: Bearer $OPENSCALE_API_KEY"

Response

200: A list of items.

FieldTypeDescription
objectstringAlways list.
dataarray of object
first_idstring or null
last_idstring or null
has_moreboolean

Errors

StatusMeaning
404No stored response (or after item) with this id.

Compact a conversation

POST https://api.openscale.so/v1/responses/compact

Summarize a conversation so it can continue in fewer tokens. Takes model and the conversation as input (and/or previous_response_id, plus instructions). The output keeps your user messages and ends with a compaction item that stands for everything else; send the output, followed by new items, as the next input. Nothing is stored. Billed like a response.

Request body

FieldTypeRequiredDescription
modelstringYes
inputanyNo
previous_response_idstringNo
instructionsstringNo

Example request

bash
curl https://api.openscale.so/v1/responses/compact \
  -H "Authorization: Bearer $OPENSCALE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "deepseek/deepseek-v4.1-flash",
  "input": [
    {
      "role": "user",
      "content": "My locker number is 7731."
    },
    {
      "type": "message",
      "role": "assistant",
      "content": [
        {
          "type": "output_text",
          "text": "Noted."
        }
      ]
    }
  ]
}'

Response

200: The compacted conversation.

FieldTypeDescription
idstring
objectstringAlways response.compaction.
created_atinteger
outputarray of object
usageobject

Errors

StatusMeaning
400The request cannot be served; param names the field.
401Missing or invalid API key.

More of the API reference

  • API reference: base URLs, authentication and a first request.
  • Chat Completions: POST /v1/chat/completions: the OpenAI Chat Completions format, streamed or not, with reasoning and tools.
  • Conversations: Keep the turns of a Responses conversation on our side and continue it by id.
  • Prompts: Save instructions, messages and settings once, then use them by id in the Responses API.
  • Anthropic Messages: POST /anthropic/v1/messages: the Anthropic Messages format, for Claude Code and Anthropic SDKs.
  • Models and pricing: Model ids, prices per 1M tokens, context windows, output limits, versions and the live catalog endpoint.
  • Batch: Upload a JSONL file of chat completions, create a batch and collect the results when it finishes.
  • Errors: The error shape, every status code and code, and which ones to retry.
  • Rate limits: Requests and tokens per minute, how a 429 tells you when to retry, and how to get more.
  • Data retention: What is stored, for how long, how to delete it, and zero data retention.
  • Interactive reference: try every endpoint in the browser.
  • OpenAPI document: the whole API as OpenAPI 3.1.

This page as Markdown: /docs/responses.md