← Code Recipes
Speech & Audio

Azure AI Speech Free code examples in C#, Python, Java and JavaScript

Microsoft's speech stack: TTS, STT, translation and custom voices.

C# Python Java JavaScript

WHAT THIS PAGE COVERS

SSML — the control the plain-text APIs do not give you.

Model en-US-Ava:DragonHDLatestNeural
Package Microsoft.CognitiveServices.Speech
Checked

Model ids change. If a sample returns a 404 on the model, that is the first thing to check against the official docs.

Install

Azure wants two values, not one: the key and where to send it. Newer samples use a full endpoint URI; older ones use a region string, and both are still supported.

dotnet add package Microsoft.CognitiveServices.Speech

setx SPEECH_KEY "your-key"
setx ENDPOINT "https://YOUR-REGION.api.cognitive.microsoft.com/"
Speak a sentence

SpeechSynthesisVoiceName is where the voice goes — there is no model parameter. With no AudioConfig the audio plays on the default speaker, which is the fastest way to hear whether it works.

using Microsoft.CognitiveServices.Speech;

var speechKey = Environment.GetEnvironmentVariable("SPEECH_KEY")
    ?? throw new InvalidOperationException("SPEECH_KEY is not set.");
var endpoint = Environment.GetEnvironmentVariable("ENDPOINT")
    ?? throw new InvalidOperationException("ENDPOINT is not set.");

var config = SpeechConfig.FromEndpoint(new Uri(endpoint), speechKey);
config.SpeechSynthesisVoiceName = "en-US-Ava:DragonHDLatestNeural";

using var synthesizer = new SpeechSynthesizer(config);

var result = await synthesizer.SpeakTextAsync(
    "The first move is what sets everything in motion.");

Console.WriteLine($"{result.Reason}, {result.AudioData.Length} bytes");
SSML — the control plain text does not give you

Three things worth the extra markup: a measured pause, a phoneme override for a name the model gets wrong, and per-word emphasis. The xmlns and the xml:lang are both required; omit either and the whole document is read aloud as literal text.

var ssml = @"
<speak version='1.0' xmlns='http://www.w3.org/2001/10/synthesis'
       xmlns:mstts='https://www.w3.org/2001/mstts' xml:lang='en-US'>
  <voice name='en-US-Ava:DragonHDLatestNeural'>
    Your order ships
    <break time='300ms'/>
    <emphasis level='strong'>today</emphasis>.
    Contact
    <phoneme alphabet='ipa' ph='ˈpʌŋkədʒ'>Pankaj</phoneme>
    if anything is wrong.
  </voice>
</speak>";

var result = await synthesizer.SpeakSsmlAsync(ssml);
Writing to a file, and reading a failure

SpeakTextAsync does NOT throw on failure — it returns a result whose Reason is Canceled. Checking only for an exception is how a silent, empty audio file reaches production.

using var output = AudioConfig.FromWavFileOutput("speech.wav");
using var fileSynth = new SpeechSynthesizer(config, output);

var result = await fileSynth.SpeakTextAsync("Written straight to disk.");

if (result.Reason == ResultReason.Canceled)
{
    var details = SpeechSynthesisCancellationDetails.FromResult(result);

    // ErrorCode 1 (AuthenticationFailure) is a bad key or the wrong
    // region for that key — the two are indistinguishable from the
    // message alone, so check both.
    Console.Error.WriteLine($"{details.Reason}: {details.ErrorDetails}");
}
Install

The PyPI name does not match the namespace: you install azure-cognitiveservices-speech and import azure.cognitiveservices.speech.

pip install azure-cognitiveservices-speech

export SPEECH_KEY="your-key"
export ENDPOINT="https://YOUR-REGION.api.cognitive.microsoft.com/"
Speak a sentence

speak_text_async() returns a future; .get() waits for it. Forgetting .get() gives you a program that exits before any audio is produced and reports no error at all.

import os
import azure.cognitiveservices.speech as speechsdk

speech_config = speechsdk.SpeechConfig(
    subscription=os.environ["SPEECH_KEY"],
    endpoint=os.environ["ENDPOINT"],
)
speech_config.speech_synthesis_voice_name = "en-US-Ava:DragonHDLatestNeural"

synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config)

result = synthesizer.speak_text_async(
    "The first move is what sets everything in motion."
).get()

