> ## Documentation Index
> Fetch the complete documentation index at: https://docs.breezeblue.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Breeze CLI Studio management

> Manage Studio projects, chapters, clips, tracks, audio instances, and uploaded audio files.

`breeze studio` edits Studio project content through the `/v1/studio` API. Every command prints the API's JSON response on `stdout`. The commands do not generate speech, charge generation credits, or export audio.

## Commands

| Group | Commands | Positional IDs |
| - | - | - |
| `projects` | `list`, `get`, `create`, `import`, `update`, `delete` | `<project_id>` |
| `chapters` | `list`, `get`, `create`, `update`, `delete`, `restore`, `reorder` | `<project_id> [<chapter_id>]` |
| `clips` | `list`, `get`, `create`, `update`, `delete`, `batch-create`, `batch-update`, `bulk-delete`, `reorder`, `move` | `<project_id> [<clip_id>]` |
| `tracks` | `list`, `get`, `create`, `update`, `delete`, `reorder` | `<project_id> [<track_id>]` |
| `instances` | `list`, `get`, `create`, `update`, `delete` | `<project_id> <track_id> [<instance_id>]` |
| `files` | `list`, `get`, `create`, `update`, `delete`, `upload`, `upload-url`, `complete`, `retry` | `[<file_id>]` |

Run any command with `--help` to see its HTTP route and argument order.

## Read projects

```bash theme={null}
breeze studio projects list --query q=story --query page_size=20 --agent
breeze studio projects get <project_id> --agent
breeze studio clips list <project_id> --query chapter_id=<chapter_id> --query page_size=400 --agent
breeze studio chapters list <project_id> --query include_deleted=true --agent
breeze studio files list --query project_id=<project_id> --agent
```

`list` and `get` accept repeatable `--query key=value` parameters:

| Command | Parameters |
| - | - |
| `projects list` | `q`, `page`, `page_size` (up to 100) |
| `chapters list` | `include_deleted` |
| `clips list` | `chapter_id`, `include_deleted`, `page`, `page_size` (up to 400) |
| `files list` | `project_id`, `q`, `offset`, `limit` (up to 500) |

Project reads and writes return `edit_token`, the project version used for concurrency control.

## Write projects

Write commands read a JSON body from `--input <file>`, or from stdin with `--input -`. Bodies use the API's snake\_case fields.

* Project-scoped writes require `expected_edit_token`, taken from the latest `edit_token` you read or received from a write.
* Writes that carry `operation_id` (project, chapter, clip, track, and instance writes, plus `files create`) get a generated UUID when the body omits it. Set `operation_id` yourself when you may need to retry the same request after a timeout.
* `files update` and `files delete` use `expected_revision` from the latest file response instead.

```bash theme={null}
cat > update.json <<'EOF'
{
  "expected_edit_token": "<edit_token>",
  "script": "The lights came on.",
  "trailing_silence_ms": 300
}
EOF
breeze studio clips update <project_id> <clip_id> --input update.json --agent
```

```bash theme={null}
breeze studio projects import --input script.json --agent
breeze studio chapters reorder <project_id> --input order.json --agent
breeze studio clips batch-create <project_id> --input clips.json --agent
breeze studio clips batch-update <project_id> --input updates.json --agent
breeze studio clips move <project_id> --input move.json --agent
breeze studio instances update <project_id> <track_id> <instance_id> --input instance.json --agent
```

`clips batch-create` and `clips bulk-delete` accept up to 400 clips; `clips batch-update` accepts up to 100. Each batch applies atomically. Move an audio instance to another auxiliary track by updating its `track_id`. The `narration` track is read-only; manage narration through clips.

## Conflicts and retries

A stale `expected_edit_token` returns HTTP 409 and leaves the project unchanged. The CLI never retries a conflict. It exits with code `1` and, in JSON mode, writes an error envelope that keeps the API details:

```json theme={null}
{
  "error": {
    "code": "general",
    "message": "Project changed. Read it again before editing.",
    "suggestion": "The project changed after it was read. ...",
    "exit_code": 1,
    "http_status": 409,
    "api_code": "CONFLICT",
    "meta": {"reason": "project_version_mismatch", "latest_edit_token": "<edit_token>"}
  }
}
```

Read the project again, reconcile your change with the current content, then submit it with the new `expected_edit_token` and a new `operation_id`. Reusing an `operation_id` with a different body also returns 409.

When a write times out or loses its connection, the server may already have applied it. Resend the same body with the same `operation_id`; the server replays the original result instead of applying it twice. If the CLI generated the `operation_id`, the error `suggestion` includes it.

## Delete

`delete` and `bulk-delete` ask for confirmation. Scripts, agents, and bodies read from stdin must pass `--yes`:

```bash theme={null}
echo '{"expected_edit_token": "<edit_token>"}' | breeze studio clips delete <project_id> <clip_id> --input - --yes --agent
breeze studio clips bulk-delete <project_id> --input delete.json --yes --agent
breeze studio projects delete <project_id> --input delete.json --yes --agent
```

Chapter deletion is soft; restore with `chapters restore`. Deleting a track removes its instances and keeps the files. Files referenced by an instance cannot be deleted.

## Upload audio files

```bash theme={null}
breeze studio files upload --file music.mp3 --project-id <project_id> --agent
breeze studio files upload --file intro.wav --operation-id <uuid> --wait=false --agent
```

| Flag | Default | Description |
| - | - | - |
| `--file` | required | Local `.mp3` or `.wav` file. |
| `--project-id` | personal files | Project that owns the file. |
| `--operation-id` | generated | UUID that makes the upload idempotent. |
| `--wait` | `true` | Wait until processing reaches `ready`. |
| `--wait-timeout` | `10m` | Maximum processing wait; each API request still uses `--timeout`. |

`files upload` creates the file record, requests a signed URL, uploads the bytes without your API key, completes the upload, and prints the file JSON. Re-run with the same `--operation-id` and file to resume an interrupted upload. With `--wait=false`, check processing with `files get`. When processing fails, inspect `error_code` and `error_message` with `files get`, then run `files retry`. Use `upload-url` and `complete` only to drive the upload steps yourself.

Timeline positions, trims, and lengths use integer frames at 48,000 Hz. For a complete workflow, see [Manage Studio projects](/guides/studio-projects).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.