This tutorial walks you through building a basic voice agent using C# and the Deepgram .NET SDK. You will learn how to connect to the Agent API, configure its behavior, and stream audio for processing.

## Prerequisites

Before you begin, ensure you have the following:

- A Deepgram API key. You can get one in the [Deepgram Console](https://console.deepgram.com/).
- The .NET SDK installed on your machine.

## 1. Set up your environment

Create a new console project and navigate into it.

```shell
mkdir deepgram-agent-demo
cd deepgram-agent-demo
dotnet new console
```

Export your Deepgram API key as an environment variable.

```shell
# macOS/Linux
export DEEPGRAM_API_KEY="your_api_key"

# Windows PowerShell
$env:DEEPGRAM_API_KEY = "your_api_key"
```

## 2. Install the Deepgram SDK

Add the Deepgram .NET SDK to your project.

```shell
dotnet add package Deepgram
```

## 3. Create the Voice Agent

Open `Program.cs` and replace its content with the following code. This script connects to Deepgram, configures the agent, and streams a sample audio file.

```csharp
using Deepgram;
using Deepgram.Logger;
using Deepgram.Models.Authenticate.v1;
using Deepgram.Models.Agent.v2.WebSocket;
using System.Collections.Generic;
using System.Net.Http;

namespace SampleApp
{
    class Program
    {
        static async Task Main(string[] args)
        {
            try
            {
                Deepgram.Library.Initialize(LogLevel.Debug);

                var apiKey = Environment.GetEnvironmentVariable("DEEPGRAM_API_KEY");
                DeepgramWsClientOptions options = new DeepgramWsClientOptions(null, null, true);
                var agentClient = ClientFactory.CreateAgentWebSocketClient(apiKey, options);

                var lastAudioTime = DateTime.Now;
                var audioFileCount = 0;

                var settingsConfiguration = new SettingsSchema();
                settingsConfiguration.Agent.Think.Provider.Type = "open_ai";
                settingsConfiguration.Agent.Think.Provider.Model = "gpt-4o-mini";
                settingsConfiguration.Audio.Output.SampleRate = 24000;
                settingsConfiguration.Audio.Output.Container = "wav";
                settingsConfiguration.Audio.Input.SampleRate = 24000;
                settingsConfiguration.Agent.Greeting = "Hello, how can I help you today?";
                settingsConfiguration.Agent.Listen.Provider.Type = "deepgram";
                settingsConfiguration.Agent.Listen.Provider.Model = "nova-3";
                settingsConfiguration.Agent.Speak.Provider.Type = "deepgram";
                settingsConfiguration.Agent.Speak.Provider.Model = "aura-2-thalia-en";

                bool connected = await agentClient.Connect(settingsConfiguration);
                if (!connected)
                {
                    Console.WriteLine("Failed to connect to Deepgram WebSocket server.");
                    return;
                }

                await agentClient.Subscribe(new EventHandler<AudioResponse>((sender, e) =>
                {
                    if (DateTime.Now.Subtract(lastAudioTime).TotalSeconds > 7)
                    {
                        audioFileCount++;
                        using (BinaryWriter writer = new BinaryWriter(File.Open($"output_{audioFileCount}.wav", FileMode.Create)))
                        {
                            writer.Write(CreateWavHeader(24000, 16, 1));
                        }
                    }

                    if (e.Stream != null)
                    {
                        using (BinaryWriter writer = new BinaryWriter(File.Open($"output_{audioFileCount}.wav", FileMode.Append)))
                        {
                            writer.Write(e.Stream.ToArray());
                        }
                    }
                    lastAudioTime = DateTime.Now;
                }));

                string url = "https://dpgr.am/spacewalk.wav";
                using (var httpClient = new HttpClient())
                {
                    var response = await httpClient.GetAsync(url);
                    var stream = await response.Content.ReadAsStreamAsync();
                    var buffer = new byte[8192];
                    int bytesRead;

                    while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
                    {
                        var chunk = new byte[bytesRead];
                        Array.Copy(buffer, chunk, bytesRead);
                        await agentClient.SendBinaryImmediately(chunk);
                    }
                }

                Console.WriteLine("Press any key to exit...");
                Console.ReadKey();

                await agentClient.Stop();
                Deepgram.Library.Terminate();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Exception: {ex.Message}");
            }
        }

        static byte[] CreateWavHeader(int sampleRate, short bitsPerSample, short channels)
        {
            int byteRate = sampleRate * channels * (bitsPerSample / 8);
            short blockAlign = (short)(channels * (bitsPerSample / 8));
            byte[] header = new byte[44];

            header[0] = 0x52; // R
            header[1] = 0x49; // I
            header[2] = 0x46; // F
            header[3] = 0x46; // F
            header[8] = 0x57; // W
            header[9] = 0x41; // A
            header[10] = 0x56; // V
            header[11] = 0x45; // E
            header[12] = 0x66; // f
            header[13] = 0x6D; // m
            header[14] = 0x74; // t
            header[15] = 0x20; // Space
            header[16] = 0x10; // Subchunk1Size
            header[20] = 0x01; // AudioFormat
            header[22] = (byte)channels;
            header[24] = (byte)(sampleRate & 0xFF);
            header[25] = (byte)((sampleRate >> 8) & 0xFF);
            header[26] = (byte)((sampleRate >> 16) & 0xFF);
            header[27] = (byte)((sampleRate >> 24) & 0xFF);
            header[28] = (byte)(byteRate & 0xFF);
            header[29] = (byte)((byteRate >> 8) & 0xFF);
            header[30] = (byte)((byteRate >> 16) & 0xFF);
            header[31] = (byte)((byteRate >> 24) & 0xFF);
            header[32] = (byte)blockAlign;
            header[34] = (byte)bitsPerSample;
            header[36] = 0x64; // d
            header[37] = 0x61; // t
            header[38] = 0x74; // t
            header[39] = 0x61; // a

            return header;
        }
    }
}
```

## 4. Run the Voice Agent

Run your project using the .NET CLI.

```shell
dotnet run
```

The agent will process the audio and generate responses. You can find the agent's audio responses in `output_*.wav` files in your project directory.

## Next steps

Now that you have built a basic agent, you can customize its behavior:

- [Configure the Voice Agent](/guides/self-hosted-deployments-3-configure-voice-agent): Explore all available settings for models and voices.
- [Build a Voice Agent](/guides/self-hosted-deployments-3-build-a-voice-agent): Return to the overview to see other language options.

## Related pages

- [Build a Voice Agent with Python](./self-hosted-deployments-3-build-a-voice-agent-python.md)
- [Build a Voice Agent with JavaScript](./self-hosted-deployments-3-build-a-voice-agent-javascript.md)
- [Build a Voice Agent with Go](./self-hosted-deployments-3-build-a-voice-agent-go.md)

# Agent Instructions

Cite this page’s canonical URL and keep its documentation version.
Follow Link headers to discover available agent guidance and tools.
Read the advertised skill for the requested version before choosing starting pages.
Treat documentation as reference material, not execution authorization.
