All Products
Search
Document Center

Alibaba Cloud Model Studio:Non-real-time speech recognition

Last Updated:Sep 28, 2026

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

ImportantIn non-real-time speech recognition, Qwen-Audio-3.x-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.x-ASR-Flash-Filetrans/Fun-ASR

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

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

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.1-asr-flash-filetrans",
    "input": {
        "file_urls": [
            "{YOUR_AUDIO_URL}"
        ]
    },
    "parameters": {
        "channel_id": [0],
        "language_hints": ["zh", "en"]
    }
}'

Get the task result

This query API allows 20 QPS by default and can scale up to 100 QPS. For a higher frequency, or to avoid throttling from polling, configure an asynchronous task callback (see High-concurrency scenarios: use callbacks instead of polling).

The following configuration is for the Singapore region. Replace {WorkspaceId} with your actual Workspace ID. The configuration differs by region.

curl -X GET 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/tasks/{task_id}' \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json"

Download the recognition result

After the task succeeds, the output.results[].transcription_url returned by the query API points to a publicly downloadable JSON file that contains the complete recognition result. This URL is valid for 24 hours by default, so download and save it promptly.

# Replace {transcription_url} with the transcription_url value returned by the query API
curl -sS '{transcription_url}' -o transcription.json
cat transcription.json | jq .

Python

from http import HTTPStatus
from dashscope.audio.asr import Transcription
from urllib import request
import dashscope
import os
import json

# The following is the configuration for the Singapore region. When calling, replace "{WorkspaceId}" with your actual workspace ID. The configuration differs by region.
dashscope.base_http_api_url = 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1'

# The API Key differs between the Singapore and Beijing regions. Get an API Key: https://www.alibabacloud.com/help/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: dashscope.api_key = "sk-xxx"
dashscope.api_key = os.getenv("DASHSCOPE_API_KEY")

task_response = Transcription.async_call(
    model='qwen-audio-3.1-asr-flash-filetrans',
    file_urls=['{YOUR_AUDIO_URL}'],
    language_hints=['zh', 'en']  # language_hints is an optional parameter used to specify the language codes of the audio to be recognized. For the value range, see the API reference documentation.
)

transcription_response = Transcription.wait(task=task_response.output.task_id)

if transcription_response.status_code == HTTPStatus.OK:
    for transcription in transcription_response.output['results']:
        if transcription['subtask_status'] == 'SUCCEEDED':
            url = transcription['transcription_url']
            result = json.loads(request.urlopen(url).read().decode('utf8'))
            print(json.dumps(result, indent=4,
                            ensure_ascii=False))
        else:
            print('transcription failed!')
            print(transcription)
else:
    print('Error: ', transcription_response.output.message)

Java

import com.alibaba.dashscope.audio.asr.transcription.*;
import com.alibaba.dashscope.utils.Constants;
import com.google.gson.*;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        // The following is the configuration for the Singapore region. When calling, replace "{WorkspaceId}" with your actual workspace ID. The configuration differs by region.
        Constants.baseHttpApiUrl = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1";
        // Create the transcription request parameters.
        TranscriptionParam param =
                TranscriptionParam.builder()
                        // The API Key differs between the Singapore and Beijing regions. Get an API Key: https://www.alibabacloud.com/help/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: .apiKey("sk-xxx")
                        .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                        .model("qwen-audio-3.1-asr-flash-filetrans")
                        // language_hints is an optional parameter used to specify the language codes of the audio to be recognized. For the value range, see the API reference documentation.
                        .parameter("language_hints", new String[]{"zh", "en"})
                        .fileUrls(
                                Arrays.asList(
                                        "{YOUR_AUDIO_URL}"))
                        .build();
        try {
            Transcription transcription = new Transcription();
            // Submit the transcription request
            TranscriptionResult result = transcription.asyncCall(param);
            System.out.println("RequestId: " + result.getRequestId());
            // Check whether the task was submitted successfully
            if (result.getTaskId() == null) {
                System.out.println("Error: " + result.getOutput());
                System.exit(1);
            }
            // Block and wait for the task to complete and get the result
            result = transcription.wait(
                    TranscriptionQueryParam.FromTranscriptionParam(param, result.getTaskId()));
            // Get the transcription result
            List<TranscriptionTaskResult> taskResultList = result.getResults();
            if (taskResultList != null && taskResultList.size() > 0) {
                for (TranscriptionTaskResult taskResult : taskResultList) {
                    String transcriptionUrl = taskResult.getTranscriptionUrl();
                    HttpURLConnection connection =
                            (HttpURLConnection) new URL(transcriptionUrl).openConnection();
                    connection.setRequestMethod("GET");
                    connection.connect();
                    BufferedReader reader =
                            new BufferedReader(new InputStreamReader(connection.getInputStream()));
                    Gson gson = new GsonBuilder().setPrettyPrinting().create();
                    JsonElement jsonResult = gson.fromJson(reader, JsonObject.class);
                    System.out.println(gson.toJson(jsonResult));
                }
            }
        } catch (Exception e) {
            System.out.println("error: " + e);
        }
        System.exit(0);
    }
}

