# Lyria 3 (music) > Lyria 3 writes a music track from a text description. It supports vocals, lyrics and several languages. Status: roasOS API v1.1. Catalog `model-catalog@2026-10-06.v5`, pricing `customer-pricing@2026-11-05.v15`. The endpoint `POST /v1/music/lyria3` is live. `POST /v1/generations` has no `music` type, so this endpoint is the only path to this model. ## Endpoint POST https://api.roasos.com/v1/music/lyria3 Auth: Authorization: Bearer roasos_sk_… (scope api:write). Idempotency-Key required. quote_only / quote_id / webhook_url as in https://docs.roasos.com/llms.txt. ## Good at Score an ad from a written brief. Describe genre, mood, instrumentation, tempo and vocal style; the model writes and performs it. Use it when you want a bed under a voice-over and you do not have a track. The price is $0.04 per track, flat. There is no duration field, so the quote is exact and nothing reconciles. The endpoint states no output length either, so roasOS publishes none: read the length of the file the job returns. roasOS states no rights position on the music this model generates. Read the terms of the model and of fal before you publish a track. ## Pricing Unit: track. Pricing key: `lyria3`. | request | credits | |---|---| | `per_track` | 1 | Credits come from the roasOS pricing table (`MODEL_COSTS`) through the catalog. No other field changes the price. ## Modes - `text-to-music` Provider endpoints: `fal-ai/lyria3`. ## Request fields | field | type | required | default | rule | |---|---|---|---|---| | `image_url` | string | no | — | https URL; ≤ 4,096 characters | | `prompt` | string | yes | — | ≥ 1 character; ≤ 5,000 characters | | `quote_id` | string | no | — | UUID | | `quote_only` | boolean | no | `false` | — | | `wait_timeout_seconds` | integer | no | `0` | 0–60 | | `webhook_url` | string | no | — | https URL; ≤ 4,096 characters | The schema is strict: a field that is not in this table returns `400 unsupported_option`. Field names are the roasOS role names, one name per role across every family. ## Media - `image_url` — first frame (or the single source image) | role | items | max size | content types | duration | |---|---|---|---|---| | `image_url` | ≤ 1 | 10 MB | `image/jpeg`, `image/png`, `image/webp` | — | - Refused: `avatar_id`, `elements`, `product_id`, `product_images`, `references`, `reference_images`, `end_image_url`, `scene_id`, `scene_image`, `video_urls`, `video_url`, `audio_urls`, `audio_url`, `voice_id`. A refused role returns `400 unsupported_option`. - Every URL must be an immutable object on `https://cdn.roasos.com/…` that your workspace owns; any other URL is `400 reference_media_not_workspace_owned`. Upload with `POST /v1/uploads` (direct POST of the bytes to `put_url`, or a `source_url` import), then use the returned CDN URL. ## Prompt Write the brief, not the adjective. Name the genre, the BPM, the instruments, the vocal style and the hook you want. "An energetic electronic dance track with soaring synth leads, punchy four-on-the-floor kick drums and a catchy vocal hook, 128 BPM" beats "upbeat music". `image_url` is mood inspiration, not a first frame: the model reads the picture's feel, not its contents. ## Not exposed - `negative_prompt`: pinned to `provider-deprecated: fal states negative prompting is not supported`. ## Result Result kind `audio`. Always present: `url`. Present when the run produces it: `timestamps`. ```json { "data": { "id": "gen_…", "kind": "audio", "model": "lyria3", "status": "completed", "result": {"timestamps":[{}],"url":"https://cdn.roasos.com/workspaces/ws_01/result"} } } ``` Files live on `https://cdn.roasos.com` and are immutable; a result URL can be a media input to the next call. Poll `GET /v1/jobs/{id}/status` → `{ id, status, updated_at }`, then `GET /v1/jobs/{id}/result` (`409 run_not_completed` until the job is `completed`, `failed` or `canceled`). Statuses: `queued → processing → completed | failed | canceled`. ## Example ```bash # 1. quote — nothing is spent curl -X POST https://api.roasos.com/v1/music/lyria3 \ -H "Authorization: Bearer roasos_sk_live_…" \ -H "Idempotency-Key: 0f1c9e2a-lyria3-0001" \ -H "Content-Type: application/json" \ -d '{"quote_only":true,"prompt":"A woman holds the bottle at eye level in a bright kitchen, morning light, static camera."}' # → 200 { "data": { "kind": "quote", "quote_id": "q_7Hk…", "credits": 1, "expires_at": "…", "confirmation": { "model": "lyria3", "example": "per_track" } } } # 2. run — the same body and the same Idempotency-Key, quote_id instead of quote_only curl -X POST https://api.roasos.com/v1/music/lyria3 \ -H "Authorization: Bearer roasos_sk_live_…" \ -H "Idempotency-Key: 0f1c9e2a-lyria3-0001" \ -H "Content-Type: application/json" \ -d '{"quote_id":"q_7Hk…","prompt":"A woman holds the bottle at eye level in a bright kitchen, morning light, static camera."}' # → 201 { "data": { "id": "gen_…", "kind": "audio", "model": "lyria3", "status": "queued", "credits_reserved": 1, "links": { "status": "/v1/jobs/gen_…/status", "result": "/v1/jobs/gen_…/result" } } } # 3. poll curl https://api.roasos.com/v1/jobs/gen_…/status -H "Authorization: Bearer roasos_sk_live_…" curl https://api.roasos.com/v1/jobs/gen_…/result -H "Authorization: Bearer roasos_sk_live_…" ``` ## Today The endpoint is `POST /v1/music/lyria3`. It is live. ## See also https://docs.roasos.com/models/music/lyria3 · https://api.roasos.com/v1/catalog/music/lyria3 · fal-ai/lyria3