Skip to main content
Speech-to-text

Non-real-time speech recognition

Non-real-time speech recognition models convert recorded audio into text. They support multilingual recognition, singing recognition, noise rejection, and speaker diarization, which makes them suitable for meeting transcription, call analysis, subtitle generation, and similar scenarios.

Overview

Transcribe recorded audio and video files in batches through asynchronous tasks.
  • Context enhancement improves recognition accuracy through configurable context.
  • Custom hotwords improve the recognition accuracy of proper nouns through a preset word list.
  • Configurable features include speaker diarization, sensitive-word filtering, and sentence-level or word-level timestamps.
  • Asynchronous transcription supports a single audio file of up to 12 hours in duration and up to 2 GB in size.
  • Any sample rate is supported, along with mainstream audio and video formats such as AAC, WAV, and MP3.
For real-time scenarios such as live subtitles, online meetings, and voice assistants, use Real-time speech recognition. For model selection guidance, see Speech-to-text.

Prerequisites

Quick start

In non-real-time speech recognition, Qwen-Audio-3.0-ASR-Flash-Filetrans, Fun-ASR, Qwen3-ASR-Flash-Filetrans, and Paraformer use asynchronous calls. Set the request header X-DashScope-Async: enable, submit the task, and then poll the query API to retrieve the result. Other models, such as Fun-ASR-Flash and Qwen3-ASR-Flash, use synchronous calls.If you call a dedicated deployment of the model service and receive the error current user api does not support asynchronous calls, the deployment supports synchronous calls only. Change the request header to X-DashScope-Async: disable and keep the rest of the call unchanged.
  • Qwen-Audio-3.0-ASR-Flash-Filetrans/Fun-ASR
  • Qwen-Audio-3.0-ASR-Flash/Fun-ASR-Flash
  • Qwen3-ASR-Flash-Filetrans
  • Qwen3-ASR-Flash
  • Paraformer
Because audio and video files can be large, the file transcription API uses asynchronous calls: submit a task, poll the query API for its status, and retrieve the recognition result after the task completes.
  • cURL
  • Python
  • Java
When you call the API with cURL, first submit the task to get a task_id, and then query the task result by using that ID.
  • Submit a task
  • Get the task result
  • Download the recognition result
The following configuration is for the Singapore region. Replace {WorkspaceId} with your actual Workspace ID. The configuration differs by region.
curl -X POST 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/asr/transcription' \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-H "X-DashScope-Async: enable" \
-d '{
    "model": "qwen-audio-3.0-asr-flash-filetrans",
    "input": {
        "file_urls": [
            "{YOUR_AUDIO_URL}"
        ]
    },
    "parameters": {
        "channel_id": [0],
        "language_hints": ["zh", "en"]
    }
}'
  • Recognition result
{
    "file_url": "{YOUR_AUDIO_URL}",
    "properties": {
        "audio_format": "pcm_s16le",
        "channels": [
            0
        ],
        "original_sampling_rate": 16000,
        "original_duration_in_milliseconds": 3834
    },
    "transcripts": [
        {
            "channel_id": 0,
            "content_duration_in_milliseconds": 2480,
            "text": "Hello World, this is the Alibaba Speech Lab.",
            "sentences": [
                {
                    "begin_time": 760,
                    "end_time": 3240,
                    "text": "Hello World, this is the Alibaba Speech Lab.",
                    "sentence_id": 1,
                    "words": [
                        {
                            "begin_time": 760,
                            "end_time": 1000,
                            "text": "Hello",
                            "punctuation": ""
                        },
                        {
                            "begin_time": 1000,
                            "end_time": 1120,
                            "text": " World",
                            "punctuation": ","
                        },
                        {
                            "begin_time": 1400,
                            "end_time": 1920,
                            "text": "this is",
                            "punctuation": ""
                        },
                        {
                            "begin_time": 1920,
                            "end_time": 2520,
                            "text": "the Alibaba",
                            "punctuation": ""
                        },
                        {
                            "begin_time": 2520,
                            "end_time": 2840,
                            "text": "Speech",
                            "punctuation": ""
                        },
                        {
                            "begin_time": 2840,
                            "end_time": 3240,
                            "text": "Lab",
                            "punctuation": "."
                        }
                    ]
                }
            ]
        }
    ]
}

