Skip to content

API reference

Character voice design API

Design a Studio character voice, read its exact job and candidates, select before expiry, or request cancellation. Retain original mutation/request/job identities. Voice creation does not generate speech; assignment_outcome and the current document determine whether casting succeeded. The project preference selects the engine for future designs independently of the sample-design provider.

BetaUpdated

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

Read the engine for future character voices

GET/studio/projects/{projectId}/new-voice-engine

Scope studio:read

Read the project's current new-voice synthesis engine. Null means Automatic. This is separate from the sample-design provider and does not change voices or create audio. Requires project.read.

Path parameters

  • projectIdstringrequireduuid

Response 200

Project engine preference; null means Automatic. Fields below are inside data.

  • schema_versionstringrequired

    One ofstudio-new-voice-engine-1

  • modelstring | nullrequired

    One offishaudio-drama-3eleven_v4inworld-2cartesia-sonic-3.6lightning_v3.1fishaudio-s2.1-proinworld-1.5-maxinworld-1.5-minicartesia-sonic-3.5fishaudiof5tts

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

curl "https://lyricwinter.com/api/v1/studio/projects/$PROJECT_ID/new-voice-engine" \
  -H "Authorization: Bearer $LYRICWINTER_API_KEY"
Response 200 (example)
{
  "data": {
    "schema_version": "studio-new-voice-engine-1",
    "model": "fishaudio-drama-3"
  },
  "request_id": "req_01J9Z3K8QF4"
}

Choose the engine for future character voices

PATCH/studio/projects/{projectId}/new-voice-engine

Scope studio:write

Save an eligible engine preference, or null for Automatic, with project.manage permission. Future designs capture it; existing voices and audio remain unchanged. This setter has no versioned mutation receipt: after uncertainty read and reconcile rather than automatically overwriting an intervening edit.

Path parameters

  • projectIdstringrequireduuid

Request body application/json

  • schema_versionstringrequired

    One ofstudio-new-voice-engine-1

  • modelstring | nullrequired

    One offishaudio-drama-3eleven_v4inworld-2cartesia-sonic-3.6lightning_v3.1fishaudio-s2.1-proinworld-1.5-maxinworld-1.5-minicartesia-sonic-3.5fishaudiof5tts

Response 200

Saved project engine preference. Fields below are inside data.

  • schema_versionstringrequired

    One ofstudio-new-voice-engine-1

  • modelstring | nullrequired

    One offishaudio-drama-3eleven_v4inworld-2cartesia-sonic-3.6lightning_v3.1fishaudio-s2.1-proinworld-1.5-maxinworld-1.5-minicartesia-sonic-3.5fishaudiof5tts

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

curl -X PATCH "https://lyricwinter.com/api/v1/studio/projects/$PROJECT_ID/new-voice-engine" \
  -H "Authorization: Bearer $LYRICWINTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "schema_version": "studio-new-voice-engine-1",
  "model": "fishaudio-drama-3"
}'
Response 200 (example)
{
  "data": {
    "schema_version": "studio-new-voice-engine-1",
    "model": "fishaudio-drama-3"
  },
  "request_id": "req_01J9Z3K8QF4"
}

Find an active character voice design

GET/studio/projects/{projectId}/speakers/{speakerId}/voice-materialization-jobs

Scope studio:read

Return the latest queued, running or awaiting-selection AI voice design for this project/speaker, or null. This is not an original-operation lookup or proof that prior work failed; retain and read an exact confirmed job ID for recovery.

Path parameters

  • projectIdstringrequireduuid
  • speakerIdstringrequireduuid

Response 200

