# Qwen-TTS

This document describes the input and output parameters of the Alibaba Cloud Qwen text-to-speech model `qwen3-tts-flash` integrated into `modelverse`, for reference when using the API.

The model offers a variety of human-like voice timbres, supports multiple languages and Chinese dialects, and can output multi-language content under the same voice. The system can adaptively adjust tone and smoothly handle complex text.

## Supported Models

| Model             | Description                                                                                                                                          |
| :---------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------- |
| `qwen3-tts-flash` | Billed per character, low latency. Suitable for navigation announcements, notifications, online education courseware, high-frequency short-text synthesis, and similar scenarios. Supports multiple languages and Chinese dialects. |

## Synchronous Synthesis

### Endpoint

`https://api-us-ca.umodelverse.ai/v1/audio/speech`

> Note: This endpoint is path-compatible with OpenAI `/v1/audio/speech`, but the **response body is the raw Alibaba Cloud JSON** (containing an audio URL), not the OpenAI binary audio stream. See the [Response Format](#response-format) section below.

### Request Parameters

| Parameter                | Type   | Required | Description                                                                                                                                                                                                                                                                                                                                                                      |
| :----------------------- | :----- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| model                    | string | Yes      | The TTS model name to use. See [Supported Models](#supported-models) above, e.g., `qwen3-tts-flash`                                                                                                                                                                                                                                                                              |
| input                    | string | Yes      | The text to be synthesized into speech. Supports mixed multi-language input. Maximum `600` characters                                                                                                                                                                                                                                                                            |
| voice                    | string | Yes      | The system voice name to use, e.g., `Cherry`, `Ethan`, `Serena`, `Chelsie`, etc. For the full voice list, see the [Alibaba Cloud Official Voice List](https://help.aliyun.com/zh/model-studio/qwen-tts)                                                                                                                                                                          |
| metadata.language_type   | string | No       | Specifies the language of the synthesized audio. If not provided, defaults to `Auto` (automatic detection, suitable for unknown or mixed-language text). Explicitly specifying the language when the input is single-language can significantly improve synthesis quality. Available values: `Chinese`, `English`, `German`, `Italian`, `Portuguese`, `Spanish`, `Japanese`, `Korean`, `French`, `Russian`, `Auto` (case-insensitive). Values are validated upstream; invalid values return a `400` error with the currently supported language list in the `message` field. |

### Request Examples

⚠️ If you are using Windows, it is recommended to use Postman or another API client tool.

#### curl

```bash
curl https://api-us-ca.umodelverse.ai/v1/audio/speech \
  -H "Authorization: Bearer $MODELVERSE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen3-tts-flash",
    "input": "那我来给大家推荐一款T恤，这款呢真的是超级好看，这个颜色呢很显气质。",
    "voice": "Cherry"
  }'
```

#### python

```python
import os
import requests

resp = requests.post(
    "https://api-us-ca.umodelverse.ai/v1/audio/speech",
    headers={
        "Authorization": f"Bearer {os.getenv('MODELVERSE_API_KEY')}",
        "Content-Type": "application/json",
    },
    json={
        "model": "qwen3-tts-flash",
        "input": "那我来给大家推荐一款T恤，这款呢真的是超级好看，这个颜色呢很显气质。",
        "voice": "Cherry",
    },
)
data = resp.json()
audio_url = data["output"]["audio"]["url"]
print("audio url:", audio_url)

# Download audio
audio_bytes = requests.get(audio_url).content
with open("output.wav", "wb") as f:
    f.write(audio_bytes)
```

### Specifying a Language (Optional)

When the input text is in a single language, explicitly specifying the language via `metadata.language_type` produces more accurate pronunciation and more natural intonation, and typically outperforms the default `Auto` mode:

```bash
curl https://api-us-ca.umodelverse.ai/v1/audio/speech \
  -H "Authorization: Bearer $MODELVERSE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen3-tts-flash",
    "input": "今天天气真好，我们去公园散步吧。",
    "voice": "Cherry",
    "metadata": {
      "language_type": "Chinese"
    }
  }'
```

## Response Format

The endpoint returns `application/json`, which is a pass-through of the raw Alibaba Cloud DashScope response structure. Clients must extract the audio URL from the `output.audio.url` field and download it separately. The URL is valid for **24 hours**.

### Output

| Parameter                  | Type    | Description                                                                                                              |
| :------------------------- | :------ | :----------------------------------------------------------------------------------------------------------------------- |
| request_id                 | string  | Unique identifier for this request, used for locating and troubleshooting issues                                         |
| code                       | string  | Business error code; empty string on success                                                                             |
| message                    | string  | Business error message; empty string on success                                                                          |
| output                     | object  | Model output                                                                                                             |
| output.finish_reason       | string  | Completion reason: `null` while generating, `stop` when finished normally                                                |
| output.audio               | object  | Synthesized audio information                                                                                            |
| output.audio.url           | string  | Full URL of the synthesized audio file. Valid for 24 hours                                                               |
| output.audio.data          | string  | Base64-encoded audio data for streaming output (in synchronous mode, always an empty string)                             |
| output.audio.id            | string  | ID of the audio object                                                                                                   |
| output.audio.expires_at    | integer | Expiration timestamp of the audio URL                                                                                    |
| usage                      | object  | Usage information for this request                                                                                       |
| usage.characters           | integer | Number of input text characters; used as the billing basis                                                               |
| usage.input_tokens         | integer | Always `0`                                                                                                               |
| usage.output_tokens        | integer | Always `0`                                                                                                               |

### Response Example

```json
{
  "request_id": "5c63c65c-cad8-4bf4-959d-xxxxxxxxxxxx",
  "code": "",
  "message": "",
  "output": {
    "finish_reason": "stop",
    "audio": {
      "data": "",
      "url": "https://dashscope-result-bj.oss-cn-beijing.aliyuncs.com/xx/xxxxxxxx.wav?Expires=1766113409&OSSAccessKeyId=LTAI5xxxxxx&Signature=xxxxxx",
      "id": "audio_5c63c65c-cad8-4bf4-959d-xxxxxxxxxxxx",
      "expires_at": 1766113409
    }
  },
  "usage": {
    "input_tokens": 0,
    "output_tokens": 0,
    "characters": 195
  }
}
```

## Error Response

When a request fails, the endpoint returns a standard JSON error response:

```json
{
  "error": {
    "message": "Error description",
    "type": "invalid_request_error",
    "code": "error_code",
    "param": "<Request ID, for feedback or troubleshooting the cause of the error>"
  }
}
```

## Notes

1. **Response is not a binary audio stream**: Unlike the native OpenAI `/v1/audio/speech`, this endpoint returns JSON rather than raw audio bytes. If you previously integrated this endpoint using the OpenAI SDK (e.g., `with_streaming_response.create(...).stream_to_file(...)`), you must switch to parsing the JSON response and downloading the audio from `output.audio.url` separately.
2. **Audio URL is valid for 24 hours**: Download the audio promptly or store it in your own object storage.
3. **Text length limit**: Maximum `600` characters. Please split longer texts before sending.
4. **Billing**: Billed per character based on the `usage.characters` value returned by the upstream service.
5. **Voice selection**: The `voice` field must be an Alibaba Cloud system voice name (e.g., `Cherry`). For the full list, refer to the Alibaba Cloud official documentation.
