Chat Completions API
/v1/chat/completions implements OpenAI’s Chat Completions format. You send the
whole conversation as a messages array and get one reply back. It is the
default endpoint, what most OpenAI code already speaks, and where
planner mode runs.
If you would rather the server keep the thread for you, and you want to retrieve or chain responses by id, use the Responses API instead.
The request
cURL
Python
Each message carries a role and content:
Carrying a conversation
This endpoint does not keep your conversation. Each request is independent, so a
follow-up turn means sending the earlier turns again, with the model’s own
replies as assistant messages:
That is the same as OpenAI’s Chat Completions API, so existing conversation handling carries over unchanged.
Because you resend the history every turn, it grows, and the whole array counts
against the model’s context window along with the reply. Keep an eye on the
context window for the model you are
using and drop the oldest turns as the conversation gets long. If you would
rather not manage this yourself, the Responses
API reconstructs the thread server
side from previous_response_id.
The reply
finish_reason tells you why generation stopped, and is the field to branch on:
Handle an unrecognized value by treating the reply as finished, so a new value does not break your client.
The rest of the fields:
choices[0].message.content- the assistant’s reply.choices[0].message.reasoning_content- the model’s reasoning, when you asked for it. See Reasoning.choices[0].message.tool_calls- tools the model wants you to run. See Tool Calling.usage.prompt_tokens/completion_tokens/total_tokens- token accounting for cost and limits.usage.prompt_tokens_details.cached_tokens- how much of your prompt was served from cache. Cached tokens still count towardprompt_tokens.usage.reasoning_tokens- tokens spent reasoning before answering.
The response may gain fields over time. Read the ones you need and ignore any you do not recognize, rather than depending on the exact shape.
Streaming
Set "stream": true and the reply arrives as server-sent events instead of one
JSON body. Use it for anything a person is waiting on, so they see text appear
rather than a blank screen.
Each frame is a data: line holding one chunk, and the stream ends with a
literal [DONE] sentinel:
Four things to handle:
- Check
choicesis non-empty before indexing it. The final chunk before the sentinel reportsusageand carrieschoices: [], so code that reaches straight forchoices[0]on every chunk will fail on the last one. - Concatenate
choices[0].delta.contentacross chunks to build the reply. Any given chunk may carry no content. - Read
finish_reasonon every chunk. It arrives on a chunk whosedeltais empty, so do not wait for one that also carries content. - Stop on
data: [DONE]. It is a literal string, not JSON, so parse it as a sentinel before attempting to decode the payload.
All four, in a loop over the raw HTTP response:
Passing stream=True to requests.post matters as much as sending it in the
body: without it the client buffers the whole response and you get the text in
one piece at the end.
When reasoning is on, it streams in its own field and generally arrives before
any content:
If you use the OpenAI SDK, its streaming iterator handles the framing and the sentinel for you.
Tool calls also arrive in the delta when streaming. Each call comes complete in
a single chunk, keyed by its index and carrying the whole arguments string,
on a chunk with finish_reason: "tool_calls". You do not need to accumulate
argument fragments. See Tool
Calling for what to do with the
call once you have it.
Image input
Ask about an image by sending an image_url content part alongside your text,
in OpenAI’s format. Image input is supported on asi1.
cURL
Python
The Python example reuses the client built in The request.
ASI:One fetches the image server side, so the URL has to be publicly reachable: a
link behind authentication or on a private network will not resolve. Pass a
hosted link rather than an inline data: URI.
The answer comes back as ordinary text, so nothing else about the request or the
reply changes. Image input is specific to this endpoint;
/v1/responses takes text input.
What else this endpoint takes
- Tool calling with
toolsandtool_choice. - Structured data with
response_format. - Reasoning with
enable_thinkingandthinking_budget. - Planner mode with
planner_mode, which runs here and not on/v1/responses. - Image input with OpenAI’s
image_urlcontent parts, onasi1.
For which OpenAI parameters apply here and which belong on /v1/responses, see
OpenAI Compatibility.
Next steps
- Responses API - The stateful alternative, with retrieve and chaining
- Tool Calling - Let the model call your own functions
- Planner Mode - Multi-step work against Agentverse agents
- Errors and Rate Limits - What each status code means and what to retry