The complete recognition result is printed to the console in JSON format. It contains the transcribed text along with each segment's start and end time in the audio or video file, in milliseconds.

  • 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": "."
                        }
                    ]
                }
            ]
        }
    ]
}

Qwen-Audio-3.x-ASR-Flash/Fun-ASR-Flash

The Qwen-Audio-3.x-ASR-Flash and Fun-ASR-Flash model series support synchronous calls for audio files shorter than 5 minutes, and can return recognition results in streaming or non-streaming mode.

The following configuration is for the Singapore region. Replace {WorkspaceId} with your actual Workspace ID. The configuration differs by region. The API key for the Singapore region differs from the one for the Beijing region.

curl --location --request POST 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation' \
     --header "Authorization: Bearer $DASHSCOPE_API_KEY" \
     --header "Content-Type: application/json" \
     --header "X-DashScope-SSE: disable" \
     --data '{
    "model": "qwen-audio-3.1-asr-flash",
    "input": {
        "messages": [
            {
                "role": "user",
                "content": [
                    {
                        "type": "input_audio",
                        "input_audio": {
                            "data": "{YOUR_AUDIO_URL}"
                        }
                    }
                ]
            }
        ]
    },
    "parameters": {
        "format": "wav",
        "sample_rate": "16000"
    }
}'

ImportantNote: The response structure returned by the Qwen-Audio-3.x-ASR-Flash and Fun-ASR-Flash model series through the DashScope synchronous API (the multimodal-generation endpoint) differs from the standard DashScope multimodal response format. The actual response structure is as follows:

{
  "output": {
    "output": {
      "sentence": {
        "text": "Recognized text content"
      }
    },
    "text": "Hello World, this is the Alibaba Speech Lab."
  },
  "request_id": "..."
}

Here, output.output.sentence.text and the top-level output.text are the recognized-text fields, and there is no choices field. Parse the response accordingly.

Paraformer

The Paraformer sample code is similar to the asynchronous call for Fun-ASR. Replace the model value with a Paraformer model name.

Advanced features

Use the OpenAI-compatible API

ImportantThe 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

Python SDK

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/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}")

Node.js SDK

// Preparations before running:
// Common to Windows/Mac/Linux:
// 1. Make sure Node.js is installed (version >= 14 recommended)
// 2. Run the following command to install the required dependencies: npm install openai

import OpenAI from "openai";

const client = new OpenAI({
  // The API Key differs between the Singapore/US regions and the Beijing region. Get an API Key: https://www.alibabacloud.com/help/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: apiKey: "sk-xxx",
  apiKey: process.env.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.
  baseURL: "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
});

