Skip to content

API reference: Responses

POST /v1/responses creates a model answer. It follows the OpenAI Responses API, so the official libraries and frameworks built on them work after you change the base URL and the model name. For a walk-through with code, read the Responses guide.

POST https://dummydomain/v1/responses
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
Field Type Description
model string, required A tier: Instant, Fast, Smart or Genius. GET /v1/models lists the tiers your key may use
input string or array The conversation. A string is one user message. An array holds input items
instructions string The system prompt for this request
tools array Function tools the model may call
tool_choice string or object auto (default), none, required, or {"type": "function", "name": "..."} to force one function
parallel_tool_calls boolean Let the model ask for several functions in one turn. Default true
text.format object {"type": "text"} (default), {"type": "json_object"}, or {"type": "json_schema", "name": "...", "schema": {...}, "strict": true}
max_output_tokens integer The longest answer you want, in tokens. Default 2048, or the tier’s max_output_tokens_with_tools when you send tools. A larger value than the tier allows in /v1/models gets HTTP 400
temperature number 0 to 2. Lower is more focused
top_p number 0 to 1. Use this or temperature
stream boolean true sends stream events as the answer is written
metadata object Up to 16 string values. Sent back in the response and not stored

Fields that OpenAI clients send with their default values are accepted, so you never have to strip them: store: false, user, prompt_cache_key, safety_identifier, max_tool_calls, client_metadata, service_tier: "auto", truncation: "disabled", include: [], reasoning: {}, background: false, top_logprobs: 0 and text.verbosity: "medium". The full field contract, including values that get HTTP 400, is in Errors.

Item Shape
Message {"role": "user", "content": "..."}. Roles: system, developer, user, assistant. content is a string or a list of parts
input_text part {"type": "input_text", "text": "..."}
input_image part {"type": "input_image", "image_url": "data:image/png;base64,..."}. PNG, JPEG, WebP, GIF or BMP. detail may be left out or set to auto
Assistant history output_text and refusal parts, as you got them in output
function_call An item from a previous output, sent back unchanged
function_call_output {"type": "function_call_output", "call_id": "...", "output": ...}. output is a string, or a list of input_text and input_image parts
reasoning Accepted and dropped, so replayed history works

A request holds up to 400 input items and 100 messages. Images, from user messages and from your functions together, are limited to 8 per request, 10 MiB each and 20 MiB in total. Send images as data: URLs. An https image address works only if your administrator has allowed its host; this is off by default, and the server then fetches the image itself, with no redirects.

{
"model": "Fast",
"input": [
{"role": "user", "content": [
{"type": "input_text", "text": "What is written on this label?"},
{"type": "input_image", "image_url": "data:image/png;base64,iVBORw0KGgo..."}
]}
]
}
{
"type": "function",
"name": "get_order_status",
"description": "Look up an order by its number",
"parameters": {
"type": "object",
"properties": {"order_id": {"type": "string"}},
"required": ["order_id"],
"additionalProperties": false
},
"strict": true
}

Function calling works on tiers whose capabilities.tools is true in /v1/models. The arguments the model sends are checked against parameters before you receive them. A function’s result goes back as a function_call_output with the same call_id. It can be text, or text and images:

{
"type": "function_call_output",
"call_id": "call_8f2c...",
"output": [
{"type": "input_text", "text": "Scan of bill B-17:"},
{"type": "input_image", "image_url": "data:image/png;base64,iVBORw0KGgo..."}
]
}

Send an output that carries images right after the function_call it answers, in the run of outputs that follows that call.

{
"id": "resp_0c9e2b...",
"object": "response",
"created_at": 1791959528,
"completed_at": 1791959529,
"status": "completed",
"model": "Fast",
"output": [
{
"type": "message",
"id": "msg_ead541...",
"role": "assistant",
"status": "completed",
"content": [{"type": "output_text", "text": "Your order SO-4471 was shipped.", "annotations": []}]
}
],
"usage": {
"input_tokens": 38,
"input_tokens_details": {"cached_tokens": 0},
"output_tokens": 9,
"output_tokens_details": {"reasoning_tokens": 0},
"total_tokens": 47
},
"error": null,
"incomplete_details": null,
"metadata": {"order": "SO-4471"},
"instructions": null,
"tools": [],
"tool_choice": "auto",
"parallel_tool_calls": true,
"text": {"format": {"type": "text"}, "verbosity": "medium"},
"temperature": null,
"top_p": null,
"max_output_tokens": null,
"store": false
}
Field Description
id resp_..., unique per response. Quote it with request_id when you report a problem
status completed, incomplete (incomplete_details.reason is max_output_tokens) or failed
output A message item with output_text parts (left out when the model only calls functions), and a function_call item (call_id, name, arguments as a JSON string) for each function the model wants run
usage Token counts for this request
error null, or code and message when status is failed
Settings model, instructions, tools, tool_choice, text, temperature, top_p, max_output_tokens, metadata as used

The OpenAI libraries add output_text: all the text of output joined together.

Nothing is kept on the server after the answer, so there is no GET or DELETE /v1/responses/{id}, no /cancel and no /input_items. The /v1 endpoints are POST /v1/responses, POST /v1/chat/completions and GET /v1/models.

With "stream": true the answer is a server-sent event stream. Each event has a type and a sequence_number. Lines that start with : keep the connection open and can be ignored.

Event When
response.created, response.in_progress At the start
response.output_item.added A message or function call starts
response.content_part.added A text part starts
response.output_text.delta A piece of text. Show delta as it arrives
response.output_text.done, response.content_part.done The text part is finished
response.function_call_arguments.delta, .done The arguments of a function call
response.output_item.done The item is finished, with its final content
response.completed The last event, carrying the whole response
response.incomplete The last event when the answer reached max_output_tokens
response.failed The last event when the request failed. response.error has code, message and request_id
event: response.output_text.delta
data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_ead541...","output_index":0,"content_index":0,"delta":"Your order"}
  • Responses guide: follow-ups, function loops, images from functions, the Agents SDK
  • Models: tiers and what each one can do
  • Errors: status codes, error codes and limits

Common questions

Which fields does ZenithAI's /v1/responses accept?

model, input, instructions, tools, tool_choice, parallel_tool_calls, text.format, max_output_tokens, temperature, top_p, stream and metadata. Client defaults such as store false are accepted too, so the OpenAI libraries work without changes.

Does a ZenithAI response object look like OpenAI's?

Yes. It has the same fields, such as id, object, created_at, status, model, output and usage, plus the settings you sent. The OpenAI libraries read it as is, including output_text.