← ElevenLabsCONTENT HISTORYWHAT CHANGED · RULE-BASED ANALYSIS
Update to ElevenLabs
Snapshot Sep 30, 2026 · 22:53 UTC · version 1.0.0
Collection source: not recorded for this historical snapshot.
First saved snapshot
No earlier snapshot is available to establish a change.
Compare saved observations
Download comparison JSONFull technical diff · 0 changed fields
Full snapshot data
{
"name": "music",
"description": "Generate music using ElevenLabs Music API. Use when creating instrumental tracks, songs with lyrics, background music, jingles, or any AI-generated music composition. Supports prompt-based generation, composition plans for granular control, and detailed output with metadata.",
"included_files": [
{
"relative_path": "references/api_reference.md",
"size_in_bytes": 17229
},
{
"relative_path": "references/installation.md",
"size_in_bytes": 2049
}
],
"skill_md_contents": "---\nname: music\ndescription: Generate music using ElevenLabs Music API. Use when creating instrumental tracks, songs with lyrics, background music, jingles, or any AI-generated music composition. Supports prompt-based generation, composition plans for granular control, and detailed output with metadata.\nlicense: MIT\ncompatibility: Requires internet access and an ElevenLabs API key (ELEVENLABS_API_KEY).\nmetadata: {\"openclaw\": {\"requires\": {\"env\": [\"ELEVENLABS_API_KEY\"]}, \"primaryEnv\": \"ELEVENLABS_API_KEY\"}}\n---\n\n# ElevenLabs Music Generation\n\nGenerate music from text prompts - supports instrumental tracks, songs with lyrics, and fine-grained control via composition plans.\n\n> **Setup:** See [Installation Guide](references/installation.md). For JavaScript, use `@elevenlabs/*` packages only.\n\nAll examples below default to `music_v2`, the current generation model. Pass `model_id=\"music_v1\"` only when explicitly requested to.\n\n## Quick Start\n\n### Python\n\n```python\nfrom elevenlabs import ElevenLabs\n\nclient = ElevenLabs()\n\naudio = client.music.compose(\n prompt=\"A chill lo-fi hip hop beat with jazzy piano chords\",\n music_length_ms=30000,\n model_id=\"music_v2\",\n)\n\nwith open(\"output.mp3\", \"wb\") as f:\n for chunk in audio:\n f.write(chunk)\n```\n\n### TypeScript\n\n```typescript\nimport { ElevenLabsClient } from \"@elevenlabs/elevenlabs-js\";\nimport { createWriteStream } from \"fs\";\n\nconst client = new ElevenLabsClient();\nconst audio = await client.music.compose({\n prompt: \"A chill lo-fi hip hop beat with jazzy piano chords\",\n musicLengthMs: 30000,\n modelId: \"music_v2\",\n});\naudio.pipe(createWriteStream(\"output.mp3\"));\n```\n\n### CLI\n\n```bash\nelevenlabs music compose \\\n --prompt \"A chill lo-fi beat\" \\\n --music-length-ms 30000 \\\n --model-id music_v2 \\\n --output output.mp3\n```\n\n## Methods\n\n| Method | Description |\n|--------|-------------|\n| `music.compose` | Generate audio from a prompt or composition plan |\n| `music.stream` | Stream audio chunks as they are generated (paid plans) |\n| `music.composition_plan.create` | Generate a structured plan for fine-grained control |\n| `music.compose_detailed` | Generate audio + composition plan + metadata; pass `store_for_inpainting=True` to enable inpainting |\n| `music.compose_detailed_stream` | Stream audio plus composition plan, metadata, and optional word timestamps as Server-Sent Events |\n| `music.video_to_music` | Generate background music from one or more uploaded video files |\n| `music.upload` | Upload an audio file for later inpainting workflows, optionally extracting its composition plan or word-level timestamps |\n| `music.finetunes.list` | List accessible music finetunes |\n| `music.finetunes.create` | Train a music finetune from uploaded audio |\n| `music.finetunes.get` | Retrieve finetune status and metadata |\n| `music.finetunes.update` | Update finetune metadata or visibility |\n| `music.finetunes.delete` | Delete a music finetune |\n\nSee [API Reference](references/api_reference.md) for full parameter details.\n\n`music.upload` is available to enterprise clients with access to the inpainting feature.\n\n## Music Finetunes\n\nCreate a finetune from training audio with\n[`POST /v1/music/finetunes`](https://elevenlabs.io/docs/api-reference/music/finetunes/create),\nthen poll the [get endpoint](https://elevenlabs.io/docs/api-reference/music/finetunes/get) until\nits status is `completed`. Pass the returned `id` as `finetune_id` when composing music.\n\nUse the [list](https://elevenlabs.io/docs/api-reference/music/finetunes/list),\n[update](https://elevenlabs.io/docs/api-reference/music/finetunes/update), and\n[delete](https://elevenlabs.io/docs/api-reference/music/finetunes/delete) endpoints to manage\naccessible finetunes.\n\n## Video to Music\n\nGenerate background music from uploaded video clips via\n[`POST /v1/music/video-to-music`](https://elevenlabs.io/docs/api-reference/music/video-to-music)\n(`client.music.video_to_music`). This is separate from prompt-based\n[`music.compose`](https://elevenlabs.io/docs/api-reference/music/compose) (`POST /v1/music`).\n\nThe API combines videos in order, accepts an optional natural-language description, and lets you\nsteer style with up to 10 tags such as `upbeat` or `cinematic`. This endpoint still defaults to\n`music_v1`; pass `model_id=\"music_v2\"` to use the newer model.\n\n### Python\n\n```python\nfrom elevenlabs import ElevenLabs\n\nclient = ElevenLabs()\n\naudio = client.music.video_to_music(\n videos=[\"trailer.mp4\"],\n description=\"Build suspense, then resolve with a warm cinematic finish.\",\n tags=[\"cinematic\", \"suspenseful\", \"uplifting\"],\n model_id=\"music_v2\",\n)\n\nwith open(\"video-score.mp3\", \"wb\") as f:\n for chunk in audio:\n f.write(chunk)\n```\n\n### TypeScript\n\n```typescript\nimport { ElevenLabsClient } from \"@elevenlabs/elevenlabs-js\";\nimport { createReadStream, createWriteStream } from \"fs\";\n\nconst client = new ElevenLabsClient();\n\nconst audio = await client.music.videoToMusic({\n videos: [createReadStream(\"trailer.mp4\")],\n description: \"Build suspense, then resolve with a warm cinematic finish.\",\n tags: [\"cinematic\", \"suspenseful\", \"uplifting\"],\n modelId: \"music_v2\",\n});\n\naudio.pipe(createWriteStream(\"video-score.mp3\"));\n```\n\n### CLI\n\n```bash\nelevenlabs music video_to_music \\\n --videos trailer.mp4 \\\n --description \"Build suspense, then resolve with a warm cinematic finish.\" \\\n --tags cinematic \\\n --model-id music_v2 \\\n --output video-score.mp3\n```\n\nThe CLI currently accepts one `--videos` file and one `--tags` value per request; use the Python\nor TypeScript SDK to send multiple videos or tags.\n\nConstraints from the current API schema:\n\n- Upload 1-10 video files per request\n- Keep total combined upload size at or below 200 MB\n- Keep total combined video duration at or below 600 seconds\n- Use `description` for high-level musical direction and `tags` for concise style cues\n\n## Composition Plans\n\n`music_v2` composition plans are an ordered list of `chunks`. Each chunk specifies its own\n`text` (section label, lyrics, inline cues), `duration_ms`, `positive_styles`, `negative_styles`,\nand `context_adherence` (`low`, `medium`, or `high`, default `high`). Up to 30 chunks per plan,\neach 3,000–120,000 ms, total length 3 s to 10 minutes.\n\nGenerate a plan first, edit it, then compose:\n\n```python\nplan = client.music.composition_plan.create(\n prompt=\"An epic orchestral piece building to a climax\",\n music_length_ms=60000,\n model_id=\"music_v2\",\n)\n\n# Edit chunks in place\nplan[\"chunks\"][0][\"text\"] = \"[Intro]\\nQuiet strings rising\"\n\naudio = client.music.compose(\n composition_plan=plan,\n model_id=\"music_v2\",\n)\n```\n\n```typescript\nconst plan = await client.music.compositionPlan.create({\n prompt: \"An epic orchestral piece building to a climax\",\n musicLengthMs: 60000,\n modelId: \"music_v2\",\n});\n\nplan.chunks[0].text = \"[Intro]\\nQuiet strings rising\";\n\nconst audio = await client.music.compose({\n compositionPlan: plan,\n modelId: \"music_v2\",\n});\n```\n\nOr hand-build a plan to control lyrics and style per section:\n\n```python\ncomposition_plan = {\n \"chunks\": [\n {\n \"text\": \"[Verse]\\nWalking down an empty street\",\n \"duration_ms\": 15000,\n \"positive_styles\": [\"pop\", \"upbeat\", \"female vocals\", \"acoustic guitar\"],\n \"negative_styles\": [\"dark\", \"slow\"],\n \"context_adherence\": \"high\",\n },\n {\n \"text\": \"[Chorus]\\nThis is my moment\",\n \"duration_ms\": 15000,\n \"positive_styles\": [\"powerful vocals\", \"full band\"],\n \"negative_styles\": [],\n \"context_adherence\": \"high\",\n },\n ]\n}\n\naudio = client.music.compose(composition_plan=composition_plan, model_id=\"music_v2\")\n```\n\n```typescript\nconst compositionPlan = {\n chunks: [\n {\n text: \"[Verse]\\nWalking down an empty street\",\n durationMs: 15000,\n positiveStyles: [\"pop\", \"upbeat\", \"female vocals\", \"acoustic guitar\"],\n negativeStyles: [\"dark\", \"slow\"],\n contextAdherence: \"high\",\n },\n {\n text: \"[Chorus]\\nThis is my moment\",\n durationMs: 15000,\n positiveStyles: [\"powerful vocals\", \"full band\"],\n negativeStyles: [],\n contextAdherence: \"high\",\n },\n ],\n};\n\nconst audio = await client.music.compose({\n compositionPlan,\n modelId: \"music_v2\",\n});\n```\n\nPut broader characteristics (genre, instrumentation, vocal style) in `positive_styles`, not in\n`text`. The first chunk's styles set the overall tone — include 6–7 styles there.\n\n## Output Formats\n\nUse the `output_format` query parameter on compose, detailed compose, or stream requests to select\nthe generated audio format. `auto` chooses a model-appropriate MP3 format; for `music_v2`, it\nselects `mp3_48000_192`. Higher-bitrate MP3 options include `mp3_48000_240` and `mp3_48000_320`.\n\n## Streaming\n\nFor paid plans, stream audio chunks as they are generated instead of waiting for the full file:\n\n```python\nfrom io import BytesIO\n\nstream = client.music.stream(\n prompt=\"A driving synthwave track with arpeggiated leads\",\n music_length_ms=30000,\n model_id=\"music_v2\",\n)\n\nbuffer = BytesIO()\nfor chunk in stream:\n if chunk:\n buffer.write(chunk)\n```\n\n```typescript\nconst stream = await client.music.stream({\n prompt: \"A driving synthwave track with arpeggiated leads\",\n musicLengthMs: 30000,\n modelId: \"music_v2\",\n});\n\nconst chunks: Buffer[] = [];\nfor await (const chunk of stream) {\n chunks.push(chunk);\n}\n```\n\n### Detailed streaming\n\nUse detailed streaming when the application needs generated music metadata while audio is still\narriving. `POST /v1/music/detailed/stream` accepts the same prompt or composition-plan body as\ndetailed compose, streams `text/event-stream`, and can include word timestamps with\n`with_timestamps`.\n\n```bash\nelevenlabs music compose_detailed_stream \\\n --prompt \"A bright indie pop hook with warm guitars\" \\\n --music-length-ms 30000 \\\n --model-id music_v2 \\\n --with-timestamps true \\\n --output-format auto\n```\n\n## Inpainting\n\nInpainting edits or extends a stored song by mixing **audio reference chunks** (unchanged slices\nof a stored song) with new **generation chunks** in a single composition plan. \n\nStep 1 — get a `song_id`, either by storing a fresh generation or uploading existing audio:\n\n```python\n# Option A: keep a generation for later editing\nresult = client.music.compose_detailed(\n prompt=\"An upbeat pop song with verse and chorus\",\n music_length_ms=60000,\n model_id=\"music_v2\",\n store_for_inpainting=True,\n)\nsong_id = result.song_id\n\n# Option B: upload an existing track and extract its plan\nuploaded = client.music.upload(\n file=open(\"my-song.mp3\", \"rb\"),\n extract_composition_plan=\"music_v2\",\n)\nsong_id = uploaded.song_id\ncomposition_plan = uploaded.composition_plan\n```\n\n```typescript\nimport { createReadStream } from \"fs\";\n\n// Option A: keep a generation for later editing\nconst result = await client.music.composeDetailed({\n prompt: \"An upbeat pop song with verse and chorus\",\n musicLengthMs: 60000,\n modelId: \"music_v2\",\n storeForInpainting: true,\n});\nlet songId = result.songId;\n\n// Option B: upload an existing track and extract its plan\nconst uploaded = await client.music.upload({\n file: createReadStream(\"my-song.mp3\"),\n extractCompositionPlan: \"music_v2\",\n});\nsongId = uploaded.songId;\nconst compositionPlan = uploaded.compositionPlan;\n```\n\nStep 2 — compose a plan that references the stored audio and regenerates the part you want to\nchange:\n\n```python\nplan = {\n \"chunks\": [\n {\"song_id\": song_id, \"range\": {\"start_ms\": 0, \"end_ms\": 30000}},\n {\n \"text\": \"[Chorus]\\nWe're rising up tonight\",\n \"duration_ms\": 30000,\n \"positive_styles\": [\"bigger drums\", \"layered vocals\", \"anthemic\"],\n \"negative_styles\": [\"sparse\"],\n \"context_adherence\": \"high\",\n },\n ]\n}\n\naudio = client.music.compose(composition_plan=plan, model_id=\"music_v2\")\n```\n\n```typescript\nconst plan = {\n chunks: [\n { songId, range: { startMs: 0, endMs: 30000 } },\n {\n text: \"[Chorus]\\nWe're rising up tonight\",\n durationMs: 30000,\n positiveStyles: [\"bigger drums\", \"layered vocals\", \"anthemic\"],\n negativeStyles: [\"sparse\"],\n contextAdherence: \"high\",\n },\n ],\n};\n\nconst audio = await client.music.compose({\n compositionPlan: plan,\n modelId: \"music_v2\",\n});\n```\n\nTo match the feel of a stored slice without copying it, attach a `conditioning_ref` (up to\n30,000 ms) plus a `condition_strength` of `low`, `medium`, `high`, or `xhigh` to a generation\nchunk. Conditioning placed on the first chunk influences every later chunk.\n\nSee [API Reference](references/api_reference.md) for the full inpainting parameter list.\n\n## Content Restrictions\n\n- Cannot reference specific artists, bands, or copyrighted lyrics\n- `bad_prompt` errors include a `prompt_suggestion` with alternative phrasing\n- `bad_composition_plan` errors include a `composition_plan_suggestion`\n\n## Error Handling\n\n```python\ntry:\n audio = client.music.compose(prompt=\"...\", music_length_ms=30000)\nexcept Exception as e:\n print(f\"API error: {e}\")\n```\n\n```typescript\ntry {\n const audio = await client.music.compose({\n prompt: \"...\",\n musicLengthMs: 30000,\n });\n} catch (err) {\n console.error(\"API error:\", err);\n}\n```\n\nCommon errors: 401 (invalid key), 422 (invalid params), 429 (rate limit).\n\n## References\n\n- [Installation Guide](references/installation.md)\n- [API Reference](references/api_reference.md)\n"
}SHA-256: 6f3f7fa698b90d60d8b31d27a8c486a1a3d6951094b801478204befc749f03bc