> This page is for Voice APIs.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://dev.hume.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://dev.hume.ai/_mcp/server.

# EVI .NET Quickstart

In this guide, you'll learn how to use Hume's .NET SDK to integrate with EVI.

> **Info**
>
> Make sure that connecting to EVI from your .NET code is the right choice.
>
> If your .NET app is a **client app** -- a desktop application or CLI that runs on the user's machine and captures audio directly from their microphone -- then connecting to EVI from .NET is appropriate.
>
> If your .NET app is a **server app** that will not run on the same machine to which the user's microphone is connected, it is usually better to connect to EVI **not from .NET code** but directly from the client to keep latency low. If you need to control an EVI chat with logic that MUST live on your backend, and have your .NET backend use the [Send Message endpoint](https://dev.hume.ai/reference/speech-to-speech-evi/control-plane/send) or [Control Plane WebSocket](https://dev.hume.ai/reference/speech-to-speech-evi/control-plane/chat-chat-id-connect) connection to control an EVI chat that was already opened from the client.
>
> The example code in this guide sends EVI hardcoded audio from a file, as a placeholder. You should replace this with logic that sends audio sourced from your user's microphone.

1. [**Environment setup**](#env-setup): Download package and system dependencies to run EVI.
2. [**Import statements**](#import-statements): Import needed symbols from the Hume SDK.
3. [**Authentication**](#authentication): Use your API credentials to authenticate your EVI application.
4. [**Connection**](#connection): Set up a secure WebSocket connection to interact with EVI.
5. [**Handling incoming messages**](#incoming-messages): Subscribe to events and process messages from EVI.
6. [**Audio input**](#audio-input): Capture audio data from an input device and send to EVI.

#### [Looking for sample code?](https://github.com/HumeAI/hume-api-examples/tree/main/evi/evi-dotnet-quickstart)

See the complete implementation of this guide on GitHub

#### [.NET SDK](https://github.com/HumeAI/hume-dotnet-sdk)

Explore or contribute to Hume's .NET SDK on GitHub

## Environment setup \[#env-setup]

Create a new .NET project and install the required packages:

#### dotnet CLI

```bash
dotnet new console -n EviDotnetQuickstart
cd EviDotnetQuickstart
dotnet add package Hume
dotnet add package DotNetEnv
```

#### Visual Studio

```bash
# Create a new Console Application project
# Add NuGet packages: Hume, DotNetEnv
```

### Download sample audio

Download the sample PCM audio file to use with this guide:

```bash
curl -O https://raw.githubusercontent.com/HumeAI/hume-api-examples/main/evi/evi-dotnet-quickstart/sample_input.pcm
```

## Import statements \[#import-statements]

First, import the needed namespaces from the .NET standard library and the Hume SDK.

#### Program.cs

```csharp maxLines=0
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using DotNetEnv;
using Hume;
using Hume.EmpathicVoice;
```

## Authentication \[#authentication]

Log into your [Hume AI Account](https://platform.hume.ai/settings/keys) and [obtain an API key](/docs/introduction/api-key). Create a `.env` file in your project directory and store your API key:

#### .env

```bash
HUME_API_KEY=your_api_key_here
```

Load the environment variables and use the API key to instantiate the `HumeClient` class. This is the main entry point provided by the Hume .NET SDK.

#### Program.cs

```csharp maxLines=0
Env.Load();

var apiKey = Environment.GetEnvironmentVariable("HUME_API_KEY")
    ?? throw new InvalidOperationException("HUME_API_KEY environment variable is required.");
var client = new HumeClient(apiKey);
```

## Connection \[#connection]

To connect to an EVI chat, create a `ChatApi` instance using the `client.EmpathicVoice.CreateChatApi` method. You can specify session settings in the `ChatApi.Options` object.

#### Program.cs

```csharp maxLines=0
// Create a signal to wait for Chat Metadata
var chatMetadataReceived = new TaskCompletionSource<bool>();

// Create the ChatApi instance
var chatApi = client.EmpathicVoice.CreateChatApi(new ChatApi.Options
{
    ApiKey = apiKey,
    SessionSettings = new ConnectSessionSettings(),
});
```

Connect to EVI and wait for the chat metadata to confirm the connection is established:

#### Program.cs

```csharp maxLines=0
// Connect to EVI
Console.WriteLine("Connecting to EVI...");
await chatApi.ConnectAsync();
Console.WriteLine("Connected!");

// Wait for Chat Metadata
Console.WriteLine("Waiting for Chat Metadata...");
await chatMetadataReceived.Task;
Console.WriteLine("Chat Metadata received.");
```

## Handling incoming messages \[#incoming-messages]

EVI communicates through events. Subscribe to the events you want to handle before connecting. The main event types are:

* `AssistantMessage`: Text messages from EVI
* `UserMessage`: Transcriptions of user speech
* `AudioOutput`: Audio data for playback
* `ChatMetadata`: Information about the chat session

#### Program.cs

```csharp maxLines=0
// Subscribe to events
chatApi.AssistantMessage.Subscribe(message =>
{
    Console.WriteLine($"Assistant: {message.Message?.Content}");
});

chatApi.UserMessage.Subscribe(message =>
{
    Console.WriteLine($"User: {message.Message?.Content}");
});

chatApi.AudioOutput.Subscribe(audio =>
{
    Console.WriteLine($"Received audio chunk: {audio.Data?.Length ?? 0} bytes");
});

chatApi.ChatMetadata.Subscribe(metadata =>
{
    Console.WriteLine($"Chat Metadata - Chat ID: {metadata.ChatId}");
    chatMetadataReceived.TrySetResult(true);
});
```

## Audio input \[#audio-input]

Before sending audio, configure the audio format by sending session settings. EVI expects audio in a specific format (e.g., 48kHz, 16-bit, mono PCM).

#### Program.cs

```csharp maxLines=0
// Configure audio format (48kHz, 16-bit, mono PCM)
const int sampleRate = 48000;
const int channels = 1;

var sessionSettings = new SessionSettings
{
    Audio = new AudioConfiguration
    {
        Encoding = "linear16",
        SampleRate = sampleRate,
        Channels = channels
    }
};

await chatApi.Send(sessionSettings);
```

### Sending audio data

Audio data should be sent as base64-encoded chunks. Here's a helper function that reads a PCM file and streams it to EVI in real-time chunks:

#### Program.cs

```csharp maxLines=0
static async Task TransmitTestAudio(ChatApi chatApi, string filePath, int sampleRate, int channels)
{
    const int chunkDurationMs = 10;
    const int bytesPerSample = 2; // 16-bit audio
    int bytesPerChunk = sampleRate * bytesPerSample * channels * chunkDurationMs / 1000;

    // Read PCM file
    var audioData = File.ReadAllBytes(filePath);

    // Split into chunks and send with appropriate timing
    for (int offset = 0; offset < audioData.Length; offset += bytesPerChunk)
    {
        var chunkSize = Math.Min(bytesPerChunk, audioData.Length - offset);
        var chunk = audioData.Skip(offset).Take(chunkSize).ToArray();

        // Pad final chunk if needed
        if (chunk.Length < bytesPerChunk)
        {
            chunk = chunk.Concat(new byte[bytesPerChunk - chunk.Length]).ToArray();
        }

        // Send as base64-encoded audio input
        var data = Convert.ToBase64String(chunk);
        await chatApi.Send(new AudioInput { Data = data });

        // Delay to simulate real-time streaming
        await Task.Delay(chunkDurationMs);
    }
}
```

## Put it all together

Here's the complete example that connects to EVI and transmits audio:

#### Program.cs

```csharp maxLines=0
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using DotNetEnv;
using Hume;
using Hume.EmpathicVoice;

Env.Load();

var apiKey = Environment.GetEnvironmentVariable("HUME_API_KEY")
    ?? throw new InvalidOperationException("HUME_API_KEY environment variable is required.");
var client = new HumeClient(apiKey);

// Create a signal to wait for Chat Metadata
var chatMetadataReceived = new TaskCompletionSource<bool>();

// Create the ChatApi instance
var chatApi = client.EmpathicVoice.CreateChatApi(new ChatApi.Options
{
    ApiKey = apiKey,
    SessionSettings = new ConnectSessionSettings(),
});

// Subscribe to events
chatApi.AssistantMessage.Subscribe(message =>
{
    Console.WriteLine($"Assistant: {message.Message?.Content}");
});

chatApi.UserMessage.Subscribe(message =>
{
    Console.WriteLine($"User: {message.Message?.Content}");
});

chatApi.AudioOutput.Subscribe(audio =>
{
    Console.WriteLine($"Received audio chunk: {audio.Data?.Length ?? 0} bytes");
});

chatApi.ChatMetadata.Subscribe(metadata =>
{
    Console.WriteLine($"Chat Metadata - Chat ID: {metadata.ChatId}");
    chatMetadataReceived.TrySetResult(true);
});

// Connect to EVI
Console.WriteLine("Connecting to EVI...");
await chatApi.ConnectAsync();
Console.WriteLine("Connected!");

// Wait for Chat Metadata
await chatMetadataReceived.Task;

// Configure audio format (48kHz, 16-bit, mono PCM)
const int sampleRate = 48000;
const int channels = 1;

var sessionSettings = new SessionSettings
{
    Audio = new AudioConfiguration
    {
        Encoding = "linear16",
        SampleRate = sampleRate,
        Channels = channels
    }
};

await chatApi.Send(sessionSettings);

// Send audio (replace with your audio source)
// await TransmitTestAudio(chatApi, "sample_input.pcm", sampleRate, channels);

// Wait for responses
await Task.Delay(5000);

await chatApi.DisposeAsync();
```

### Running the example

#### dotnet CLI

```bash
dotnet run
```

#### Visual Studio

```bash
# Press F5 or Ctrl+F5 to run the application
```

View the complete example code on [GitHub](https://github.com/HumeAI/hume-api-examples/tree/main/evi/evi-dotnet-quickstart).

## Next steps

Next, consider exploring these areas to enhance your EVI application:

#### [Configure EVI](/docs/speech-to-speech-evi/configuration/build-a-configuration)

See detailed instructions on how you can customize EVI for your application needs.

#### [Chat History](/docs/speech-to-speech-evi/features/chat-history)

Learn how you can access and manage conversation transcripts and expression measures.

> **Info**
>
> For further details and practical examples, explore the [API Reference](/reference/speech-to-speech-evi/chat) and our [Hume API Examples](https://github.com/HumeAI/hume-api-examples/tree/main/evi) on GitHub.

---