Active voice design or null when none is active. Fields below are inside data.

  • idstringrequireduuid
  • project_idstringrequireduuid
  • section_idstring | nullrequireduuid
  • speaker_idstring | nullrequireduuid
  • source_voice_idstring | nullrequireduuid
  • materialization_kindanyrequired

    One ofprovider_assetai_voice_creation

  • provideranyrequired

    One ofinworldcartesiafish_audiosmallest_aielevenlabsphonon

  • modelstringrequiredmin 1 chars
  • selection_modeanyrequired

    One ofautomaticmanual

  • requested_candidate_countintegerrequired1–3
  • statusanyrequired

    One ofqueuedrunningawaiting_selectioncompletedfailedcancelled

  • selection_expires_atstring | nullrequired
  • selected_candidate_idstring | nullrequireduuid
  • cancel_requested_atstring | nullrequired
  • output_voice_idstring | nullrequireduuid
  • output_provider_asset_idstring | nullrequireduuid
  • assignment_outcomeanyrequired

    One ofnot_applicableassignedspeaker_changed

  • error_codestring | nullrequired
  • error_messagestring | nullrequired
  • created_atstringrequired
  • completed_atstring | nullrequired
  • candidatesarray of objectrequiredmax 3 items
    6 item attributes
    • idstringrequireduuid
    • candidate_indexintegerrequired0–2
    • preview_urlstring | nullrequireduri
    • preview_textstringrequired1–500 chars
    • duration_msinteger | nullrequired≥ 0
    • statusanyrequired

      One ofavailableselectedfinalizeddiscarded

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

curl "https://lyricwinter.com/api/v1/studio/projects/$PROJECT_ID/speakers/$SPEAKER_ID/voice-materialization-jobs" \
  -H "Authorization: Bearer $LYRICWINTER_API_KEY"
Response 200 (example)
{
  "data": {
    "id": "8f14e45f-ceea-4e7a-9c2d-3b1a5f2e7c10",
    "project_id": "c9f0f895-fb98-4b91-9e3f-1d2a6b7c8d20",
    "section_id": "45c48cce-2e2d-4fbd-8a1c-5e6f7a8b9c30",
    "speaker_id": "d3d94468-02a4-4c5e-b6f7-0a1b2c3d4e40",
    "source_voice_id": "8f14e45f-ceea-4e7a-9c2d-3b1a5f2e7c10",
    "materialization_kind": "provider_asset",
    "provider": "inworld",
    "model": "string",
    "selection_mode": "automatic",
    "requested_candidate_count": 1,
    "status": "queued",
    "selection_expires_at": "2026-09-30T17:00:00.000Z",
    "selected_candidate_id": "c9f0f895-fb98-4b91-9e3f-1d2a6b7c8d20",
    "cancel_requested_at": "2026-09-30T17:00:00.000Z",
    "output_voice_id": "45c48cce-2e2d-4fbd-8a1c-5e6f7a8b9c30",
    "output_provider_asset_id": "d3d94468-02a4-4c5e-b6f7-0a1b2c3d4e40",
    "assignment_outcome": "not_applicable",
    "error_code": "string",
    "error_message": "string",
    "created_at": "2026-09-30T17:00:00.000Z",
    "completed_at": "2026-09-30T17:00:00.000Z",
    "candidates": [
      {
        "id": "8f14e45f-ceea-4e7a-9c2d-3b1a5f2e7c10",
        "candidate_index": 1,
        "preview_url": "https://lyricwinter.com/…",
        "preview_text": "string",
        "duration_ms": 1,
        "status": "available"
      }
    ]
  },
  "request_id": "req_01J9Z3K8QF4"
}

Design or prepare a character voice

POST/studio/projects/{projectId}/speakers/{speakerId}/voice-materialization-jobs

Scope studio:writeRetry with the same client_mutation_id

Submit the canonical voice materialization request with its original client_mutation_id. New AI designs use schema_version 2 and optional voice_direction; provider preparation and legacy v1 remain supported. Manual mode exposes up to three candidates; automatic mode requires one. The ordinary server captures authority and the project's casting engine. Recover only the identical original request after uncertainty; never substitute another voice or mutation. This operation does not generate speech.

Path parameters

  • projectIdstringrequireduuid
  • speakerIdstringrequireduuid

Request body application/json

One of 3 shapes:

schema_version: 1, materialization_kind: "provider_asset"
  • schema_version1required
  • client_mutation_idstringrequireduuid
  • materialization_kind"provider_asset"
  • expected_source_voice_idstringuuid
  • provideranyrequired

    One ofinworldcartesiafish_audiosmallest_aielevenlabsphonon

  • modelanyrequired

    One ofinworld-2cartesia-sonic-3.5fishaudio-s2.1-prolightning_v3.1eleven_v4phonon-31m-en

