Azure AI Voice Live SDK for .NET. Build real-time voice AI applications with bidirectional WebSocket communication.
Real-time voice AI SDK for building bidirectional voice assistants with Azure AI.
dotnet add package Azure.AI.VoiceLive
dotnet add package Azure.Identity
dotnet add package NAudio # For audio capture/playback
Current Versions: Stable v1.0.0, Preview v1.1.0-beta.1
AZURE_VOICELIVE_ENDPOINT=https://<resource>.services.ai.azure.com/
AZURE_VOICELIVE_MODEL=gpt-4o-realtime-preview
AZURE_VOICELIVE_VOICE=en-US-AvaNeural
# Optional: API key if not using Entra ID
AZURE_VOICELIVE_API_KEY=<your-api-key>
using Azure.Identity;
using Azure.AI.VoiceLive;
Uri endpoint = new Uri("https://your-resource.cognitiveservices.azure.com");
DefaultAzureCredential credential = new DefaultAzureCredential();
VoiceLiveClient client = new VoiceLiveClient(endpoint, credential);
Required Role: Cognitive Services User (assign in Azure Portal → Access control)
Uri endpoint = new Uri("https://your-resource.cognitiveservices.azure.com");
AzureKeyCredential credential = new AzureKeyCredential("your-api-key");
VoiceLiveClient client = new VoiceLiveClient(endpoint, credential);
VoiceLiveClient
└── VoiceLiveSession (WebSocket connection)
├── ConfigureSessionAsync()
├── GetUpdatesAsync() → SessionUpdate events
├── AddItemAsync() → UserMessageItem, FunctionCallOutputItem
├── SendAudioAsync()
└── StartResponseAsync()
using Azure.Identity;
using Azure.AI.VoiceLive;
var endpoint = new Uri(Environment.GetEnvironmentVariable("AZURE_VOICELIVE_ENDPOINT"));
var client = new VoiceLiveClient(endpoint, new DefaultAzureCredential());
var model = "gpt-4o-mini-realtime-preview";
// Start session
using VoiceLiveSession session = await client.StartSessionAsync(model);
// Configure session
VoiceLiveSessionOptions sessionOptions = new()
{
Model = model,
Instructions = "You are a helpful AI assistant. Respond naturally.",
Voice = new AzureStandardVoice("en-US-AvaNeural"),
TurnDetection = new AzureSemanticVadTurnDetection()
{
Threshold = 0.5f,
PrefixPadding = TimeSpan.FromMilliseconds(300),
SilenceDuration = TimeSpan.FromMilliseconds(500)
},
InputAudioFormat = InputAudioFormat.Pcm16,
OutputAudioFormat = OutputAudioFormat.Pcm16
};
// Set modalities (both text and audio for voice assistants)
sessionOptions.Modalities.Clear();
sessionOptions.Modalities.Add(InteractionModality.Text);
sessionOptions.Modalities.Add(InteractionModality.Audio);
await session.ConfigureSessionAsync(sessionOptions);
await foreach (SessionUpdate serverEvent in session.GetUpdatesAsync())
{
switch (serverEvent)
{
case SessionUpdateResponseAudioDelta audioDelta:
byte[] audioData = audioDelta.Delta.ToArray();
// Play audio via NAudio or other audio library
break;
case SessionUpdateResponseTextDelta textDelta:
Console.Write(textDelta.Delta);
break;
case SessionUpdateResponseFunctionCallArgumentsDone functionCall:
// Handle function call (see Function Calling section)
break;
case SessionUpdateError error:
Console.WriteLine($"Error: {error.Error.Message}");
break;
case SessionUpdateResponseDone:
Console.WriteLine("\n--- Response complete ---");
break;
}
}
await session.AddItemAsync(new UserMessageItem("Hello, can you help me?"));
await session.StartResponseAsync();
// Define function
var weatherFunction = new VoiceLiveFunctionDefinition("get_current_weather")
{
Description = "Get the current weather for a given location",
Parameters = BinaryData.FromString("""
{
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state or country"
}
},
"required": ["location"]
}
""")
};
// Add to session options
sessionOptions.Tools.Add(weatherFunction);
// Handle function call in event loop
if (serverEvent is SessionUpdateResponseFunctionCallArgumentsDone functionCall)
{
if (functionCall.Name == "get_current_weather")
{
var parameters = JsonSerializer.Deserialize<Dictionary<string, string>>(functionCall.Arguments);
string location = parameters?["location"] ?? "";
// Call external service
string weatherInfo = $"The weather in {location} is sunny, 75°F.";
// Send response
await session.AddItemAsync(new FunctionCallOutputItem(functionCall.CallId, weatherInfo));
await session.StartResponseAsync();
}
}
| Voice Type | Class | Example |
|------------|-------|---------|
| Azure Standard | AzureStandardVoice | "en-US-AvaNeural" |
| Azure HD | AzureStandardVoice | "en-US-Ava:DragonHDLatestNeural" |
| Azure Custom | AzureCustomVoice | Custom voice with endpoint ID |
| Model | Description |
|-------|-------------|
| gpt-4o-realtime-preview | GPT-4o with real-time audio |
| gpt-4o-mini-realtime-preview | Lightweight, fast interactions |
| phi4-mm-realtime | Cost-effective multimodal |
| Type | Purpose |
|------|---------|
| VoiceLiveClient | Main client for creating sessions |
| VoiceLiveSession | Active WebSocket session |
| VoiceLiveSessionOptions | Session configuration |
| AzureStandardVoice | Standard Azure voice provider |
| AzureSemanticVadTurnDetection | Voice activity detection |
| VoiceLiveFunctionDefinition | Function tool definition |
| UserMessageItem | User text message |
| FunctionCallOutputItem | Function call response |
| SessionUpdateResponseAudioDelta | Audio chunk event |
| SessionUpdateResponseTextDelta | Text chunk event |
Text and Audio for voice assistantsAzureSemanticVadTurnDetection — Provides natural conversation flowusing statement — Ensures proper session disposalif (serverEvent is SessionUpdateError error)
{
if (error.Error.Message.Contains("Cancellation failed: no active response"))
{
// Benign error, can ignore
}
else
{
Console.WriteLine($"Error: {error.Error.Message}");
}
}
InputAudioFormat.Pcm16 (16-bit PCM)OutputAudioFormat.Pcm16| SDK | Purpose | Install |
|-----|---------|---------|
| Azure.AI.VoiceLive | Real-time voice (this SDK) | dotnet add package Azure.AI.VoiceLive |
| Microsoft.CognitiveServices.Speech | Speech-to-text, text-to-speech | dotnet add package Microsoft.CognitiveServices.Speech |
| NAudio | Audio capture/playback | dotnet add package NAudio |
| Resource | URL | |----------|-----| | NuGet Package | https://www.nuget.org/packages/Azure.AI.VoiceLive | | API Reference | https://learn.microsoft.com/dotnet/api/azure.ai.voicelive | | GitHub Source | https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/ai/Azure.AI.VoiceLive | | Quickstart | https://learn.microsoft.com/azure/ai-services/speech-service/voice-live-quickstart |
This skill is applicable to execute the workflow or actions described in the overview.
Copy a source-pinned command for your client. You run it yourself.
Destination: .claude/skills/azure-ai-voicelive-dotnet · pinned to the source commit
# Run from your project root
git clone https://github.com/sickn33/agentic-awesome-skills.git .skillboard-tmp
git -C .skillboard-tmp checkout 5cf4dfeb13ea966daa1e117897689cd7991e3f44
mkdir -p ".claude/skills"
cp -r ".skillboard-tmp/plugins/agentic-awesome-skills-claude/skills/azure-ai-voicelive-dotnet" ".claude/skills/"
rm -rf .skillboard-tmpReview the source before running. This copies files into your project; it is not a one-click install and does not verify runtime safety.
sudo apt update && sudo apt install -y gitnpm install -g @anthropic-ai/claude-code# Run from your project root
git clone https://github.com/sickn33/agentic-awesome-skills.git .skillboard-tmp
git -C .skillboard-tmp checkout 5cf4dfeb13ea966daa1e117897689cd7991e3f44
mkdir -p ".claude/skills"
cp -r ".skillboard-tmp/plugins/agentic-awesome-skills-claude/skills/azure-ai-voicelive-dotnet" ".claude/skills/"
rm -rf .skillboard-tmpDestination: .claude/skills/azure-ai-voicelive-dotnet
Scanner static-checks@0.1.0 · commit 5cf4dfeb13ea. Static checks cannot prove runtime safety – review the source and the exact diff before installing. How checks work.
References credentials, tokens or secret files that a skill should not need.
Evidence: [redacted]· fingerprint ccae6d912a41bfef