Advanced features

Use the OpenAI-compatible API

The US region does not support the OpenAI-compatible mode.
Only the Qwen3-ASR-Flash series models support calls through the OpenAI-compatible mode. This mode accepts only publicly accessible audio file URLs. It does not accept the absolute path of a local audio file. Use OpenAI Python SDK 1.52.0 or later, or Node.js SDK 4.68.0 or later. To install or upgrade the SDK, run:
# Python
pip install -U "openai>=1.52.0"

# Node.js
npm install openai@^4.68.0
asr_options is not a standard OpenAI parameter. With the OpenAI Python SDK, pass it through extra_body. With the Node.js OpenAI SDK, pass asr_options directly as a top-level parameter in the request body.
  • Input: audio file URL
  • Input: Base64-encoded audio file
  • Python SDK
  • Node.js SDK
  • cURL
from openai import OpenAI
import os

try:
    client = OpenAI(
        # The API Key differs between the Singapore/US regions and the Beijing region. Get an API Key: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
        # If you have not configured the environment variable, replace the following line with your Alibaba Cloud Model Studio API Key: api_key = "sk-xxx",
        api_key=os.getenv("DASHSCOPE_API_KEY"),
        # The following is the configuration for the Singapore region. When calling, replace "{WorkspaceId}" with your actual workspace ID. The configuration differs by region.
        base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
    )

    stream_enabled = False  # Whether to enable streaming output
    completion = client.chat.completions.create(
        model="qwen3-asr-flash",
        messages=[
            {
                "content": [
                    {
                        "type": "input_audio",
                        "input_audio": {
                            "data": "{YOUR_AUDIO_URL}"
                        }
                    }
                ],
                "role": "user"
            }
        ],
        stream=stream_enabled,
        # When stream is set to False, the stream_options parameter cannot be set
        # stream_options={"include_usage": True},
        extra_body={
            "asr_options": {
                # "language": "zh",
                "enable_itn": False
            }
        }
    )
    if stream_enabled:
        full_content = ""
        print("The streaming output is:")
        for chunk in completion:
            # If stream_options.include_usage is True, the choices field of the last chunk is an empty list and needs to be skipped (you can get the Token usage via chunk.usage)
            print(chunk)
            if chunk.choices and chunk.choices[0].delta.content:
                full_content += chunk.choices[0].delta.content
        print(f"The complete content is: {full_content}")
    else:
        print(f"The non-streaming output is: {completion.choices[0].message.content}")
except Exception as e:
    print(f"Error message: {e}")

Process long audio files

Non-real-time speech recognition supports asynchronous transcription of long audio files. This suits scenarios such as meeting minutes, interview transcripts, and call playback. Limitations:
  • Qwen-Audio-3.0-ASR-Flash-Filetrans/Fun-ASR / Qwen3-ASR-Flash-Filetrans / Paraformer: a single audio file can be up to 2 GB in size and 12 hours in duration.
  • Qwen-Audio-3.0-ASR-Flash/Fun-ASR-Flash/Qwen3-ASR-Flash: a single audio file can be up to 10 MB in size and 5 minutes in duration. For longer audio, use Qwen-Audio-3.0-ASR-Flash-Filetrans, Fun-ASR, or Qwen3-ASR-Flash-Filetrans.
  • When speaker diarization is enabled: keep the audio duration within 2 hours. Longer audio may cause recognition failures or timeouts. For more information, see Speaker diarization.
Call flow: long audio transcription uses an asynchronous task model with three steps:
  1. Submit the transcription task and get a task_id.
  2. Poll the query API for the task status, or use the SDK's wait method to block until the task completes.
  3. After the task completes, download the recognition result JSON from the returned URL.
For sample code, see the Quick start code in Non-real-time speech recognition.

Streaming output