schema_version: 1, materialization_kind: "ai_voice_creation"
  • schema_version1required
  • client_mutation_idstringrequireduuid
  • materialization_kind"ai_voice_creation"required
  • section_idstringrequireduuid
  • actor_session_idstringrequireduuid
  • provideranyrequired

    One ofinworldfish_audio

  • modelanyrequired

    One ofinworld-2fishaudio-s2.1-pro

  • selection_modeanyrequired

    One ofautomaticmanual

  • candidate_countintegerrequired1–3
  • custom_promptstring30–250 chars
schema_version: 2, materialization_kind: "ai_voice_creation"
  • schema_version2required
  • client_mutation_idstringrequireduuid
  • materialization_kind"ai_voice_creation"required
  • section_idstringrequireduuid
  • actor_session_idstringrequireduuid
  • provideranyrequired

    One ofinworldfish_audio

  • modelanyrequired

    One ofinworld-2fishaudio-s2.1-pro

  • selection_modeanyrequired

    One ofautomaticmanual

  • candidate_countintegerrequired1–3
  • voice_directionstring30–250 chars

Response 200

The provider voice was already ready. Fields below are inside data.

  • idstringrequireduuid
  • project_idstringrequireduuid
  • section_idstring | nullrequireduuid
  • speaker_idstring | nullrequireduuid
  • source_voice_idstring | nullrequireduuid
  • materialization_kindanyrequired

    One ofprovider_assetai_voice_creation

  • provideranyrequired

    One ofinworldcartesiafish_audiosmallest_aielevenlabsphonon

  • modelstringrequiredmin 1 chars
  • selection_modeanyrequired

    One ofautomaticmanual

  • requested_candidate_countintegerrequired1–3
  • statusanyrequired

    One ofqueuedrunningawaiting_selectioncompletedfailedcancelled

  • selection_expires_atstring | nullrequired
  • selected_candidate_idstring | nullrequireduuid
  • cancel_requested_atstring | nullrequired
  • output_voice_idstring | nullrequireduuid
  • output_provider_asset_idstring | nullrequireduuid
  • assignment_outcomeanyrequired

    One ofnot_applicableassignedspeaker_changed

  • error_codestring | nullrequired
  • error_messagestring | nullrequired
  • created_atstringrequired
  • completed_atstring | nullrequired
  • candidatesarray of objectrequiredmax 3 items
    6 item attributes
    • idstringrequireduuid
    • candidate_indexintegerrequired0–2
    • preview_urlstring | nullrequireduri
    • preview_textstringrequired1–500 chars
    • duration_msinteger | nullrequired≥ 0
    • statusanyrequired

      One ofavailableselectedfinalizeddiscarded

Response 202

Durable voice preparation accepted. Fields below are inside data.

  • idstringrequireduuid
  • project_idstringrequireduuid
  • section_idstring | nullrequireduuid
  • speaker_idstring | nullrequireduuid
  • source_voice_idstring | nullrequireduuid
  • materialization_kindanyrequired

    One ofprovider_assetai_voice_creation

  • provideranyrequired

    One ofinworldcartesiafish_audiosmallest_aielevenlabsphonon

  • modelstringrequiredmin 1 chars
  • selection_modeanyrequired

    One ofautomaticmanual

  • requested_candidate_countintegerrequired1–3
  • statusanyrequired

    One ofqueuedrunningawaiting_selectioncompletedfailedcancelled

  • selection_expires_atstring | nullrequired
  • selected_candidate_idstring | nullrequireduuid
  • cancel_requested_atstring | nullrequired
  • output_voice_idstring | nullrequireduuid
  • output_provider_asset_idstring | nullrequireduuid
  • assignment_outcomeanyrequired

    One ofnot_applicableassignedspeaker_changed

  • error_codestring | nullrequired
  • error_messagestring | nullrequired
  • created_atstringrequired
  • completed_atstring | nullrequired
  • candidatesarray of objectrequiredmax 3 items
    6 item attributes
    • idstringrequireduuid
    • candidate_indexintegerrequired0–2
    • preview_urlstring | nullrequireduri
    • preview_textstringrequired1–500 chars
    • duration_msinteger | nullrequired≥ 0
    • statusanyrequired

      One ofavailableselectedfinalizeddiscarded

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

