API Operation Details
The CosyVoice Voice Cloning service uses advanced Large Language Model (LLM) technology for feature extraction. It performs voice cloning without a training process. You only need to provide 10 to 20 seconds of audio. The service quickly generates highly similar and natural-sounding custom voices. This topic describes how to use the CosyVoice Voice Cloning service and its operational flow, enabling you to quickly clone voices.
NoteThe voice cloning service supports the cosyvoice-v2 model as of April 17, 2025. It provides better cloning results than cosyvoice-v1.
The v1 model's cloning service will continue to be supported. Voices cloned previously using cosyvoice-v1 can still be used normally.
You can also re-clone with cosyvoice-v2 as the targetModel using the original audio for improved cloning results.
Scenarios
- Companion scenarios: Provide personalized companionship by cloning family members' voices. You can use it for smart assistants, in-car navigation, and home entertainment. For example, you can read picture books to family members, control home appliances, or provide educational guidance.
- Education scenarios: Clone teachers' voices to enhance teacher-student interaction. Enrich teaching videos and courseware. This creates a more engaging and vivid learning experience.
- Audio and video industry: Clone streamers' voices for post-production re-recording and dubbing. This improves audio and video production efficiency.
- Intelligent customer service: Clone account managers' voices to provide voice services. This includes customer callbacks and marketing calls, which enhances service personalization and human interaction.
Benefits
- Low audio sample requirements: You can clone voices with only 10 to 20 seconds of recording. This significantly reduces recording costs and improves efficiency.
- High fidelity: Using Alibaba Speech Lab's self-developed CosyVoice generative neural network Large Language Model (LLM) algorithm, combined with cutting-edge zero-shot learning technology, it accurately restores real human voices in terms of intonation, rhythm, and emotional expression, making them difficult to distinguish from real recordings.
- Instant synthesis: It restores real voice timbre in seconds, providing an efficient, real-time voice cloning service.
Supported Models
The voice cloning service supports cosyvoice-v1 and cosyvoice-v2 models.
Notes
Note the following when using the CosyVoice Voice Cloning service:
-
Audio file format requirements:
- Number of sound channels: Mono or Stereo
- Sample rate: Greater than or equal to 16,000 Hz
- Format: WAV (16bit), MP3, M4A
- File size: Up to 10 MB
- Audio duration: 10 to 20 seconds. Do not exceed 60 seconds. Maintain continuity when reading. Include at least one continuous speech segment longer than 5 seconds.
-
Voice cloning quantity limit: Each Alibaba Cloud account can clone a maximum of 1,000 voices. If your needs exceed this limit, contact our pre-sales team in advance or join the developer group. Voices that remain unused for over 1 year will be taken offline.
-
Copyright and legality: You are responsible for the ownership and legal rights to use the provided voice. Read the Terms of Service.
-
Using cloned voices: Voices (VoiceName) generated using the voice cloning service are used in the same way as official default voices, such as longxiaoxia, provided in the Java SDK.
-
Service invocation method: The voice cloning service currently supports API invocation only.
Billing
The Voice Cloning service is provided free of charge, but charges apply when you use the cloned voice for speech synthesis. For billing details, see CosyVoice Speech Synthesis.
Prerequisites
- You have activated the service and obtained an API key. We recommend that you configure your API key as an environment variable (being phased out and integrated into the Configure API Key procedure) to reduce the risk of API key leakage.
- Install the latest version of the SDK.
- An audio URL accessible over the public network is available. We recommend uploading the audio to OSS.
API Details
When using different APIs, ensure that you use the same account for all operations.
Create Voice
Python
You can clone a voice using the create_voice method of the VoiceEnrollmentService class. Import the VoiceEnrollmentService class as follows: from dashscope.audio.tts_v2 import VoiceEnrollmentService.
The create_voice method returns a voice ID. You can use this ID for CosyVoice speech synthesis as a voice.
def create_voice(self, target_model: str, prefix: str, url: str) -> str:
'''
Create a voice
param: target_model The model used for voice cloning. Supported models are cosyvoice-v1 and cosyvoice-v2.
param: prefix A custom prefix for the voice. Only digits and lowercase letters are allowed, with a maximum of 10 characters.
param: url The URL of the audio file used to clone the voice. This URL must be publicly accessible.
return: The voice ID
'''
Java
You can clone a voice using the createVoice method of the VoiceEnrollmentService class. Import the VoiceEnrollmentService class as follows: import com.alibaba.dashscope.audio.ttsv2.enrollment.VoiceEnrollmentService;.
The getVoiceId method of the Voice class, returned by createVoice, obtains the voice ID. You can use this ID for CosyVoice speech synthesis as a voice.
/**
* Create a voice
*
* @param targetModel The model used for voice cloning. Supported models are cosyvoice-v1 and cosyvoice-v2.
* @param prefix A custom prefix for the voice. Only digits and lowercase letters are allowed, with a maximum of 10 characters.
* @param url The URL of the audio file used to clone the voice. This URL must be publicly accessible.
* @return Voice object
* @throws NoApiKeyException If the API key is empty
* @throws InputRequiredException If a required parameter is empty
*/
public Voice createVoice(String targetModel, String prefix, String url) throws NoApiKeyException, InputRequiredException
RESTful
Basic information
URL | |
Request method | POST |
Request headers | |
Message body | The message body contains all request parameters. Omit optional fields as needed: |
Request parameters
Click to view the request example
curl -X POST https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "voice-enrollment",
"input": {
"action": "create_voice",
"target_model": "cosyvoice-v1",
"prefix": "testpfx",
"url": "https://yourAudioFileUrl"
}
}'
Parameter | Type | Default | Required | Description |
|---|---|---|---|---|
model | string | - | Yes | Fixed as |
action | string | - | Yes | Fixed as |
target_model | string | - | Yes | The model used for voice cloning. Supported models are cosyvoice-v1 and cosyvoice-v2. |
prefix | string | - | Yes | A custom prefix for the voice. Only digits and lowercase letters are allowed, with a maximum of 10 characters. |
url | string | - | Yes | The URL of the audio file used to clone the voice. This URL must be publicly accessible. For more information, see Audio Recording Guide. |
Response parameters
Click to view the response example
{
"output": {
"voice_id": "yourVoiceId"
},
"usage": {
"count": 1
},
"request_id": "yourRequestId"
}
Parameter | Type | Description |
|---|---|---|
voice_id | string | The voice ID. Use this ID for CosyVoice speech synthesis as a voice. |
Query all voices
Python
You can use the list_voices method of the VoiceEnrollmentService class to query all voices. Import the VoiceEnrollmentService class as follows: from dashscope.audio.tts_v2 import VoiceEnrollmentService.
There are two timbre states:
- UNDEPLOYED: cannot be invoked
- Callable
def list_voices(self, prefix=None, page_index: int = 0, page_size: int = 10) -> List[dict]:
'''
Queries all created voices.
param: prefix The voice prefix. If set to None, all voices are returned.
param: page_index The page index for the query.
param: page_size The number of entries per page.
return: List[dict] A list of voices. Each entry contains the voice ID, creation time, modification time, and status.
'''
Response example:
[
{
"gmt_create": "2024-09-13 11:29:41",
"voice_id": "yourVoiceId",
"gmt_modified": "2024-09-13 11:29:41",
"status": "OK"
},
{
"gmt_create": "2024-09-13 13:22:38",
"voice_id": "yourVoiceId",
"gmt_modified": "2024-09-13 13:22:38",
"status": "OK"
}
]
Response parameters:
Parameter | Type | Description |
|---|---|---|
voice_id | string | The voice ID. You can use this ID for CosyVoice speech synthesis. |
gmt_create | string | The time when the voice was created. |
gmt_modified | string | The time when the voice was last modified. |
status | string | The status.
|
Java
You can use the listVoice method of the VoiceEnrollmentService class to query all voices. Import the VoiceEnrollmentService class as follows: import com.alibaba.dashscope.audio.ttsv2.enrollment.VoiceEnrollmentService;.
Two timbre states are available:
- UNDEPLOYED: The voice cannot be invoked.
- OK: Callable
/**
* Queries all created voices. The default page index is 0 and the default page size is 10.
*
* @param prefix The custom voice prefix. It can contain only digits and lowercase letters and must be less than 10 characters long. This parameter can be null.
* @return Voice[] An array of voice objects.
* @throws NoApiKeyException If the API key is empty.
* @throws InputRequiredException If a required parameter is empty.
*/
public Voice[] listVoice(String prefix) throws NoApiKeyException, InputRequiredException
/**
* Queries all created voices.
*
* @param prefix The custom voice prefix. It can contain only digits and lowercase letters and must be less than 10 characters long.
* @param pageIndex The page index for the query.
* @param pageSize The number of entries per page.
* @return Voice[] An array of voice objects.
* @throws NoApiKeyException If the API key is empty.
* @throws InputRequiredException If a required parameter is empty.
*/
public Voice[] listVoice(String prefix, int pageIndex, int pageSize) throws NoApiKeyException, InputRequiredException
Response example:
[
{
"gmt_create": "2024-09-13 11:29:41",
"voice_id": "yourVoiceId",
"gmt_modified": "2024-09-13 11:29:41",
"status": "OK"
},
{
"gmt_create": "2024-09-13 13:22:38",
"voice_id": "yourVoiceId",
"gmt_modified": "2024-09-13 13:22:38",
"status": "OK"
}
]
Response parameters:
Parameter | Type | Description |
|---|---|---|
voice_id | string | The voice ID. You can use this ID for CosyVoice speech synthesis. |
gmt_create | string | The time when the voice was created. |
gmt_modified | string | The time when the voice was last modified. |
status | string | The status.
|
RESTful
Basic information
URL | |
Request method | POST |
Request header | |
Message body | The message body that contains all request parameters is as follows. Optional fields can be omitted as needed: |
Request parameters
Click to view a request example
curl -X POST https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "voice-enrollment",
"input": {
"action": "list_voice",
"prefix": "testpfx",
"page_index": 0,
"page_size": 10
}
}'
Parameter | Type | Default value | Required | Description |
|---|---|---|---|---|
model | string | - | Yes | Set to |
action | string | - | Yes | Set to |
prefix | string | null | No | The custom voice prefix. It can contain only digits and lowercase letters and must be less than 10 characters long. |
page_index | integer | 0 | No | The page index. The value starts from 0. |
page_size | integer | 10 | No | The number of entries on each page. |
Response parameters
Click to view a response example
{
"output": {
"voice_list": [
{
"gmt_create": "2024-12-11 13:38:02",
"voice_id": "yourVoiceId",
"gmt_modified": "2024-12-11 13:38:02",
"status": "OK"
}
]
},
"usage": {
"count": 1
},
"request_id": "yourRequestId"
}
Parameter | Type | Description |
|---|---|---|
voice_id | string | The voice ID. You can use this ID for CosyVoice speech synthesis. |
gmt_create | string | The time when the voice was created. |
gmt_modified | string | The time when the voice was last modified. |
status | string | The status.
|
Query a specific voice
Python
You can call the query_voices method of the VoiceEnrollmentService class to query a specific voice. Import the VoiceEnrollmentService class as follows: from dashscope.audio.tts_v2 import VoiceEnrollmentService.
def query_voices(self, voice_id: str) -> List[str]:
'''
Query all created voices.
param: voice_id: voice to query
return: bytes: audio used to register the voice
'''
Response example:
{
"gmt_create": "2024-09-13 11:29:41",
"resource_link": "https://yourAudioFileUrl",
"target_model": "cosyvoice-v1",
"gmt_modified": "2024-09-13 11:29:41",
"status": "OK"
}
Response parameters:
Parameter | Type | Description |
|---|---|---|
resource_link | string | The URL of the audio file for cloning. |
target_model | string | The model used for voice cloning. |
gmt_create | string | The time when the voice was created. |
gmt_modified | string | The time when the voice was last modified. |
status | string | The status.
|
Java
You can call the queryVoice method of the VoiceEnrollmentService class to query a specific voice. Import the VoiceEnrollmentService class as follows: import com.alibaba.dashscope.audio.ttsv2.enrollment.VoiceEnrollmentService;.
/**
* Queries a specific voice.
*
* @param voiceId The ID of the voice to query.
* @return Voice A Voice object that contains the status information and the URL of the audio file for cloning.
* @throws NoApiKeyException If the API key is empty.
* @throws InputRequiredException If a required parameter is empty.
*/
public Voice queryVoice(String voiceId) throws NoApiKeyException, InputRequiredException
Response example:
{
"gmt_create": "2024-09-13 11:29:41",
"resource_link": "https://yourAudioFileUrl",
"target_model": "cosyvoice-v1",
"gmt_modified": "2024-09-13 11:29:41",
"status": "OK"
}
Response parameters:
Parameter | Type | Description |
|---|---|---|
resource_link | string | The URL of the audio file for cloning. |
target_model | string | The model used for voice cloning. |
gmt_create | string | The time when the voice was created. |
gmt_modified | string | The time when the voice was last modified. |
status | string | The status.
|
RESTful
Basic information
URL | |
Request method | POST |
Request header | |
Message body | The following message body contains all request parameters. You can omit optional fields. |
Request parameters
Click to view a request example
curl -X POST https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "voice-enrollment",
"input": {
"action": "query_voice",
"voice_id": "yourVoiceId"
}
}'
Parameter | Type | Default value | Required | Description |
|---|---|---|---|---|
model | string | - | Yes | Set to |
action | string | - | Yes | Set to |
voice_id | string | - | Yes | The ID of the voice to query. |
Response parameters
Click to view a response example
{
"output": {
"gmt_create": "2024-12-11 13:38:02",
"resource_link": "https://yourAudioFileUrl",
"target_model": "cosyvoice-v1",
"gmt_modified": "2024-12-11 13:38:02",
"status": "OK"
},
"usage": {
"count": 1
},
"request_id": "2450f969-d9ea-9483-bafc-************"
}
Parameter | Type | Description |
|---|---|---|
resource_link | string | The URL of the audio file for cloning. |
target_model | string | The model used for voice cloning. |
gmt_create | string | The time when the voice was created. |
gmt_modified | string | The time when the voice was last modified. |
status | string | The status.
|
Update voice
Python
You can update a voice using the update_voice method of the VoiceEnrollmentService class. Import the VoiceEnrollmentService class as follows: from dashscope.audio.tts_v2 import VoiceEnrollmentService.
def update_voice(self, voice_id: str, url: str) -> None:
'''
Update a voice.
param: voice_id The voice ID.
param: url The URL of the audio file for cloning.
'''
Java
You can update a voice using the updateVoice method of the VoiceEnrollmentService class. Import the VoiceEnrollmentService class as follows: import com.alibaba.dashscope.audio.ttsv2.enrollment.VoiceEnrollmentService;.
/**
* Update a voice.
*
* @param voiceId The voice to update.
* @param url The URL of the audio file for cloning.
* @throws NoApiKeyException if the API key is empty.
* @throws InputRequiredException if a required parameter is empty.
*/
public void updateVoice(String voiceId, String url)
throws NoApiKeyException, InputRequiredException
RESTful
Basic information
URL | |
Request method | POST |
Request header | |
Message body | The message body that contains all request parameters is as follows. You can omit optional fields as needed. |
Request parameters
Click to view a request example
curl -X POST https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "voice-enrollment",
"input": {
"action": "update_voice",
"voice_id": "yourVoiceId",
"url": "https://yourAudioFileUrl"
}
}'
Parameter | Type | Default value | Required | Description |
|---|---|---|---|---|
model | string | - | Yes | Set to |
action | string | - | Yes | Set to |
voice_id | string | - | Yes | The ID of the voice to update. |
url | string | - | Yes | The URL of the audio file used to update the voice. The URL must be accessible over the public network. For more information about how to record audio, see Audio Recording Guide. |
Click to view a response example
{
"output": {},
"usage": {
"count": 1
},
"request_id": "yourRequestId"
}
Delete a voice
Python
To delete a voice, call the delete_voice method of the VoiceEnrollmentService class. The VoiceEnrollmentService class is imported as follows: from dashscope.audio.tts_v2 import VoiceEnrollmentService.
def delete_voice(self, voice_id: str) -> None:
'''
Delete a voice.
Args:
voice_id: The ID of the voice to delete.
'''
Java
You can delete a voice using the VoiceEnrollmentService class's deleteVoice method. The VoiceEnrollmentService class is imported as follows: import com.alibaba.dashscope.audio.ttsv2.enrollment.VoiceEnrollmentService;.
/**
* Delete a voice.
*
* @param voiceId The ID of the voice to delete.
* @throws NoApiKeyException If the API key is empty.
* @throws InputRequiredException If a required parameter is empty.
*/
public void deleteVoice(String voiceId) throws NoApiKeyException, InputRequiredException
RESTful
Basic information
URL | |
HTTP method | POST |
Request headers | |
Request body | The request body includes all required parameters. Omit optional fields as needed: |
Request parameters
Click to view the request example
curl -X POST https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "voice-enrollment",
"input": {
"action": "delete_voice",
"voice_id": "yourVoiceId"
}
}'
Parameter | Type | Default value | Required | Description |
|---|---|---|---|---|
model | string | - | Yes | Set to |
action | string | - | Yes | Set to |
voice_id | string | - | Yes | The ID of the voice to delete. |
Click to view the response example
{
"output": {},
"usage": {
"count": 1
},
"request_id": "yourRequestId"
}
Use a cloned voice for speech synthesis
This document describes the voice management API. You can use it to create, query, update, and delete voices. To use a cloned voice for speech synthesis, follow these steps. Make sure to use the same account for both voice cloning and speech synthesis:
-
Obtain the voice ID
Call the Create Voice or Query Voice List API to obtain the voice ID.
-
Call the CosyVoice speech synthesis API
Select the API documentation for your programming language. Pass the voice ID that you obtained in Step 1 as the
voiceparameter to the synthesis API:- Java: Java SDK
- Python: Python SDK
- Other programming languages (such as Go, C#, PHP, and Node.js): WebSocket API
The following code samples show how to clone a voice, use the CosyVoice-v2 model to call the cloned voice, and transform the text "How is the weather today?" into speech.
Note
- The concurrent call limit for the
VoiceEnrollmentServiceAPI is 10 RPS. - The concurrent call limit for speech synthesis with a cloned voice is 3 RPS, which is the same as for standard CosyVoice voices.
Important
Make sure thetargetModel field used for cloning and the model field used for the speech synthesis call have the same value.import os
import dashscope
from dashscope.audio.tts_v2 import VoiceEnrollmentService, SpeechSynthesizer
dashscope.api_key = os.getenv('DASHSCOPE_API_KEY') # If you have not configured the environment variable, provide your API key here.
url = "https://your-audio-file-url" # Replace this with the actual URL.
prefix = 'prefix'
target_model = "cosyvoice-v2"
# Create a service instance for voice enrollment.
service = VoiceEnrollmentService()
# Call the create_voice method to clone the voice and generate a voice_id.
voice_id = service.create_voice(target_model=target_model, prefix=prefix, url=url)
print("requestId: ", service.get_last_request_id())
print(f"your voice id is {voice_id}")
# Use the cloned voice for speech synthesis.
synthesizer = SpeechSynthesizer(model=target_model, voice=voice_id)
audio = synthesizer.call("How is the weather today?")
print("requestId: ", synthesizer.get_last_request_id())
# Save the synthesized audio to a local file.
with open("output.mp3", "wb") as f:
f.write(audio)
import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesisParam;
import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesizer;
import com.alibaba.dashscope.audio.ttsv2.enrollment.Voice;
import com.alibaba.dashscope.audio.ttsv2.enrollment.VoiceEnrollmentService;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import static java.lang.System.exit;
public class VoiceEnrollmentSampleCodes {
public static String apiKey = System.getenv("DASHSCOPE_API_KEY"); // If you have not configured the environment variable, provide your API key here.
private static String fileUrl = "https://your-audio-file-url"; // Replace this with the actual URL.
private static String prefix = "prefix";
private static String targetModel = "cosyvoice-v2";
public static void main(String[] args)
throws NoApiKeyException, InputRequiredException {
// Clone the voice.
VoiceEnrollmentService service = new VoiceEnrollmentService(apiKey);
Voice myVoice = service.createVoice(targetModel, prefix, fileUrl);
System.out.println("RequestId: " + service.getLastRequestId());
System.out.println("your voice id is " + myVoice.getVoiceId());
// Use the cloned voice to synthesize text into speech.
SpeechSynthesisParam param = SpeechSynthesisParam.builder()
.apiKey(apiKey)
.model(targetModel)
.voice(myVoice.getVoiceId())
.build();
SpeechSynthesizer synthesizer = new SpeechSynthesizer(param, null);
ByteBuffer audio = synthesizer.call("How is the weather today?");
// Save the synthesized speech to a file.
System.out.println("TTS RequestId: " + synthesizer.getLastRequestId());
File file = new File("output.mp3");
try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write(audio.array());
} catch (IOException e) {
throw new RuntimeException(e);
}
exit(0);
}
}
Error codes
If an error occurs during a call in the Python SDK, the system throws a VoiceEnrollmentException. This exception includes a status code, an error code, and an error message.
class VoiceEnrollmentException(Exception):
def __init__(self, status_code: int, code: str, error_message: str)
If an error occurs during a call in the Java SDK, the system throws either a NoApiKeyException or a InputRequiredException.
The following table lists the error codes for Voice Clone.
HTTP return code | Error code | Error message (The specific message may vary by scenario.) | Description |
|---|---|---|---|
415 | BadRequest.UnsupportedFileFormat | File format unsupported. | The file format is not supported. |
416 | BadRequest.ResourceNotExist | The required resource does not exist. | The resource does not exist for an update, query, or delete API call. |
430 | Audio.DecoderError | Failed to decode the audio file. | Failed to decode the audio file. |
430 | Audio.FileSizeExceed | File too large | The file size exceeds the limit. The voice clone file must be smaller than 10 MB. |
430 | Audio.AudioRateError | File sample rate unsupported | The file sample rate is not supported. The sample rate must be 16 kHz or higher. |
430 | Audio.AudioSilentError | Silent file unsupported | The file contains only silence, or the non-silent part is too short. Voice cloning requires more than 10 seconds of valid audio. |
500 | InternalError | Audio preprocess server error | The audio file is invalid. For example, the audio has issues, such as noise or fluctuating volume. |
For more information about common error codes, see Error messages.