Qwen-Audio-3.0-ASR-Flash/Fun-ASR-Flash/Qwen3-ASR-Flash support streaming output: they return intermediate results as recognition proceeds. This suits scenarios that need real-time progress feedback. Asynchronous transcription models such as Qwen-Audio-3.0-ASR-Flash-Filetrans, Fun-ASR, Qwen3-ASR-Flash-Filetrans, and Paraformer do not support streaming output. Get the final result by polling the task (for more information, see Process long audio files). How to enable:
  • DashScope Python SDK: set the stream parameter to True.
  • DashScope Java SDK: call the streamCall API.
  • DashScope HTTP: set the X-DashScope-SSE header to enable.
  • OpenAI-compatible SDK: set the stream parameter to True.
For streaming output sample code, see the Non-real-time speech recognition section for Qwen3-ASR-Flash in the Quick start.

Improve accuracy with hotwords

Hotwords improve recognition accuracy for domain-specific proper nouns such as names, place names, and product names. For details on how to create and use hotwords, see Improve recognition accuracy. Different SDKs use different naming conventions for these parameters, such as dictionary keys, object properties, or methods. For the full field mapping, see the API reference for each SDK.

Improve accuracy with context enhancement

Context enhancement passes the conversation history to the ASR model, which significantly improves transcription accuracy for proper nouns. For details on how to use this feature and for example results, see Context enhancement.

Speaker diarization

Speaker diarization automatically identifies different speakers in the audio and labels each sentence in the transcription result with a speaker tag. This suits scenarios such as multi-party meetings and interview recordings. Supported models: the Qwen-Audio-3.0-ASR-Flash-Filetrans, Fun-ASR, and Paraformer series models. How to enable: set the diarization_enabled parameter to true in the API request. In the result, each sentence includes a speaker_id field that identifies the speaker. Example return structure (excerpt):
{
  "transcripts": [
    {
      "sentences": [
        { "begin_time": 100, "end_time": 3820, "text": "Hello, let's discuss the project progress today.", "speaker_id": 0 },
        { "begin_time": 3820, "end_time": 6500, "text": "Sure, let me give a quick report first.", "speaker_id": 1 }
      ]
    }
  ]
}
Different SDKs use different naming conventions for these fields, such as dictionary keys, object properties, or methods. For the full field mapping, see the API reference for each SDK.
When speaker diarization is enabled, keep the audio duration within 2 hours. Longer audio may cause recognition failures or timeouts. For the audio length limits when diarization is disabled, see Process long audio files. Speaker diarization supports mono audio only.
For the full field definitions, see the API reference.

Sensitive word filtering

Sensitive word filtering replaces or removes sensitive words in the recognition result. This suits scenarios such as customer service quality inspection, content compliance, and subtitle moderation. Supported models: the Qwen-Audio-3.0-ASR-Flash-Filetrans, Fun-ASR, and Paraformer series models. Default behavior: when the special_word_filter parameter is not passed, the system uses the built-in Model Studio sensitive word list. Matched words are replaced with an equal-length string of *. Custom configuration: special_word_filter is a JSON object with three subfields:
  • filter_with_signed.word_list: a string array of sensitive words to replace with an equal-length string of *. For example, with ["test"], "Please help me test this" becomes "Please help me **** this".
  • filter_with_empty.word_list: a string array of sensitive words to remove entirely from the result. For example, with ["start"], "Is the game about to start now" becomes "Is the game about to now".
  • system_reserved_filter: a boolean value that defaults to true. It controls whether to also apply the system's built-in sensitive word list, which takes effect together with your custom list.
Configuration example:
{
  "special_word_filter": {
    "filter_with_signed": {
      "word_list": ["test"]
    },
    "filter_with_empty": {
      "word_list": ["start", "happen"]
    },
    "system_reserved_filter": true
  }
}
Different SDKs use different naming conventions for these parameters, such as dictionary keys, object properties, or methods. For the full field mapping, see the API reference.

Emotion recognition

