cURL
curl -sG 'https://api.inworld.ai/voices/v1/pvcVoices' \
-H "Authorization: Basic $INWORLD_API_KEY" \
--data-urlencode 'pageSize=20'import requests
url = "https://api.inworld.ai/voices/v1/pvcVoices"
headers = {"Authorization": "Basic <api-key>"}
params = {"pageSize": 20}
while True:
response = requests.get(url, headers=headers, params=params)
data = response.json()
for voice in data.get("pvcVoices", []):
print(voice["displayName"], voice["state"])
next_token = data.get("nextPageToken", "")
if not next_token:
break
params["pageToken"] = next_tokenconst base = 'https://api.inworld.ai/voices/v1/pvcVoices';
const headers = { 'Authorization': 'Basic <api-key>' };
let pageToken = '';
do {
const params = new URLSearchParams({
pageSize: '20',
...(pageToken && { pageToken }),
});
const res = await fetch(`${base}?${params}`, { headers });
const data = await res.json();
for (const voice of data.pvcVoices ?? []) {
console.log(voice.displayName, voice.state);
}
pageToken = data.nextPageToken ?? '';
} while (pageToken);{
"pvcVoices": [
{
"name": "workspaces/your_workspace_id/pvcVoices/my-professional-voice",
"voiceId": "my-professional-voice",
"displayName": "my-professional-voice",
"languageCode": "en-US",
"state": "PVC_VOICE_STATE_READY",
"incarnationId": "a1b2c3d4",
"createTime": "2026-08-31T12:00:00Z",
"updateTime": "2026-08-31T12:41:00Z"
}
],
"nextPageToken": ""
}{
"code": 123,
"message": "<string>",
"details": [
{
"@type": "<string>"
}
]
}Professional Voice Cloning
List PVC voices
Lists Professional Voice Clones owned by the calling workspace, across every state (draft, queued, training, ready, and failed).
GET
/
voices
/
v1
/
pvcVoices
cURL
curl -sG 'https://api.inworld.ai/voices/v1/pvcVoices' \
-H "Authorization: Basic $INWORLD_API_KEY" \
--data-urlencode 'pageSize=20'import requests
url = "https://api.inworld.ai/voices/v1/pvcVoices"
headers = {"Authorization": "Basic <api-key>"}
params = {"pageSize": 20}
while True:
response = requests.get(url, headers=headers, params=params)
data = response.json()
for voice in data.get("pvcVoices", []):
print(voice["displayName"], voice["state"])
next_token = data.get("nextPageToken", "")
if not next_token:
break
params["pageToken"] = next_tokenconst base = 'https://api.inworld.ai/voices/v1/pvcVoices';
const headers = { 'Authorization': 'Basic <api-key>' };
let pageToken = '';
do {
const params = new URLSearchParams({
pageSize: '20',
...(pageToken && { pageToken }),
});
const res = await fetch(`${base}?${params}`, { headers });
const data = await res.json();
for (const voice of data.pvcVoices ?? []) {
console.log(voice.displayName, voice.state);
}
pageToken = data.nextPageToken ?? '';
} while (pageToken);{
"pvcVoices": [
{
"name": "workspaces/your_workspace_id/pvcVoices/my-professional-voice",
"voiceId": "my-professional-voice",
"displayName": "my-professional-voice",
"languageCode": "en-US",
"state": "PVC_VOICE_STATE_READY",
"incarnationId": "a1b2c3d4",
"createTime": "2026-08-31T12:00:00Z",
"updateTime": "2026-08-31T12:41:00Z"
}
],
"nextPageToken": ""
}{
"code": 123,
"message": "<string>",
"details": [
{
"@type": "<string>"
}
]
}Returns PVC voices in every lifecycle state — draft, queued, training, ready, and failed — for the workspace resolved from your API key. There’s no server-side
state filter yet; filter the state field on the client if you only want, for example, ready voices.PVC_VOICE_STATE_READY here, it’s also returned alongside your other voices from List voices (source = "PVC").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.
Query Parameters
Maximum number of voices to return per page.
Opaque pagination cursor from a previous response's nextPageToken. Pass it back unchanged to retrieve the next page.