curl --request PUT \
--url https://api.rask.ai/v3/projects/{project_id}/speakers/{speaker_id}/voice \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'If-Match: <if-match>' \
--data '
{
"voice_id": "e9b3d7f1-4a8c-4e2b-9d6f-1c5a9e3b7d03"
}
'{
"object": "speaker_voice_update_result",
"speaker": {
"object": "speaker",
"id": "SPEAKER_00",
"label": "Speaker 1",
"number": 1,
"project_id": "6f1c2b7e-8a4d-4e3f-9b5c-1d0a7e2f3c58",
"voice": {
"id": "e9b3d7f1-4a8c-4e2b-9d6f-1c5a9e3b7d03",
"type": "library_clone",
"name": "Maria (narrator)",
"language": "es-es",
"voice_clone_id": "2c9e5a1f-8d3b-4f7e-a1c6-5e9b3d7f1a84",
"selectable": true
},
"voice_origin": "assigned",
"instant_clone_settings": null,
"segment_count": 2,
"speech_seconds": 5.8,
"voice_pending": false,
"instant_clone": {
"eligible": true,
"reason": null,
"min_speech_seconds": 1.5
},
"etag": "\"v-5e4d3c2b1a0f9e8d\""
},
"effects": {
"needs_redub_segment_ids": [
"5f0e2c7a-1b3d-4e6f-8a9c-2d4e6f8a0b11",
"2c7e9a4f-3d1b-4f8e-a6c2-9b5d1f3e7a33"
],
"audio_dropped_segment_ids": [
"5f0e2c7a-1b3d-4e6f-8a9c-2d4e6f8a0b11",
"2c7e9a4f-3d1b-4f8e-a6c2-9b5d1f3e7a33"
],
"next_dub_mode": "changed_segments"
},
"warnings": []
}Speakers
Set a speaker's voice
Assigns a voice from listProjectVoices to one speaker.
PUT
/
projects
/
{project_id}
/
speakers
/
{speaker_id}
/
voice
curl --request PUT \
--url https://api.rask.ai/v3/projects/{project_id}/speakers/{speaker_id}/voice \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'If-Match: <if-match>' \
--data '
{
"voice_id": "e9b3d7f1-4a8c-4e2b-9d6f-1c5a9e3b7d03"
}
'{
"object": "speaker_voice_update_result",
"speaker": {
"object": "speaker",
"id": "SPEAKER_00",
"label": "Speaker 1",
"number": 1,
"project_id": "6f1c2b7e-8a4d-4e3f-9b5c-1d0a7e2f3c58",
"voice": {
"id": "e9b3d7f1-4a8c-4e2b-9d6f-1c5a9e3b7d03",
"type": "library_clone",
"name": "Maria (narrator)",
"language": "es-es",
"voice_clone_id": "2c9e5a1f-8d3b-4f7e-a1c6-5e9b3d7f1a84",
"selectable": true
},
"voice_origin": "assigned",
"instant_clone_settings": null,
"segment_count": 2,
"speech_seconds": 5.8,
"voice_pending": false,
"instant_clone": {
"eligible": true,
"reason": null,
"min_speech_seconds": 1.5
},
"etag": "\"v-5e4d3c2b1a0f9e8d\""
},
"effects": {
"needs_redub_segment_ids": [
"5f0e2c7a-1b3d-4e6f-8a9c-2d4e6f8a0b11",
"2c7e9a4f-3d1b-4f8e-a6c2-9b5d1f3e7a33"
],
"audio_dropped_segment_ids": [
"5f0e2c7a-1b3d-4e6f-8a9c-2d4e6f8a0b11",
"2c7e9a4f-3d1b-4f8e-a6c2-9b5d1f3e7a33"
],
"next_dub_mode": "changed_segments"
},
"warnings": []
}For the speaker’s own
instant_clone voice, instant_clone_settings (accent, expressiveness) may be set. If the voice changes, the speaker’s segments lose their audio and become outdated; the result says which mode the next dub will use. A voice with meaning_first_compatible: false on a meaning-first project warns meaning_first_disabled.
When to use: to give a speaker another voice (stock, library clone or their own instant clone); then estimateDub and createDub with mode changed_segments.
Side effects: The project’s pipeline_status becomes voice_edited when the voice changed; voice_origin becomes assigned.
Cost: Free (the redub is priced by estimateDub). A new instant clone counts against the daily clone-creation cap (429 rate_limited, policy clone-create-day).
Idempotency: Idempotency-Key accepted (SDKs send one); retries within 24 h replay the first response.
Concurrency: If-Match with the current speaker ETag is required (428 if missing or *, 412 with current_etag if stale). On 412 re-read, re-apply once and retry.
Plan: an instant_clone voice -> instant_voice_clone.
Required scopes: voices:write
Errors: dub_in_progress (409), voice_not_in_pool (422), instant_clone_not_available (422), feature_not_in_plan (403)Authorizations
API key from Settings -> API keys, sent as Authorization: Bearer <key> (SDK environment variable RASK_API_KEY). Bound to one workspace and one acting user. Operations list the scopes they need (OpenAPI 3.1 scopes on a bearer scheme).
Scopes
voices:write
Headers
Optional. A unique key per logical request (SDKs send a bare UUIDv4; an RFC 9651 quoted string is accepted and unquoted); reuse it unchanged on retries to replay the first response.
Required string length:
1 - 255Pattern:
^[\x20-\x7E]+$Required: the speaker's current ETag (getSpeaker or listSpeakers).
Maximum string length:
128Path Parameters
Project id (from createProject or listProjects).
Maximum string length:
64Speaker id.
Maximum string length:
11Pattern:
^SPEAKER_\d{2,3}$Body
application/json
Response
OK: SpeakerVoiceUpdateResult.
Result of updateSpeakerVoice. Transient (no id).