The Qwen3-ASR-Flash-Filetrans and Qwen3-ASR-Flash series models have emotion recognition permanently enabled, with no additional configuration required. The result includes an emotion tag for the speaker, chosen from seven fine-grained emotions: surprised, neutral, happy, sad, disgusted, angry, and fearful. Field paths (vary by API):
  • OpenAI-compatible API (Qwen3-ASR-Flash real-time transcription): nested in choices[].delta.annotations[].emotion (streaming output) or choices[].message.annotations[].emotion (non-streaming).
  • DashScope synchronous API (Qwen3-ASR-Flash): nested in output.choices[].message.annotations[].emotion.
  • DashScope asynchronous task API (Qwen3-ASR-Flash-Filetrans recording file transcription): nested in transcripts[].sentences[].emotion, alongside the timestamp, speaker, and other fields in each sentence object.
Example return structure (excerpt from the DashScope asynchronous task API):
{
  "transcripts": [{
    "sentences": [{
      "begin_time": 0,
      "end_time": 1440,
      "text": "Welcome to Alibaba Cloud.",
      "emotion": "neutral",
      "language": "en"
    }]
  }]
}
Different SDKs use different naming conventions for these fields, such as dictionary keys, object properties, or methods. For the full field mapping, see the API reference.
The Qwen-Audio-3.0-ASR-Flash-Filetrans, Qwen-Audio-3.0-ASR-Flash, Fun-ASR-Flash, Fun-ASR, and Paraformer non-real-time models do not support emotion recognition. To use emotion recognition in real-time recognition, see the corresponding section in Real-time speech recognition.

Get timestamps

Non-real-time speech recognition can output timestamps in the transcription result, which helps with subtitle generation, keyword highlighting, and audio/video editing. Qwen-Audio-3.0-ASR-Flash-Filetrans, Qwen-Audio-3.0-ASR-Flash, Fun-ASR, Fun-ASR-Flash, Qwen3-ASR-Flash-Filetrans, and Paraformer all support timestamps, but the default behavior and control method differ by model:
  • Qwen-Audio-3.0-ASR-Flash-Filetrans/Qwen-Audio-3.0-ASR-Flash/Fun-ASR/Fun-ASR-Flash/Paraformer: timestamps are permanently enabled and cannot be turned off.
  • Qwen3-ASR-Flash-Filetrans: only the DashScope asynchronous call supports timestamps, and timestamps are permanently enabled. Use the enable_words request parameter to control the timestamp level: set it to false (default) to return sentence-level timestamps, or true to return word-level timestamps. Word-level timestamps support only the following languages: Chinese, English, Japanese, Korean, German, French, Spanish, Italian, Portuguese, and Russian. Accuracy is not guaranteed for other languages.
When you call Qwen3-ASR-Flash through the OpenAI-compatible API, the output form is chat.completion, which does not return timestamp fields. For timestamps, use Qwen3-ASR-Flash-Filetrans (the asynchronous task API).
Timestamps are in milliseconds and are returned at two levels:
  • Sentence level: sentences[].begin_time and sentences[].end_time mark the start and end time of each sentence in the audio.
  • Word level: the sentences[].words[] array, where each element contains begin_time, end_time, and text (the text of that word).
Example return structure (excerpt from the DashScope asynchronous task API):
{
  "transcripts": [{
    "sentences": [{
      "begin_time": 100,
      "end_time": 3820,
      "text": "Hello, let's discuss the project progress today.",
      "words": [
        { "begin_time": 100, "end_time": 596, "text": "Hello," },
        { "begin_time": 596, "end_time": 844, "text": "let's" }
      ]
    }]
  }]
}
The in-audio timestamp is a millisecond integer (such as 100). Do not confuse it with the task-level end_time (the task completion time, a string date such as "2024-09-12 15:11:40.903"). These are different fields.
Different SDKs use different naming conventions for these fields, such as dictionary keys, object properties, or methods. For the full field mapping, see the API reference.

Apply in production

When you apply non-real-time speech recognition in production, the following best practices improve recognition quality and system stability.

High-concurrency scenarios: use callbacks instead of polling

