Choosing your connection
Foundry exposes two endpoints and two SDKs. The choice depends on whether you need Foundry-native features or maximum OpenAI compatibility.
| Foundry SDK | OpenAI SDK | |
|---|---|---|
| Endpoint | Project endpoint (…/api/projects/<name>) | Azure OpenAI endpoint (…/openai/v1) |
| Use when | Agents, tool approval, cloud evaluations, tracing, Foundry direct models, project governance | Max OpenAI compatibility, portability, plain model inference |
| Package (Python) | azure-ai-projects | openai |
Key concept · They compose, and auth matters
You can use both SDKs together — the Foundry AIProjectClient for project-level features, the OpenAI client (via project_client.get_openai_client()) for inference. Even the Foundry SDK's chat functionality is derived from the OpenAI SDK. For auth, prefer Microsoft Entra ID (via DefaultAzureCredential) in production; if you must use keys, store them in Azure Key Vault, never in code. Code must run in an authenticated Azure session (e.g. az login).
Stateful, multi-turn — the recommended path
The Responses API unifies the old ChatCompletions (stateless) and Assistants (stateful) APIs into one. It's the recommended way to generate responses in Foundry apps and works with Azure OpenAI and Foundry direct models (Phi, DeepSeek).
Key concept · previous_response_id maintains context
Pass the prior response's id as previous_response_id and the API automatically threads in the system instructions, the new input, and the previous turn — no manual message list. A multi-turn loop just saves response.id each turn. It also supports instructions (system prompt), temperature/max_output_tokens/top_p, streaming, and async. Caveat: state management is convenient but doesn't reduce tokens — every call still sends instructions + history + tool schemas + retrieved context.
Read the answer from response.output_text; the object also carries id, status, usage.total_tokens, and model.
The established, stateless alternative
The ChatCompletions API is widely compatible across models and platforms — good for maintaining existing code — but it is stateless: you manage the conversation yourself as a list of message objects, each with a role and content.
| Role | Purpose |
|---|---|
| system | Sets the assistant's behavior, personality, and instructions. |
| user | Carries the user's prompt. |
| assistant | Holds previous model responses, appended to preserve context. |
To keep context you append each user message and each assistant reply to a growing messages list and resubmit the whole list every call — which increases token usage. The reply is read from completion.choices[0].message.content. Because the Responses API tracks state for you, it's preferred for new development.
Chapter 3 quiz
Fourteen questions on endpoints/SDKs, the Responses API, and the ChatCompletions API. Answer first, then expand Show answer.
Part A · Multiple choice
Which endpoint + SDK do you use to build agents with tool-approval workflows and tracing?
- A Azure OpenAI endpoint + OpenAI SDK
- B Project endpoint + Foundry SDK
- C Any REST call
- D Playground only
Show answer
B. The Foundry SDK against the project endpoint provides agents, evaluations, tracing, and Foundry direct models.
Which chat API is recommended for most new development?
- A The ChatCompletions API
- B The Responses API
- C The Assistants API
- D The Embeddings API
Show answer
B — the Responses API. It unifies the older APIs and manages state.
How does the Responses API maintain conversation context automatically?
- A Via the
previous_response_idparameter - B By retraining the model
- C By storing a cookie
- D It doesn't — it's stateless
Show answer
A. Passing the prior response's id threads in instructions, new input, and the previous turn.
Which three roles does a ChatCompletions message list use?
- A admin, guest, bot
- B system, user, assistant
- C prompt, context, output
- D input, tool, result
Show answer
B — system, user, assistant.
Where do you read the generated text from a Responses API call?
- A
response.output_text - B
completion.choices[0].message.content - C
response.body - D
response.tokens
Show answer
A — response.output_text. (ChatCompletions uses completion.choices[0].message.content.)
Which authentication method is recommended for production?
- A Hardcoded API keys
- B Microsoft Entra ID (DefaultAzureCredential)
- C No authentication
- D A shared password
Show answer
B. Keys, if used, belong in Azure Key Vault — never in code.
Part B · True or false
The ChatCompletions API is stateful and tracks conversation history for you.
Show answer
False. It's stateless — you resend the full message list every call.
You can use the Foundry SDK and the OpenAI SDK together in one application.
Show answer
True. Foundry SDK for project features, OpenAI SDK (via get_openai_client) for inference.
The Responses API works only with Azure OpenAI models.
Show answer
False. It also works with Foundry direct models like Phi and DeepSeek.
Using previous_response_id reduces the tokens sent on each call.
Show answer
False. It manages state conveniently but every call still sends instructions + history + context.
Streaming responses improve UX for long outputs.
Show answer
True. The Responses API supports streaming (and async) for responsive interfaces.
Part C · Short answer
Name the two endpoint types Foundry exposes.
Show answer
The project (Foundry-native) endpoint and the Azure OpenAI endpoint.
Which two APIs did the Responses API unify?
Show answer
The stateless ChatCompletions API and the stateful Assistants API.
In ChatCompletions, how do you preserve context across turns?
Show answer
Append each user message and each assistant reply to a growing messages list and resubmit the whole list every call.