print(result.reason, len(result.audio_data), "bytes")
SSML — pauses, phonemes and emphasis

A break in milliseconds, an IPA override for a name, and emphasis on the word that carries the meaning. This is the whole reason to pick Azure over a plain-text TTS API.

ssml = """
<speak version='1.0' xmlns='http://www.w3.org/2001/10/synthesis'
       xml:lang='en-US'>
  <voice name='en-US-Ava:DragonHDLatestNeural'>
    Your order ships
    <break time='300ms'/>
    <emphasis level='strong'>today</emphasis>.
    Contact
    <phoneme alphabet='ipa' ph='ˈpʌŋkədʒ'>Pankaj</phoneme>
    if anything is wrong.
  </voice>
</speak>
"""

result = synthesizer.speak_ssml_async(ssml).get()
Checking the result properly

The SDK does not raise on failure. A canceled result with an empty audio buffer is what a wrong key looks like, and it is indistinguishable from success unless you check reason.

result = synthesizer.speak_text_async("Checking this properly.").get()

if result.reason == speechsdk.ResultReason.SynthesizingAudioCompleted:
    with open("speech.wav", "wb") as handle:
        handle.write(result.audio_data)

elif result.reason == speechsdk.ResultReason.Canceled:
    details = result.cancellation_details
    print("canceled:", details.reason)

    # An authentication failure here usually means the key is valid
    # but the endpoint belongs to a different region.
    if details.reason == speechsdk.CancellationReason.Error:
        print("error:", details.error_details)
Install

The Maven artifact is client-sdk under com.microsoft.cognitiveservices.speech. It carries native binaries, so the platform classifier matters on a build agent that is not your laptop.

# Gradle
implementation("com.microsoft.cognitiveservices.speech:client-sdk:1.46.0")

export SPEECH_KEY="your-key"
export SPEECH_REGION="your-region"
Speak a sentence

SpeechSynthesizer is AutoCloseable and holds a native handle. Leaking it leaks unmanaged memory that the JVM heap will never show you.

import com.microsoft.cognitiveservices.speech.SpeechConfig;
import com.microsoft.cognitiveservices.speech.SpeechSynthesizer;
import com.microsoft.cognitiveservices.speech.SpeechSynthesisResult;

public class Speak {
    public static void main(String[] args) throws Exception {
        String key = System.getenv("SPEECH_KEY");
        String region = System.getenv("SPEECH_REGION");
        if (key == null || region == null) {
            throw new IllegalStateException("SPEECH_KEY and SPEECH_REGION must be set.");
        }

        SpeechConfig config = SpeechConfig.fromSubscription(key, region);
        config.setSpeechSynthesisVoiceName("en-US-Ava:DragonHDLatestNeural");

        try (SpeechSynthesizer synthesizer = new SpeechSynthesizer(config);
             SpeechSynthesisResult result = synthesizer
                 .SpeakTextAsync("The first move is what sets everything in motion.")
                 .get()) {

            System.out.println(result.getReason() + " "
                + result.getAudioData().length + " bytes");
        }
    }
}
SSML — pauses, emphasis and phonemes

SpeakSsmlAsync takes the document as a string. The xmlns is not decoration: without it Azure reads the tags aloud rather than acting on them.

String ssml = """
    <speak version='1.0' xmlns='http://www.w3.org/2001/10/synthesis'
           xml:lang='en-US'>
      <voice name='en-US-Ava:DragonHDLatestNeural'>
        Your order ships
        <break time='300ms'/>
        <emphasis level='strong'>today</emphasis>.
      </voice>
    </speak>
    """;

try (SpeechSynthesizer synthesizer = new SpeechSynthesizer(config);
     SpeechSynthesisResult result = synthesizer.SpeakSsmlAsync(ssml).get()) {

    System.out.println(result.getReason());
}
Checking for cancellation

No exception is thrown for a bad key. The result comes back with reason Canceled and an empty audio buffer, so a program that only catches exceptions writes a zero-byte WAV and reports success.

import com.microsoft.cognitiveservices.speech.ResultReason;
import com.microsoft.cognitiveservices.speech.SpeechSynthesisCancellationDetails;

if (result.getReason() == ResultReason.Canceled) {
    SpeechSynthesisCancellationDetails details =
        SpeechSynthesisCancellationDetails.fromResult(result);

    // An authentication failure is most often a valid key paired with
    // the wrong region, which the message does not distinguish.
    System.err.println(details.getReason() + ": " + details.getErrorDetails());
}
Install