curl -X POST "https://lyricwinter.com/api/v1/studio/projects/$PROJECT_ID/speakers/$SPEAKER_ID/voice-materialization-jobs" \
  -H "Authorization: Bearer $LYRICWINTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
Response 200 (example)
{
  "data": {
    "id": "8f14e45f-ceea-4e7a-9c2d-3b1a5f2e7c10",
    "project_id": "c9f0f895-fb98-4b91-9e3f-1d2a6b7c8d20",
    "section_id": "45c48cce-2e2d-4fbd-8a1c-5e6f7a8b9c30",
    "speaker_id": "d3d94468-02a4-4c5e-b6f7-0a1b2c3d4e40",
    "source_voice_id": "8f14e45f-ceea-4e7a-9c2d-3b1a5f2e7c10",
    "materialization_kind": "provider_asset",
    "provider": "inworld",
    "model": "string",
    "selection_mode": "automatic",
    "requested_candidate_count": 1,
    "status": "queued",
    "selection_expires_at": "2026-09-30T17:00:00.000Z",
    "selected_candidate_id": "c9f0f895-fb98-4b91-9e3f-1d2a6b7c8d20",
    "cancel_requested_at": "2026-09-30T17:00:00.000Z",
    "output_voice_id": "45c48cce-2e2d-4fbd-8a1c-5e6f7a8b9c30",
    "output_provider_asset_id": "d3d94468-02a4-4c5e-b6f7-0a1b2c3d4e40",
    "assignment_outcome": "not_applicable",
    "error_code": "string",
    "error_message": "string",
    "created_at": "2026-09-30T17:00:00.000Z",
    "completed_at": "2026-09-30T17:00:00.000Z",
    "candidates": [
      {
        "id": "8f14e45f-ceea-4e7a-9c2d-3b1a5f2e7c10",
        "candidate_index": 1,
        "preview_url": "https://lyricwinter.com/…",
        "preview_text": "string",
        "duration_ms": 1,
        "status": "available"
      }
    ]
  },
  "request_id": "req_01J9Z3K8QF4"
}

Read a character voice job

GET/studio/voice-materialization-jobs/{jobId}

Scope studio:read

Read the original job's status, candidate previews and expiry, output identities, cancellation and assignment_outcome. A completed voice with speaker_changed was not cast; verify the current document before generating speech. Optional wait_seconds from 0 to 25 waits for a status change; terminal or actionable states return immediately.

Path parameters

  • jobIdstringrequireduuid

Query parameters

  • wait_secondsinteger0–25

    Optional bounded wait for a status change. Returns immediately for terminal or actionable jobs; omitted or 0 reads immediately. Available to every Studio client.

Response 200

Current voice preparation state. Fields below are inside data.

  • idstringrequireduuid
  • project_idstringrequireduuid
  • section_idstring | nullrequireduuid
  • speaker_idstring | nullrequireduuid
  • source_voice_idstring | nullrequireduuid
  • materialization_kindanyrequired

    One ofprovider_assetai_voice_creation

  • provideranyrequired

    One ofinworldcartesiafish_audiosmallest_aielevenlabsphonon

  • modelstringrequiredmin 1 chars
  • selection_modeanyrequired

    One ofautomaticmanual

  • requested_candidate_countintegerrequired1–3
  • statusanyrequired

    One ofqueuedrunningawaiting_selectioncompletedfailedcancelled

  • selection_expires_atstring | nullrequired
  • selected_candidate_idstring | nullrequireduuid
  • cancel_requested_atstring | nullrequired
  • output_voice_idstring | nullrequireduuid
  • output_provider_asset_idstring | nullrequireduuid
  • assignment_outcomeanyrequired

    One ofnot_applicableassignedspeaker_changed

  • error_codestring | nullrequired
  • error_messagestring | nullrequired
  • created_atstringrequired
  • completed_atstring | nullrequired
  • candidatesarray of objectrequiredmax 3 items
    6 item attributes
    • idstringrequireduuid
    • candidate_indexintegerrequired0–2
    • preview_urlstring | nullrequireduri
    • preview_textstringrequired1–500 chars
    • duration_msinteger | nullrequired≥ 0
    • statusanyrequired

      One ofavailableselectedfinalizeddiscarded

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

