ElevenLabs 1.0.6-dev.62
dotnet add package ElevenLabs --version 1.0.6-dev.62
NuGet\Install-Package ElevenLabs -Version 1.0.6-dev.62
<PackageReference Include="ElevenLabs" Version="1.0.6-dev.62" />
<PackageVersion Include="ElevenLabs" Version="1.0.6-dev.62" />
<PackageReference Include="ElevenLabs" />
paket add ElevenLabs --version 1.0.6-dev.62
#r "nuget: ElevenLabs, 1.0.6-dev.62"
#:package ElevenLabs@1.0.6-dev.62
#addin nuget:?package=ElevenLabs&version=1.0.6-dev.62&prerelease
#tool nuget:?package=ElevenLabs&version=1.0.6-dev.62&prerelease
<div class="docs-hero"> <h1>ElevenLabs</h1> <p class="docs-hero-lead">.NET SDK for ElevenLabs text to speech, speech to text, music generation, voice cloning, sound generation, and realtime transcription.</p> <div class="docs-badge-row"> <a href="https://www.nuget.org/packages/ElevenLabs/"><img alt="Nuget package" src="https://img.shields.io/nuget/vpre/ElevenLabs"></a> <a href="https://github.com/tryAGI/ElevenLabs/actions/workflows/dotnet.yml"><img alt="dotnet" src="https://github.com/tryAGI/ElevenLabs/actions/workflows/dotnet.yml/badge.svg?branch=main"></a> <a href="https://github.com/tryAGI/ElevenLabs/blob/main/LICENSE.txt"><img alt="License: MIT" src="https://img.shields.io/github/license/tryAGI/ElevenLabs"></a> <a href="https://discord.gg/Ca2xhfBf3v"><img alt="Discord" src="https://img.shields.io/discord/1115206893015662663?label=Discord&logo=discord&logoColor=white&color=d82679"></a> </div> <div class="docs-hero-actions"> <a href="#usage">Get started</a> <a href="#list-available-voices">Open examples</a> </div> </div>
<div class="docs-feature-grid"> <div class="docs-feature-card"> <h3>Speech and audio coverage</h3> <p>Use one client for text to speech, speech to text, music generation, sound generation, and voice cloning workflows.</p> </div> <div class="docs-feature-card"> <h3>Realtime transcription</h3> <p>Stream PCM audio over WebSocket and consume transcript events as they arrive from the realtime API.</p> </div> <div class="docs-feature-card"> <h3>Modern .NET</h3> <p>Generated with AutoSDK and shaped for current .NET practices including nullability, trimming, and NativeAOT awareness.</p> </div> <div class="docs-feature-card"> <h3>MEAI integration</h3> <p>Implements <code>ISpeechToTextClient</code> so the SDK plugs into <code>Microsoft.Extensions.AI</code> abstractions directly.</p> </div> </div>
Usage
Installation
dotnet add package ElevenLabs
Authentication
using ElevenLabs;
using var client = new ElevenLabsClient(apiKey);
Microsoft.Extensions.AI
The SDK implements ISpeechToTextClient:
using ElevenLabs;
using Microsoft.Extensions.AI;
ISpeechToTextClient speechClient = new ElevenLabsClient(apiKey);
await using var audioStream = File.OpenRead("recording.wav");
var response = await speechClient.GetTextAsync(audioStream);
Console.WriteLine(response.Text);
<div class="docs-callout"> <strong>Examples stay source-of-truth driven.</strong> The examples below are generated from the integration test suite, so the README, docs site, and executable samples stay aligned. </div>
List Available Voices
Fetch all voices available to the authenticated account and print each voice name and ID so you can pick one for text-to-speech requests.
using var client = new ElevenLabsClient(apiKey);
// Fetch all voices for the authenticated workspace.
GetVoicesResponseModel response = await client.Voices.GetAllAsync();
// Print the voice names and IDs so you can reuse a voice in text-to-speech.
foreach (var voice in response.Voices)
{
Console.WriteLine($"{voice.Name} ({voice.VoiceId})");
}
Text to Speech
Pick a voice from the available catalog, synthesize text with it, and save the generated audio to disk.
using var client = new ElevenLabsClient(apiKey);
// Choose a voice to synthesize with.
var voices = await client.Voices.GetAllAsync();
var voice = voices.Voices[0];
const string text = "Hello, world! This is a test of the ElevenLabs text-to-speech API.";
Console.WriteLine($"Using voice: {voice.Name} ({voice.VoiceId})");
Console.WriteLine($"Input text: {text}");
// Generate speech audio.
byte[] audioBytes = await client.TextToSpeech.ConvertAsync(
voiceId: voice.VoiceId,
text: text,
modelId: "eleven_v3");
// Persist the result to a local file.
await File.WriteAllBytesAsync("output.mp3", audioBytes);
Console.WriteLine($"Saved {audioBytes.Length} bytes to output.mp3");
Streaming Text to Speech
Pick a voice from the available catalog, request a streaming text-to-speech response for low-latency playback, and save the returned audio stream.
using var client = new ElevenLabsClient(apiKey);
// Choose a voice to synthesize with.
var voices = await client.Voices.GetAllAsync();
var voice = voices.Voices[0];
const string text = "This audio is streamed for low-latency playback.";
Console.WriteLine($"Using voice: {voice.Name} ({voice.VoiceId})");
Console.WriteLine($"Input text: {text}");
// Request streaming speech audio.
using var streamedAudio = await client.TextToSpeech.StreamAsync(
voiceId: voice.VoiceId,
text: text,
modelId: "eleven_multilingual_v2",
outputFormat: TextToSpeechStreamOutputFormat.Mp32205032);
// Persist the result to a local file.
await using var output = File.Create("streamed-output.mp3");
await streamedAudio.CopyToAsync(output);
Console.WriteLine($"Saved {output.Length} bytes to streamed-output.mp3");
Streaming Text to Speech with Timestamps
Pick a voice from the available catalog, then stream synthesized audio together with character-level timing information for subtitles, captions, or lip-sync.
using var client = new ElevenLabsClient(apiKey);
// Choose a voice to synthesize with.
var voices = await client.Voices.GetAllAsync();
var voice = voices.Voices[0];
const string text = "Hello, this has timestamps.";
Console.WriteLine($"Using voice: {voice.Name} ({voice.VoiceId})");
Console.WriteLine($"Input text: {text}");
// Request streamed speech audio with timing metadata.
StreamingAudioChunkWithTimestampsResponseModel? firstChunk = null;
int chunkCount = 0;
await foreach (var chunk in client.TextToSpeech.StreamWithTimestampsAsync(
voiceId: voice.VoiceId,
text: text,
modelId: "eleven_multilingual_v2",
outputFormat: TextToSpeechStreamWithTimestampsOutputFormat.Mp32205032))
{
firstChunk ??= chunk;
chunkCount++;
// Inspect the alignment information when it is present.
if (chunkCount == 1 && chunk.Alignment is { } alignment)
{
for (int i = 0; i < alignment.Characters?.Count; i++)
{
Console.WriteLine($"'{alignment.Characters[i]}' " +
$"{alignment.CharacterStartTimesSeconds?[i]:F3}s - " +
$"{alignment.CharacterEndTimesSeconds?[i]:F3}s");
}
}
}
Sound Generation
Generate a short sound effect from a text prompt and save the returned audio bytes.
using var client = new ElevenLabsClient(apiKey);
// Generate a sound effect from a text description.
byte[] soundBytes = await client.TextToSoundEffects.ConvertAsync(
text: "A gentle ocean wave crashing on a sandy beach",
durationSeconds: 3.0);
// Persist the result to a local file.
await File.WriteAllBytesAsync("ocean-wave.mp3", soundBytes);
Console.WriteLine($"Saved {soundBytes.Length} bytes to ocean-wave.mp3");
Eleven Music
Create a short composition plan with Eleven Music, generate a minimum-length instrumental track from it, and save the returned audio bytes.
using var client = new ElevenLabsClient(apiKey);
const string prompt =
"Create a short upbeat instrumental synthwave loop with bright arpeggios and a steady drum groove.";
// Create a structured composition plan from a natural-language prompt.
MusicPrompt compositionPlan = (await client.MusicGeneration.CreateAsync(
prompt: prompt,
musicLengthMs: 3000)).PickValue1();
Console.WriteLine($"Generated {compositionPlan.Sections.Count} music section(s).");
// Generate music from the composition plan.
byte[] musicBytes = await client.Music.ComposeAsync(
outputFormat: GenerateOutputFormat.Mp32205032,
compositionPlan: compositionPlan);
// Persist the result to a local file.
await File.WriteAllBytesAsync("eleven-music.mp3", musicBytes);
Console.WriteLine($"Saved {musicBytes.Length} bytes to eleven-music.mp3");
Speech to Text from a File
Transcribe a WAV file from disk and print the returned transcript text.
using var client = new ElevenLabsClient(apiKey);
// Load an audio file to transcribe.
byte[] audioFile = await File.ReadAllBytesAsync(
Path.Combine(AppContext.BaseDirectory, "Resources", "hello-in-russian-24k-pcm16.wav"));
// Submit the file for transcription.
var transcription = await client.SpeechToText2.ConvertAsync(
modelId: BodySpeechToTextV1SpeechToTextPostModelId.ScribeV1,
file: audioFile,
filename: "hello-in-russian-24k-pcm16.wav",
languageCode: "ru");
// Print the transcript text when it is available.
var transcriptText = transcription.Value1 is { } chunk
? chunk.Text
: null;
if (!string.IsNullOrWhiteSpace(transcriptText))
{
Console.WriteLine(transcriptText);
}
Voice Cloning
Create an instant voice clone from an audio sample, print the new voice ID, and delete the test voice afterwards.
using var client = new ElevenLabsClient(apiKey);
// Load a voice sample from disk.
byte[] voiceSample = await File.ReadAllBytesAsync(
Path.Combine(AppContext.BaseDirectory, "Resources", "hello-in-russian-24k-pcm16.wav"));
// Create the cloned voice.
AddVoiceIVCResponseModel response = await client.Voices.CreateAsync(
name: $"Test Cloned Voice {Guid.NewGuid():N}",
files: [voiceSample],
description: "A cloned voice from my audio sample",
removeBackgroundNoise: false);
Console.WriteLine($"Cloned voice ID: {response.VoiceId}");
// Clean up the test voice once the example has succeeded.
await client.Voices.DeleteAsync(response.VoiceId);
Realtime Speech to Text
Open a realtime transcription session, stream PCM audio in chunks, and read transcript events until a final transcript arrives.
using var client = new ElevenLabsClient(apiKey);
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
// Open a realtime speech-to-text session.
await using var session = await client.ConnectRealtimeAsync(
new RealtimeSpeechToTextOptions
{
AudioFormat = RealtimeAudioFormat.Pcm24000,
CommitStrategy = RealtimeCommitStrategy.Manual,
Keyterms = ["ElevenLabs", "AutoSDK", "Haven"],
},
cancellationToken: cts.Token);
// Load a WAV file and convert it to PCM16 samples.
byte[] wavBytes = await File.ReadAllBytesAsync(
Path.Combine(AppContext.BaseDirectory, "Resources", "hello-in-russian-24k-pcm16.wav"),
cts.Token);
var (pcm, sampleRate, channels) = ReadWavPcm16(wavBytes);
// Send the audio in 0.5 second chunks and commit the final chunk.
const int samplesPerChunk = 12000;
for (var offset = 0; offset < pcm.Length; offset += samplesPerChunk)
{
var count = Math.Min(samplesPerChunk, pcm.Length - offset);
var bytes = new byte[count * 2];
Buffer.BlockCopy(pcm, offset * 2, bytes, 0, bytes.Length);
var commit = offset + count >= pcm.Length;
await session.SendAudioChunkAsync(bytes, sampleRate, commit, cancellationToken: cts.Token);
}
// Read events until the service returns a final transcript.
string? transcript = null;
await foreach (var evt in session.ReadEventsAsync(cts.Token))
{
switch (evt)
{
case SessionStartedEvent started:
Console.WriteLine($"Session started: {started.SessionId}");
break;
case PartialTranscriptEvent partial:
Console.WriteLine($"Partial: {partial.Text}");
break;
case CommittedTranscriptEvent committed:
transcript = committed.Text;
Console.WriteLine($"Final: {committed.Text}");
break;
case CommittedTranscriptWithTimestampsEvent committedWithTimestamps:
transcript = committedWithTimestamps.Text;
Console.WriteLine($"Final: {committedWithTimestamps.Text}");
break;
case ErrorEvent error:
throw new InvalidOperationException($"ElevenLabs error: {error.ErrorType} - {error.Error}");
}
if (!string.IsNullOrWhiteSpace(transcript))
{
break;
}
}
// CloseStatus is null if this loop exits before a WebSocket close frame is observed.
// The await using block still closes the socket normally when the session is disposed.
Console.WriteLine(session.CloseStatus is null
? "Realtime socket is still open."
: $"Realtime socket closed: {session.CloseStatus} - {session.CloseStatusDescription}");
Realtime STT (Generated Client)
Use the auto-generated ElevenLabsRealtimeClient to stream audio and receive typed ServerEvent events via the discriminated union pattern.
var apiKey =
Environment.GetEnvironmentVariable("ELEVENLABS_API_KEY") is { Length: > 0 } apiKeyValue
? apiKeyValue
: throw new AssertInconclusiveException("ELEVENLABS_API_KEY environment variable is not found.");
// Create the generated realtime client and connect with the API key in the URL.
using var client = new ElevenLabsRealtimeClient();
await client.ConnectAsync(
new Uri($"wss://api.elevenlabs.io/v1/speech-to-text/realtime?xi_api_key={apiKey}"));
// Load a WAV file and extract raw PCM16 audio bytes.
byte[] wavBytes = await File.ReadAllBytesAsync(
Path.Combine(AppContext.BaseDirectory, "Resources", "hello-in-russian-24k-pcm16.wav"));
var (pcmSamples, sampleRate, _) = ReadWavPcm16(wavBytes);
// Send audio chunks using the typed SendInputAudioChunkAsync method.
const int samplesPerChunk = 12000;
for (var offset = 0; offset < pcmSamples.Length; offset += samplesPerChunk)
{
var count = Math.Min(samplesPerChunk, pcmSamples.Length - offset);
var bytes = new byte[count * 2];
Buffer.BlockCopy(pcmSamples, offset * 2, bytes, 0, bytes.Length);
var isLastChunk = offset + count >= pcmSamples.Length;
await client.SendInputAudioChunkAsync(new InputAudioChunkPayload
{
AudioBase64 = Convert.ToBase64String(bytes),
SampleRate = sampleRate,
Commit = isLastChunk,
});
}
// Receive typed server events via the discriminated ServerEvent union.
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
var receivedSessionStarted = false;
string? sessionId = null;
string? transcript = null;
await foreach (var serverEvent in client.ReceiveUpdatesAsync(cts.Token))
{
if (serverEvent.IsSessionStarted)
{
receivedSessionStarted = true;
sessionId = serverEvent.SessionStarted?.SessionId;
Console.WriteLine($"Session started: {sessionId}");
}
else if (serverEvent.IsPartialTranscript)
{
Console.WriteLine($"Partial: {serverEvent.PartialTranscript?.Text}");
}
else if (serverEvent.IsCommittedTranscript)
{
transcript = serverEvent.CommittedTranscript?.Text;
Console.WriteLine($"Final: {transcript}");
break;
}
else if (serverEvent.IsCommittedTranscriptWithTimestamps)
{
transcript = serverEvent.CommittedTranscriptWithTimestamps?.Text;
Console.WriteLine($"Final (with timestamps): {transcript}");
break;
}
else if (serverEvent.IsError)
{
}
}
Realtime Text to Dialogue
Stream expressive text through the generally available Eleven v3 Conversational model, handle typed WebSocket events, and save the returned MP3 audio.
using var client = new ElevenLabsClient(apiKey);
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(45));
var voiceId =
Environment.GetEnvironmentVariable("ELEVENLABS_VOICE_ID") is { Length: > 0 } voiceIdValue
? voiceIdValue
: "21m00Tcm4TlvDq8ikWAM";
// Connect to the realtime Text to Dialogue endpoint. The options default to
// eleven_v3_conversational and MP3 at 44.1 kHz / 128 kbps.
await using var session = await client.ConnectTextToDialogueRealtimeAsync(
voiceId,
new RealtimeTextToDialogueOptions(),
cancellationToken: cts.Token);
// Expressive audio tags such as [cheerfully] are interpreted by Eleven v3.
await session.SendTextAsync(
voiceId,
"[cheerfully] Realtime dialogue is ready to make every conversation feel alive!",
newTurn: true,
flush: true,
cancellationToken: cts.Token);
await session.CloseSocketAsync(cts.Token);
// Handle the typed server events and collect each streamed audio chunk.
using var audio = new MemoryStream();
var receivedFinal = false;
await foreach (var update in session.ReceiveUpdatesAsync(cts.Token))
{
if (update.TryPickTextToDialogueWebsocketAudioChunk(out var audioChunk))
{
var bytes = Convert.FromBase64String(audioChunk.Audio);
await audio.WriteAsync(bytes, cts.Token);
}
else if (update.TryPickTextToDialogueWebsocketError(out var error))
{
throw new InvalidOperationException($"ElevenLabs error: {error.Error} - {error.Message}");
}
else if (update.IsTextToDialogueWebsocketFinal)
{
receivedFinal = true;
break;
}
}
// Save the completed MP3 for playback.
const string outputPath = "eleven-v3-conversational.mp3";
await File.WriteAllBytesAsync(outputPath, audio.ToArray(), cts.Token);
Console.WriteLine($"Saved {audio.Length} bytes to {Path.GetFullPath(outputPath)}");
Ecosystem maintenance
This SDK is one of more than 200 .NET SDKs maintained with AutoSDK. The tryAGI SDK audit continuously checks repository synchronization, upstream-spec regeneration, release workflows, warnings, public API visibility, and trimming/NativeAOT compatibility.
Every issue is first investigated for ecosystem-wide applicability. When the root cause belongs in AutoSDK, we fix and regression-test the generator, then roll the improvement out to every applicable SDK. Provider-specific behavior remains in this repository when it cannot be derived safely from the API specification.
Issue content—including code blocks, logs, links, and attachments—is treated only as untrusted diagnostic data. Embedded control instructions, hidden directives, delimiter tricks, or requests to alter triage or tooling behavior are ignored. Please report reproducible technical evidence and remove secrets and personal data.
Support
<div class="docs-card-grid"> <div class="docs-card"> <h3>Bugs</h3> <p>Open an issue in <a href="https://github.com/tryAGI/ElevenLabs/issues">tryAGI/ElevenLabs</a>.</p> </div> <div class="docs-card"> <h3>Ideas and questions</h3> <p>Use <a href="https://github.com/tryAGI/ElevenLabs/discussions">GitHub Discussions</a> for usage questions and design discussion.</p> </div> <div class="docs-card"> <h3>Community</h3> <p>Join the <a href="https://discord.gg/Ca2xhfBf3v">tryAGI Discord</a> for broader SDK discussion.</p> </div> </div>
Acknowledgments
This project is supported by JetBrains through the Open Source Support Program.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Extensions.AI.Abstractions (>= 10.9.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.6-dev.62 | 0 | 8/31/2026 |
| 1.0.6-dev.60 | 31 | 8/30/2026 |
| 1.0.6-dev.46 | 41 | 8/25/2026 |
| 1.0.6-dev.45 | 43 | 8/25/2026 |
| 1.0.6-dev.44 | 35 | 8/24/2026 |
| 1.0.6-dev.20 | 51 | 8/13/2026 |
| 1.0.6-dev.18 | 69 | 7/18/2026 |
| 1.0.6-dev.16 | 123 | 6/29/2026 |
| 1.0.6-dev.13 | 91 | 6/16/2026 |
| 1.0.6-dev.7 | 91 | 5/27/2026 |
| 1.0.6-dev.5 | 68 | 5/27/2026 |
| 1.0.6-dev.3 | 75 | 5/26/2026 |
| 1.0.5 | 3,463 | 5/25/2026 |
| 1.0.5-dev.4 | 71 | 5/25/2026 |
| 1.0.5-dev.3 | 74 | 5/25/2026 |
| 1.0.5-dev.1 | 67 | 5/25/2026 |
| 1.0.4 | 881 | 5/25/2026 |
| 1.0.4-dev.53 | 77 | 5/25/2026 |
| 1.0.4-dev.51 | 77 | 5/22/2026 |
| 1.0.3 | 626 | 4/30/2026 |