Skip to content

API reference

Projects API

A Studio project groups ordered sections (chapters) that share one cast of speakers. Standalone stories appear as unassigned stories until you turn them into a named project.

BetaUpdated

Base URL
https://lyricwinter.com/api/v1
Authentication
Authorization: Bearer lw_…
Contract
openapi.json

List projects and standalone stories

GET/studio/projects

Scope studio:read

Returns named projects in projects and standalone stories in unassigned_sections. Every standalone story still has a project_id that works with project-scoped endpoints. Section summaries include source_word_count when available: the word count of saved source text, including text excluded from narration.

Response 200

Named projects and unassigned Studio story summaries. Fields below are inside data.

  • projectsarray of objectrequired
    4 item attributes
    • last_active_atstring | nulldate-time
    • idstringrequireduuid
    • namestringrequired
    • project_kind"named"required
  • unassigned_sectionsarray of objectrequired

    Standalone Studio stories shown under the virtual Unassigned group, one section per hidden project.

    2 item attributes
    • project_idstringrequireduuid

      Hidden standalone project container that owns the story.

    • sectionobjectrequired
      11 child attributes
      • last_opened_atstring | nulldate-time
      • has_audioboolean

        Present, and true, only with activity_status needs_audio: at least one line already has finished audio, so the section needs updating or finishing rather than creating.

      • idstringrequireduuid
      • project_idstringrequireduuid
      • titlestringrequired
      • document_versionintegerrequired≥ 1
      • source_text_lengthintegerrequired≥ 0

        Length of the section's exact source-text projection in UTF-16 code units.

      • source_word_countinteger≥ 0

        Word count of the saved source text using Unicode word segmentation. Includes text excluded from narration; sound prompts and notes are not source text. Omitted when unavailable.

      • activity_statusstringrequired

        Navigator state: working (active workflow or pending audio), audio_failed (latest audio attempt failed), audio_ready (every generatable block has current audio and no unparsed text remains), needs_audio (generatable or unparsed text without complete current audio), or blank (nothing to generate).

        One ofblankworkingneeds_audioaudio_readyaudio_failed

      • created_atstringrequireddate-time
      • updated_atstringrequireddate-time

Errors 401, 500 use the standard error envelope.

curl "https://lyricwinter.com/api/v1/studio/projects" \
  -H "Authorization: Bearer $LYRICWINTER_API_KEY"
Response 200 (example)
{
  "data": {
    "projects": [
      {
        "last_active_at": "2026-09-30T17:00:00.000Z",
        "id": "8f14e45f-ceea-4e7a-9c2d-3b1a5f2e7c10",
        "name": "My integration",
        "project_kind": "named"
      }
    ],
    "unassigned_sections": [
      {
        "project_id": "c9f0f895-fb98-4b91-9e3f-1d2a6b7c8d20",
        "section": {
          "last_opened_at": "2026-09-30T17:00:00.000Z",
          "has_audio": true,
          "id": "45c48cce-2e2d-4fbd-8a1c-5e6f7a8b9c30",
          "project_id": "d3d94468-02a4-4c5e-b6f7-0a1b2c3d4e40",
          "title": "Chapter One",
          "document_version": 1,
          "source_text_length": 1,
          "source_word_count": 1,
          "activity_status": "blank",
          "created_at": "2026-09-30T17:00:00.000Z",
          "updated_at": "2026-09-30T17:00:00.000Z"
        }
      }
    ]
  },
  "request_id": "req_01J9Z3K8QF4"
}

Turn a standalone story into a project

PATCH/studio/projects/{projectId}

Scope studio:write

Gives a standalone story a project name so you can add more sections to it. Its section, cast, audio, and share links are kept.

Path parameters

  • projectIdstringrequireduuid

Request body application/json

  • schema_version1required
  • namestringrequiredmin 1 charspattern \S

    Project name. Leading and trailing whitespace is trimmed; the trimmed name must be 1-120 characters and must not contain null characters or malformed Unicode.

Response 200

The promoted named project, or the existing project when it is already named with the same name. Fields below are inside data.

  • projectobjectrequired
    4 child attributes
    • last_active_atstring | nulldate-time
    • idstringrequireduuid
    • namestringrequired
    • project_kind"named"required

Errors 400, 401, 404, 409, 500 use the standard error envelope.

curl -X PATCH "https://lyricwinter.com/api/v1/studio/projects/$PROJECT_ID" \
  -H "Authorization: Bearer $LYRICWINTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "schema_version": 1,
  "name": "My integration"
}'
Response 200 (example)
{
  "data": {
    "project": {
      "last_active_at": "2026-09-30T17:00:00.000Z",
      "id": "8f14e45f-ceea-4e7a-9c2d-3b1a5f2e7c10",
      "name": "My integration",
      "project_kind": "named"
    }
  },
  "request_id": "req_01J9Z3K8QF4"
}

Preview project deletion

GET/studio/projects/{projectId}/deletion-info

Scope studio:read

Returns the contents deletion would remove. Add consent_version=1 to receive a deletion_revision, current project kind and display_name for confirmation. The display name is the current project name, or the current section title for a standalone story. Keep that revision with the confirmed deletion, including across interrupted requests.

