Skip to main content
The /v1/studio endpoints create and edit Studio projects. They do not generate speech, charge generation credits, or export audio; open the project in Studio for that. Creating or importing a project requires a paid Studio subscription and a free saved-project slot.

Project structure

Timeline positions, trims, and lengths are integer frames at 48,000 Hz. Silence is in milliseconds and fades are in seconds. The SDKs provide seconds_to_frames / secondsToFrames and frames_to_seconds / framesToSeconds.

Edit tokens and operation IDs

Every read and write returns the project’s current edit_token. Each project write needs two values:
  • expected_edit_token: the latest edit_token you received. If someone changed the project since, the write returns 409 with meta.latest_edit_token. Read the project again and reconcile before sending a new write; do not resend blindly.
  • operation_id: a new UUID for each write. If a write times out, resend the same body with the same operation_id; the server returns the original result instead of applying it twice. Reusing an operation_id with a different body returns 409.
Project creation and import take operation_id only. File rename and delete use the file’s revision as expected_revision instead of an edit token.

Import a script

Import creates a complete project in one step: up to 20 chapters with up to 400 clips each. Every voice_id is checked first; if any is unavailable, nothing is created. Label chapters and clips with client_ref to find their IDs in client_refs.
Clips without voice_id use default_voice_id. To start from an empty project instead, create a project; it contains one chapter with one empty clip.

Edit clips

Omitted fields keep their values. Empty instructions and a null trailing_silence_ms inherit the project defaults; a trailing_silence_ms of 0 means no pause.
A clip script is one paragraph; line breaks inside it become spaces. Changing the project’s default_silence_ms also makes clips with an explicit 0 ms silence inherit the new default. Assigning a voice to a clip never changes the voice itself; voice.available is false when a voice was deleted or is no longer accessible. Batch endpoints apply atomically: create or delete up to 400 clips, or update up to 100 clips, in one write.

Organize chapters

  • Deleting a chapter keeps it restorable. Pass move_to_chapter_id to move its clips to another chapter first; otherwise they stay with the deleted chapter. A project keeps at least one active chapter and one clip.
  • Reorder requests list every active chapter, or every clip in a chapter, exactly once.
  • A project holds up to 20 active chapters with 400 clips each.

Arrange background audio

Upload a file, add an audio track, then place the file on the track as an instance.
files.upload registers the file, uploads it to a signed URL without your API key, completes the upload, and waits until status is ready. Reusing the same operation_id resumes an interrupted upload. Without project_id, the file goes to your personal library. If processing fails, inspect error_code and error_message with files.get, then call files.retry. Instance placement:
  • length longer than the trimmed audio repeats it to fill the region.
  • {"mode": "follow", "clip_id": "clp_…", "edge": "start", "offset": 0} starts the instance relative to a clip. When the clip moves to another chapter, audio that follows it on a chapter track moves too. If the clip is deleted, the instance reports anchor_missing in issues.
  • Instances on the same track cannot overlap.
  • Set chapter_id on a track to limit it to one chapter; omit it to span the whole project.
Deleting a track or instance keeps the audio file. A file that instances still use cannot be deleted.

TypeScript

The TypeScript SDK uses camelCase fields and method names.

CLI

The CLI uses the API’s snake_case JSON and generates a missing operation_id. See Studio CLI for every command.