Migrate to the OpenAI Responses API: Field Mapping, Code and the Decisions API
Move from Chat Completions to the OpenAI Responses API: field mapping, code, tools, structured outputs and state. Plus what the Decisions API is for.
Last Updated:

Short answer: Chat Completions is still supported, but OpenAI recommends the Responses API for all new projects, and the Assistants API was shut down on 2026-08-26. To migrate, replace messages with instructions plus input, read response.output_text instead of choices[0].message.content, move response_format to text.format, and flatten function definitions. For classification, routing and scoring, OpenAI's new Decisions API (POST /v1/decisions) returns typed answers, which OpenAI says arrive about 10 times faster than from the Responses API, and it does not charge for output tokens.
Key takeaways
- Most changes are renames.
messagesbecomesinputandinstructions,choicesbecomesoutputitems, andresponse_formatbecomestext.format. - Responses are stored by default. Set
store: falseif you do not want OpenAI to keep them, and resend context yourself. - Hosted tools come built in. Web search and other OpenAI tools are a line in
tools, with no integration code. - Decisions is not a chat API. It answers fixed questions with a probability, a choice from your list, or a score on a rubric.
Why migrate
OpenAI's migration guide says: "While Chat Completions remains supported, Responses is recommended for all new projects." It lists three benefits: built-in tools, multi-turn state managed by OpenAI, and better use of the prompt cache.
The Assistants API "was officially sunset on August 26, 2026, and is no longer available." If you still have Assistants code, the Responses API is the replacement.
Field mapping
| Chat Completions | Responses API |
|---|---|
messages with a system message | instructions plus input (a string or a list of items) |
choices[0].message.content | output_text, or the items in output |
response_format | text.format |
tools: [{ "type": "function", "function": { ... } }] | tools: [{ "type": "function", "name": ..., "parameters": ... }] |
tool_calls on the message, answered with role: "tool" | function_call items, answered with function_call_output items that carry the same call_id |
| Your own web search code | tools: [{ "type": "web_search" }] |
| Resend the full history every turn | previous_response_id, or resend the items yourself |
delta chunks in the stream | Typed events such as response.output_text.delta and response.completed |
| Stored by default for new accounts | Stored by default; store: false turns it off |
Before and after
Chat Completions:
from openai import OpenAI
client = OpenAI()
completion = client.chat.completions.create(
model="gpt-6-astra",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello!"},
],
)
print(completion.choices[0].message.content)
Responses API:
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-6-astra",
instructions="You are a helpful assistant.",
input="Hello!",
)
print(response.output_text)
What changes for agents
Function calling
In Chat Completions, function definitions are wrapped in a function object. In the Responses API they are flat: type, name, description and parameters sit at the top level of each tool. When the model calls a function, output contains a function_call item with a call_id and JSON arguments. Run the function, then send a function_call_output item with the same call_id in the next request.
Structured outputs
Move the schema from response_format to text.format:
response = client.responses.create(
model="gpt-6-astra",
input="Extract the company and the amount: Acme paid $1,200 on 3 March.",
text={
"format": {
"type": "json_schema",
"name": "payment",
"schema": {
"type": "object",
"properties": {
"company": {"type": "string"},
"amount": {"type": "number"},
},
"required": ["company", "amount"],
"additionalProperties": False,
},
"strict": True,
}
},
)
Conversation state
You have two options:
- Let OpenAI keep the state. Pass
previous_response_idfrom the last response. Sendinstructionsagain on every request, because they do not carry over. - Keep the state yourself. Set
store: falseand send the earlier items back ininput. This works when you cannot store data with OpenAI, and it works the same way on gateways that serve the Responses format.
Streaming
Responses streaming sends typed server-sent events. Switch on the event type: append text on response.output_text.delta and finish on response.completed, instead of reading delta fields from chunks.
Migration checklist
- Move the system message to
instructionsand the rest toinput. - Read
output_text, or walkoutputitems if you use tools. - Flatten function definitions and answer calls with
function_call_outputitems keyed bycall_id. - Move
response_formattotext.format. - Decide on state:
previous_response_id, orstore: falsewith your own history. - Rewrite stream handling for typed events.
- Replace your own web search or file search code with hosted tools where they fit.
- Run both paths on the same prompts and compare outputs, token use and latency before you switch traffic.
The OpenAI Decisions API
The Decisions API "evaluates text, images, and JSON and returns typed answers." It is generally available at POST /v1/decisions, and gpt-6-luna is the only supported model. It does not write text. Each request asks 1 to 400 questions of three types:
| Type | Returns | Example use |
|---|---|---|
predicate | The probability that a condition is true | Does this product photo show damage? |
choice | One value from options you supply, with probabilities and a confidence | Which team should handle this ticket? |
score | A probability-weighted score against 2 to 10 ordered levels | How severe is this incident? |
A request has model, input and questions. Each question has a type, a name to match the answer and instructions. A choice question also has choices:
{
"model": "gpt-6-luna",
"input": "My card was charged twice for the same order.",
"questions": [
{
"type": "choice",
"name": "department",
"instructions": "Which team should handle this message?",
"choices": [{ "value": "billing" }, { "value": "shipping" }, { "value": "technical" }]
},
{
"type": "predicate",
"name": "money_lost",
"instructions": "The customer says they lost money."
}
]
}
The response has an answers array: a choice answer carries choice, probabilities and confidence, and a predicate answer carries probability.
Price. Uncached input costs $0.10 per million tokens on gpt-6-luna, and output tokens are not charged. Prompt caching needs a shared prefix of at least 1,024 tokens.
When to use it. Use Decisions for routing, moderation, triage and grading, where the answer is a yes or no, a label or a score. Use the Responses API with structured outputs when you need your own JSON schema, and function calling when the model must call tools with arguments.
Use the Responses API on other models with AIsa
AIsa serves the Responses format at https://api.aisa.one/v1/responses, so the OpenAI SDK works with a different base URL. In the AIsa model catalog, the OpenAI models and other families such as GLM list /v1/responses as a route, so one agent can switch between them by changing the model string:
from openai import OpenAI
client = OpenAI(api_key="YOUR_AISA_API_KEY", base_url="https://api.aisa.one/v1")
response = client.responses.create(
model="gpt-6-luna",
instructions="Answer in one short sentence.",
input="What does previous_response_id do in the Responses API?",
)
print(response.output_text)
We ran this call on 2026-11-15: it returned a completed response with 27 input tokens and 34 output tokens. For state, check whether previous_response_id works for your key before you depend on it, or resend the items yourself, which works on any provider. AIsa does not list the Decisions API. The same key also reaches 6,000+ data APIs that an agent can call as tools. Create a key in the AIsa console.
FAQ
Is OpenAI deprecating Chat Completions?
No date has been announced. OpenAI says Chat Completions remains supported and recommends the Responses API for new projects.
When was the Assistants API shut down?
On 2026-08-26. It is no longer available, and OpenAI points to the Responses API as the replacement.
What is the difference between previous_response_id and store?
store decides whether OpenAI keeps the response. previous_response_id asks OpenAI to continue from a stored response. With store: false, you resend the conversation items yourself.
What is the OpenAI Decisions API?
An endpoint at POST /v1/decisions that answers predicate, choice and score questions about text, images or JSON with gpt-6-luna. It does not generate text, and output tokens are free.
How much does the Decisions API cost?
$0.10 per million uncached input tokens on gpt-6-luna, with no charge for output tokens. Cache writes are charged and cache hits are discounted.
Sources
- Migrate to the Responses API and Decisions API guide, OpenAI developer docs, read 2026-11-15
- Test call to
gpt-6-lunaonhttps://api.aisa.one/v1/responses, 2026-11-15, and the AIsa model catalog