Azure Voice Live STT: How to enforce a hard per-session language lock (es-ES only)?

Jurado, Jose Luis 0 Reputation points
2026-07-01T09:06:04.2966667+00:00

Issue context:

We are using Azure Voice Live realtime STT in production voice sessions and need strict monolingual behavior per session.

Observed behavior:

  • We send session.update with input_audio_transcription.language set to es-ES.
    • We also set turn_detection.type to azure_semantic_vad_multilingual.
      • Despite language=es-ES, STT still detects/transcribes other languages when speakers switch language.
    • Expected behavior:
      • A hard language lock so STT only recognizes/transcribes Spanish (es-ES) for that session.
    • Current payload example:
    • {
    • "type": "session.update",
    • "session": {
    • "input_audio_transcription": {
      
    •   "model": "azure-speech",
      
    •   "language": "es-ES"
      
    • },
      
    • "turn_detection": {
      
    •   "type": "azure_semantic_vad_multilingual",
      
    •   "threshold": 0.5,
      
    •   "prefix_padding_ms": 500,
      
    •   "silence_duration_ms": 1400,
      
    •   "barge_in": true
      
    • }
      
    • }
    • }
  • Question:
    1. Is strict hard language lock supported today for Voice Live STT per session?
      1. If yes, what exact parameter(s) and API version enforce it?
        1. If not, what is the recommended workaround and roadmap?
      2. Any official guidance is appreciated.
Azure Speech in Foundry Tools

2 answers

Sort by: Most helpful
  1. Jurado, Jose Luis 0 Reputation points
    2026-07-08T11:00:57.8566667+00:00

    wrong placement

    Was this answer helpful?

    0 comments No comments

  2. Manish Deshpande 7,815 Reputation points Microsoft External Staff Moderator
    2026-07-07T19:52:16.8266667+00:00

    Hello @Jurado, Jose Luis

    Thanks for testing that so precisely the fact that it still leaks after moving to gpt-realtime is actually the key clue, and it points straight at the root cause. Two things to untangle here.

    1. Turn detection is not your language control turn_detection (server_vad, azure_semantic_vad, azure_semantic_vad_multilingual) only governs when the service decides a turn started/ended (and, with a languages array, filler-word removal). It has no effect on which language your transcript comes back in. So swapping the _multilingual suffix didn't lock anything — you can set VAD to whatever endpoints best; it's orthogonal to language.

    2. The real reason it leaks: gpt-realtime is a native-audio (multimodal) model. Multimodal models (gpt-realtime, gpt-realtime-mini, phi4-mm-realtime) listen to the audio directly. For these, input_audio_transcription.language is only a hint to improve transcription quality — not a hard lock, and the model returns results for languages not listed (just at lower quality). The transcription runs as a separate pass, so it can't constrain what the underlying model hears or answers. That's exactly why a Spanish-only setting still lets non-Spanish through.

    Also note: with gpt-realtime/-mini, the available transcription models are the OpenAI ones (whisper-1, gpt-4o-transcribe, gpt-4o-mini-transcribe, gpt-4o-transcribe-diarize) — not azure-speech. So you can't get the azure-speech "single language" restriction while staying on a native-audio model.

    How to actually enforce a per-session Spanish lock at the recognition layer: Use a non-multimodal (text) chat model — e.g. gpt-4.1 — paired with azure-speech transcription in single-language mode:

    User's image

    This is the documented "single language configuration," which restricts the transcription languages detected. Two things to watch:

    • language must be a single value with no comma. If it ever becomes "es-ES,en-US", Voice Live treats it as multi-language detection and will happily transcribe those other languages.
    • "Restrict" ≠ "reject." There's no flag that makes the recognizer refuse non-Spanish audio outright — a single-language config biases recognition to Spanish rather than returning a correct English/Portuguese transcript. If you need to hard-drop non-Spanish turns, do it at the application layer (run language identification / confidence-score filtering on the transcript and discard turns below your Spanish-confidence threshold).

    A few validation/robustness steps:

    • Send session.update before streaming audio, and confirm the session.updated echo shows model: "azure-speech" and language: "es-ES" — a later session.update elsewhere in your code can silently reset it.
    • If you keep any native-audio model, pin the model's own behavior with an instruction and pin the output voice locale so replies don't drift:
        "instructions": "The caller always speaks Spanish (es-ES). Transcribe and respond only in Spanish, even if you detect another language in the input audio."
      
      (This biases behavior; it's not a hard STT lock — only the text-model + azure-speech path gives you the recognition-layer restriction.)
    • Make sure you're on the GA API version (2025-10-01 or newer), since transcription/session behavior has changed across versions.

    Links:
    Voice Live supported languages (three language modes / single-language config)
    https://learn.microsoft.com/en-us/azure/ai-services/speech-service/voice-live-language-support?tabs=speechinput
    How to use the Voice Live API (audio input transcription, turn detection):
    https://learn.microsoft.com/en-us/azure/ai-services/speech-service/voice-live-how-to

    Speech-to-text language & locale support:

    https://learn.microsoft.com/en-us/azure/ai-services/speech-service/language-support?tabs=stt

    VAD isn't the lever. On a native-audio model like gpt-realtime, language is only a hint — no hard lock exists. For a true per-session es-ES lock, switch to a text chat model + azure-speech transcription with a single es-ES locale (no comma), and handle any hard rejection of non-Spanish turns at the app layer.

    Thanks,
    Manish.

    Was this answer helpful?

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.