The npm package works in Node and in the browser, but only the Node path should ever hold a SPEECH_KEY — browser use needs a short-lived token minted server-side.

npm install microsoft-cognitiveservices-speech-sdk

export SPEECH_KEY="your-key"
export SPEECH_REGION="your-region"
Speak a sentence

The Node SDK is callback-based. Wrapping it in a Promise once, as below, is worth doing before it spreads through the codebase.

import sdk from "microsoft-cognitiveservices-speech-sdk";

const config = sdk.SpeechConfig.fromSubscription(
  process.env.SPEECH_KEY,
  process.env.SPEECH_REGION,
);
config.speechSynthesisVoiceName = "en-US-Ava:DragonHDLatestNeural";

function speak(text) {
  const synthesizer = new sdk.SpeechSynthesizer(config);

  return new Promise((resolve, reject) => {
    synthesizer.speakTextAsync(
      text,
      (result) => { synthesizer.close(); resolve(result); },
      (error) => { synthesizer.close(); reject(error); },
    );
  });
}

const result = await speak("The first move is what sets everything in motion.");
console.log(result.reason, result.audioData.byteLength, "bytes");
SSML — the control plain text does not give you

speakSsmlAsync takes the same callback shape. Note the voice moves into the markup: the voice name on the config is ignored once the SSML names one.

const ssml = `
<speak version='1.0' xmlns='http://www.w3.org/2001/10/synthesis'
       xml:lang='en-US'>
  <voice name='en-US-Ava:DragonHDLatestNeural'>
    Your order ships
    <break time='300ms'/>
    <emphasis level='strong'>today</emphasis>.
  </voice>
</speak>`;

const synthesizer = new sdk.SpeechSynthesizer(config);

synthesizer.speakSsmlAsync(
  ssml,
  (result) => {
    synthesizer.close();
    console.log(result.reason);
  },
  (error) => {
    synthesizer.close();
    console.error(error);
  },
);
Not shipping the key to the browser

SPEECH_KEY in front-end JavaScript is a published key. Mint a ten-minute token on the server and hand the browser that instead — the SDK has a constructor for exactly this.

// --- server ---------------------------------------------------------
app.get("/speech-token", async (_request, response) => {
  const minted = await fetch(
    `https://${process.env.SPEECH_REGION}.api.cognitive.microsoft.com` +
      "/sts/v1.0/issueToken",
    {
      method: "POST",
      headers: { "Ocp-Apim-Subscription-Key": process.env.SPEECH_KEY },
    },
  );

  response.json({
    token: await minted.text(),
    region: process.env.SPEECH_REGION,
  });
});

// --- browser --------------------------------------------------------
const { token, region } = await fetch("/speech-token").then((r) => r.json());
const browserConfig = sdk.SpeechConfig.fromAuthorizationToken(token, region);
browserConfig.speechSynthesisVoiceName = "en-US-Ava:DragonHDLatestNeural";

QUESTIONS

Which languages are the Azure AI Speech examples in?

C#, Python, Java and JavaScript. Every sample runs as pasted and reads its credentials from an environment variable — no key is ever written into the code.

Which package do I install for Azure AI Speech?

The samples use Microsoft.CognitiveServices.Speech. The install step on each language tab gives the exact command.

Which Azure AI Speech model do these examples use?

en-US-Ava:DragonHDLatestNeural, checked against the official documentation on 26 September 2026. Model ids change often; if a call returns a model-not-found error, check the current list in the official docs.

Where is the official Azure AI Speech documentation?

https://learn.microsoft.com/azure/ai-services/speech-service/ — it is linked at the bottom of this page, and it is the authority whenever it disagrees with a sample here.

ALSO IN SPEECH & AUDIO

The authority

Official Azure AI Speech documentation

Model names, pricing and rate limits change faster than any page here can. When this page and the official docs disagree, the official docs are right.

Read the docs ↗

https://learn.microsoft.com/azure/ai-services/speech-service/

New drops, every week

Free tools & Claude templates, landing regularly.

We keep shipping new free tools, code recipes and Claude Code templates. Follow @freeyantra on Instagram or join the newsletter so you never miss one.

Follow @freeyantra

or get them by email

Double opt-in. Unsubscribe any time. Privacy