Path parameters

  • projectIdstringrequireduuid

Query parameters

  • consent_versionstring

    Set to 1 to review the exact saved contents before confirmation.

    One of1

Response 200

Project deletion preview.

One of 2 shapes:

StudioProjectDeletionInfoEnvelope
  • dataobjectrequired
    9 child attributes
    • project_idstringrequireduuid
    • section_countintegerrequired≥ 0
    • other_story_countintegerrequired≥ 0
    • block_countintegerrequired≥ 0
    • audio_run_countintegerrequired≥ 0
    • clip_countintegerrequired≥ 0
    • studio_media_countintegerrequired≥ 0
    • active_share_link_countintegerrequired≥ 0
    • ai_designed_voice_countintegerrequired≥ 0
  • request_idstring
StudioProjectDeletionReviewEnvelope
  • dataobjectrequired
    12 child attributes
    • project_idstringrequireduuid
    • section_countintegerrequired≥ 0
    • other_story_countintegerrequired≥ 0
    • block_countintegerrequired≥ 0
    • audio_run_countintegerrequired≥ 0
    • clip_countintegerrequired≥ 0
    • studio_media_countintegerrequired≥ 0
    • active_share_link_countintegerrequired≥ 0
    • ai_designed_voice_countintegerrequired≥ 0
    • deletion_revisionstringrequiredpattern ^pd1:[0-9a-f]{64}$
    • project_kindstringrequired

      One ofstandalonenamed

    • display_namestringrequired

      The current named project name or standalone story section title, read with deletion_revision.

  • request_idstring

Errors 400, 401, 404, 500 use the standard error envelope.

curl "https://lyricwinter.com/api/v1/studio/projects/$PROJECT_ID/deletion-info" \
  -H "Authorization: Bearer $LYRICWINTER_API_KEY"
Response 200 (example)
{
  "data": {
    "project_id": "8f14e45f-ceea-4e7a-9c2d-3b1a5f2e7c10",
    "section_count": 1,
    "other_story_count": 1,
    "block_count": 1,
    "audio_run_count": 1,
    "clip_count": 1,
    "studio_media_count": 1,
    "active_share_link_count": 1,
    "ai_designed_voice_count": 1
  },
  "request_id": "c9f0f895-fb98-4b91-9e3f-1d2a6b7c8d20"
}

Delete a project

DELETE/studio/projects/{projectId}

Scope studio:write

Deletes a project with all of its sections, in-progress work, playback and share links. Send schema_version: 2, the reviewed expected_project_kind and the exact expected_deletion_revision the caller confirmed. Changed contents or legacy consent return 409 PROJECT_DELETION_REVIEW_REQUIRED; obtain explicit renewed confirmation instead of silently adopting a new revision. 409 PROJECT_DELETION_BUSY allows a later user-initiated retry with the original consent; do not retry automatically. This cannot be undone through the API.

Path parameters

  • projectIdstringrequireduuid

Request body application/json

  • schema_version2required
  • expected_project_kindstringrequired

    The project kind the deleting client most recently observed. The server rejects deletion if the live kind has changed.

    One ofstandalonenamed

  • delete_ai_designed_voicesbooleanrequired
  • expected_deletion_revisionstringrequiredpattern ^pd1:[0-9a-f]{64}$

    The unchanged deletion_revision returned by the review the caller confirmed.

Response 200

Project deletion counts and optional AI-designed voice cleanup result. Fields below are inside data.

  • successtruerequired
  • project_idstringrequireduuid
  • mode"project_and_stories"required
  • stories_deletedintegerrequired≥ 0
  • audio_runs_deletedintegerrequired≥ 0
  • clips_deletedintegerrequired≥ 0
  • public_stories_deletedintegerrequired≥ 0
  • shared_stories_deletedintegerrequired≥ 0
  • active_share_links_deletedintegerrequired≥ 0
  • studio_sections_deletedintegerrequired≥ 0
  • studio_media_marked_for_deletionintegerrequired≥ 0
  • files_deletedintegerrequired≥ 0
  • ai_designed_voices_deletedintegerrequired≥ 0
  • ai_designed_voices_retainedintegerrequired≥ 0

Errors 400, 401, 404, 409, 500 use the standard error envelope.

curl -X DELETE "https://lyricwinter.com/api/v1/studio/projects/$PROJECT_ID" \
  -H "Authorization: Bearer $LYRICWINTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "schema_version": 2,
  "expected_project_kind": "standalone",
  "delete_ai_designed_voices": true,
  "expected_deletion_revision": "string"
}'
Response 200 (example)
{
  "data": {
    "success": true,
    "project_id": "8f14e45f-ceea-4e7a-9c2d-3b1a5f2e7c10",
    "mode": "project_and_stories",
    "stories_deleted": 1,
    "audio_runs_deleted": 1,
    "clips_deleted": 1,
    "public_stories_deleted": 1,
    "shared_stories_deleted": 1,
    "active_share_links_deleted": 1,
    "studio_sections_deleted": 1,
    "studio_media_marked_for_deletion": 1,
    "files_deleted": 1,
    "ai_designed_voices_deleted": 1,
    "ai_designed_voices_retained": 1
  },
  "request_id": "req_01J9Z3K8QF4"
}