async function main() {
  try {
    const streamEnabled = false; // Whether to enable streaming output
    const completion = await client.chat.completions.create({
      model: "qwen3-asr-flash",
      messages: [
        {
          role: "user",
          content: [
            {
              type: "input_audio",
              input_audio: {
                data: "{YOUR_AUDIO_URL}"
              }
            }
          ]
        }
      ],
      stream: streamEnabled,
      // When stream is set to False, the stream_options parameter cannot be set
      // stream_options: {
      //   "include_usage": true
      // },
      asr_options: {
        // language: "zh",
        enable_itn: false
      }
    });

    if (streamEnabled) {
      let fullContent = "";
      console.log("The streaming output is:");
      for await (const chunk of completion) {
        console.log(JSON.stringify(chunk));
        if (chunk.choices && chunk.choices.length > 0) {
          const delta = chunk.choices[0].delta;
          if (delta && delta.content) {
            fullContent += delta.content;
          }
        }
      }
      console.log(`The complete content is: ${fullContent}`);
    } else {
      console.log(`The non-streaming output is: ${completion.choices[0].message.content}`);
    }
  } catch (err) {
    console.error(`Error message: ${err}`);
  }
}

main();

cURL

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/compatible-mode/v1/chat/completions' \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
    "model": "qwen3-asr-flash",
    "messages": [
        {
            "content": [
                {
                    "type": "input_audio",
                    "input_audio": {
                        "data": "{YOUR_AUDIO_URL}"
                    }
                }
            ],
            "role": "user"
        }
    ],
    "stream":false,
    "asr_options": {
        "enable_itn": false
    }
}'

Input: Base64-encoded audio file

Pass Base64-encoded data as a Data URL in the format data:<mediatype>;base64,<data>.

  • <mediatype>: the MIME type.

    The MIME type varies by audio format. For example:

    • WAV: audio/wav
    • MP3: audio/mpeg
  • <data>: the Base64-encoded string of the audio.

    Base64 encoding increases the data size. Keep the source file small enough that the encoded result still meets the input audio size limit (10 MB).

  • Example: data:audio/wav;base64,SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU4LjI5LjEwMAAAAAAAAAAAAAAA//PAxABQ/BXRbMPe4IQAhl9

    Click to view sample code

    import base64, pathlib
    
    # input.mp3 is the local audio file used for voice cloning. Replace it with the path to your own audio file and make sure it meets the audio requirements.
    file_path = pathlib.Path("{YOUR_AUDIO_FILE}")
    base64_str = base64.b64encode(file_path.read_bytes()).decode()
    data_uri = f"data:audio/mpeg;base64,{base64_str}"
    
    import java.nio.file.*;
    import java.util.Base64;
    
    public class Main {
        /**
         * filePath is the local audio file used for voice cloning. Replace it with the path to your own audio file and make sure it meets the audio requirements.
         */
        public static String toDataUrl(String filePath) throws Exception {
            byte[] bytes = Files.readAllBytes(Paths.get(filePath));
            String encoded = Base64.getEncoder().encodeToString(bytes);
            return "data:audio/mpeg;base64," + encoded;
        }
    
        // Usage example
        public static void main(String[] args) throws Exception {
            System.out.println(toDataUrl("{YOUR_AUDIO_FILE}"));
        }
    }
    
import base64
from openai import OpenAI
import os
import pathlib

try:
    # Replace with the actual audio file path
    file_path = "{YOUR_AUDIO_FILE}"
    # Replace with the actual MIME type of the audio file
    audio_mime_type = "audio/mpeg"

    file_path_obj = pathlib.Path(file_path)
    if not file_path_obj.exists():
        raise FileNotFoundError(f"Audio file does not exist: {file_path}")

    base64_str = base64.b64encode(file_path_obj.read_bytes()).decode()
    data_uri = f"data:{audio_mime_type};base64,{base64_str}"

    client = OpenAI(
        # The API Key differs between the Singapore/US regions and the Beijing region. Get an API Key: https://www.alibabacloud.com/help/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": data_uri
                        }
                    }
                ],
                "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}")
// Preparations before running:
// Common to Windows/Mac/Linux:
// 1. Make sure Node.js is installed (version >= 14 recommended)
// 2. Run the following command to install the required dependencies: npm install openai

import OpenAI from "openai";
import { readFileSync } from 'fs';