curl "https://lyricwinter.com/api/v1/studio/voice-materialization-jobs/$JOB_ID" \
  -H "Authorization: Bearer $LYRICWINTER_API_KEY"
Response 200 (example)
{
  "data": {
    "id": "8f14e45f-ceea-4e7a-9c2d-3b1a5f2e7c10",
    "project_id": "c9f0f895-fb98-4b91-9e3f-1d2a6b7c8d20",
    "section_id": "45c48cce-2e2d-4fbd-8a1c-5e6f7a8b9c30",
    "speaker_id": "d3d94468-02a4-4c5e-b6f7-0a1b2c3d4e40",
    "source_voice_id": "8f14e45f-ceea-4e7a-9c2d-3b1a5f2e7c10",
    "materialization_kind": "provider_asset",
    "provider": "inworld",
    "model": "string",
    "selection_mode": "automatic",
    "requested_candidate_count": 1,
    "status": "queued",
    "selection_expires_at": "2026-09-30T17:00:00.000Z",
    "selected_candidate_id": "c9f0f895-fb98-4b91-9e3f-1d2a6b7c8d20",
    "cancel_requested_at": "2026-09-30T17:00:00.000Z",
    "output_voice_id": "45c48cce-2e2d-4fbd-8a1c-5e6f7a8b9c30",
    "output_provider_asset_id": "d3d94468-02a4-4c5e-b6f7-0a1b2c3d4e40",
    "assignment_outcome": "not_applicable",
    "error_code": "string",
    "error_message": "string",
    "created_at": "2026-09-30T17:00:00.000Z",
    "completed_at": "2026-09-30T17:00:00.000Z",
    "candidates": [
      {
        "id": "8f14e45f-ceea-4e7a-9c2d-3b1a5f2e7c10",
        "candidate_index": 1,
        "preview_url": "https://lyricwinter.com/…",
        "preview_text": "string",
        "duration_ms": 1,
        "status": "available"
      }
    ]
  },
  "request_id": "req_01J9Z3K8QF4"
}

Cancel a character voice job

POST/studio/voice-materialization-jobs/{jobId}/cancel

Scope studio:write

Request cancellation of the exact original job and read its actual state. Pending cancellation is not completed cleanup or immediate hard deletion and does not reverse existing casting. Do not create replacement work to recover an unknown response.

Path parameters

  • jobIdstringrequireduuid

Response 200

Current cancelled or canceling preparation state. Fields below are inside data.

  • idstringrequireduuid
  • project_idstringrequireduuid
  • section_idstring | nullrequireduuid
  • speaker_idstring | nullrequireduuid
  • source_voice_idstring | nullrequireduuid
  • materialization_kindanyrequired

    One ofprovider_assetai_voice_creation

  • provideranyrequired

    One ofinworldcartesiafish_audiosmallest_aielevenlabsphonon

  • modelstringrequiredmin 1 chars
  • selection_modeanyrequired

    One ofautomaticmanual

  • requested_candidate_countintegerrequired1–3
  • statusanyrequired

    One ofqueuedrunningawaiting_selectioncompletedfailedcancelled

  • selection_expires_atstring | nullrequired
  • selected_candidate_idstring | nullrequireduuid
  • cancel_requested_atstring | nullrequired
  • output_voice_idstring | nullrequireduuid
  • output_provider_asset_idstring | nullrequireduuid
  • assignment_outcomeanyrequired

    One ofnot_applicableassignedspeaker_changed

  • error_codestring | nullrequired
  • error_messagestring | nullrequired
  • created_atstringrequired
  • completed_atstring | nullrequired
  • candidatesarray of objectrequiredmax 3 items
    6 item attributes
    • idstringrequireduuid
    • candidate_indexintegerrequired0–2
    • preview_urlstring | nullrequireduri
    • preview_textstringrequired1–500 chars
    • duration_msinteger | nullrequired≥ 0
    • statusanyrequired

      One ofavailableselectedfinalizeddiscarded

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

