Azure Speech SDK: audio logging works with a subscription key but not with an STS token

Toshiki Takei 20 Reputation points
2026-10-08T05:53:29.53+00:00

Speech recognition succeeds with both subscription-key authentication and STS token authentication. However, audio and transcription logs are available only when I supply the subscription key directly to the SDK.

Is this expected behavior, or is additional configuration required for logging with STS token authentication?

Environment

Region: japaneast

Recognition language: en-US

Python Speech SDK: 1.52.0

Runtime: Google Colab

BYOS: Not enabled

Standard speech-to-text model, without a custom deployment

Input: A 4.3-second WAV file, streamed through PushAudioInputStream

Audio format: 16 kHz, 16-bit PCM, mono

Recognition method: recognize_once_async()

The STS token is obtained by exchanging the same Speech resource key at:

POST https://japaneast.api.cognitive.microsoft.com/sts/v1.0/issueToken

This is not a Microsoft Entra ID token.

Observed results

I used the same resource key, region, language, and audio file for both tests. Log retrieval used subscription-key authentication in both cases.

Recognition authentication Recognition Audio/transcription logs
STS token Successful No logs appeared during five minutes of polling
Subscription key Successful Both logs appeared on the first check

Both tests reported EnableAudioLogging: true, returned ResultReason.RecognizedSpeech, and ended the recognition session normally.

Reproduction

Install the dependencies:

%pip install azure-cognitiveservices-speech==1.52.0 requests

Upload a short WAV file containing English speech, encoded as 16 kHz, 16-bit PCM, mono. Update WAV_PATH below.

Run once with USE_STS_TOKEN = True, then again with USE_STS_TOKEN = False.

import getpass
import time
import wave

import requests
import azure.cognitiveservices.speech as speechsdk

KEY = getpass.getpass("Speech resource key: ")
REGION = "japaneast"
LANGUAGE = "en-US"
WAV_PATH = "/content/test_16k.wav"
USE_STS_TOKEN = True

API_ORIGIN = f"https://{REGION}.api.cognitive.microsoft.com"
LOG_URL = (
    f"{API_ORIGIN}/speechtotext/v3.2"
    f"/endpoints/base/{LANGUAGE}/files/logs"
)


def list_logs():
    entries = []
    url = LOG_URL
    params = {"sasValidityInSeconds": 3600}

    while url:
        response = requests.get(
            url,
            headers={"Ocp-Apim-Subscription-Key": KEY},
            params=params,
            timeout=30,
        )
        response.raise_for_status()
        body = response.json()
        entries.extend(body.get("values", []))
        url = body.get("@nextLink")
        params = None

    return entries


def identity(entry):
    return entry.get("self") or entry["name"]


with wave.open(WAV_PATH, "rb") as audio:
    assert audio.getframerate() == 16000
    assert audio.getsampwidth() == 2
    assert audio.getnchannels() == 1
    assert audio.getcomptype() == "NONE"
    assert 0 < audio.getnframes() / 16000 <= 15

before_ids = {identity(entry) for entry in list_logs()}

if USE_STS_TOKEN:
    response = requests.post(
        f"{API_ORIGIN}/sts/v1.0/issueToken",
        headers={"Ocp-Apim-Subscription-Key": KEY},
        timeout=30,
    )
    response.raise_for_status()
    config = speechsdk.SpeechConfig(
        auth_token=response.text,
        region=REGION,
    )
else:
    config = speechsdk.SpeechConfig(
        subscription=KEY,
        region=REGION,
    )

config.speech_recognition_language = LANGUAGE
config.enable_audio_logging()

print(
    "EnableAudioLogging:",
    config.get_property(
        speechsdk.PropertyId.SpeechServiceConnection_EnableAudioLogging
    ),
)

stream = speechsdk.audio.PushAudioInputStream(
    stream_format=speechsdk.audio.AudioStreamFormat(
        samples_per_second=16000,
        bits_per_sample=16,
        channels=1,
    )
)
recognizer = speechsdk.SpeechRecognizer(
    speech_config=config,
    audio_config=speechsdk.audio.AudioConfig(stream=stream),
)

recognizer.session_stopped.connect(
    lambda _: print("Session stopped")
)

future = recognizer.recognize_once_async()

try:
    with wave.open(WAV_PATH, "rb") as audio:
        while True:
            chunk = audio.readframes(1600)
            if not chunk:
                break
            stream.write(chunk)
            time.sleep(0.1)
finally:
    stream.close()

result = future.get()
print("Result reason:", result.reason)
print("Recognized text:", result.text)

if result.reason == speechsdk.ResultReason.Canceled:
    details = speechsdk.CancellationDetails(result)
    print("Cancellation reason:", details.reason)
    print("Error details:", details.error_details)

for attempt in range(21):
    current = list_logs()
    new_logs = [
        entry for entry in current
        if identity(entry) not in before_ids
    ]
    print(
        f"Check {attempt + 1}: "
        f"total logs={len(current)}, new logs={len(new_logs)}"
    )

    for entry in new_logs:
        print(entry.get("kind"), entry["name"])

    if {"Audio", "Transcription"}.issubset(
        {entry.get("kind") for entry in new_logs}
    ):
        break

    if attempt < 20:
        time.sleep(15)

I could not find an authentication-related restriction in the audio and transcription logging documentation.

Does STS token authentication support this logging feature? If so, does it require an additional scope or configuration, or could this be a service/SDK issue?

Azure Speech in Foundry Tools
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.