Responses API
/v1/responses implements OpenAI’s Responses format. It takes a single input
instead of a messages array, and unlike
/v1/chat/completions it
holds state: a response gets an id you can fetch later, chain the next turn onto,
or cancel while it runs.
Reach for it when you want the server to keep the thread, when you want to start
long work and collect it later, or when you need store, metadata or
background, which are specific to this endpoint. See OpenAI
Compatibility for the
full comparison.
Creating a response
cURL
Python
The OpenAI SDK’s responses client works against this endpoint unchanged, so
create, retrieve, stream, cancel and delete are all available on it.
Every Python example further down this page reuses the client built here.
output_text is an SDK convenience that concatenates the text for you; the
underlying object is below.
The reply is a response object:
The three fields you will reach for:
id- what you pass to retrieve, cancel, delete, orprevious_response_id.status-completed,failed,incompleteorcancelledonce the run has ended;queuedorin_progresswhile it is still going. This is what you poll on for a background response.output- an array of items, not a single string. The assistant’s text is atoutput[0].content[0].text. Reasoning and tool calls arrive as their own items in the same array, so walk it bytyperather than assuming position.
usage uses the Responses spelling: input_tokens and output_tokens rather
than the prompt_tokens and completion_tokens you get from
/v1/chat/completions.
There are three ways to take delivery, and they are the main decision on this endpoint.
Synchronous is the default and is right for short work. Streaming is right for anything a person is waiting on. Background is right for work you want to start and collect later, possibly from a different process.
background requires store to be left at its default of true. A background
response is delivered by id, so it has to be retrievable. Sending
"background": true with "store": false returns a 400.
Storing and retrieving
Responses are stored by default, which is what makes the rest of this page possible. Fetch one by id:
cURL
Python
A stored response stays retrievable for three days after it finishes. After that
GET, cancel, delete and chaining onto it all return a 404, which means
gone rather than still running.
Send "store": false on create when you do not want the response kept. It is
then delivered on the request itself and is not retrievable afterwards, so all
four of those stop applying to it immediately.
GET /v1/responses/{id}/input_items returns the input items for that single
turn. It does not return the whole reconstructed conversation.
Streaming
Send "stream": true on create and the POST returns server-sent events. Each
frame carries a named event: and a JSON data: payload, which is the main
difference from /v1/chat/completions, where every frame is an anonymous chunk
containing choices[0].delta.
response.created carries the response id, which is how you capture it when
streaming a create: you need it to cancel the run or to chain the next turn onto
it.
A full run emits, in order: response.created, response.in_progress,
response.output_item.added, response.content_part.added, one
response.output_text.delta per fragment, response.output_text.done,
response.content_part.done, response.output_item.done, and a terminal event.
Reasoning arrives first, on response.reasoning_text.delta events closed by a
response.reasoning_text.done, as its own output item ahead of the text.
Three event types are terminal, and receiving any of them means the stream is finished:
response.completed carries the finished response object, including usage.
That is where to read token counts when streaming; the earlier events do not
carry them.
There is no [DONE] sentinel on this endpoint: a terminal event is the end of
the stream. Treat the event set as open and ignore any type you do not recognize,
so new event types do not break your client.
Cancelling a run also produces response.incomplete, so read the response
status to tell a cancellation from a token limit.
The OpenAI SDK handles the framing and gives you the assembled response at the
end, so you branch on event.type rather than parsing frames yourself:
A background response can also be streamed from the retrieve endpoint, which is how you attach to work that was started elsewhere:
cURL
Python
Streaming from retrieve applies to background responses. Adding ?stream=true
to a response that was not created with "background": true returns a 400.
Retrieve it without the parameter to get the stored snapshot.
Continuing a conversation
Pass a previous response’s id as previous_response_id and the server
reconstructs the thread for you, including any tool calls and reasoning it
contains. You send only the new turn.
cURL
Python
This is the main practical difference from
/v1/chat/completions,
where you resend the whole messages array every turn.
Chain onto a parent that has finished and is still stored. Chaining onto a run
that is still going returns a 409, and onto one created with "store": false,
or older than the three-day window, a 404.
Cancelling and deleting
cURL
Python
Cancelling a response that has already finished returns the final response rather than an error, so a cancel racing a completion is safe to send. Deleting cancels the run first if it is still going, then removes the stored response.
What this endpoint takes
input takes either a string or an array of input items, so you can send a
whole thread in one request rather than a single prompt:
Every content part is text. To ask about an image, use /v1/chat/completions
with an image_url content
part; an
input_image part here is rejected with a 400.
Reasoning uses OpenAI’s standard reasoning object here. enable_thinking and
thinking_budget also work on this endpoint, so you can migrate at your own
pace. See
Reasoning.
Tool calling works on both endpoints, and this one additionally accepts the flat Responses tool shape alongside the nested one. See Tool Calling.
Structured output uses text.format here rather than response_format, taking
the same JSON schema. See Structured
Data.
max_output_tokens bounds the tokens generated for the response, the way
max_tokens does on /v1/chat/completions.
metadata takes up to 16 key-value string pairs, which are stored with the
response and returned again when you retrieve it. Use it to tag a response with
your own trace or tenant id so you can match it up later.
Planner mode runs on
/v1/chat/completions.
Next steps
- Chat Completions API - The stateless endpoint, and where planner mode runs
- OpenAI Compatibility - Which parameters are supported on each endpoint
- Tool Calling - Let the model call your own functions
- Errors and Rate Limits - What each status code means and what to retry