curl -X POST "https://lyricwinter.com/api/v1/studio/voice-materialization-jobs/$JOB_ID/cancel" \
  -H "Authorization: Bearer $LYRICWINTER_API_KEY"
Response 200 (example)
{
  "data": {
    "id": "8f14e45f-ceea-4e7a-9c2d-3b1a5f2e7c10",
    "project_id": "c9f0f895-fb98-4b91-9e3f-1d2a6b7c8d20",
    "section_id": "45c48cce-2e2d-4fbd-8a1c-5e6f7a8b9c30",
    "speaker_id": "d3d94468-02a4-4c5e-b6f7-0a1b2c3d4e40",
    "source_voice_id": "8f14e45f-ceea-4e7a-9c2d-3b1a5f2e7c10",
    "materialization_kind": "provider_asset",
    "provider": "inworld",
    "model": "string",
    "selection_mode": "automatic",
    "requested_candidate_count": 1,
    "status": "queued",
    "selection_expires_at": "2026-09-30T17:00:00.000Z",
    "selected_candidate_id": "c9f0f895-fb98-4b91-9e3f-1d2a6b7c8d20",
    "cancel_requested_at": "2026-09-30T17:00:00.000Z",
    "output_voice_id": "45c48cce-2e2d-4fbd-8a1c-5e6f7a8b9c30",
    "output_provider_asset_id": "d3d94468-02a4-4c5e-b6f7-0a1b2c3d4e40",
    "assignment_outcome": "not_applicable",
    "error_code": "string",
    "error_message": "string",
    "created_at": "2026-09-30T17:00:00.000Z",
    "completed_at": "2026-09-30T17:00:00.000Z",
    "candidates": [
      {
        "id": "8f14e45f-ceea-4e7a-9c2d-3b1a5f2e7c10",
        "candidate_index": 1,
        "preview_url": "https://lyricwinter.com/…",
        "preview_text": "string",
        "duration_ms": 1,
        "status": "available"
      }
    ]
  },
  "request_id": "req_01J9Z3K8QF4"
}

Select a character voice candidate

POST/studio/voice-materialization-jobs/{jobId}/selection

Scope studio:write

Choose one exact candidate from its original job before selection expires. The server checks candidate ownership and speaker authority; finalization can be asynchronous. Return the actual assignment outcome, and read the same job after uncertainty. No speech generation is started.

Path parameters

  • jobIdstringrequireduuid

Request body application/json

  • schema_version1required
  • candidate_idstringrequireduuid

Response 200

The selected voice was already finalized. Fields below are inside data.

  • idstringrequireduuid
  • project_idstringrequireduuid
  • section_idstring | nullrequireduuid
  • speaker_idstring | nullrequireduuid
  • source_voice_idstring | nullrequireduuid
  • materialization_kindanyrequired

    One ofprovider_assetai_voice_creation

  • provideranyrequired

    One ofinworldcartesiafish_audiosmallest_aielevenlabsphonon

  • modelstringrequiredmin 1 chars
  • selection_modeanyrequired

    One ofautomaticmanual

  • requested_candidate_countintegerrequired1–3
  • statusanyrequired

    One ofqueuedrunningawaiting_selectioncompletedfailedcancelled

  • selection_expires_atstring | nullrequired
  • selected_candidate_idstring | nullrequireduuid
  • cancel_requested_atstring | nullrequired
  • output_voice_idstring | nullrequireduuid
  • output_provider_asset_idstring | nullrequireduuid
  • assignment_outcomeanyrequired

    One ofnot_applicableassignedspeaker_changed

  • error_codestring | nullrequired
  • error_messagestring | nullrequired
  • created_atstringrequired
  • completed_atstring | nullrequired
  • candidatesarray of objectrequiredmax 3 items
    6 item attributes
    • idstringrequireduuid
    • candidate_indexintegerrequired0–2
    • preview_urlstring | nullrequireduri
    • preview_textstringrequired1–500 chars
    • duration_msinteger | nullrequired≥ 0
    • statusanyrequired

      One ofavailableselectedfinalizeddiscarded