For asynchronous transcription tasks (Qwen-Audio-3.0-ASR-Flash-Filetrans, Fun-ASR, Qwen3-ASR-Flash-Filetrans, and Paraformer), you submit the task through POST /api/v1/services/audio/asr/transcription and then usually get the result by periodically calling the query API GET /api/v1/tasks/{task_id}. This query API defaults to 20 QPS and scales up to 100 QPS. In high-concurrency batch scenarios, frequent polling easily triggers throttling. Configure callback notifications through EventBridge. When a task completes, Model Studio automatically pushes a dashscope:System:AsyncTaskFinish event to your configured target (an HTTP/HTTPS endpoint or a RocketMQ topic). After the consumer receives the event, it no longer needs to call the query API, which avoids the throttling risk of frequent polling. For more information, see Configure EventBridge callback notifications.

Supported models

  • Supported: Qwen-Audio-3.0-ASR-Flash-Filetrans, Fun-ASR, Qwen3-ASR-Flash-Filetrans, and Paraformer (all asynchronous transcription tasks).
  • Not supported: Qwen3-ASR-Flash (synchronous or streaming calls, which are not asynchronous tasks).

Callback message content

For all three models, the callback message body has data.contain_result set to true, and data.output_result directly carries transcription_url. After the consumer receives the callback, it can get the recognition result without calling GET /api/v1/tasks/{task_id} again. However, the result field path and structure differ across the three models. See the following table.
When you write the consumer, choose the correct path for the model you use. Do not hardcode a single path. In failure scenarios, data.output_result.output no longer contains results/result; instead it contains code and message fields. Check data.task_status first, then read the result.

Model

Submission parameter

Result field path (based on the callback body)

usage field

Qwen-Audio-3.0-ASR-Flash-Filetrans, Fun-ASR

input.file_urls (array; only 1 URL per call)

data.output_result.output.results[ ].transcription_url (array, one entry per file, with subtask_status; also includes task_metrics)

duration

Paraformer

input.file_urls (array; only 1 URL per call)

Same as Qwen-Audio-3.0-ASR-Flash-Filetrans/Fun-ASR: data.output_result.output.results[ ].transcription_url

duration

Qwen3-ASR-Flash-Filetrans

input.file_url (single object; only 1 URL per call)

data.output_result.output.result.transcription_url (single object, without results[ ] / task_metrics)

seconds

Usage notes

Security (HTTP/HTTPS delivery): in production, verify the X-Eventbridge-Signature* header fields in the callback request before you consume it. Otherwise, any external IP can forge an AsyncTaskFinish event and inject fake recognition results. Also set a receive timeout of at least 5 seconds on the receiver. The RocketMQ delivery method has no message-level signature; its security is guaranteed by the RocketMQ authentication mechanism. Delivery latency: from task completion (end_time) to when the delivery target (an HTTP/HTTPS endpoint or a RocketMQ topic) receives the message, the delay is typically about 1 to 90 seconds. The exact latency depends on the real-time load of EventBridge. Idempotency: the same event may be delivered multiple times due to retries. Implement idempotent processing on the consumer, using the CloudEvents data.id or data.task_id as the deduplication key.

Production recommendations

  • File hosting: upload audio files to Alibaba Cloud OSS and call the API by URL. Avoid local file uploads (local file calls are capped at 100 QPS and cannot be scaled up).
  • Asynchronous polling: long audio transcription uses an asynchronous model. Set a reasonable polling interval (such as 2 to 5 seconds) to avoid frequent queries that consume your quota. To exceed the 20 to 100 QPS query limit, switch to event callback notifications. For more information, see High-concurrency scenarios: use callbacks instead of polling.
  • Error handling: implement a robust retry mechanism. For network timeouts or temporary server-side errors (5xx), retry with an exponential backoff strategy.
  • Noise reduction: for noisy audio, preprocess it with a tool such as FFmpeg before you submit it for recognition.
  • Model selection: choose the right model based on audio duration. For short audio within 5 minutes, use Qwen3-ASR-Flash. For long audio over 5 minutes, use Qwen-Audio-3.0-ASR-Flash-Filetrans, Fun-ASR, or Qwen3-ASR-Flash-Filetrans.

