curl --location 'https://api.inworld.ai/voices/v1/pvcVoices' \
--header "Authorization: Basic $INWORLD_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"displayName": "my-professional-voice",
"languageCode": "en-US"
}'import requests
url = "https://api.inworld.ai/voices/v1/pvcVoices"
headers = {
"Authorization": "Basic <api-key>",
"Content-Type": "application/json"
}
payload = {
"displayName": "my-professional-voice",
"languageCode": "en-US"
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())const url = 'https://api.inworld.ai/voices/v1/pvcVoices';
const response = await fetch(url, {
method: 'POST',
headers: {
'Authorization': 'Basic <api-key>',
'Content-Type': 'application/json',
},
body: JSON.stringify({
displayName: 'my-professional-voice',
languageCode: 'en-US',
}),
});
const data = await response.json();
console.log(data);{
"name": "workspaces/your_workspace_id/pvcVoices/my-professional-voice",
"voiceId": "my-professional-voice",
"displayName": "my-professional-voice",
"languageCode": "en-US",
"state": "PVC_VOICE_STATE_DRAFT",
"incarnationId": "a1b2c3d4",
"samples": [],
"createTime": "2026-08-31T12:00:00Z",
"updateTime": "2026-08-31T12:00:00Z"
}{
"code": 123,
"message": "<string>",
"details": [
{
"@type": "<string>"
}
]
}Create a PVC voice
Creates a new Professional Voice Clone in PVC_VOICE_STATE_DRAFT. Upload audio samples with Upload PVC voice samples, then start training with Train a PVC voice.
curl --location 'https://api.inworld.ai/voices/v1/pvcVoices' \
--header "Authorization: Basic $INWORLD_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"displayName": "my-professional-voice",
"languageCode": "en-US"
}'import requests
url = "https://api.inworld.ai/voices/v1/pvcVoices"
headers = {
"Authorization": "Basic <api-key>",
"Content-Type": "application/json"
}
payload = {
"displayName": "my-professional-voice",
"languageCode": "en-US"
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())const url = 'https://api.inworld.ai/voices/v1/pvcVoices';
const response = await fetch(url, {
method: 'POST',
headers: {
'Authorization': 'Basic <api-key>',
'Content-Type': 'application/json',
},
body: JSON.stringify({
displayName: 'my-professional-voice',
languageCode: 'en-US',
}),
});
const data = await response.json();
console.log(data);{
"name": "workspaces/your_workspace_id/pvcVoices/my-professional-voice",
"voiceId": "my-professional-voice",
"displayName": "my-professional-voice",
"languageCode": "en-US",
"state": "PVC_VOICE_STATE_DRAFT",
"incarnationId": "a1b2c3d4",
"samples": [],
"createTime": "2026-08-31T12:00:00Z",
"updateTime": "2026-08-31T12:00:00Z"
}{
"code": 123,
"message": "<string>",
"details": [
{
"@type": "<string>"
}
]
}en-US is currently supported for Professional Voice Cloning. languageCode is immutable after creation.usedPvcVoiceSlots / maxPvcVoiceSlots); when all slots are taken, creation is refused until a slot is freed or the plan is upgraded. On-Demand accounts also need a payment method on file.
Creates a new voice in PVC_VOICE_STATE_DRAFT. A draft voice has no audio yet — build it out with the rest of this API before training:
Upload audio samples
Train
PVC_VOICE_STATE_QUEUED.Poll until ready
state progress to PVC_VOICE_STATE_READY (or PVC_VOICE_STATE_FAILED). Once ready, use the voiceId anywhere you’d use a regular voice, e.g. Synthesize speech.Authorizations
Your API key. Read permissions are required for GET endpoints. Write permissions are required for POST, PATCH, and DELETE endpoints.
For Basic authentication, please populate Basic $INWORLD_API_KEY. You can create a key in one command with the Inworld CLI: inworld workspace add-key.
Body
Request message for CreatePvcVoice.
The human-readable name shown anywhere the voice is listed or selected. The voice's voiceId is derived from this value; renaming the voice later does not change its voiceId.
The voice's language as a BCP-47-shaped locale string. Currently only en-US is supported for Professional Voice Cloning; defaults to en-US if omitted. Immutable after creation.
Response
A successful response.
A Professional Voice Clone resource.
Resource name. Format: workspaces/{workspace}/pvcVoices/{voice}.
Voice ID, derived from displayName at creation time. Use this value as {voiceId} on every other PVC endpoint, and as the voiceId in TTS synthesis requests once the voice is PVC_VOICE_STATE_READY.
The human-readable name shown anywhere the voice is listed or selected.
The voice's language as a BCP-47-shaped locale string, e.g. en-US. Immutable after creation.
Lifecycle state of a PVC voice.
PVC_VOICE_STATE_DRAFT: Editable. Samples can be added, trimmed, or removed, and metadata can be updated.PVC_VOICE_STATE_QUEUED: Training requested; waiting for a training slot.PVC_VOICE_STATE_TRAINING: Actively training.PVC_VOICE_STATE_READY: Training succeeded. Usable for TTS synthesis; permanent — cannot be deleted through this API.PVC_VOICE_STATE_FAILED: Training failed. Editing the voice (e.g. renaming it, or adding/removing a sample) returns it toPVC_VOICE_STATE_DRAFTwith its remaining samples intact.
PVC_VOICE_STATE_UNSPECIFIED, PVC_VOICE_STATE_DRAFT, PVC_VOICE_STATE_QUEUED, PVC_VOICE_STATE_TRAINING, PVC_VOICE_STATE_READY, PVC_VOICE_STATE_FAILED Populated on a PVC voice when its state is PVC_VOICE_STATE_FAILED.
Show child attributes
Show child attributes
Identifier that stays stable across edits to the same voice, and changes each time it is retrained. Use it to tell two reads of the same voiceId apart across a retrain.
Audio samples currently attached to the voice.
Show child attributes
Show child attributes