# Responses API vs Chat Completions: which to use in 2026

URL: https://infro.io/blog/responses-api-vs-chat-completions
Author: INFRO Editorial (https://infro.io/blog/editorial)
Publisher: INFRO
Published: 2026-10-20
Last modified: 2026-10-20
Last reviewed: 2026-10-20 (next review due 2026-11-19)
Topic: Architecture and migration
Format: Guide

> OpenAI recommends the Responses API for all new projects; Chat Completions remains supported, and the Assistants API was sunset on 26 August 2026. Responses returns typed items (messages, reasoning, function calls) instead of a messages array, stores responses by default, can chain turns with previous_response_id, and includes hosted tools such as web search, file search, code interpreter and remote MCP servers. Chat Completions is the more portable shape across providers and gateways. Use Responses for OpenAI-specific agent features; keep Chat Completions, or send full state with store: false, where portability and failover matter.

Key takeaways:
- OpenAI recommends Responses for all new projects; Chat Completions is still supported; the Assistants API was sunset on 26 August 2026.
- Responses returns typed items, stores responses by default, can chain turns with previous_response_id, and has hosted tools.
- previous_response_id still bills the earlier input tokens and does not carry over top-level instructions.
- Chat Completions is the shape most other providers, gateways and open-source servers speak, so it is the portable choice.
- For portability on Responses, send the whole conversation each turn with store: false and replay reasoning items.

**Should you use OpenAI's Responses API or Chat Completions?** OpenAI says "Responses is recommended for all new projects", while Chat Completions remains supported, so existing code can migrate one flow at a time[1]. Choose **Responses** when you want OpenAI's agent features: typed reasoning and tool-call items, hosted tools such as web search and remote MCP servers, and optional server-side conversation state. Keep **Chat Completions** — or use Responses statelessly — where portability matters, because Chat Completions is the shape nearly every other provider, gateway and open-source server speaks.

One decision is already made: OpenAI states the Assistants API "was officially sunset on August 26, 2026, and is no longer available"[1]. If anything still calls it, that is the first migration.

## What actually differs

|  | Chat Completions | Responses |
| --- | --- | --- |
| Input and output | `messages` array in, `choices[].message` out | Typed items: messages, reasoning, function calls in an `output` array |
| Multiple generations | `n` parameter | One generation per request |
| Storage | Stored by default only for new accounts | Stored by default; `store: false` disables |
| Conversation state | You resend the transcript | `previous_response_id`, the Conversations API, or replaying items |
| Hosted tools | Not included | Web search, file search, code interpreter, remote MCP servers |
| Reasoning across turns | Not carried | Reasoning items, with encrypted content for `store: false` |
| Portability | Spoken by most providers and gateways | OpenAI and Azure OpenAI; elsewhere through translation |

Table: From OpenAI's migration guide, 2026-10-20, and the compatibility pages cited below.

### Items instead of messages

Responses returns an ordered list of typed items rather than one assistant message[1]. For a reasoning model calling tools, the output can hold a reasoning item, a function call, then a message. That makes agent loops more explicit, and it means code that read `choices[0].message.content` needs a different accessor (the SDKs provide `output_text` for the simple case).

### State is optional, and not free

Responses can keep state server-side: pass `previous_response_id` and the next turn continues from the stored response, or use the Conversations API. OpenAI's guide adds two caveats worth reading twice: `previous_response_id` does not carry over top-level `instructions`, and the prior input tokens remain billed[1]. Server-side state saves you sending the transcript; it does not save you paying for it. Prompt caching is what lowers the cost of repeated context.

### Reasoning that survives a turn

Reasoning models produce reasoning tokens that are billed as output and not shown[2]. Responses can return reasoning items so the next turn continues from them; for stateless or zero-data-retention setups, OpenAI's guidance is to set `store: false` and replay the returned reasoning items, which carry encrypted content[1]. Chat Completions has no equivalent, so multi-turn agents on reasoning models lose that continuity there.

### Hosted tools

Responses includes OpenAI-hosted tools — web search, file search, code interpreter and remote MCP servers[1]. They save you building the tools, and they bind the workload to OpenAI: a request that uses a hosted tool cannot fail over to a provider that does not have it.

## Portability: the case for Chat Completions

Chat Completions became the industry's common dialect. Google's OpenAI compatibility layer for Gemini documents chat completions (plus images, video, embeddings and batch)[3]; Anthropic's compatibility layer for Claude is also Chat Completions; and open-source servers and most gateways accept it. Azure OpenAI's v1 API serves both Responses and Chat Completions, and recommends Responses for its OpenAI models while using Chat Completions syntax for other providers' models such as DeepSeek and Grok[4].

So the choice is partly about lock-in. Code written against Chat Completions can move to another provider by changing the base URL. Code written against Responses with stored state and hosted tools is OpenAI-shaped by design. [Avoiding LLM vendor lock-in](https://infro.io/blog/avoid-llm-vendor-lock-in) covers the wider trade.

## A decision guide

| Your situation | Use |
| --- | --- |
| New agent on OpenAI reasoning models, hosted tools wanted | Responses |
| Existing Chat Completions code that works | Keep it; migrate flows that need Responses features |
| Product that must fail over between providers | Chat Completions, or Responses with `store: false` and no hosted tools |
| Zero data retention requirement | Responses with `store: false` and encrypted reasoning items, or Chat Completions |
| Codex or the OpenAI Agents SDK | Responses (Codex supports only the Responses wire API) |
| Anything still on the Assistants API | Responses, now |

## The same request in both shapes

```python
from openai import OpenAI

client = OpenAI()
history = [
    {"role": "system", "content": "You are a concise support assistant."},
    {"role": "user", "content": "Where is order 4471?"},
]
reply = client.chat.completions.create(model="gpt-6-sol", messages=history)
history.append({"role": "assistant", "content": reply.choices[0].message.content})
```

```python
from openai import OpenAI

client = OpenAI()
items = [{"role": "user", "content": "Where is order 4471?"}]
response = client.responses.create(
    model="gpt-6-sol",
    instructions="You are a concise support assistant.",
    input=items,
    store=False,                              # keep state on your side
    include=["reasoning.encrypted_content"],  # so reasoning can be replayed next turn
)
items += response.output                       # carry every returned item forward
print(response.output_text)
```

The stateless Responses version carries the returned items — reasoning included — into the next turn itself, so it keeps the benefits of reasoning continuity without storing anything at OpenAI and without depending on `previous_response_id`. Note that `instructions` is sent on every call; it is not part of the item history.

## Mistakes that show up after a migration

- **Reading only the text.** Code that takes `output_text` and ignores the other items drops function calls and reasoning, and an agent loop silently stops calling its tools.
- **Losing the system prompt.** Teams that move to `previous_response_id` forget that top-level `instructions` are not carried over and must be sent again on each request.
- **Unintended storage.** Responses are stored by default. If your data policy says prompts must not be retained by the provider, set `store: false` explicitly on every call and verify it in tests.
- **Expecting `n`.** Responses returns one generation per request; code that asked for several completions needs several requests.
- **Assuming state saves money.** Chained turns still bill the earlier input; check the usage fields before and after the migration on the same conversations.

## Migrating without lock-in

If you move to Responses but want to keep failover options:

1. **Send the full conversation every turn** and set `store: false`, so no state lives on the provider.
2. **Replay reasoning items** you received, rather than relying on `previous_response_id`.
3. **Use your own function tools** for anything you might need on another provider; keep hosted tools to features you accept as OpenAI-only.
4. **Wrap the call** behind your own interface so the shape is decided in one place.

Migrate one user flow at a time, compare outputs and cost on real traffic, then move the next — the approach OpenAI's guide itself suggests[1].

## Both shapes through INFRO

INFRO answers both: `POST /v1/chat/completions` and `POST /v1/responses`. On an OpenAI or Azure OpenAI connection a Responses request goes to the provider as written, including reasoning items and Codex's custom tools; on other providers it is translated for messages, images, function tools and JSON-schema output, and a request that needs something only OpenAI provides is refused with `400 unsupported_on_targets` rather than sent in reduced form. INFRO keeps no responses, so `previous_response_id`, `conversation` and `background: true` are refused: a failover to another account or model could not resolve them. Send the whole conversation each turn, which is what Codex does. Budgets, allowlists and the cost estimate apply to both endpoints the same way.

## Summary

Use Responses for new OpenAI agent work and anything still on Assistants; keep Chat Completions where it works and where portability matters; and if you adopt Responses but want options, keep state on your side with `store: false`, replay reasoning items, and reserve hosted tools for features you accept as OpenAI-only.

## Questions

### Is Chat Completions deprecated?

No. OpenAI's migration guide recommends the Responses API for all new projects but says Chat Completions is still supported, so teams can migrate one flow at a time. The Assistants API, by contrast, was sunset on 26 August 2026.

### What is the difference between the Responses API and Chat Completions?

Chat Completions takes and returns a messages array and leaves conversation state to you. Responses returns typed items such as messages, reasoning and function calls, stores responses by default, can chain turns with previous_response_id or the Conversations API, and includes hosted tools such as web search, file search, code interpreter and remote MCP servers.

### Does previous_response_id save tokens?

No. OpenAI's guide notes that prior input tokens remain billed when you chain with previous_response_id, and top-level instructions are not carried over. It saves you sending the transcript, not paying for it; prompt caching is what lowers the cost of repeated context.

### Can I use the Responses API with Claude or Gemini?

Not directly through their own APIs: Anthropic's compatibility layer and Google's OpenAI compatibility layer document Chat Completions. A gateway that accepts the Responses shape and translates it can reach other providers, usually for a subset of features such as messages, function tools and JSON-schema output.

## Sources

1. Migrate to the Responses API — OpenAI. https://developers.openai.com/api/docs/guides/migrate-to-responses (accessed 2026-10-20)
2. Reasoning models — OpenAI. https://developers.openai.com/api/docs/guides/reasoning (accessed 2026-10-20)
3. OpenAI compatibility — Google. https://ai.google.dev/gemini-api/docs/openai (accessed 2026-10-20)
4. Azure OpenAI in Microsoft Foundry Models v1 API — Microsoft. https://learn.microsoft.com/en-us/azure/foundry/openai/api-version-lifecycle (accessed 2026-10-20)
