Calling the OpenAI API from C# takes about ten lines of code once you know which package to use. This guide walks through it from scratch — installing the SDK, sending your first chat completion, streaming the response, and (the part tutorials skip) keeping your API key out of your source code. By the end you’ll have a working C# console app talking to a model.
Which package to use
There are two solid choices in .NET, and they serve different needs:
OpenAI— the official OpenAI SDK for .NET. Use it when you’re talking specifically to OpenAI.Microsoft.Extensions.AI— Microsoft’s provider-agnostic abstraction (IChatClient). Use it when you want to swap between OpenAI, Azure OpenAI, or other providers without rewriting your code. This is what the Microsoft Agent Framework builds on.
For a first call, start with the official SDK; graduate to Microsoft.Extensions.AI when you want portability.
Step 1: Install and set your key
dotnet new console -n OpenAiDemo
cd OpenAiDemo
dotnet add package OpenAI
Never hard-code your API key. Put it in an environment variable (or user-secrets in development) so it never lands in source control:
setx OPENAI_API_KEY "sk-..." # Windows; reopen the terminal afterwards
Step 2: Your first chat completion
using OpenAI.Chat;
var client = new ChatClient(
model: "gpt-4o-mini",
apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
ChatCompletion completion = await client.CompleteChatAsync(
"Explain what an API is, in one sentence.");
Console.WriteLine(completion.Content[0].Text);
Run it and you’ll get a one-sentence answer. That’s the whole round-trip: create a client, send a message, read the reply.
Step 3: Add a system prompt and conversation
Real apps set behaviour with a system message and keep a conversation going by passing the message history:
List<ChatMessage> messages =
[
new SystemChatMessage("You are a concise assistant that answers in bullet points."),
new UserChatMessage("Give me three tips for writing clean C#."),
];
var completion = await client.CompleteChatAsync(messages);
Console.WriteLine(completion.Content[0].Text);
To continue the conversation, append the assistant’s reply and the next user message to messages and call again.
Step 4: Stream the response
For anything user-facing, stream tokens as they arrive so the answer appears progressively instead of after a long pause:
await foreach (StreamingChatCompletionUpdate update
in client.CompleteChatStreamingAsync("Write a haiku about C#."))
{
foreach (var part in update.ContentUpdate)
Console.Write(part.Text);
}
(For streaming all the way to a browser, see streaming agent responses to a web UI.)
Step 5: Keep the key safe in production
Environment variables are fine locally, but in production prefer a secrets manager or, better, a keyless setup. If you deploy on Azure, use Azure OpenAI with DefaultAzureCredential and a managed identity so there’s no key at all — the app authenticates as itself. This is covered in the Azure deployment guide, and the security reasoning in securing AI agents.
Note: SDK class names (
ChatClient,CompleteChatAsync) can change between versions. Verify against the official OpenAI .NET SDK for the version you install; the flow — client, messages, complete, stream — is stable.
Where to go next
Calling the API is the foundation. The interesting part is what you build on top:
- Give the model tools it can call → build a tool-using agent in C#.
- Get structured JSON back instead of prose → structured output in .NET.
- Run a model locally with no API key → local LLMs in .NET with Ollama.
Takeaway
Calling OpenAI from C# is a three-line round-trip with the official OpenAI SDK: create a ChatClient, send messages, read the reply — and stream for anything users see. Keep your key in an environment variable locally and move to a keyless managed-identity setup in production. Once that plumbing works, everything else — tools, structured output, agents — is built on the exact same call.
Have a correction or a topic you want covered? Email mani.bc72@gmail.com.