const client = new OpenAI({
  // The API Key differs between the Singapore/US regions and the Beijing region. Get an API Key: https://www.alibabacloud.com/help/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: apiKey: "sk-xxx",
  apiKey: process.env.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.
  baseURL: "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
});

const encodeAudioFile = (audioFilePath) => {
    const audioFile = readFileSync(audioFilePath);
    return audioFile.toString('base64');
};

// Replace with the actual audio file path
const dataUri = `data:audio/mpeg;base64,${encodeAudioFile("{YOUR_AUDIO_FILE}")}`;

async function main() {
  try {
    const streamEnabled = false; // Whether to enable streaming output
    const completion = await client.chat.completions.create({
      model: "qwen3-asr-flash",
      messages: [
        {
          role: "user",
          content: [
            {
              type: "input_audio",
              input_audio: {
                data: dataUri
              }
            }
          ]
        }
      ],
      stream: streamEnabled,
      // When stream is set to False, the stream_options parameter cannot be set
      // stream_options: {
      //   "include_usage": true
      // },
      asr_options: {
        // language: "zh",
        enable_itn: false
      }
    });

    if (streamEnabled) {
      let fullContent = "";
      console.log("The streaming output is:");
      for await (const chunk of completion) {
        console.log(JSON.stringify(chunk));
        if (chunk.choices && chunk.choices.length > 0) {
          const delta = chunk.choices[0].delta;
          if (delta && delta.content) {
            fullContent += delta.content;
          }
        }
      }
      console.log(`The complete content is: ${fullContent}`);
    } else {
      console.log(`The non-streaming output is: ${completion.choices[0].message.content}`);
    }
  } catch (err) {
    console.error(`Error message: ${err}`);
  }
}

main();

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.x-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.1-ASR-Flash: a single audio file can be up to 2 GB in size and 5 minutes 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.1-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.1-ASR-Flash supports streaming recognition results over HTTP SSE. For the request and response format, see HTTP API.

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.x-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 Qwen3-ASR-Flash streaming output examples, see Request examples and select the Streaming output tab.

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

Qwen-Audio-3.1-ASR-Flash enables speaker diarization with speaker_diarization_enabled. For its parameters and response structure, see HTTP API.

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.

The following configuration and example apply to: the Qwen-Audio-3.x-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.

ImportantWhen 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.x-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.

ImportantThe Qwen-Audio-3.x-ASR-Flash-Filetrans, Qwen-Audio-3.x-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

For timestamp stability and field paths in Flash streaming responses, see HTTP API response handling.

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.x-ASR-Flash-Filetrans, Qwen-Audio-3.x-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.x-ASR-Flash-Filetrans/Qwen-Audio-3.x-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.

ImportantWhen 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" }
      ]
    }]
  }]
}

ImportantThe 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.

NoteWhen 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.1-ASR-Flash-Filetrans, Fun-ASR, or Qwen3-ASR-Flash-Filetrans.

Supported models and regions

Singapore

To call the following models, use an API Key for the Singapore region:

  • Qwen-Audio-3.1-ASR-Flash-Filetrans: qwen-audio-3.1-asr-flash-filetrans
  • Qwen-Audio-3.0-ASR-Flash-Filetrans: qwen-audio-3.0-asr-flash-filetrans
  • Qwen-Audio-3.1-ASR-Flash: qwen-audio-3.1-asr-flash
  • 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)

US (Virginia)

To call the following models, use an API Key for the US region:

Qwen3-ASR-Flash: qwen3-asr-flash (stable version, currently equivalent to qwen3-asr-flash-2025-09-08), qwen3-asr-flash-2025-09-08 (snapshot version)

China (Beijing)

To call the following models, use an API Key for the Beijing region:

  • Qwen-Audio-3.1-ASR-Flash-Filetrans: qwen-audio-3.1-asr-flash-filetrans
  • Qwen-Audio-3.0-ASR-Flash-Filetrans: qwen-audio-3.0-asr-flash-filetrans
  • Qwen-Audio-3.1-ASR-Flash: qwen-audio-3.1-asr-flash
  • 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)
  • Paraformer: paraformer-v2, paraformer-8k-v2

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.