Skip to content
Introducing AI Conversations: Natural Language Interaction for Your Apps! Learn More

ElevenLabs

DownloadsNuGet downloads for Shiny.Speech.ElevenLabs
Frameworks
.NET
.NET MAUI
Operating Systems
Android
iOS
Windows

ElevenLabs provides high-quality, AI-powered text-to-speech with natural-sounding multilingual voices, and the Scribe speech-to-text model for transcription. This provider replaces the platform-native ITextToSpeechService and/or ISpeechToTextService registrations with ElevenLabs cloud calls while still using platform-native audio capture / playback for the actual microphone and speakers.

Shiny.Speech.ElevenLabsNuGet package Shiny.Speech.ElevenLabs
// In MauiProgram.cs — register both STT (Scribe) and TTS
builder.Services.AddElevenLabsSpeech("your-api-key");
// Or pick one:
builder.Services.AddElevenLabsSpeechToText("your-api-key"); // Scribe only
builder.Services.AddElevenLabsTextToSpeech("your-api-key"); // TTS only

IAudioSource (microphone) is auto-registered when STT is enabled; IAudioPlayer (speakers) is auto-registered when TTS is enabled.

Or with a config object:

builder.Services.AddElevenLabsSpeech(new ElevenLabsConfig
{
ApiKey = "your-api-key",
SpeechToTextModel = "scribe_v1", // default
TextToSpeechModel = "eleven_multilingual_v2", // default
DefaultVoiceId = "21m00Tcm4TlvDq8ikWAM" // Rachel (default)
});
public record ElevenLabsConfig
{
public required string ApiKey { get; init; }
public string DefaultVoiceId { get; init; } = "21m00Tcm4TlvDq8ikWAM"; // Rachel
public string TextToSpeechModel { get; init; } = "eleven_multilingual_v2";
public string SpeechToTextModel { get; init; } = "scribe_v1";
}
PropertyDescriptionDefault
ApiKeyYour ElevenLabs API key(required)
DefaultVoiceIdVoice ID to use when none specified in TextToSpeechOptions21m00Tcm4TlvDq8ikWAM (Rachel)
TextToSpeechModelThe TTS model to useeleven_multilingual_v2
SpeechToTextModelThe Scribe transcription model to usescribe_v1
public class MyViewModel(ITextToSpeechService tts)
{
async Task Speak()
{
await tts.SpeakAsync("Hello from ElevenLabs!");
var voices = await tts.GetVoicesAsync();
var voice = voices.FirstOrDefault(v => v.Name.Contains("Adam"));
if (voice != null)
{
await tts.SpeakAsync("Hello!", new TextToSpeechOptions
{
Voice = voice,
SpeechRate = 1.0f,
Volume = 0.9f
});
}
}
}

Use it like any other ISpeechToTextService. Because Scribe is non-streaming, you’ll get partial results from the audio source only after Stop() is called:

public class MyViewModel(ISpeechToTextService stt)
{
async Task Listen(CancellationToken ct)
{
var access = await stt.RequestAccess();
if (access != AccessState.Available)
return;
stt.ResultReceived += (_, r) => Console.WriteLine($"[final] {r.Text}");
await stt.Start(new SpeechRecognitionOptions
{
Culture = CultureInfo.GetCultureInfo("en-US")
});
// ... user speaks ...
await stt.Stop(); // triggers the single POST + final result
}
// Or with the convenience extension method:
async Task<string?> ListenOnce(CancellationToken ct)
=> await stt.ListenUntilSilence(cancellationToken: ct);
}

Combining ElevenLabs STT with Native TTS (or vice versa)

Section titled “Combining ElevenLabs STT with Native TTS (or vice versa)”

You can mix-and-match — register only the direction you need, and let the other side stay platform-native:

// Scribe STT + native TTS
builder.Services.AddSpeechServices();
builder.Services.AddElevenLabsSpeechToText("your-api-key");
// Native STT + ElevenLabs TTS
builder.Services.AddSpeechServices();
builder.Services.AddElevenLabsTextToSpeech("your-api-key");

Later registrations win when the same service is registered twice.