Response 202

Candidate finalization accepted. Fields below are inside data.

  • idstringrequireduuid
  • project_idstringrequireduuid
  • section_idstring | nullrequireduuid
  • speaker_idstring | nullrequireduuid
  • source_voice_idstring | nullrequireduuid
  • materialization_kindanyrequired

    One ofprovider_assetai_voice_creation

  • provideranyrequired

    One ofinworldcartesiafish_audiosmallest_aielevenlabsphonon

  • modelstringrequiredmin 1 chars
  • selection_modeanyrequired

    One ofautomaticmanual

  • requested_candidate_countintegerrequired1–3
  • statusanyrequired

    One ofqueuedrunningawaiting_selectioncompletedfailedcancelled

  • selection_expires_atstring | nullrequired
  • selected_candidate_idstring | nullrequireduuid
  • cancel_requested_atstring | nullrequired
  • output_voice_idstring | nullrequireduuid
  • output_provider_asset_idstring | nullrequireduuid
  • assignment_outcomeanyrequired

    One ofnot_applicableassignedspeaker_changed

  • error_codestring | nullrequired
  • error_messagestring | nullrequired
  • created_atstringrequired
  • completed_atstring | nullrequired
  • candidatesarray of objectrequiredmax 3 items
    6 item attributes
    • idstringrequireduuid
    • candidate_indexintegerrequired0–2
    • preview_urlstring | nullrequireduri
    • preview_textstringrequired1–500 chars
    • duration_msinteger | nullrequired≥ 0
    • statusanyrequired

      One ofavailableselectedfinalizeddiscarded

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

curl -X POST "https://lyricwinter.com/api/v1/studio/voice-materialization-jobs/$JOB_ID/selection" \
  -H "Authorization: Bearer $LYRICWINTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "schema_version": 1,
  "candidate_id": "8f14e45f-ceea-4e7a-9c2d-3b1a5f2e7c10"
}'
Response 200 (example)
{
  "data": {
    "id": "8f14e45f-ceea-4e7a-9c2d-3b1a5f2e7c10",
    "project_id": "c9f0f895-fb98-4b91-9e3f-1d2a6b7c8d20",
    "section_id": "45c48cce-2e2d-4fbd-8a1c-5e6f7a8b9c30",
    "speaker_id": "d3d94468-02a4-4c5e-b6f7-0a1b2c3d4e40",
    "source_voice_id": "8f14e45f-ceea-4e7a-9c2d-3b1a5f2e7c10",
    "materialization_kind": "provider_asset",
    "provider": "inworld",
    "model": "string",
    "selection_mode": "automatic",
    "requested_candidate_count": 1,
    "status": "queued",
    "selection_expires_at": "2026-09-30T17:00:00.000Z",
    "selected_candidate_id": "c9f0f895-fb98-4b91-9e3f-1d2a6b7c8d20",
    "cancel_requested_at": "2026-09-30T17:00:00.000Z",
    "output_voice_id": "45c48cce-2e2d-4fbd-8a1c-5e6f7a8b9c30",
    "output_provider_asset_id": "d3d94468-02a4-4c5e-b6f7-0a1b2c3d4e40",
    "assignment_outcome": "not_applicable",
    "error_code": "string",
    "error_message": "string",
    "created_at": "2026-09-30T17:00:00.000Z",
    "completed_at": "2026-09-30T17:00:00.000Z",
    "candidates": [
      {
        "id": "8f14e45f-ceea-4e7a-9c2d-3b1a5f2e7c10",
        "candidate_index": 1,
        "preview_url": "https://lyricwinter.com/…",
        "preview_text": "string",
        "duration_ms": 1,
        "status": "available"
      }
    ]
  },
  "request_id": "req_01J9Z3K8QF4"
}