Supported models and regions

  • Singapore
  • US (Virginia)
  • China (Beijing)
To call the following models, use an API Key for the Singapore region:
  • Qwen-Audio-3.0-ASR-Flash-Filetrans: qwen-audio-3.0-asr-flash-filetrans
  • Qwen-Audio-3.0-ASR-Flash: qwen-audio-3.0-asr-flash
  • Fun-ASR: fun-asr (stable version, currently equivalent to fun-asr-2025-11-07), fun-asr-2025-11-07 (snapshot version), fun-asr-2025-08-25 (snapshot version), fun-asr-mtl (stable version, currently equivalent to fun-asr-mtl-2025-08-25), fun-asr-mtl-2025-08-25 (snapshot version)
  • Fun-ASR-Flash: fun-asr-flash-2026-06-15
  • Qwen3-ASR-Flash-Filetrans: qwen3-asr-flash-filetrans (stable version, currently equivalent to qwen3-asr-flash-filetrans-2025-11-17), qwen3-asr-flash-filetrans-2025-11-17 (snapshot version)
  • Qwen3-ASR-Flash: qwen3-asr-flash (stable version, currently equivalent to qwen3-asr-flash-2025-09-08), qwen3-asr-flash-2026-02-10 (latest snapshot version), qwen3-asr-flash-2025-09-08 (snapshot version)

API reference

FAQ

Q: How do I provide a publicly accessible audio URL to the API?

Use Alibaba Cloud Object Storage Service (OSS). OSS provides highly available and reliable storage, and lets you generate a public access URL. Verify that the generated URL is accessible over the public network: open the URL in a browser or with the curl command to confirm that the audio file downloads or plays (HTTP status code 200).

Q: How do I check whether the audio format meets the requirements?

Use the open-source tool ffprobe to quickly get detailed audio information:
# Query the container format (format_name), codec (codec_name), sample rate (sample_rate), and number of channels (channels) of the audio
ffprobe -v error -show_entries format=format_name -show_entries stream=codec_name,sample_rate,channels -of default=noprint_wrappers=1 your_audio_file.mp3

Q: How do I process audio to meet the model requirements?

Use the open-source tool FFmpeg to trim or convert the audio:
  • Trim audio: extract a clip from a long audio file
# -i: input file
# -ss 00:01:30: set the trim start time (start at 1 minute 30 seconds)
# -t 00:02:00: set the trim duration (trim 2 minutes)
# -c copy: copy the audio stream directly without re-encoding, which is fast
# output_clip.wav: output file
ffmpeg -i long_audio.wav -ss 00:01:30 -t 00:02:00 -c copy output_clip.wav
  • Convert the format For example, convert any audio to a 16 kHz, 16-bit, mono WAV file:
# -i: input file
# -ac 1: set the number of channels to 1 (mono)
# -ar 16000: set the sample rate to 16000 Hz (16 kHz)
# -sample_fmt s16: set the sample format to 16-bit signed integer PCM
# output.wav: output file
ffmpeg -i input.mp3 -ac 1 -ar 16000 -sample_fmt s16 output.wav

Q: How do I improve recognition accuracy?

The following factors affect recognition accuracy. Check each one and optimize accordingly. Main factors:
  1. Audio quality: the quality of the recording device, the sample rate, and environmental noise directly affect audio clarity. High-quality audio input is the foundation of accurate recognition.
  2. Speaker characteristics: pitch, speech rate, accent, and dialect differences (especially rare dialects or strong accents) increase recognition difficulty.
  3. Language and vocabulary: mixed languages, technical terms, or slang increase recognition difficulty. Configure hotwords to improve accuracy for domain-specific terms.
Optimization methods:
  1. Improve audio quality: use a high-performance microphone, record at the recommended sample rate, and minimize environmental noise and echo.
  2. Adapt to the speaker: for audio with strong accents or noticeable dialects, choose a model that supports the corresponding dialect.
  3. Configure hotwords: set hotwords for technical terms, proper nouns, and similar words.
Token Plan
Model Playground
Statistics and Monitoring
Support