---
title: "Documents and speakers API"
description: "Every section has a versioned document of narration and dialogue blocks attributed to speakers. Read the document before editing it or generating audio, and list the project's speakers and casting."
canonical_url: https://lyricwinter.com/docs/api/documents
markdown_url: https://lyricwinter.com/docs/api/documents.md
last_updated: 2026-10-01
status: beta
---
# LyricWinter API reference: Documents and speakers

> Every section has a versioned document of narration and dialogue blocks attributed to speakers. Read the document before editing it or generating audio, and list the project's speakers and casting.

The LyricWinter API is in beta. Base URL: `https://lyricwinter.com/api/v1`. Authenticate every request with `Authorization: Bearer lw_...`. Successful responses are wrapped as `{ "data": ..., "request_id": "req_..." }`. Machine-readable contract: https://lyricwinter.com/api/v1/openapi.json.

## Endpoints

- [Get a section document](https://lyricwinter.com/docs/api/documents#get-studio-document): `GET /studio/sections/{sectionId}/document`
- [Edit a section document](https://lyricwinter.com/docs/api/documents#save-studio-document): `PATCH /studio/sections/{sectionId}/document`
- [Import a speaker-labeled script](https://lyricwinter.com/docs/api/documents#import-studio-script): `POST /studio/sections/{sectionId}/script`
- [List project speakers](https://lyricwinter.com/docs/api/documents#get-studio-project-speaker-usage): `GET /studio/projects/{projectId}/speakers`
- [Assign a speaker's voice and model](https://lyricwinter.com/docs/api/documents#update-studio-project-speaker-casting): `PATCH /studio/projects/{projectId}/speakers/{speakerId}/casting`

### Get a section document

`GET /studio/sections/{sectionId}/document`

Scope: `studio:read` · Operation ID: `getStudioDocument`

Returns the section's current document: its `document_version`, blocks, the project's speakers and `speaker_registry_version`, and whether section sound effects are enabled. Read it before editing the section or generating audio.

#### Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `sectionId` | string, uuid | Yes |  |

#### Response 200

Canonical Studio document and optional recovery draft.

Fields inside `data`:

- `actor_user_id` (string, uuid; required): Authenticated caller; clients partition local recovery state by this ID.
- `project_id` (string, uuid; required)
- `document` (object; required): The canonical structured script of one section (studio-ast-2): its versions, speakers, and ordered blocks.
  - `blocks` (array of object, max 100000 items; required)
    - One of:
      - **kind: "speech"**
        - `block_version` (integer, > 0; required)
        - `content` (object; required)
          - `annotations` (array of object; required)
            - One of:
              - **kind: "exclusion"**
                - `end_utf16` (integer, ≥ 0; required)
                - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                - `kind` ("exclusion"; required)
                - `reason` (string, one of `speaker_label`, `stage_direction`, `metadata`, `user`; required)
                - `start_utf16` (integer, ≥ 0; required)
              - **kind: "pronunciation"**
                - `alphabet` (string, one of `ipa`, `x-sampa`, `cmu`, `alias`; required)
                - `end_utf16` (integer, ≥ 0; required)
                - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                - `kind` ("pronunciation"; required)
                - `start_utf16` (integer, ≥ 0; required)
                - `value` (string, 1–500 chars; required)
              - **kind: "extension"**
                - `end_utf16` (integer, ≥ 0; required)
                - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                - `kind` ("extension"; required)
                - `name` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
                - `namespace` (string, pattern ^[a-z][a-z0-9_.-]{0,63}$; required)
                - `payload` (object | null; required)
                - `start_utf16` (integer, ≥ 0; required)
                - `version` (integer, > 0; required)
          - `delivery_control_sets` (array of object, max 32 items; required)
            - `capability_revision` (string, 1–200 chars; required)
            - `directives` (array of StudioAstDeliveryDirective, max 256 items; required)
            - `format` (string, one of `eleven-v4-1`, `inworld-tts2-1`, `inworld-tts2-experimental-1`, `inworld-tts15-max-1`, `inworld-tts15-mini-1`, `fish-s2-inline-1`, `fish-s2.1-inline-1`, `fish-drama-3-inline-1`, `cartesia-sonic36-1`, `cartesia-sonic35-1`, `openai-gpt4o-mini-tts-1`, `openai-tts1-hd-1`, `openai-tts1-1`, `smallest-lightning31-1`, `chatterbox-classic-1`, `zyphra-zonos2-cloud-1`, `f5tts-v1-1`, `misotts-8b-1`; required)
            - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
            - `model` (string, 1–200 chars; required)
            - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
            - `provider_text_override` (string, 1–65536 chars, pattern [\s\S]*\S[\s\S]*; optional)
            - `schema_version` (string, one of `studio-delivery-control-set-1`, `studio-delivery-control-set-2`; required)
            - `settings` (array of StudioAstDeliverySetting, max 32 items; required)
            - `source_fingerprint` (string | null, pattern ^[0-9a-f]{64}$; required)
            - `source_utf16_length` (integer | null, ≥ 0; required)
          - `points` (array of object; required)
            - One of:
              - **kind: "timed_silence"**
                - `duration_ms` (integer, 1–300000; required)
                - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                - `kind` ("timed_silence"; required)
                - `offset_utf16` (integer, ≥ 0; required)
              - **kind: "extension"**
                - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                - `kind` ("extension"; required)
                - `name` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
                - `namespace` (string, pattern ^[a-z][a-z0-9_.-]{0,63}$; required)
                - `offset_utf16` (integer, ≥ 0; required)
                - `payload` (object | null; required)
                - `version` (integer, > 0; required)
          - `schema_version` ("studio-ast-2"; required)
          - `text` (string, max 65536 chars; required): Exact block text; at most 65,536 UTF-16 code units. Annotation, point, and delivery offsets are UTF-16 offsets into this string.
          - `type` ("text"; required)
        - `generation_profile_override` (object | null; required): Partial saved profile. New document mutations validate the effective inherited provider/model and options against StudioGenerationProfileRequest. The read schema stays permissive for historical profiles. Join options with speaker context; an override is not a standalone full profile.
          - `controls` (string, one of `strict`, `best_effort`; optional)
          - `fallback` (string, one of `strict`, `best_effort`; optional)
          - `model` (string, 1–200 chars; optional)
          - `options` (map of boolean | string | integer | number | array of StudioAstJsonValue | map of StudioAstJsonValue | null; optional)
          - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; optional)
        - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
        - `kind` ("speech"; required)
        - `placement` (any | null; required)
        - `speaker_id` (string | null, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
      - **kind: "narration"**
        - `block_version` (integer, > 0; required)
        - `content` (object; required)
          - `annotations` (array of object; required)
            - One of:
              - **kind: "exclusion"**
                - `end_utf16` (integer, ≥ 0; required)
                - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                - `kind` ("exclusion"; required)
                - `reason` (string, one of `speaker_label`, `stage_direction`, `metadata`, `user`; required)
                - `start_utf16` (integer, ≥ 0; required)
              - **kind: "pronunciation"**
                - `alphabet` (string, one of `ipa`, `x-sampa`, `cmu`, `alias`; required)
                - `end_utf16` (integer, ≥ 0; required)
                - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                - `kind` ("pronunciation"; required)
                - `start_utf16` (integer, ≥ 0; required)
                - `value` (string, 1–500 chars; required)
              - **kind: "extension"**
                - `end_utf16` (integer, ≥ 0; required)
                - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                - `kind` ("extension"; required)
                - `name` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
                - `namespace` (string, pattern ^[a-z][a-z0-9_.-]{0,63}$; required)
                - `payload` (object | null; required)
                - `start_utf16` (integer, ≥ 0; required)
                - `version` (integer, > 0; required)
          - `delivery_control_sets` (array of object, max 32 items; required)
            - `capability_revision` (string, 1–200 chars; required)
            - `directives` (array of StudioAstDeliveryDirective, max 256 items; required)
            - `format` (string, one of `eleven-v4-1`, `inworld-tts2-1`, `inworld-tts2-experimental-1`, `inworld-tts15-max-1`, `inworld-tts15-mini-1`, `fish-s2-inline-1`, `fish-s2.1-inline-1`, `fish-drama-3-inline-1`, `cartesia-sonic36-1`, `cartesia-sonic35-1`, `openai-gpt4o-mini-tts-1`, `openai-tts1-hd-1`, `openai-tts1-1`, `smallest-lightning31-1`, `chatterbox-classic-1`, `zyphra-zonos2-cloud-1`, `f5tts-v1-1`, `misotts-8b-1`; required)
            - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
            - `model` (string, 1–200 chars; required)
            - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
            - `provider_text_override` (string, 1–65536 chars, pattern [\s\S]*\S[\s\S]*; optional)
            - `schema_version` (string, one of `studio-delivery-control-set-1`, `studio-delivery-control-set-2`; required)
            - `settings` (array of StudioAstDeliverySetting, max 32 items; required)
            - `source_fingerprint` (string | null, pattern ^[0-9a-f]{64}$; required)
            - `source_utf16_length` (integer | null, ≥ 0; required)
          - `points` (array of object; required)
            - One of:
              - **kind: "timed_silence"**
                - `duration_ms` (integer, 1–300000; required)
                - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                - `kind` ("timed_silence"; required)
                - `offset_utf16` (integer, ≥ 0; required)
              - **kind: "extension"**
                - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                - `kind` ("extension"; required)
                - `name` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
                - `namespace` (string, pattern ^[a-z][a-z0-9_.-]{0,63}$; required)
                - `offset_utf16` (integer, ≥ 0; required)
                - `payload` (object | null; required)
                - `version` (integer, > 0; required)
          - `schema_version` ("studio-ast-2"; required)
          - `text` (string, max 65536 chars; required): Exact block text; at most 65,536 UTF-16 code units. Annotation, point, and delivery offsets are UTF-16 offsets into this string.
          - `type` ("text"; required)
        - `generation_profile_override` (object | null; required): Partial saved profile. New document mutations validate the effective inherited provider/model and options against StudioGenerationProfileRequest. The read schema stays permissive for historical profiles. Join options with speaker context; an override is not a standalone full profile.
          - `controls` (string, one of `strict`, `best_effort`; optional)
          - `fallback` (string, one of `strict`, `best_effort`; optional)
          - `model` (string, 1–200 chars; optional)
          - `options` (map of boolean | string | integer | number | array of StudioAstJsonValue | map of StudioAstJsonValue | null; optional)
          - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; optional)
        - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
        - `kind` ("narration"; required)
        - `placement` (any | null; required)
        - `speaker_id` (string | null, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
      - **kind: "unparsed"**
        - `block_version` (integer, > 0; required)
        - `content` (object; required)
          - `annotations` (array of object; required)
            - One of:
              - **kind: "exclusion"**
                - `end_utf16` (integer, ≥ 0; required)
                - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                - `kind` ("exclusion"; required)
                - `reason` (string, one of `speaker_label`, `stage_direction`, `metadata`, `user`; required)
                - `start_utf16` (integer, ≥ 0; required)
              - **kind: "pronunciation"**
                - `alphabet` (string, one of `ipa`, `x-sampa`, `cmu`, `alias`; required)
                - `end_utf16` (integer, ≥ 0; required)
                - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                - `kind` ("pronunciation"; required)
                - `start_utf16` (integer, ≥ 0; required)
                - `value` (string, 1–500 chars; required)
              - **kind: "extension"**
                - `end_utf16` (integer, ≥ 0; required)
                - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                - `kind` ("extension"; required)
                - `name` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
                - `namespace` (string, pattern ^[a-z][a-z0-9_.-]{0,63}$; required)
                - `payload` (object | null; required)
                - `start_utf16` (integer, ≥ 0; required)
                - `version` (integer, > 0; required)
          - `delivery_control_sets` (array of object, max 32 items; required)
            - `capability_revision` (string, 1–200 chars; required)
            - `directives` (array of StudioAstDeliveryDirective, max 256 items; required)
            - `format` (string, one of `eleven-v4-1`, `inworld-tts2-1`, `inworld-tts2-experimental-1`, `inworld-tts15-max-1`, `inworld-tts15-mini-1`, `fish-s2-inline-1`, `fish-s2.1-inline-1`, `fish-drama-3-inline-1`, `cartesia-sonic36-1`, `cartesia-sonic35-1`, `openai-gpt4o-mini-tts-1`, `openai-tts1-hd-1`, `openai-tts1-1`, `smallest-lightning31-1`, `chatterbox-classic-1`, `zyphra-zonos2-cloud-1`, `f5tts-v1-1`, `misotts-8b-1`; required)
            - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
            - `model` (string, 1–200 chars; required)
            - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
            - `provider_text_override` (string, 1–65536 chars, pattern [\s\S]*\S[\s\S]*; optional)
            - `schema_version` (string, one of `studio-delivery-control-set-1`, `studio-delivery-control-set-2`; required)
            - `settings` (array of StudioAstDeliverySetting, max 32 items; required)
            - `source_fingerprint` (string | null, pattern ^[0-9a-f]{64}$; required)
            - `source_utf16_length` (integer | null, ≥ 0; required)
          - `points` (array of object; required)
            - One of:
              - **kind: "timed_silence"**
                - `duration_ms` (integer, 1–300000; required)
                - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                - `kind` ("timed_silence"; required)
                - `offset_utf16` (integer, ≥ 0; required)
              - **kind: "extension"**
                - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                - `kind` ("extension"; required)
                - `name` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
                - `namespace` (string, pattern ^[a-z][a-z0-9_.-]{0,63}$; required)
                - `offset_utf16` (integer, ≥ 0; required)
                - `payload` (object | null; required)
                - `version` (integer, > 0; required)
          - `schema_version` ("studio-ast-2"; required)
          - `text` (string, max 65536 chars; required): Exact block text; at most 65,536 UTF-16 code units. Annotation, point, and delivery offsets are UTF-16 offsets into this string.
          - `type` ("text"; required)
        - `generation_profile_override` (object | null; required): Partial saved profile. New document mutations validate the effective inherited provider/model and options against StudioGenerationProfileRequest. The read schema stays permissive for historical profiles. Join options with speaker context; an override is not a standalone full profile.
          - `controls` (string, one of `strict`, `best_effort`; optional)
          - `fallback` (string, one of `strict`, `best_effort`; optional)
          - `model` (string, 1–200 chars; optional)
          - `options` (map of boolean | string | integer | number | array of StudioAstJsonValue | map of StudioAstJsonValue | null; optional)
          - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; optional)
        - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
        - `kind` ("unparsed"; required)
        - `placement` (any | null; required)
        - `speaker_id` (any | null; required)
      - **kind: "excluded"**
        - `block_version` (integer, > 0; required)
        - `content` (object; required)
          - `annotations` (array of object; required)
            - One of:
              - **kind: "exclusion"**
                - `end_utf16` (integer, ≥ 0; required)
                - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                - `kind` ("exclusion"; required)
                - `reason` (string, one of `speaker_label`, `stage_direction`, `metadata`, `user`; required)
                - `start_utf16` (integer, ≥ 0; required)
              - **kind: "pronunciation"**
                - `alphabet` (string, one of `ipa`, `x-sampa`, `cmu`, `alias`; required)
                - `end_utf16` (integer, ≥ 0; required)
                - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                - `kind` ("pronunciation"; required)
                - `start_utf16` (integer, ≥ 0; required)
                - `value` (string, 1–500 chars; required)
              - **kind: "extension"**
                - `end_utf16` (integer, ≥ 0; required)
                - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                - `kind` ("extension"; required)
                - `name` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
                - `namespace` (string, pattern ^[a-z][a-z0-9_.-]{0,63}$; required)
                - `payload` (object | null; required)
                - `start_utf16` (integer, ≥ 0; required)
                - `version` (integer, > 0; required)
          - `delivery_control_sets` (array of object, max 32 items; required)
            - `capability_revision` (string, 1–200 chars; required)
            - `directives` (array of StudioAstDeliveryDirective, max 256 items; required)
            - `format` (string, one of `eleven-v4-1`, `inworld-tts2-1`, `inworld-tts2-experimental-1`, `inworld-tts15-max-1`, `inworld-tts15-mini-1`, `fish-s2-inline-1`, `fish-s2.1-inline-1`, `fish-drama-3-inline-1`, `cartesia-sonic36-1`, `cartesia-sonic35-1`, `openai-gpt4o-mini-tts-1`, `openai-tts1-hd-1`, `openai-tts1-1`, `smallest-lightning31-1`, `chatterbox-classic-1`, `zyphra-zonos2-cloud-1`, `f5tts-v1-1`, `misotts-8b-1`; required)
            - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
            - `model` (string, 1–200 chars; required)
            - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
            - `provider_text_override` (string, 1–65536 chars, pattern [\s\S]*\S[\s\S]*; optional)
            - `schema_version` (string, one of `studio-delivery-control-set-1`, `studio-delivery-control-set-2`; required)
            - `settings` (array of StudioAstDeliverySetting, max 32 items; required)
            - `source_fingerprint` (string | null, pattern ^[0-9a-f]{64}$; required)
            - `source_utf16_length` (integer | null, ≥ 0; required)
          - `points` (array of object; required)
            - One of:
              - **kind: "timed_silence"**
                - `duration_ms` (integer, 1–300000; required)
                - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                - `kind` ("timed_silence"; required)
                - `offset_utf16` (integer, ≥ 0; required)
              - **kind: "extension"**
                - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                - `kind` ("extension"; required)
                - `name` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
                - `namespace` (string, pattern ^[a-z][a-z0-9_.-]{0,63}$; required)
                - `offset_utf16` (integer, ≥ 0; required)
                - `payload` (object | null; required)
                - `version` (integer, > 0; required)
          - `schema_version` ("studio-ast-2"; required)
          - `text` (string, max 65536 chars; required): Exact block text; at most 65,536 UTF-16 code units. Annotation, point, and delivery offsets are UTF-16 offsets into this string.
          - `type` ("text"; required)
        - `generation_profile_override` (object | null; required): Partial saved profile. New document mutations validate the effective inherited provider/model and options against StudioGenerationProfileRequest. The read schema stays permissive for historical profiles. Join options with speaker context; an override is not a standalone full profile.
          - `controls` (string, one of `strict`, `best_effort`; optional)
          - `fallback` (string, one of `strict`, `best_effort`; optional)
          - `model` (string, 1–200 chars; optional)
          - `options` (map of boolean | string | integer | number | array of StudioAstJsonValue | map of StudioAstJsonValue | null; optional)
          - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; optional)
        - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
        - `kind` ("excluded"; required)
        - `placement` (any | null; required)
        - `speaker_id` (any | null; required)
      - **kind: "note"**
        - `block_version` (integer, > 0; required)
        - `content` (object; required)
          - `schema_version` ("studio-ast-2"; required)
          - `text` (string, max 20000 chars; required)
          - `type` ("note"; required)
        - `generation_profile_override` (object | null; required): Partial saved profile. New document mutations validate the effective inherited provider/model and options against StudioGenerationProfileRequest. The read schema stays permissive for historical profiles. Join options with speaker context; an override is not a standalone full profile.
          - `controls` (string, one of `strict`, `best_effort`; optional)
          - `fallback` (string, one of `strict`, `best_effort`; optional)
          - `model` (string, 1–200 chars; optional)
          - `options` (map of boolean | string | integer | number | array of StudioAstJsonValue | map of StudioAstJsonValue | null; optional)
          - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; optional)
        - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
        - `kind` ("note"; required)
        - `placement` (any | null; required)
        - `speaker_id` (any | null; required)
      - **kind: "sfx"**
        - `block_version` (integer, > 0; required)
        - `content` (object; required)
          - `duration_ms` (integer, 100–3900000; required): Generated sound effects (no source) allow up to 300000 ms; a pinned project sound allows up to 3900000 ms.
          - `prompt` (string, 1–4000 chars; required)
          - `schema_version` ("studio-ast-2"; required)
          - `seed` (integer | null, ≥ -9007199254740991; required)
          - `type` ("sfx"; required)
          - `source` (object; optional): Present only when the SFX block plays an uploaded project sound; seed is then null.
            - `kind` ("project_sound"; required)
            - `sound_effect_id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
            - `sound_effect_revision_id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
        - `generation_profile_override` (object | null; required): Partial saved profile. New document mutations validate the effective inherited provider/model and options against StudioGenerationProfileRequest. The read schema stays permissive for historical profiles. Join options with speaker context; an override is not a standalone full profile.
          - `controls` (string, one of `strict`, `best_effort`; optional)
          - `fallback` (string, one of `strict`, `best_effort`; optional)
          - `model` (string, 1–200 chars; optional)
          - `options` (map of boolean | string | integer | number | array of StudioAstJsonValue | map of StudioAstJsonValue | null; optional)
          - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; optional)
        - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
        - `kind` ("sfx"; required)
        - `placement` (object; required)
          - `anchor` (object; required)
            - One of:
              - **kind: "block"**
                - `block_id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                - `fraction` (number | null, 0–1; required)
                - `kind` ("block"; required)
                - `position` (string, one of `start`, `fraction`, `end`, `after`; required)
              - **kind: "section"**
                - `kind` ("section"; required)
                - `position` (string, one of `start`, `end`; required)
              - **kind: "unplaced"**
                - `kind` ("unplaced"; required)
          - `fade_in_ms` (integer, 0–300000; required)
          - `fade_out_ms` (integer, 0–300000; required)
          - `gain_db` (number, -60–24; required)
          - `offset_ms` (integer, -300000–300000; required)
        - `speaker_id` (any | null; required)
  - `different_speaker_gap_ms` (integer, 0–1000; required): Silence in milliseconds inserted between adjacent spoken blocks with different speakers.
  - `document_version` (integer, > 0; required)
  - `sfx_enabled` (boolean; required): Whether authored section sound effects are audible in playback and included in rendered exports. Legacy sections without a stored value report true.
  - `same_speaker_gap_ms` (integer, 0–1000; required): Silence in milliseconds inserted between adjacent spoken blocks with the same speaker.
  - `schema_version` ("studio-ast-2"; required)
  - `section_id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required): Canonical lowercase UUID of the section.
  - `speaker_registry_version` (integer, > 0; required): Project-wide speaker registry version the speakers list was read at.
  - `speakers` (array of object; required): Every active speaker in the project registry, not only speakers referenced by this section.
    - `generation_profile` (object | null; required): Saved profile read shape, including historical options. For new full-profile requests use StudioGenerationProfileRequest; its provider/model branches list accepted option keys. Generation eligibility and actual audio readiness are separate reads.
      - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
      - `model` (string, 1–200 chars; required)
      - `fallback` (string, one of `strict`, `best_effort`; required)
      - `controls` (string, one of `strict`, `best_effort`; required)
      - `options` (object; required)
    - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
    - `name` (string, 1–200 chars; required)
    - `speaker_version` (integer, > 0; required)
    - `voice_id` (string | null, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
  - `title` (string, max 500 chars; required)
- `source_draft` (object | null; required): The caller's saved, uncommitted Advanced Source draft for this section, or null.
  - `source_text` (string; required)
  - `base_document_version` (integer, ≥ 1; required)
  - `base_speaker_registry_version` (integer, ≥ 1; required)
  - `base_speaker_versions` (map of integer; required): Speaker versions keyed by speaker ID when the draft began.
  - `diagnostics` (array of object, max 1000 items; required)
    - `code` (string, one of `INVALID_SOURCE`, `STALE_SOURCE`; required)
    - `message` (string, 1–2000 chars; required)
  - `updated_at` (string, date-time; required)

Errors: `400`, `401`, `403`, `404`, `500` return the standard error envelope.

#### Example request

```bash
curl "https://lyricwinter.com/api/v1/studio/sections/$SECTION_ID/document" \
  -H "Authorization: Bearer $LYRICWINTER_API_KEY"
```

### Edit a section document

`PATCH /studio/sections/{sectionId}/document`

Scope: `studio:write` · Retries: reuse the same `client_mutation_id` · Operation ID: `saveStudioDocument`

Applies a batch of document commands against the versions you last read. The whole batch commits atomically; if any targeted version changed, the request fails with `409` and nothing is applied. For an existing pinned project-sound block, `content.duration_ms` must equal its immutable source revision's duration; changing it returns `400 STUDIO_PROJECT_SOUND_DURATION_MISMATCH` with expected_duration_ms and requested_duration_ms. Placement gain/fades do not trim the source or shorten the timeline. To change only the gaps between passages, send `set_section_pacing` with integer `same_speaker_gap_ms` and `different_speaker_gap_ms` from 0 through 1000; use empty target-version maps for this section-only command. This preserves the script and existing takes.

#### Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `sectionId` | string, uuid | Yes |  |

#### Request body (application/json, required)

- `schema_version` (1; required)
- `actor_session_id` (string, uuid; required)
- `client_mutation_id` (string, uuid; required)
- `base_document_version` (integer, ≥ 1; required)
- `base_speaker_registry_version` (integer, ≥ 1; required)
- `target_block_versions` (map of integer; required)
- `target_speaker_versions` (map of integer; required)
- `commands` (array of object, 1–1000 items; required)
  - One of:
    - **kind: "set_title"**
      - `kind` ("set_title"; required)
      - `title` (string, max 500 chars; required)
    - **kind: "set_section_pacing"**: Set silence between consecutive audible passages without replacing the script. Both gaps are required; normal document and cast version checks apply.
      - `kind` ("set_section_pacing"; required)
      - `same_speaker_gap_ms` (integer, 0–1000; required)
      - `different_speaker_gap_ms` (integer, 0–1000; required)
    - **kind: "set_section_sfx_enabled"**
      - `kind` ("set_section_sfx_enabled"; required)
      - `sfx_enabled` (boolean; required): Whether authored section sound effects are audible in playback and included in rendered exports. Disabling preserves authored SFX blocks and renditions.
    - **kind: "replace_text"**: Offsets are UTF-16 indices. Runtime also verifies the expected text hash and range against the current block.
      - `kind` ("replace_text"; required)
      - `block_id` (string, pattern ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$; required)
      - `start_utf16` (integer, ≥ 0; required)
      - `end_utf16` (integer, ≥ 0; required)
      - `expected_text_hash` (string, pattern ^[0-9a-f]{64}$; required)
      - `text` (string; required)
    - **kind: "insert_block"**
      - `kind` ("insert_block"; required)
      - `index` (integer, ≥ 0; required)
      - `block` (object; required)
        - One of:
          - **kind: "speech"**
            - `block_version` (integer, > 0; required)
            - `content` (object; required)
              - `annotations` (array of object; required)
                - One of:
                  - **kind: "exclusion"**
                    - `end_utf16` (integer, ≥ 0; required)
                    - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                    - `kind` ("exclusion"; required)
                    - `reason` (string, one of `speaker_label`, `stage_direction`, `metadata`, `user`; required)
                    - `start_utf16` (integer, ≥ 0; required)
                  - **kind: "pronunciation"**
                    - `alphabet` (string, one of `ipa`, `x-sampa`, `cmu`, `alias`; required)
                    - `end_utf16` (integer, ≥ 0; required)
                    - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                    - `kind` ("pronunciation"; required)
                    - `start_utf16` (integer, ≥ 0; required)
                    - `value` (string, 1–500 chars; required)
                  - **kind: "extension"**
                    - `end_utf16` (integer, ≥ 0; required)
                    - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                    - `kind` ("extension"; required)
                    - `name` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
                    - `namespace` (string, pattern ^[a-z][a-z0-9_.-]{0,63}$; required)
                    - `payload` (object | null; required)
                    - `start_utf16` (integer, ≥ 0; required)
                    - `version` (integer, > 0; required)
              - `delivery_control_sets` (array of object, max 32 items; required)
                - `capability_revision` (string, 1–200 chars; required)
                - `directives` (array of StudioAstDeliveryDirective, max 256 items; required)
                - `format` (string, one of `eleven-v4-1`, `inworld-tts2-1`, `inworld-tts2-experimental-1`, `inworld-tts15-max-1`, `inworld-tts15-mini-1`, `fish-s2-inline-1`, `fish-s2.1-inline-1`, `fish-drama-3-inline-1`, `cartesia-sonic36-1`, `cartesia-sonic35-1`, `openai-gpt4o-mini-tts-1`, `openai-tts1-hd-1`, `openai-tts1-1`, `smallest-lightning31-1`, `chatterbox-classic-1`, `zyphra-zonos2-cloud-1`, `f5tts-v1-1`, `misotts-8b-1`; required)
                - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                - `model` (string, 1–200 chars; required)
                - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
                - `provider_text_override` (string, 1–65536 chars, pattern [\s\S]*\S[\s\S]*; optional)
                - `schema_version` (string, one of `studio-delivery-control-set-1`, `studio-delivery-control-set-2`; required)
                - `settings` (array of StudioAstDeliverySetting, max 32 items; required)
                - `source_fingerprint` (string | null, pattern ^[0-9a-f]{64}$; required)
                - `source_utf16_length` (integer | null, ≥ 0; required)
              - `points` (array of object; required)
                - One of:
                  - **kind: "timed_silence"**
                    - `duration_ms` (integer, 1–300000; required)
                    - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                    - `kind` ("timed_silence"; required)
                    - `offset_utf16` (integer, ≥ 0; required)
                  - **kind: "extension"**
                    - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                    - `kind` ("extension"; required)
                    - `name` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
                    - `namespace` (string, pattern ^[a-z][a-z0-9_.-]{0,63}$; required)
                    - `offset_utf16` (integer, ≥ 0; required)
                    - `payload` (object | null; required)
                    - `version` (integer, > 0; required)
              - `schema_version` ("studio-ast-2"; required)
              - `text` (string, max 65536 chars; required): Exact block text; at most 65,536 UTF-16 code units. Annotation, point, and delivery offsets are UTF-16 offsets into this string.
              - `type` ("text"; required)
            - `generation_profile_override` (object | null; required): Partial saved profile. New document mutations validate the effective inherited provider/model and options against StudioGenerationProfileRequest. The read schema stays permissive for historical profiles. Join options with speaker context; an override is not a standalone full profile.
              - `controls` (string, one of `strict`, `best_effort`; optional)
              - `fallback` (string, one of `strict`, `best_effort`; optional)
              - `model` (string, 1–200 chars; optional)
              - `options` (map of boolean | string | integer | number | array of StudioAstJsonValue | map of StudioAstJsonValue | null; optional)
              - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; optional)
            - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
            - `kind` ("speech"; required)
            - `placement` (any | null; required)
            - `speaker_id` (string | null, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
          - **kind: "narration"**
            - `block_version` (integer, > 0; required)
            - `content` (object; required)
              - `annotations` (array of object; required)
                - One of:
                  - **kind: "exclusion"**
                    - `end_utf16` (integer, ≥ 0; required)
                    - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                    - `kind` ("exclusion"; required)
                    - `reason` (string, one of `speaker_label`, `stage_direction`, `metadata`, `user`; required)
                    - `start_utf16` (integer, ≥ 0; required)
                  - **kind: "pronunciation"**
                    - `alphabet` (string, one of `ipa`, `x-sampa`, `cmu`, `alias`; required)
                    - `end_utf16` (integer, ≥ 0; required)
                    - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                    - `kind` ("pronunciation"; required)
                    - `start_utf16` (integer, ≥ 0; required)
                    - `value` (string, 1–500 chars; required)
                  - **kind: "extension"**
                    - `end_utf16` (integer, ≥ 0; required)
                    - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                    - `kind` ("extension"; required)
                    - `name` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
                    - `namespace` (string, pattern ^[a-z][a-z0-9_.-]{0,63}$; required)
                    - `payload` (object | null; required)
                    - `start_utf16` (integer, ≥ 0; required)
                    - `version` (integer, > 0; required)
              - `delivery_control_sets` (array of object, max 32 items; required)
                - `capability_revision` (string, 1–200 chars; required)
                - `directives` (array of StudioAstDeliveryDirective, max 256 items; required)
                - `format` (string, one of `eleven-v4-1`, `inworld-tts2-1`, `inworld-tts2-experimental-1`, `inworld-tts15-max-1`, `inworld-tts15-mini-1`, `fish-s2-inline-1`, `fish-s2.1-inline-1`, `fish-drama-3-inline-1`, `cartesia-sonic36-1`, `cartesia-sonic35-1`, `openai-gpt4o-mini-tts-1`, `openai-tts1-hd-1`, `openai-tts1-1`, `smallest-lightning31-1`, `chatterbox-classic-1`, `zyphra-zonos2-cloud-1`, `f5tts-v1-1`, `misotts-8b-1`; required)
                - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                - `model` (string, 1–200 chars; required)
                - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
                - `provider_text_override` (string, 1–65536 chars, pattern [\s\S]*\S[\s\S]*; optional)
                - `schema_version` (string, one of `studio-delivery-control-set-1`, `studio-delivery-control-set-2`; required)
                - `settings` (array of StudioAstDeliverySetting, max 32 items; required)
                - `source_fingerprint` (string | null, pattern ^[0-9a-f]{64}$; required)
                - `source_utf16_length` (integer | null, ≥ 0; required)
              - `points` (array of object; required)
                - One of:
                  - **kind: "timed_silence"**
                    - `duration_ms` (integer, 1–300000; required)
                    - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                    - `kind` ("timed_silence"; required)
                    - `offset_utf16` (integer, ≥ 0; required)
                  - **kind: "extension"**
                    - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                    - `kind` ("extension"; required)
                    - `name` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
                    - `namespace` (string, pattern ^[a-z][a-z0-9_.-]{0,63}$; required)
                    - `offset_utf16` (integer, ≥ 0; required)
                    - `payload` (object | null; required)
                    - `version` (integer, > 0; required)
              - `schema_version` ("studio-ast-2"; required)
              - `text` (string, max 65536 chars; required): Exact block text; at most 65,536 UTF-16 code units. Annotation, point, and delivery offsets are UTF-16 offsets into this string.
              - `type` ("text"; required)
            - `generation_profile_override` (object | null; required): Partial saved profile. New document mutations validate the effective inherited provider/model and options against StudioGenerationProfileRequest. The read schema stays permissive for historical profiles. Join options with speaker context; an override is not a standalone full profile.
              - `controls` (string, one of `strict`, `best_effort`; optional)
              - `fallback` (string, one of `strict`, `best_effort`; optional)
              - `model` (string, 1–200 chars; optional)
              - `options` (map of boolean | string | integer | number | array of StudioAstJsonValue | map of StudioAstJsonValue | null; optional)
              - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; optional)
            - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
            - `kind` ("narration"; required)
            - `placement` (any | null; required)
            - `speaker_id` (string | null, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
          - **kind: "unparsed"**
            - `block_version` (integer, > 0; required)
            - `content` (object; required)
              - `annotations` (array of object; required)
                - One of:
                  - **kind: "exclusion"**
                    - `end_utf16` (integer, ≥ 0; required)
                    - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                    - `kind` ("exclusion"; required)
                    - `reason` (string, one of `speaker_label`, `stage_direction`, `metadata`, `user`; required)
                    - `start_utf16` (integer, ≥ 0; required)
                  - **kind: "pronunciation"**
                    - `alphabet` (string, one of `ipa`, `x-sampa`, `cmu`, `alias`; required)
                    - `end_utf16` (integer, ≥ 0; required)
                    - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                    - `kind` ("pronunciation"; required)
                    - `start_utf16` (integer, ≥ 0; required)
                    - `value` (string, 1–500 chars; required)
                  - **kind: "extension"**
                    - `end_utf16` (integer, ≥ 0; required)
                    - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                    - `kind` ("extension"; required)
                    - `name` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
                    - `namespace` (string, pattern ^[a-z][a-z0-9_.-]{0,63}$; required)
                    - `payload` (object | null; required)
                    - `start_utf16` (integer, ≥ 0; required)
                    - `version` (integer, > 0; required)
              - `delivery_control_sets` (array of object, max 32 items; required)
                - `capability_revision` (string, 1–200 chars; required)
                - `directives` (array of StudioAstDeliveryDirective, max 256 items; required)
                - `format` (string, one of `eleven-v4-1`, `inworld-tts2-1`, `inworld-tts2-experimental-1`, `inworld-tts15-max-1`, `inworld-tts15-mini-1`, `fish-s2-inline-1`, `fish-s2.1-inline-1`, `fish-drama-3-inline-1`, `cartesia-sonic36-1`, `cartesia-sonic35-1`, `openai-gpt4o-mini-tts-1`, `openai-tts1-hd-1`, `openai-tts1-1`, `smallest-lightning31-1`, `chatterbox-classic-1`, `zyphra-zonos2-cloud-1`, `f5tts-v1-1`, `misotts-8b-1`; required)
                - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                - `model` (string, 1–200 chars; required)
                - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
                - `provider_text_override` (string, 1–65536 chars, pattern [\s\S]*\S[\s\S]*; optional)
                - `schema_version` (string, one of `studio-delivery-control-set-1`, `studio-delivery-control-set-2`; required)
                - `settings` (array of StudioAstDeliverySetting, max 32 items; required)
                - `source_fingerprint` (string | null, pattern ^[0-9a-f]{64}$; required)
                - `source_utf16_length` (integer | null, ≥ 0; required)
              - `points` (array of object; required)
                - One of:
                  - **kind: "timed_silence"**
                    - `duration_ms` (integer, 1–300000; required)
                    - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                    - `kind` ("timed_silence"; required)
                    - `offset_utf16` (integer, ≥ 0; required)
                  - **kind: "extension"**
                    - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                    - `kind` ("extension"; required)
                    - `name` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
                    - `namespace` (string, pattern ^[a-z][a-z0-9_.-]{0,63}$; required)
                    - `offset_utf16` (integer, ≥ 0; required)
                    - `payload` (object | null; required)
                    - `version` (integer, > 0; required)
              - `schema_version` ("studio-ast-2"; required)
              - `text` (string, max 65536 chars; required): Exact block text; at most 65,536 UTF-16 code units. Annotation, point, and delivery offsets are UTF-16 offsets into this string.
              - `type` ("text"; required)
            - `generation_profile_override` (object | null; required): Partial saved profile. New document mutations validate the effective inherited provider/model and options against StudioGenerationProfileRequest. The read schema stays permissive for historical profiles. Join options with speaker context; an override is not a standalone full profile.
              - `controls` (string, one of `strict`, `best_effort`; optional)
              - `fallback` (string, one of `strict`, `best_effort`; optional)
              - `model` (string, 1–200 chars; optional)
              - `options` (map of boolean | string | integer | number | array of StudioAstJsonValue | map of StudioAstJsonValue | null; optional)
              - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; optional)
            - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
            - `kind` ("unparsed"; required)
            - `placement` (any | null; required)
            - `speaker_id` (any | null; required)
          - **kind: "excluded"**
            - `block_version` (integer, > 0; required)
            - `content` (object; required)
              - `annotations` (array of object; required)
                - One of:
                  - **kind: "exclusion"**
                    - `end_utf16` (integer, ≥ 0; required)
                    - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                    - `kind` ("exclusion"; required)
                    - `reason` (string, one of `speaker_label`, `stage_direction`, `metadata`, `user`; required)
                    - `start_utf16` (integer, ≥ 0; required)
                  - **kind: "pronunciation"**
                    - `alphabet` (string, one of `ipa`, `x-sampa`, `cmu`, `alias`; required)
                    - `end_utf16` (integer, ≥ 0; required)
                    - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                    - `kind` ("pronunciation"; required)
                    - `start_utf16` (integer, ≥ 0; required)
                    - `value` (string, 1–500 chars; required)
                  - **kind: "extension"**
                    - `end_utf16` (integer, ≥ 0; required)
                    - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                    - `kind` ("extension"; required)
                    - `name` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
                    - `namespace` (string, pattern ^[a-z][a-z0-9_.-]{0,63}$; required)
                    - `payload` (object | null; required)
                    - `start_utf16` (integer, ≥ 0; required)
                    - `version` (integer, > 0; required)
              - `delivery_control_sets` (array of object, max 32 items; required)
                - `capability_revision` (string, 1–200 chars; required)
                - `directives` (array of StudioAstDeliveryDirective, max 256 items; required)
                - `format` (string, one of `eleven-v4-1`, `inworld-tts2-1`, `inworld-tts2-experimental-1`, `inworld-tts15-max-1`, `inworld-tts15-mini-1`, `fish-s2-inline-1`, `fish-s2.1-inline-1`, `fish-drama-3-inline-1`, `cartesia-sonic36-1`, `cartesia-sonic35-1`, `openai-gpt4o-mini-tts-1`, `openai-tts1-hd-1`, `openai-tts1-1`, `smallest-lightning31-1`, `chatterbox-classic-1`, `zyphra-zonos2-cloud-1`, `f5tts-v1-1`, `misotts-8b-1`; required)
                - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                - `model` (string, 1–200 chars; required)
                - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
                - `provider_text_override` (string, 1–65536 chars, pattern [\s\S]*\S[\s\S]*; optional)
                - `schema_version` (string, one of `studio-delivery-control-set-1`, `studio-delivery-control-set-2`; required)
                - `settings` (array of StudioAstDeliverySetting, max 32 items; required)
                - `source_fingerprint` (string | null, pattern ^[0-9a-f]{64}$; required)
                - `source_utf16_length` (integer | null, ≥ 0; required)
              - `points` (array of object; required)
                - One of:
                  - **kind: "timed_silence"**
                    - `duration_ms` (integer, 1–300000; required)
                    - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                    - `kind` ("timed_silence"; required)
                    - `offset_utf16` (integer, ≥ 0; required)
                  - **kind: "extension"**
                    - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                    - `kind` ("extension"; required)
                    - `name` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
                    - `namespace` (string, pattern ^[a-z][a-z0-9_.-]{0,63}$; required)
                    - `offset_utf16` (integer, ≥ 0; required)
                    - `payload` (object | null; required)
                    - `version` (integer, > 0; required)
              - `schema_version` ("studio-ast-2"; required)
              - `text` (string, max 65536 chars; required): Exact block text; at most 65,536 UTF-16 code units. Annotation, point, and delivery offsets are UTF-16 offsets into this string.
              - `type` ("text"; required)
            - `generation_profile_override` (object | null; required): Partial saved profile. New document mutations validate the effective inherited provider/model and options against StudioGenerationProfileRequest. The read schema stays permissive for historical profiles. Join options with speaker context; an override is not a standalone full profile.
              - `controls` (string, one of `strict`, `best_effort`; optional)
              - `fallback` (string, one of `strict`, `best_effort`; optional)
              - `model` (string, 1–200 chars; optional)
              - `options` (map of boolean | string | integer | number | array of StudioAstJsonValue | map of StudioAstJsonValue | null; optional)
              - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; optional)
            - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
            - `kind` ("excluded"; required)
            - `placement` (any | null; required)
            - `speaker_id` (any | null; required)
          - **kind: "note"**
            - `block_version` (integer, > 0; required)
            - `content` (object; required)
              - `schema_version` ("studio-ast-2"; required)
              - `text` (string, max 20000 chars; required)
              - `type` ("note"; required)
            - `generation_profile_override` (object | null; required): Partial saved profile. New document mutations validate the effective inherited provider/model and options against StudioGenerationProfileRequest. The read schema stays permissive for historical profiles. Join options with speaker context; an override is not a standalone full profile.
              - `controls` (string, one of `strict`, `best_effort`; optional)
              - `fallback` (string, one of `strict`, `best_effort`; optional)
              - `model` (string, 1–200 chars; optional)
              - `options` (map of boolean | string | integer | number | array of StudioAstJsonValue | map of StudioAstJsonValue | null; optional)
              - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; optional)
            - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
            - `kind` ("note"; required)
            - `placement` (any | null; required)
            - `speaker_id` (any | null; required)
          - **kind: "sfx"**
            - `block_version` (integer, > 0; required)
            - `content` (object; required)
              - `duration_ms` (integer, 100–3900000; required): Generated sound effects (no source) allow up to 300000 ms; a pinned project sound allows up to 3900000 ms.
              - `prompt` (string, 1–4000 chars; required)
              - `schema_version` ("studio-ast-2"; required)
              - `seed` (integer | null, ≥ -9007199254740991; required)
              - `type` ("sfx"; required)
              - `source` (object; optional): Present only when the SFX block plays an uploaded project sound; seed is then null.
                - `kind` ("project_sound"; required)
                - `sound_effect_id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                - `sound_effect_revision_id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
            - `generation_profile_override` (object | null; required): Partial saved profile. New document mutations validate the effective inherited provider/model and options against StudioGenerationProfileRequest. The read schema stays permissive for historical profiles. Join options with speaker context; an override is not a standalone full profile.
              - `controls` (string, one of `strict`, `best_effort`; optional)
              - `fallback` (string, one of `strict`, `best_effort`; optional)
              - `model` (string, 1–200 chars; optional)
              - `options` (map of boolean | string | integer | number | array of StudioAstJsonValue | map of StudioAstJsonValue | null; optional)
              - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; optional)
            - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
            - `kind` ("sfx"; required)
            - `placement` (object; required)
              - `anchor` (object; required)
                - One of:
                  - **kind: "block"**
                    - `block_id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
                    - `fraction` (number | null, 0–1; required)
                    - `kind` ("block"; required)
                    - `position` (string, one of `start`, `fraction`, `end`, `after`; required)
                  - **kind: "section"**
                    - `kind` ("section"; required)
                    - `position` (string, one of `start`, `end`; required)
                  - **kind: "unplaced"**
                    - `kind` ("unplaced"; required)
              - `fade_in_ms` (integer, 0–300000; required)
              - `fade_out_ms` (integer, 0–300000; required)
              - `gain_db` (number, -60–24; required)
              - `offset_ms` (integer, -300000–300000; required)
            - `speaker_id` (any | null; required)
    - **kind: "delete_block"**
      - `kind` ("delete_block"; required)
      - `block_id` (string, pattern ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$; required)
    - **kind: "move_block"**
      - `kind` ("move_block"; required)
      - `block_id` (string, pattern ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$; required)
      - `to_index` (integer, ≥ 0; required)
    - **kind: "create_sfx"**: For an uploaded project sound, use content.source.kind=project_sound, seed=null, and a section or block placement anchor.
      - `kind` ("create_sfx"; required)
      - `block_id` (string, pattern ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$; required)
      - `content` (object; required)
        - `duration_ms` (integer, 100–3900000; required): Generated sound effects (no source) allow up to 300000 ms; a pinned project sound allows up to 3900000 ms.
        - `prompt` (string, 1–4000 chars; required)
        - `schema_version` ("studio-ast-2"; required)
        - `seed` (integer | null, ≥ -9007199254740991; required)
        - `type` ("sfx"; required)
        - `source` (object; optional): Present only when the SFX block plays an uploaded project sound; seed is then null.
          - `kind` ("project_sound"; required)
          - `sound_effect_id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
          - `sound_effect_revision_id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
      - `placement` (object; required)
        - `anchor` (object; required)
          - One of:
            - **kind: "block"**
              - `block_id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
              - `fraction` (number | null, 0–1; required)
              - `kind` ("block"; required)
              - `position` (string, one of `start`, `fraction`, `end`, `after`; required)
            - **kind: "section"**
              - `kind` ("section"; required)
              - `position` (string, one of `start`, `end`; required)
            - **kind: "unplaced"**
              - `kind` ("unplaced"; required)
        - `fade_in_ms` (integer, 0–300000; required)
        - `fade_out_ms` (integer, 0–300000; required)
        - `gain_db` (number, -60–24; required)
        - `offset_ms` (integer, -300000–300000; required)
    - **kind: "update_sfx"**
      - `kind` ("update_sfx"; required)
      - `block_id` (string, pattern ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$; required)
      - `content` (object; required)
        - `duration_ms` (integer, 100–3900000; required): Generated sound effects (no source) allow up to 300000 ms; a pinned project sound allows up to 3900000 ms.
        - `prompt` (string, 1–4000 chars; required)
        - `schema_version` ("studio-ast-2"; required)
        - `seed` (integer | null, ≥ -9007199254740991; required)
        - `type` ("sfx"; required)
        - `source` (object; optional): Present only when the SFX block plays an uploaded project sound; seed is then null.
          - `kind` ("project_sound"; required)
          - `sound_effect_id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
          - `sound_effect_revision_id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
      - `placement` (object; required)
        - `anchor` (object; required)
          - One of:
            - **kind: "block"**
              - `block_id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
              - `fraction` (number | null, 0–1; required)
              - `kind` ("block"; required)
              - `position` (string, one of `start`, `fraction`, `end`, `after`; required)
            - **kind: "section"**
              - `kind` ("section"; required)
              - `position` (string, one of `start`, `end`; required)
            - **kind: "unplaced"**
              - `kind` ("unplaced"; required)
        - `fade_in_ms` (integer, 0–300000; required)
        - `fade_out_ms` (integer, 0–300000; required)
        - `gain_db` (number, -60–24; required)
        - `offset_ms` (integer, -300000–300000; required)
    - **kind: "split_blocks"**
      - `kind` ("split_blocks"; required)
      - `targets` (array of object, 1–2 items; required)
        - `block_id` (string, pattern ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$; required)
        - `split_offsets_utf16` (array of integer, 1–2 items; required)
        - `new_block_ids` (array of string, 1–2 items; required)
        - `annotation_fragment_ids` (map of array of string; required)
    - **kind: "merge_blocks"**: Left and right block IDs must differ.
      - `kind` ("merge_blocks"; required)
      - `left_block_id` (string, pattern ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$; required)
      - `right_block_id` (string, pattern ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$; required)
      - `expected_left_text_length_utf16` (integer, ≥ 0; required)
    - **kind: "upsert_annotation"**
      - `kind` ("upsert_annotation"; required)
      - `block_id` (string, pattern ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$; required)
      - `annotation` (object; required)
        - One of:
          - **kind: "exclusion"**
            - `end_utf16` (integer, ≥ 0; required)
            - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
            - `kind` ("exclusion"; required)
            - `reason` (string, one of `speaker_label`, `stage_direction`, `metadata`, `user`; required)
            - `start_utf16` (integer, ≥ 0; required)
          - **kind: "pronunciation"**
            - `alphabet` (string, one of `ipa`, `x-sampa`, `cmu`, `alias`; required)
            - `end_utf16` (integer, ≥ 0; required)
            - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
            - `kind` ("pronunciation"; required)
            - `start_utf16` (integer, ≥ 0; required)
            - `value` (string, 1–500 chars; required)
          - **kind: "extension"**
            - `end_utf16` (integer, ≥ 0; required)
            - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
            - `kind` ("extension"; required)
            - `name` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
            - `namespace` (string, pattern ^[a-z][a-z0-9_.-]{0,63}$; required)
            - `payload` (boolean | string | integer | number | array of boolean | string | integer | number | array of StudioAstJsonValue | map of StudioAstJsonValue | null | map of boolean | string | integer | number | array of StudioAstJsonValue | map of StudioAstJsonValue | null | null; required)
            - `start_utf16` (integer, ≥ 0; required)
            - `version` (integer, > 0; required)
    - **kind: "remove_annotation"**
      - `kind` ("remove_annotation"; required)
      - `block_id` (string, pattern ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$; required)
      - `annotation_id` (string, pattern ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$; required)
    - **kind: "upsert_point"**
      - `kind` ("upsert_point"; required)
      - `block_id` (string, pattern ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$; required)
      - `point` (object; required)
        - One of:
          - **kind: "timed_silence"**
            - `duration_ms` (integer, 1–300000; required)
            - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
            - `kind` ("timed_silence"; required)
            - `offset_utf16` (integer, ≥ 0; required)
          - **kind: "extension"**
            - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
            - `kind` ("extension"; required)
            - `name` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
            - `namespace` (string, pattern ^[a-z][a-z0-9_.-]{0,63}$; required)
            - `offset_utf16` (integer, ≥ 0; required)
            - `payload` (boolean | string | integer | number | array of boolean | string | integer | number | array of StudioAstJsonValue | map of StudioAstJsonValue | null | map of boolean | string | integer | number | array of StudioAstJsonValue | map of StudioAstJsonValue | null | null; required)
            - `version` (integer, > 0; required)
    - **kind: "remove_point"**
      - `kind` ("remove_point"; required)
      - `block_id` (string, pattern ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$; required)
      - `point_id` (string, pattern ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$; required)
    - **kind: "upsert_delivery_control_set"**
      - `kind` ("upsert_delivery_control_set"; required)
      - `block_id` (string, pattern ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$; required)
      - `set` (object; required): Provider-specific delivery controls for one provider/model. The format fixes the provider, model, and which setting and directive kinds are allowed (StudioDeliveryControlSetSchema in libs/studio/ast/v2/delivery-controls.ts). source_fingerprint and source_utf16_length are non-null exactly when directives or provider_text_override are present.
        - `capability_revision` (string, 1–200 chars; required)
        - `directives` (array of object, max 256 items; required)
          - One of:
            - **kind: "inworld.turn_instruction"**
              - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
              - `instruction` (string, 1–4000 chars; required)
              - `kind` ("inworld.turn_instruction"; required)
              - `scope` (object; optional)
                - One of:
                  - **kind: "block"**
                    - `kind` ("block"; required)
                  - **kind: "point"**
                    - `kind` ("point"; required)
                    - `offset_utf16` (integer, ≥ 0; required)
                    - `ordinal` (integer, 0–255; required)
            - **kind: "inworld.nonverbal"**
              - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
              - `kind` ("inworld.nonverbal"; required)
              - `offset_utf16` (integer, ≥ 0; required)
              - `ordinal` (integer, 0–255; required)
              - `value` (string, one of `laugh`, `breathe`, `clear_throat`, `sigh`, `cough`, `yawn`; required)
            - **kind: "fish.inline_instruction"**
              - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
              - `instruction` (string, 1–4000 chars; required)
              - `kind` ("fish.inline_instruction"; required)
              - `offset_utf16` (integer, ≥ 0; required)
              - `ordinal` (integer, 0–255; required)
            - **kind: "elevenlabs.audio_tag"**
              - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
              - `kind` ("elevenlabs.audio_tag"; required)
              - `instruction` (string, 1–200 chars; required): Trimmed audio-tag text without square brackets or control characters.
              - `scope` (object; required)
                - One of:
                  - **kind: "block"**
                    - `kind` ("block"; required)
                  - **kind: "point"**
                    - `kind` ("point"; required)
                    - `offset_utf16` (integer, ≥ 0; required)
                    - `ordinal` (integer, 0–255; required)
            - **kind: "cartesia.emotion"**
              - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
              - `kind` ("cartesia.emotion"; required)
              - `scope` (object; required)
                - One of:
                  - **kind: "block"**
                    - `kind` ("block"; required)
                  - **kind: "point"**
                    - `kind` ("point"; required)
                    - `offset_utf16` (integer, ≥ 0; required)
                    - `ordinal` (integer, 0–255; required)
              - `value` (string, one of `neutral`, `happy`, `excited`, `enthusiastic`, `elated`, `euphoric`, `triumphant`, `amazed`, `surprised`, `flirtatious`, `curious`, `content`, `peaceful`, `serene`, `calm`, `grateful`, `affectionate`, `trust`, `sympathetic`, `anticipation`, `mysterious`, `angry`, `mad`, `outraged`, `frustrated`, `agitated`, `threatened`, `disgusted`, `contempt`, `envious`, `sarcastic`, `ironic`, `sad`, `dejected`, `melancholic`, `disappointed`, `hurt`, `guilty`, `bored`, `tired`, `rejected`, `nostalgic`, `wistful`, `apologetic`, `hesitant`, `insecure`, `confused`, `resigned`, `anxious`, `panicked`, `alarmed`, `scared`, `proud`, `confident`, `distant`, `skeptical`, `contemplative`, `determined`; required)
            - **kind: "cartesia.laughter"**
              - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
              - `kind` ("cartesia.laughter"; required)
              - `offset_utf16` (integer, ≥ 0; required)
              - `ordinal` (integer, 0–255; required)
            - **kind: "openai.instructions"**
              - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
              - `instruction` (string, 1–4000 chars; required)
              - `kind` ("openai.instructions"; required)
            - **kind: "chatterbox.nonverbal"**
              - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
              - `kind` ("chatterbox.nonverbal"; required)
              - `offset_utf16` (integer, ≥ 0; required)
              - `ordinal` (integer, 0–255; required)
              - `value` (string, one of `laugh`, `chuckle`, `sigh`, `cough`, `sniffle`, `groan`, `yawn`, `gasp`; required)
        - `format` (string, one of `eleven-v4-1`, `inworld-tts2-1`, `inworld-tts2-experimental-1`, `inworld-tts15-max-1`, `inworld-tts15-mini-1`, `fish-s2-inline-1`, `fish-s2.1-inline-1`, `fish-drama-3-inline-1`, `cartesia-sonic36-1`, `cartesia-sonic35-1`, `openai-gpt4o-mini-tts-1`, `openai-tts1-hd-1`, `openai-tts1-1`, `smallest-lightning31-1`, `chatterbox-classic-1`, `zyphra-zonos2-cloud-1`, `f5tts-v1-1`, `misotts-8b-1`; required)
        - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
        - `model` (string, 1–200 chars; required)
        - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
        - `provider_text_override` (string, 1–65536 chars, pattern [\s\S]*\S[\s\S]*; optional)
        - `schema_version` (string, one of `studio-delivery-control-set-1`, `studio-delivery-control-set-2`; required)
        - `settings` (array of object, max 32 items; required)
          - One of:
            - **kind: "inworld.speaking_rate"**
              - `kind` ("inworld.speaking_rate"; required)
              - `value` (number, 0.5–1.5; required)
            - **kind: "inworld.delivery_mode"**
              - `kind` ("inworld.delivery_mode"; required)
              - `value` (string, one of `stable`, `balanced`, `creative`; required)
            - **kind: "fish.speed"**
              - `kind` ("fish.speed"; required)
              - `value` (number, 0.5–2; required)
            - **kind: "fish.volume"**
              - `kind` ("fish.volume"; required)
              - `value` (number, -20–20; required)
            - **kind: "openai.speed"**
              - `kind` ("openai.speed"; required)
              - `value` (number, 0.25–4; required)
            - **kind: "smallest.speed"**
              - `kind` ("smallest.speed"; required)
              - `value` (number, 0.5–2; required)
            - **kind: "chatterbox.exaggeration"**
              - `kind` ("chatterbox.exaggeration"; required)
              - `value` (number, 0–1; required)
            - **kind: "chatterbox.cfg"**
              - `kind` ("chatterbox.cfg"; required)
              - `value` (number, 0–1; required)
            - **kind: "zyphra.mode"**
              - `kind` ("zyphra.mode"; required)
              - `value` (string, one of `stable`, `expressive`; required)
            - **kind: "zyphra.speaking_rate_bucket"**
              - `kind` ("zyphra.speaking_rate_bucket"; required)
              - `value` (integer, 0–7; required)
            - **kind: "f5tts.speed"**
              - `kind` ("f5tts.speed"; required)
              - `value` (number, 0.3–2; required)
        - `source_fingerprint` (string | null, pattern ^[0-9a-f]{64}$; required)
        - `source_utf16_length` (integer | null, ≥ 0; required)
    - **kind: "remove_delivery_control_set"**
      - `kind` ("remove_delivery_control_set"; required)
      - `block_id` (string, pattern ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$; required)
      - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
      - `model` (string, 1–200 chars; required)
    - **kind: "set_block_attribution"**: Target block IDs must be unique.
      - `kind` ("set_block_attribution"; required)
      - `targets` (array of object, 1–1000 items; required)
        - `block_id` (string, pattern ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$; required)
        - `block_kind` (string, one of `speech`, `narration`, `unparsed`, `excluded`; required)
        - `speaker_id` (string | null, pattern ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$; required)
    - **kind: "create_speaker"**: The speaker name must be trimmed. speaker_version is 1 for a new speaker, or restore_from_speaker_version+1. A non-null casting_default_key must equal the normalized speaker name and requires voice_id.
      - `kind` ("create_speaker"; required)
      - `speaker` (object; required): A speaker written by a document command. New full profiles use the strict provider/model request contract; saved-document reads retain their historical profile shape.
        - `generation_profile` (object | null; required): Saved profile read shape, including historical options. For new full-profile requests use StudioGenerationProfileRequest; its provider/model branches list accepted option keys. Generation eligibility and actual audio readiness are separate reads.
          - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
          - `model` (string, 1–200 chars; required)
          - `fallback` (string, one of `strict`, `best_effort`; required)
          - `controls` (string, one of `strict`, `best_effort`; required)
          - `options` (object; required)
        - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
        - `name` (string, 1–200 chars; required)
        - `speaker_version` (integer, > 0; required)
        - `voice_id` (string | null, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
      - `restore_from_speaker_version` (integer | null, ≥ 1; required)
      - `casting_default_key` (string | null, 1–200 chars; required)
    - **kind: "update_speaker"**: The name must be trimmed.
      - `kind` ("update_speaker"; required)
      - `speaker_id` (string, pattern ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$; required)
      - `name` (string, 1–200 chars; required)
    - **kind: "delete_speaker"**
      - `kind` ("delete_speaker"; required)
      - `speaker_id` (string, pattern ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$; required)
    - **kind: "set_speaker_casting"**: A non-null casting_default_key requires a voice_id. The effective profile is validated in speaker context.
      - `kind` ("set_speaker_casting"; required)
      - `speaker_id` (string, pattern ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$; required)
      - `voice_id` (string | null, pattern ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$; required)
      - `generation_profile` (object | null; required): Request-only provider/model-specific options for new full profiles. Catalog-only compatibility models can be saved but are unavailable for generation; check generation-availability. Historical document profiles remain permissive. Partial overrides are validated after inheriting their effective provider, model, and options. Stable Audio is for generated SFX, not speaker casting.
      - `casting_default_key` (string | null, 1–200 chars; required)
    - **kind: "set_generation_profile_override"**: Target block IDs must be unique; effective options are validated against the inherited provider/model.
      - `kind` ("set_generation_profile_override"; required)
      - `targets` (array of object, 1–1000 items; required)
        - `block_id` (string, pattern ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$; required)
        - `generation_profile_override` (object | null; required): Partial saved profile. New document mutations validate the effective inherited provider/model and options against StudioGenerationProfileRequest. The read schema stays permissive for historical profiles. Join options with speaker context; an override is not a standalone full profile.
          - `controls` (string, one of `strict`, `best_effort`; optional)
          - `fallback` (string, one of `strict`, `best_effort`; optional)
          - `model` (string, 1–200 chars; optional)
          - `options` (map of object | null; optional)
          - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; optional)
    - **kind: "apply_source_document"**: Replaces the source document under the save request's version fences.
      - `kind` ("apply_source_document"; required)
      - `document` (object; required): A replacement source document written by a command. Speaker profiles use the strict new-write request contract.
        - `blocks` (array of object, max 100000 items; required)
          - One of:
            - **kind: "speech"**
              - `block_version` (integer, > 0; required)
              - `content` (object; required)
                - `annotations` (array of StudioAstTextAnnotation; required)
                - `delivery_control_sets` (array of StudioAstDeliveryControlSet, max 32 items; required)
                - `points` (array of StudioAstPointNode; required)
                - `schema_version` ("studio-ast-2"; required)
                - `text` (string, max 65536 chars; required): Exact block text; at most 65,536 UTF-16 code units. Annotation, point, and delivery offsets are UTF-16 offsets into this string.
                - `type` ("text"; required)
              - `generation_profile_override` (object | null; required): Partial saved profile. New document mutations validate the effective inherited provider/model and options against StudioGenerationProfileRequest. The read schema stays permissive for historical profiles. Join options with speaker context; an override is not a standalone full profile.
                - `controls` (string, one of `strict`, `best_effort`; optional)
                - `fallback` (string, one of `strict`, `best_effort`; optional)
                - `model` (string, 1–200 chars; optional)
                - `options` (map of StudioAstJsonValue; optional)
                - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; optional)
              - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
              - `kind` ("speech"; required)
              - `placement` (any | null; required)
              - `speaker_id` (string | null, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
            - **kind: "narration"**
              - `block_version` (integer, > 0; required)
              - `content` (object; required)
                - `annotations` (array of StudioAstTextAnnotation; required)
                - `delivery_control_sets` (array of StudioAstDeliveryControlSet, max 32 items; required)
                - `points` (array of StudioAstPointNode; required)
                - `schema_version` ("studio-ast-2"; required)
                - `text` (string, max 65536 chars; required): Exact block text; at most 65,536 UTF-16 code units. Annotation, point, and delivery offsets are UTF-16 offsets into this string.
                - `type` ("text"; required)
              - `generation_profile_override` (object | null; required): Partial saved profile. New document mutations validate the effective inherited provider/model and options against StudioGenerationProfileRequest. The read schema stays permissive for historical profiles. Join options with speaker context; an override is not a standalone full profile.
                - `controls` (string, one of `strict`, `best_effort`; optional)
                - `fallback` (string, one of `strict`, `best_effort`; optional)
                - `model` (string, 1–200 chars; optional)
                - `options` (map of StudioAstJsonValue; optional)
                - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; optional)
              - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
              - `kind` ("narration"; required)
              - `placement` (any | null; required)
              - `speaker_id` (string | null, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
            - **kind: "unparsed"**
              - `block_version` (integer, > 0; required)
              - `content` (object; required)
                - `annotations` (array of StudioAstTextAnnotation; required)
                - `delivery_control_sets` (array of StudioAstDeliveryControlSet, max 32 items; required)
                - `points` (array of StudioAstPointNode; required)
                - `schema_version` ("studio-ast-2"; required)
                - `text` (string, max 65536 chars; required): Exact block text; at most 65,536 UTF-16 code units. Annotation, point, and delivery offsets are UTF-16 offsets into this string.
                - `type` ("text"; required)
              - `generation_profile_override` (object | null; required): Partial saved profile. New document mutations validate the effective inherited provider/model and options against StudioGenerationProfileRequest. The read schema stays permissive for historical profiles. Join options with speaker context; an override is not a standalone full profile.
                - `controls` (string, one of `strict`, `best_effort`; optional)
                - `fallback` (string, one of `strict`, `best_effort`; optional)
                - `model` (string, 1–200 chars; optional)
                - `options` (map of StudioAstJsonValue; optional)
                - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; optional)
              - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
              - `kind` ("unparsed"; required)
              - `placement` (any | null; required)
              - `speaker_id` (any | null; required)
            - **kind: "excluded"**
              - `block_version` (integer, > 0; required)
              - `content` (object; required)
                - `annotations` (array of StudioAstTextAnnotation; required)
                - `delivery_control_sets` (array of StudioAstDeliveryControlSet, max 32 items; required)
                - `points` (array of StudioAstPointNode; required)
                - `schema_version` ("studio-ast-2"; required)
                - `text` (string, max 65536 chars; required): Exact block text; at most 65,536 UTF-16 code units. Annotation, point, and delivery offsets are UTF-16 offsets into this string.
                - `type` ("text"; required)
              - `generation_profile_override` (object | null; required): Partial saved profile. New document mutations validate the effective inherited provider/model and options against StudioGenerationProfileRequest. The read schema stays permissive for historical profiles. Join options with speaker context; an override is not a standalone full profile.
                - `controls` (string, one of `strict`, `best_effort`; optional)
                - `fallback` (string, one of `strict`, `best_effort`; optional)
                - `model` (string, 1–200 chars; optional)
                - `options` (map of StudioAstJsonValue; optional)
                - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; optional)
              - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
              - `kind` ("excluded"; required)
              - `placement` (any | null; required)
              - `speaker_id` (any | null; required)
            - **kind: "note"**
              - `block_version` (integer, > 0; required)
              - `content` (object; required)
                - `schema_version` ("studio-ast-2"; required)
                - `text` (string, max 20000 chars; required)
                - `type` ("note"; required)
              - `generation_profile_override` (object | null; required): Partial saved profile. New document mutations validate the effective inherited provider/model and options against StudioGenerationProfileRequest. The read schema stays permissive for historical profiles. Join options with speaker context; an override is not a standalone full profile.
                - `controls` (string, one of `strict`, `best_effort`; optional)
                - `fallback` (string, one of `strict`, `best_effort`; optional)
                - `model` (string, 1–200 chars; optional)
                - `options` (map of StudioAstJsonValue; optional)
                - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; optional)
              - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
              - `kind` ("note"; required)
              - `placement` (any | null; required)
              - `speaker_id` (any | null; required)
            - **kind: "sfx"**
              - `block_version` (integer, > 0; required)
              - `content` (object; required)
                - `duration_ms` (integer, 100–3900000; required): Generated sound effects (no source) allow up to 300000 ms; a pinned project sound allows up to 3900000 ms.
                - `prompt` (string, 1–4000 chars; required)
                - `schema_version` ("studio-ast-2"; required)
                - `seed` (integer | null, ≥ -9007199254740991; required)
                - `type` ("sfx"; required)
                - `source` (object; optional): Present only when the SFX block plays an uploaded project sound; seed is then null.
                  - `kind` (object; required)
                  - `sound_effect_id` (object; required)
                  - `sound_effect_revision_id` (object; required)
              - `generation_profile_override` (object | null; required): Partial saved profile. New document mutations validate the effective inherited provider/model and options against StudioGenerationProfileRequest. The read schema stays permissive for historical profiles. Join options with speaker context; an override is not a standalone full profile.
                - `controls` (string, one of `strict`, `best_effort`; optional)
                - `fallback` (string, one of `strict`, `best_effort`; optional)
                - `model` (string, 1–200 chars; optional)
                - `options` (map of StudioAstJsonValue; optional)
                - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; optional)
              - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
              - `kind` ("sfx"; required)
              - `placement` (object; required)
                - `anchor` (object; required)
                  - One of:
                    - **kind: "block"**
                      - `block_id` (object; required)
                      - `fraction` (object; required)
                      - `kind` (object; required)
                      - `position` (object; required)
                    - **kind: "section"**
                      - `kind` (object; required)
                      - `position` (object; required)
                    - **kind: "unplaced"**
                      - `kind` (object; required)
                - `fade_in_ms` (integer, 0–300000; required)
                - `fade_out_ms` (integer, 0–300000; required)
                - `gain_db` (number, -60–24; required)
                - `offset_ms` (integer, -300000–300000; required)
              - `speaker_id` (any | null; required)
        - `different_speaker_gap_ms` (integer, 0–1000; required): Silence in milliseconds inserted between adjacent spoken blocks with different speakers.
        - `document_version` (integer, > 0; required)
        - `sfx_enabled` (boolean; required): Whether authored section sound effects are audible in playback and included in rendered exports. Legacy sections without a stored value report true.
        - `same_speaker_gap_ms` (integer, 0–1000; required): Silence in milliseconds inserted between adjacent spoken blocks with the same speaker.
        - `schema_version` ("studio-ast-2"; required)
        - `section_id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required): Canonical lowercase UUID of the section.
        - `speaker_registry_version` (integer, > 0; required): Project-wide speaker registry version the speakers list was read at.
        - `speakers` (array of object; required): Every active speaker in the project registry, not only speakers referenced by this section.
          - `generation_profile` (object | null; required): Saved profile read shape, including historical options. For new full-profile requests use StudioGenerationProfileRequest; its provider/model branches list accepted option keys. Generation eligibility and actual audio readiness are separate reads.
            - `provider` (string, pattern ^[a-z][a-z0-9_-]{0,63}$; required)
            - `model` (string, 1–200 chars; required)
            - `fallback` (string, one of `strict`, `best_effort`; required)
            - `controls` (string, one of `strict`, `best_effort`; required)
            - `options` (object; required)
          - `id` (string, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
          - `name` (string, 1–200 chars; required)
          - `speaker_version` (integer, > 0; required)
          - `voice_id` (string | null, pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$; required)
        - `title` (string, max 500 chars; required)

#### Response 200

Authoritative document after commit or idempotent replay.

Fields inside `data`:

- `actor_user_id` (string, uuid; required): Authenticated caller; clients partition local recovery state by this ID.
- `project_id` (string, uuid; required)
- `document` (object; required): The canonical structured script of one section (studio-ast-2): its versions, speakers, and ordered blocks. See [Get a section document](https://lyricwinter.com/docs/api/documents#get-studio-document) for its fields.
- `source_draft` (object | null; required): The caller's saved, uncommitted Advanced Source draft for this section, or null.
  - `source_text` (string; required)
  - `base_document_version` (integer, ≥ 1; required)
  - `base_speaker_registry_version` (integer, ≥ 1; required)
  - `base_speaker_versions` (map of integer; required): Speaker versions keyed by speaker ID when the draft began.
  - `diagnostics` (array of object, max 1000 items; required)
    - `code` (string, one of `INVALID_SOURCE`, `STALE_SOURCE`; required)
    - `message` (string, 1–2000 chars; required)
  - `updated_at` (string, date-time; required)

Errors: `400`, `401`, `403`, `404`, `409`, `500` return the standard error envelope.

#### Example request

```bash
curl -X PATCH "https://lyricwinter.com/api/v1/studio/sections/$SECTION_ID/document" \
  -H "Authorization: Bearer $LYRICWINTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "schema_version": 1,
  "actor_session_id": "8f14e45f-ceea-4e7a-9c2d-3b1a5f2e7c10",
  "client_mutation_id": "c9f0f895-fb98-4b91-9e3f-1d2a6b7c8d20",
  "base_document_version": 1,
  "base_speaker_registry_version": 1,
  "target_block_versions": {},
  "target_speaker_versions": {},
  "commands": [
    {
      "kind": "set_title",
      "title": "Chapter One"
    }
  ]
}'
```

### Import a speaker-labeled script

`POST /studio/sections/{sectionId}/script`

Scope: `studio:write` · Retries: reuse the same `client_mutation_id` · Operation ID: `importStudioScript`

Turn `SPEAKER: [optional direction] spoken text` lines into a Studio document without building an AST. Map each speaker label to a voice and generation profile. A separate `(silence 4s)` line adds exact silence after the preceding spoken line. Unsupported lines or directions fail rather than disappearing. This replaces the section script; it does not generate audio. Send the current document and speaker-registry versions. Reusing an existing speaker name updates that project-wide speaker's voice and profile. Retry uncertain responses with the same mutation ID and body; a receipt that cannot be verified returns `409` without importing again.

#### Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `sectionId` | string, uuid | Yes |  |

#### Request body (application/json, required)

- `schema_version` (1; required)
- `actor_session_id` (string, uuid; required)
- `client_mutation_id` (string, uuid; required)
- `base_document_version` (integer, ≥ 1; required)
- `base_speaker_registry_version` (integer, ≥ 1; required)
- `script` (string, min 1 chars; required): One SPEAKER: [optional direction] spoken text per nonblank line. A separate (silence 4s) or (silence 4000ms) line adds 1-300 seconds of silence after the preceding spoken line. Labels match speaker-map keys exactly. Unsupported lines are rejected.
- `speakers` (map of object; required): Exact speaker-label keys used in the script, each with an explicit voice and generation profile. Existing project speakers with the same name are reused.
  - `voice_id` (string | null, uuid; required)
  - `generation_profile` (object; required): Request-only provider/model-specific options for new full profiles. Catalog-only compatibility models can be saved but are unavailable for generation; check generation-availability. Historical document profiles remain permissive. Partial overrides are validated after inheriting their effective provider, model, and options. Stable Audio is for generated SFX, not speaker casting.

#### Response 200

Canonical Studio document after the import.

Fields inside `data`:

- `actor_user_id` (string, uuid; required): Authenticated caller; clients partition local recovery state by this ID.
- `project_id` (string, uuid; required)
- `document` (object; required): The canonical structured script of one section (studio-ast-2): its versions, speakers, and ordered blocks. See [Get a section document](https://lyricwinter.com/docs/api/documents#get-studio-document) for its fields.
- `source_draft` (object | null; required): The caller's saved, uncommitted Advanced Source draft for this section, or null.
  - `source_text` (string; required)
  - `base_document_version` (integer, ≥ 1; required)
  - `base_speaker_registry_version` (integer, ≥ 1; required)
  - `base_speaker_versions` (map of integer; required): Speaker versions keyed by speaker ID when the draft began.
  - `diagnostics` (array of object, max 1000 items; required)
    - `code` (string, one of `INVALID_SOURCE`, `STALE_SOURCE`; required)
    - `message` (string, 1–2000 chars; required)
  - `updated_at` (string, date-time; required)

Errors: `400`, `401`, `403`, `404`, `409`, `500` return the standard error envelope.

#### Example request

```bash
curl -X POST "https://lyricwinter.com/api/v1/studio/sections/$SECTION_ID/script" \
  -H "Authorization: Bearer $LYRICWINTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "schema_version": 1,
  "actor_session_id": "8f14e45f-ceea-4e7a-9c2d-3b1a5f2e7c10",
  "client_mutation_id": "c9f0f895-fb98-4b91-9e3f-1d2a6b7c8d20",
  "base_document_version": 1,
  "base_speaker_registry_version": 1,
  "script": "string",
  "speakers": {}
}'
```

### List project speakers

`GET /studio/projects/{projectId}/speakers`

Scope: `studio:read` · Operation ID: `getStudioProjectSpeakerUsage`

Returns the project's speakers with how many lines and sections each one appears in, plus the current `speaker_registry_version`.

#### Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string, uuid | Yes |  |

#### Response 200

Project-wide character usage and current character registry authority.

Fields inside `data`:

- `project_id` (string, uuid; required)
- `speaker_registry_version` (integer, ≥ 1; required)
- `speakers` (array of object, max 10000 items; required): Every active project speaker, including unused speakers with zero counts.
  - `speaker_id` (string, uuid; required)
  - `line_count` (integer, ≥ 0; required): Active speech and narration blocks assigned to the speaker across active sections.
  - `block_override_count` (integer, ≥ 0; required): Of those blocks, how many carry a block-level generation profile override.
  - `section_count` (integer, ≥ 0; required): Active sections containing at least one of those blocks.

Errors: `400`, `401`, `403`, `404`, `500` return the standard error envelope.

#### Example request

```bash
curl "https://lyricwinter.com/api/v1/studio/projects/$PROJECT_ID/speakers" \
  -H "Authorization: Bearer $LYRICWINTER_API_KEY"
```

### Assign a speaker's voice and model

`PATCH /studio/projects/{projectId}/speakers/{speakerId}/casting`

Scope: `studio:write` · Retries: reuse the same `client_mutation_id` · Operation ID: `updateStudioProjectSpeakerCasting`

Updates one speaker across its project with a voice and full generation profile, or clears both together. Send current speaker and speaker-registry versions plus session/mutation IDs and a current section ID; the result contains the casting mutation and the current section document. Selecting ElevenLabs v4 requires an active paid plan; otherwise the request returns 403 VOICE_MODEL_SUBSCRIPTION_REQUIRED. Provider options are typed by provider/model. ElevenLabs v4 accepts optional stability (0-1) and integer seed (1-4294967295); empty options retain defaults. Seed is best-effort, not guaranteed deterministic. Speed and similarity_boost are not exposed by the connected transport. Unsupported keys fail before saving or generation. Author delivery directions through control sets. Partial block overrides inherit speaker settings and are checked against the resulting effective profile.

#### Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string, uuid | Yes |  |
| `speakerId` | string, uuid | Yes |  |

#### Request body (application/json, required)

- `schema_version` (1; required)
- `actor_session_id` (string, uuid; required)
- `client_mutation_id` (string, uuid; required)
- `current_section_id` (string, uuid; required)
- `base_speaker_registry_version` (integer, ≥ 1; required)
- `speaker_version` (integer, ≥ 1; required)
- `voice_id` (string | null, uuid; required)
- `generation_profile` (object | null; required): Request-only provider/model-specific options for new full profiles. Catalog-only compatibility models can be saved but are unavailable for generation; check generation-availability. Historical document profiles remain permissive. Partial overrides are validated after inheriting their effective provider, model, and options. Stable Audio is for generated SFX, not speaker casting.
- `casting_default_key` (string | null, 1–200 chars; required)

#### Response 200

Project casting changed and the current section returned at the committed speaker authority.

Fields inside `data`:

- `mutation` (object; required)
  - `mutation_id` (string, uuid; required)
  - `reverted_mutation_id` (string | null, uuid; required)
  - `project_id` (string, uuid; required)
  - `speaker_id` (string, uuid; required)
  - `speaker_registry_version` (integer, ≥ 1; required)
  - `speaker_version` (integer, ≥ 1; required)
  - `affected_block_count` (integer, ≥ 0; required)
  - `affected_section_count` (integer, ≥ 0; required)
  - `idempotent_replay` (boolean; required)
- `document` (object; required)
  - `actor_user_id` (string, uuid; required): Authenticated caller; clients partition local recovery state by this ID.
  - `project_id` (string, uuid; required)
  - `document` (object; required): The canonical structured script of one section (studio-ast-2): its versions, speakers, and ordered blocks. See [Get a section document](https://lyricwinter.com/docs/api/documents#get-studio-document) for its fields.
  - `source_draft` (object | null; required): The caller's saved, uncommitted Advanced Source draft for this section, or null.
    - `source_text` (string; required)
    - `base_document_version` (integer, ≥ 1; required)
    - `base_speaker_registry_version` (integer, ≥ 1; required)
    - `base_speaker_versions` (map of integer; required): Speaker versions keyed by speaker ID when the draft began.
    - `diagnostics` (array of object, max 1000 items; required)
      - `code` (string, one of `INVALID_SOURCE`, `STALE_SOURCE`; required)
      - `message` (string, 1–2000 chars; required)
    - `updated_at` (string, date-time; required)

Errors: `400`, `401`, `403`, `404`, `409`, `500` return the standard error envelope.

#### Example request

```bash
curl -X PATCH "https://lyricwinter.com/api/v1/studio/projects/$PROJECT_ID/speakers/$SPEAKER_ID/casting" \
  -H "Authorization: Bearer $LYRICWINTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "schema_version": 1,
  "actor_session_id": "8f14e45f-ceea-4e7a-9c2d-3b1a5f2e7c10",
  "client_mutation_id": "c9f0f895-fb98-4b91-9e3f-1d2a6b7c8d20",
  "current_section_id": "45c48cce-2e2d-4fbd-8a1c-5e6f7a8b9c30",
  "base_speaker_registry_version": 1,
  "speaker_version": 1,
  "voice_id": "d3d94468-02a4-4c5e-b6f7-0a1b2c3d4e40",
  "generation_profile": {},
  "casting_default_key": "string"
}'
```

