Card 08 of 38· Domain 2 · Generative AI and agents

The two chat APIs — ChatCompletions vs Responses

Models are stateless, and these are the two ways to cope. Which endpoint talks to what, the one hard rule about keys, and the bridge pattern you will write constantly.

The two chat APIs — ChatCompletions vs Responses
Open the card in a new tab to read it at full size.

Start from the fact that makes everything else here necessary: a language model has no memory. Each call arrives with no knowledge of the last one. Everything that feels like a conversation is a trick played on top of a stateless system, and there are two ways to play it.

Two approaches to the same problem

Chat Completions solves it by resending. Every turn, you send the entire conversation history again. The model reads the lot and answers the last message. Simple, and the payload grows steadily as the conversation goes on — which costs both tokens and latency.

The Responses API solves it by remembering server-side. You pass a previous_response_id, and the state is held for you. Your payload stays a constant size no matter how long the conversation runs.

The mechanical differences follow from that, and they get tested directly:

Chat Completions Responses
History Resent every turn Held server-side
Payload size Grows Constant
System message An entry in messages with role:"system" The instructions parameter
Reading the reply completion.choices[0].message.content response.output_text

Note where the system message goes. It is a message in one and a named parameter in the other, and mixing those up is an easy mark to drop.

Two endpoints, and the one hard rule

Azure OpenAI endpoint Foundry project endpoint
Talks to The model, directly The platform — agents, tools, grounding
Package openai azure-ai-projects (2.0.0+)
Client AzureOpenAI AIProjectClient
Authentication Keys or Entra ID Entra ID only
OpenAI API coverage Broadest Shaped to the platform

The authentication row is the one to memorise. The project endpoint never accepts an API key. If a question offers a key-based answer for the project endpoint, it is wrong regardless of how reasonable the rest of it looks.

Choose between them on what you are reaching for. Raw model access, and you want the Azure OpenAI endpoint and the broadest API surface. Agents, tools or grounding, and you want the project endpoint.

The bridge you will write constantly

There is a pattern that connects the two, and it is worth being able to write from memory:

  1. Create an AIProjectClient with the endpoint and DefaultAzureCredential().
  2. Call project.get_openai_client() on it.
  3. Call client.responses.create(model=agent_name, ...).

You authenticate once at the platform level and get a working model client out the other side. Useful to know: openai arrives as a transitive dependency of azure-ai-projects, so you do not install it separately.

The distractors

Asked which method generates a reply with the Responses API, the plausible wrong answers are create on its own and get_response_id. The answer is responses.create.

Both distractors work by being almost right — one is the method name without its object, the other is a real-sounding function that does something else. That is the general shape of distractors on this exam: recognisable fragments assembled incorrectly. Read the whole call, not the verb.