Music
ElevenLabsOfficialPublished by ElevenLabs
- Skill
- Tool integration
- Automation and integrations
- MIT
- Medium risk
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides an interface to the ElevenLabs Music API, enabling the generation of instrumental tracks, songs with lyrics, and background music. It supports prompt-based generation, structured composition plans for granular control, and advanced features like inpainting, video-to-music conversion, and custom finetuning.
What it does
- Generates music from text prompts or structured composition plans.
- Converts video files into synchronized background music scores.
- Supports inpainting to edit or extend existing audio tracks.
- Enables training and management of custom music finetunes.
- Provides streaming capabilities for audio generation.
- Allows detailed output with metadata and word-level timestamps.
When to use it
- When you need to generate original background music or songs for creative projects.
- When you require precise control over musical structure, lyrics, or instrumentation.
- When you need to score video content with AI-generated music.
- When you want to edit or extend previously generated audio using inpainting.
Advantages
- Offers granular control via composition plans for specific sections and styles.
- Supports both simple prompt-based generation and complex multi-step workflows.
- Provides tools for managing and reusing custom music finetunes.
- Enables integration with video workflows for automated scoring.
Usage examples
- “Generate a 30-second chill lo-fi hip hop beat.”
- The agent uses the music.compose method to generate an MP3 file based on the provided prompt and duration.
- “Create a background score for this video file.”
- The agent uses the music.video_to_music method to analyze the video and generate a matching musical score.
- “Create a composition plan for an orchestral piece.”
- The agent generates a structured JSON plan that can be edited before final audio synthesis.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/elevenlabs/music/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip music.zip -d .agents/skills
Documentation by ElevenLabs
ElevenLabs Music Generation
Generate music from text prompts - supports instrumental tracks, songs with lyrics, and fine-grained control via composition plans.
Setup, before writing any code: if
ELEVENLABS_API_KEYisn't set for this project, runnpx -y @elevenlabs/cli@latest onboard initfrom the app's folder first and follow what it prints: it signs the user in and stores a key for the project, so nobody copies one by hand. Otherwise see the Installation Guide. For JavaScript, use@elevenlabs/*packages only.
All examples below use music_v2_5, the most advanced generation model. Pass music_v2 or
music_v1 only when an older model is explicitly requested.
Quick Start
Python
from elevenlabs import ElevenLabs
client = ElevenLabs()
audio = client.music.compose(
prompt="A chill lo-fi hip hop beat with jazzy piano chords",
music_length_ms=30000,
model_id="music_v2_5",
)
with open("output.mp3", "wb") as f:
for chunk in audio:
f.write(chunk)TypeScript
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
import { createWriteStream } from "fs";
const client = new ElevenLabsClient();
const audio = await client.music.compose({
prompt: "A chill lo-fi hip hop beat with jazzy piano chords",
musicLengthMs: 30000,
modelId: "music_v2_5",
});
audio.pipe(createWriteStream("output.mp3"));CLI
elevenlabs music compose \
--prompt "A chill lo-fi beat" \
--music-length-ms 30000 \
--model-id music_v2_5 \
--output output.mp3Methods
| Method | Description |
|---|---|
music.compose | Generate audio from a prompt or composition plan |
music.stream | Stream audio chunks as they are generated (paid plans) |
music.composition_plan.create | Generate a structured plan for fine-grained control |
music.compose_detailed | Generate audio + composition plan + metadata; pass store_for_inpainting=True to enable inpainting |
music.compose_detailed_stream | Stream audio plus composition plan, metadata, and optional word timestamps as Server-Sent Events |
music.video_to_music | Generate background music from one or more uploaded video files |
music.upload | Upload an audio file for later inpainting workflows, optionally extracting its composition plan or word-level timestamps |
music.finetunes.list | List accessible music finetunes |
music.finetunes.create | Train a music finetune from uploaded audio |
music.finetunes.get | Retrieve finetune status and metadata |
music.finetunes.update | Update finetune metadata or visibility |
music.finetunes.delete | Delete a music finetune |
See API Reference for full parameter details.
music.upload is available to enterprise clients with access to the inpainting feature.
Music Finetunes
Create a finetune from training audio with
POST /v1/music/finetunes,
then poll the get endpoint until
its status is completed. Pass the returned id as finetune_id when composing music.
Use the list, update, and delete endpoints to manage accessible finetunes.
Video to Music
Generate background music from uploaded video clips via
POST /v1/music/video-to-music
(client.music.video_to_music). This is separate from prompt-based
music.compose (POST /v1/music).
The API combines videos in order, accepts an optional natural-language description, and lets you
steer style with up to 10 tags such as upbeat or cinematic. This endpoint still defaults to
music_v1; pass model_id="music_v2_5" to use the most advanced model.
Three optional flags shape the result: use_audio_as_reference takes genre, BPM, instrumentation,
and mood from the video's own audio, add_sfx adds sound effects that match the video, and
separate_tracks returns a ZIP with the music and sound effects as separate files for mixing.
Python
from elevenlabs import ElevenLabs
client = ElevenLabs()
audio = client.music.video_to_music(
videos=["trailer.mp4"],
description="Build suspense, then resolve with a warm cinematic finish.",
tags=["cinematic", "suspenseful", "uplifting"],
model_id="music_v2_5",
)
with open("video-score.mp3", "wb") as f:
for chunk in audio:
f.write(chunk)TypeScript
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
import { createReadStream, createWriteStream } from "fs";
const client = new ElevenLabsClient();
const audio = await client.music.videoToMusic({
videos: [createReadStream("trailer.mp4")],
description: "Build suspense, then resolve with a warm cinematic finish.",
tags: ["cinematic", "suspenseful", "uplifting"],
modelId: "music_v2_5",
});
audio.pipe(createWriteStream("video-score.mp3"));CLI
elevenlabs music video_to_music \
--videos trailer.mp4 \
--description "Build suspense, then resolve with a warm cinematic finish." \
--tags cinematic \
--model-id music_v2_5 \
--output video-score.mp3The CLI currently accepts one --videos file and one --tags value per request; use the Python
or TypeScript SDK to send multiple videos or tags.
Constraints from the current API schema:
Upload 1-10 video files per request
Keep total combined upload size at or below 200 MB
Keep total combined video duration at or below 600 seconds
Use
descriptionfor high-level musical direction andtagsfor concise style cues
Composition Plans
music_v2_5 composition plans are an ordered list of chunks. Each chunk specifies its own
text (section label, lyrics, inline cues), duration_ms, positive_styles, negative_styles,
and context_adherence (low, medium, or high, default high). Up to 30 chunks per plan,
each 3,000–120,000 ms, total length 3 s to 10 minutes. Each chunk's text supports up to 6,132
characters, with up to 30 lines of 200 characters each.
Generate a plan first, edit it, then compose:
plan = client.music.composition_plan.create(
prompt="An epic orchestral piece building to a climax",
music_length_ms=60000,
model_id="music_v2_5",
)
# Edit chunks in place
plan["chunks"][0]["text"] = "[Intro]\nQuiet strings rising"
audio = client.music.compose(
composition_plan=plan,
model_id="music_v2_5",
)const plan = await client.music.compositionPlan.create({
prompt: "An epic orchestral piece building to a climax",
musicLengthMs: 60000,
modelId: "music_v2_5",
});
plan.chunks[0].text = "[Intro]\nQuiet strings rising";
const audio = await client.music.compose({
compositionPlan: plan,
modelId: "music_v2_5",
});Or hand-build a plan to control lyrics and style per section:
composition_plan = {
"chunks": [
{
"text": "[Verse]\nWalking down an empty street",
"duration_ms": 15000,
"positive_styles": ["pop", "upbeat", "female vocals", "acoustic guitar"],
"negative_styles": ["dark", "slow"],
"context_adherence": "high",
},
{
"text": "[Chorus]\nThis is my moment",
"duration_ms": 15000,
"positive_styles": ["powerful vocals", "full band"],
"negative_styles": [],
"context_adherence": "high",
},
]
}
audio = client.music.compose(composition_plan=composition_plan, model_id="music_v2_5")const compositionPlan = {
chunks: [
{
text: "[Verse]\nWalking down an empty street",
durationMs: 15000,
positiveStyles: ["pop", "upbeat", "female vocals", "acoustic guitar"],
negativeStyles: ["dark", "slow"],
contextAdherence: "high",
},
{
text: "[Chorus]\nThis is my moment",
durationMs: 15000,
positiveStyles: ["powerful vocals", "full band"],
negativeStyles: [],
contextAdherence: "high",
},
],
};
const audio = await client.music.compose({
compositionPlan,
modelId: "music_v2_5",
});Put broader characteristics (genre, instrumentation, vocal style) in positive_styles, not in
text. The first chunk's styles set the overall tone — include 6–7 styles there.
Output Formats
Use the output_format query parameter on compose, detailed compose, or stream requests to select
the generated audio format. auto chooses a model-appropriate MP3 format; for music_v2 and
music_v2_5, it selects mp3_48000_192. Higher-bitrate MP3 options include
mp3_48000_240 and mp3_48000_320.
Streaming
For paid plans, stream audio chunks as they are generated instead of waiting for the full file:
from io import BytesIO
stream = client.music.stream(
prompt="A driving synthwave track with arpeggiated leads",
music_length_ms=30000,
model_id="music_v2_5",
)
buffer = BytesIO()
for chunk in stream:
if chunk:
buffer.write(chunk)const stream = await client.music.stream({
prompt: "A driving synthwave track with arpeggiated leads",
musicLengthMs: 30000,
modelId: "music_v2_5",
});
const chunks: Buffer[] = [];
for await (const chunk of stream) {
chunks.push(chunk);
}Detailed streaming
Use detailed streaming when the application needs generated music metadata while audio is still
arriving. POST /v1/music/detailed/stream accepts the same prompt or composition-plan body as
detailed compose, streams text/event-stream, and can include word timestamps with
with_timestamps.
elevenlabs music compose_detailed_stream \
--prompt "A bright indie pop hook with warm guitars" \
--music-length-ms 30000 \
--model-id music_v2_5 \
--with-timestamps true \
--output-format autoInpainting
Inpainting edits or extends a stored song by mixing audio reference chunks (unchanged slices of a stored song) with new generation chunks in a single composition plan.
Step 1 — get a song_id, either by storing a fresh generation or uploading existing audio:
# Option A: keep a generation for later editing
result = client.music.compose_detailed(
prompt="An upbeat pop song with verse and chorus",
music_length_ms=60000,
model_id="music_v2_5",
store_for_inpainting=True,
)
song_id = result.song_id
# Option B: upload an existing track and extract its plan
uploaded = client.music.upload(
file=open("my-song.mp3", "rb"),
extract_composition_plan="music_v2_5",
)
song_id = uploaded.song_id
composition_plan = uploaded.composition_planimport { createReadStream } from "fs";
// Option A: keep a generation for later editing
const result = await client.music.composeDetailed({
prompt: "An upbeat pop song with verse and chorus",
musicLengthMs: 60000,
modelId: "music_v2_5",
storeForInpainting: true,
});
let songId = result.songId;
// Option B: upload an existing track and extract its plan
const uploaded = await client.music.upload({
file: createReadStream("my-song.mp3"),
extractCompositionPlan: "music_v2_5",
});
songId = uploaded.songId;
const compositionPlan = uploaded.compositionPlan;Step 2 — compose a plan that references the stored audio and regenerates the part you want to change:
plan = {
"chunks": [
{"song_id": song_id, "range": {"start_ms": 0, "end_ms": 30000}},
{
"text": "[Chorus]\nWe're rising up tonight",
"duration_ms": 30000,
"positive_styles": ["bigger drums", "layered vocals", "anthemic"],
"negative_styles": ["sparse"],
"context_adherence": "high",
},
]
}
audio = client.music.compose(composition_plan=plan, model_id="music_v2_5")const plan = {
chunks: [
{ songId, range: { startMs: 0, endMs: 30000 } },
{
text: "[Chorus]\nWe're rising up tonight",
durationMs: 30000,
positiveStyles: ["bigger drums", "layered vocals", "anthemic"],
negativeStyles: ["sparse"],
contextAdherence: "high",
},
],
};
const audio = await client.music.compose({
compositionPlan: plan,
modelId: "music_v2_5",
});To match the feel of a stored slice without copying it, attach a conditioning_ref (up to
30,000 ms) plus a condition_strength of low, medium, high, or xhigh to a generation
chunk. Conditioning placed on the first chunk influences every later chunk.
See API Reference for the full inpainting parameter list.
Content Restrictions
Cannot reference specific artists, bands, or copyrighted lyrics
bad_prompterrors include aprompt_suggestionwith alternative phrasingbad_composition_planerrors include acomposition_plan_suggestion
Error Handling
try:
audio = client.music.compose(prompt="...", music_length_ms=30000)
except Exception as e:
print(f"API error: {e}")try {
const audio = await client.music.compose({
prompt: "...",
musicLengthMs: 30000,
});
} catch (err) {
console.error("API error:", err);
}Common errors: 401 (invalid key), 422 (invalid params), 429 (rate limit).
References
Files
- ATTRIBUTION.mdAdded by AutoGineer794 B
- LICENSELicence file added by AutoGineer1.0 KiB
- SKILL.md13.9 KiB
- references/api_reference.md18.1 KiB
- references/installation.md2.2 KiB
references/api_reference.md
Music API Reference
All endpoints below default to music_v1 unless noted for backwards compatibility. Pass
music_v2_5 unless the caller explicitly needs an older model.
Table of Contents
compose
stream
composition_plan.create
compose_detailed
compose_detailed_stream
upload
video_to_music
Inpainting
Error Handling
compose
Generate music from a text prompt or composition plan. Returns an audio stream.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
prompt | string | Yes* | Description of desired music |
composition_plan | object | Yes* | Pre-defined composition plan (alternative to prompt) |
music_length_ms | integer | No | Duration in milliseconds (3,000–600,000) when using prompt; if omitted, the model chooses. Returns an error if a composition plan is also provided. |
model_id | string | No | Music model: music_v1, music_v2, or music_v2_5. Defaults to music_v1. |
force_instrumental | boolean | No | Guarantee an instrumental output (prompt mode only) |
finetune_id | string | No | ID of the music finetune to use for generation. |
respect_sections_durations | boolean | No | Enforce exact duration_ms for each composition plan chunk. Ignored for music_v2 and music_v2_5. |
output_format | string | No | Query parameter for output codec/sample-rate/bitrate. auto selects mp3_44100_128 for music_v1 and mp3_48000_192 for v2 models; high-bitrate MP3 options include mp3_48000_240 and mp3_48000_320. |
*Provide either prompt or composition_plan, not both.
Python
audio = client.music.compose(
prompt="An upbeat electronic track with synth leads",
music_length_ms=30000,
model_id="music_v2_5",
)
with open("output.mp3", "wb") as f:
for chunk in audio:
f.write(chunk)TypeScript
const audio = await client.music.compose({
prompt: "An upbeat electronic track with synth leads",
musicLengthMs: 30000,
modelId: "music_v2_5",
});
const writeStream = createWriteStream("output.mp3");
audio.pipe(writeStream);With Composition Plan
plan = client.music.composition_plan.create(
prompt="A jazz ballad with piano and saxophone",
music_length_ms=60000,
model_id="music_v2_5",
)
# Modify the plan as needed
audio = client.music.compose(
composition_plan=plan,
model_id="music_v2_5",
)const plan = await client.music.compositionPlan.create({
prompt: "A jazz ballad with piano and saxophone",
musicLengthMs: 60000,
modelId: "music_v2_5",
});
// Modify the plan as needed
const audio = await client.music.compose({
compositionPlan: plan,
modelId: "music_v2_5",
});stream
Stream audio chunks as they are generated. Same parameters as compose; returns an
iterable/async-iterable of audio bytes instead of a single response. Available on paid plans only.
Python
from io import BytesIO
stream = client.music.stream(
prompt="A driving synthwave track with arpeggiated leads",
music_length_ms=30000,
model_id="music_v2_5",
)
buffer = BytesIO()
for chunk in stream:
if chunk:
buffer.write(chunk)TypeScript
const stream = await client.music.stream({
prompt: "A driving synthwave track with arpeggiated leads",
musicLengthMs: 30000,
modelId: "music_v2_5",
});
const chunks: Buffer[] = [];
for await (const chunk of stream) {
chunks.push(chunk);
}composition_plan.create
Generate a structured composition plan from a prompt for granular control before generating audio.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
prompt | string | Yes | Music description |
music_length_ms | integer | Yes | Total duration in milliseconds (3,000–600,000) |
model_id | string | No | Supports music_v1, music_v2, and music_v2_5. Defaults to music_v1. Plan structure differs between model generations. |
Plan Structure (music_v2 and music_v2_5)
A plan is an ordered list of chunks. Each chunk is either a generation chunk or an
audio reference chunk (see Inpainting).
| Field | Type | Description |
|---|---|---|
chunks | array | Up to 30 chunks; 3 s to 10 min total |
chunks[].text | string | Section labels ([Verse 1]), lyrics, inline cues like {guitar solo}. Up to 6,132 characters, 30 lines, and 200 characters per line. |
chunks[].duration_ms | integer | 3,000–120,000 ms |
chunks[].positive_styles | array<string> | Up to 50 desired qualities (genre, instrumentation, vocal style). Must be English. |
chunks[].negative_styles | array<string> | Up to 50 qualities to avoid |
chunks[].context_adherence | string | low, medium, or high (default). Higher = stays consistent with surrounding chunks. |
Python
plan = client.music.composition_plan.create(
prompt="A peaceful ambient track with nature sounds",
music_length_ms=60000,
model_id="music_v2_5",
)
# Inspect or edit the plan in place
print(plan["chunks"][0]["positive_styles"])
plan["chunks"][0]["text"] = "[Intro]\nSoft pad with rain"
audio = client.music.compose(composition_plan=plan, model_id="music_v2_5")TypeScript
const plan = await client.music.compositionPlan.create({
prompt: "A peaceful ambient track with nature sounds",
musicLengthMs: 60000,
modelId: "music_v2_5",
});
plan.chunks[0].text = "[Intro]\nSoft pad with rain";
const audio = await client.music.compose({ compositionPlan: plan, modelId: "music_v2_5" });compose_detailed
Generate music while returning both the composition plan and metadata alongside the audio.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
prompt | string | Yes* | Description of desired music |
composition_plan | object | Yes* | Pre-defined composition plan (alternative to prompt) |
music_length_ms | integer | No | Total duration in milliseconds when using prompt |
model_id | string | No | Supports music_v1, music_v2, and music_v2_5. Defaults to music_v1. |
store_for_inpainting | boolean | No | If true, retains the generated audio under a song_id so it can be referenced by later inpainting plans |
force_instrumental | boolean | No | Guarantee an instrumental output (prompt mode only) |
with_waveform_visual | boolean | No | Include a low-resolution waveform preview; defaults to false |
output_format | string | No | Query parameter for output codec/sample-rate/bitrate. auto selects mp3_44100_128 for music_v1 and mp3_48000_192 for v2 models; high-bitrate MP3 options include mp3_48000_240 and mp3_48000_320. |
*Provide either prompt or composition_plan, not both.
Returns
| Field | Description |
|---|---|
json | Composition plan + song metadata (includes lyrics if applicable) |
filename | Output file identifier |
audio | Audio bytes |
song_id | Identifier for the stored song (only when store_for_inpainting=True) |
json.waveform_visual | Optional integer array sampled four times per second, with values from -1000 to 1000 |
Python
result = client.music.compose_detailed(
prompt="A pop song about summer adventures",
music_length_ms=120000,
model_id="music_v2_5",
store_for_inpainting=True,
)
print(result.json) # composition plan + metadata
print(result.song_id) # reusable identifier for inpainting
with open(result.filename, "wb") as f:
f.write(result.audio)TypeScript
import { writeFileSync } from "fs";
const result = await client.music.composeDetailed({
prompt: "A pop song about summer adventures",
musicLengthMs: 120000,
modelId: "music_v2_5",
storeForInpainting: true,
});
console.log(result.json); // composition plan + metadata
console.log(result.songId); // reusable identifier for inpainting
writeFileSync(result.filename, result.audio);compose_detailed_stream
Stream music generation details as Server-Sent Events from
POST /v1/music/detailed/stream.
Use this when a client should receive the composition plan, song metadata, audio chunks, optional
word timestamps, and completion signal incrementally.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
prompt | string | Yes* | Description of desired music |
composition_plan | object | Yes* | Pre-defined composition plan (alternative to prompt) |
music_length_ms | integer | No | Duration in milliseconds when using prompt |
model_id | string | No | Defaults to music_v1; pass music_v2_5 for the most advanced model |
seed | integer | No | Random seed for more consistent generation; cannot be used with prompt |
force_instrumental | boolean | No | Guarantee an instrumental output (prompt mode only) |
store_for_inpainting | boolean | No | Store the generated song so it can be referenced by later inpainting plans |
with_timestamps | boolean | No | Include word timestamps in the streamed events |
with_waveform_visual | boolean | No | Include a low-resolution waveform preview in the streamed events |
output_format | string | No | Query parameter for output codec/sample-rate/bitrate. auto selects mp3_44100_128 for music_v1 and mp3_48000_192 for v2 models. |
*Provide either prompt or composition_plan, not both.
CLI
elevenlabs music compose_detailed_stream \
--prompt "A bright indie pop hook with warm guitars" \
--music-length-ms 30000 \
--model-id music_v2_5 \
--with-timestamps true \
--output-format autoupload
Upload a music file for later inpainting workflows. This endpoint is available to enterprise clients with access to the inpainting feature.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
file | file | Yes | The audio file to upload |
extract_composition_plan | boolean | string | No | If true (or a model ID such as "music_v2_5"), the response includes an extracted composition plan; passing a model ID chooses the extraction model. The request may take longer to return. |
with_timestamps | boolean | No | Transcribe the uploaded song and include word-level timestamps in the response. The request may take longer to return. |
with_waveform_visual | boolean | No | Include a low-resolution waveform preview in the response |
Returns
| Field | Description |
|---|---|
song_id | Unique identifier for the uploaded song |
composition_plan | Extracted composition plan, or null when extract_composition_plan is not enabled |
words_timestamps | Word-level timestamps when with_timestamps is enabled |
waveform_visual | Integer array sampled four times per second, with values from -1000 to 1000, when with_waveform_visual is enabled |
Python
response = client.music.upload(
file=open("my-song.mp3", "rb"),
extract_composition_plan="music_v2_5",
)
song_id = response.song_id
composition_plan = response.composition_planTypeScript
import { createReadStream } from "fs";
const response = await client.music.upload({
file: createReadStream("my-song.mp3"),
extractCompositionPlan: "music_v2_5",
});
const songId = response.songId;
const compositionPlan = response.compositionPlan;CLI
elevenlabs music upload \
--file my-song.mp3 \
--extract-composition-plan music_v2_5video_to_music
Generate background music from uploaded video clips. This is a separate endpoint from
compose (POST /v1/music/video-to-music, not POST /v1/music). See the
Video to music API reference.
Videos are combined in order before music generation.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
videos | array of files | Yes | One or more video files. Up to 10 files, 200MB combined size, and 600 seconds total duration. |
description | string | No | Optional text prompt describing the desired music (up to 1000 characters). |
tags | array of strings | No | Optional style tags such as upbeat or cinematic (up to 10 tags). |
model_id | string | No | Music model to use. Defaults to music_v1 on this endpoint; pass music_v2_5 for the most advanced model. |
use_audio_as_reference | boolean | No | Use the genres, BPM, instrumentation, mood, and arc of the video's own audio track as reference. Defaults to false. |
add_sfx | boolean | No | Add sound effects that match the video. Defaults to false. |
separate_tracks | boolean | No | Return a ZIP with separate music and sound effects tracks instead of a single mixed file. Defaults to false. |
sign_with_c2pa | boolean | No | Sign generated MP3 output with C2PA metadata. Defaults to false. |
output_format | string | No | Output codec/sample-rate/bitrate, such as mp3_44100_128, pcm_44100, or opus_48000_96. |
Python
audio = client.music.video_to_music(
videos=[open("scene-1.mp4", "rb"), open("scene-2.mp4", "rb")],
description="Cinematic ambient score with a gentle build",
tags=["cinematic", "ambient"],
model_id="music_v2_5",
)
with open("video-score.mp3", "wb") as f:
for chunk in audio:
f.write(chunk)TypeScript
import { createReadStream, createWriteStream } from "fs";
const audio = await client.music.videoToMusic({
videos: [createReadStream("scene-1.mp4"), createReadStream("scene-2.mp4")],
description: "Cinematic ambient score with a gentle build",
tags: ["cinematic", "ambient"],
modelId: "music_v2_5",
});
audio.pipe(createWriteStream("video-score.mp3"));CLI
elevenlabs music video_to_music \
--videos scene-1.mp4 \
--description "Cinematic ambient score with a gentle build" \
--tags cinematic \
--output-format mp3_44100_128 \
--output video-score.mp3The CLI currently accepts one --videos file and one --tags value per request; use the Python
or TypeScript SDK to send multiple videos or tags.
Inpainting
Inpainting edits or extends a stored song by combining audio reference chunks (unchanged
slices of stored audio) with generation chunks in a single music_v2 or music_v2_5
composition plan.
Available to enterprise clients.
Getting a song_id
Call
compose_detailedorcomposewithstore_for_inpainting=Trueto keep a generation for later editing.Call
uploadwithextract_composition_plan="music_v2_5"to import an existing track and recover its plan.
Chunk Types
Audio reference chunk — replay a slice of a stored song unchanged:
| Field | Type | Description |
|---|---|---|
song_id | string | Stored song identifier |
range.start_ms | integer | Start offset (minimum 50 ms range) |
range.end_ms | integer | End offset |
Generation chunk — same fields as a normal v2 model plan chunk (text,
duration_ms, positive_styles, negative_styles, context_adherence), with two optional
fields for matching the feel of an existing slice:
| Field | Type | Description |
|---|---|---|
conditioning_ref.song_id | string | Song to condition on |
conditioning_ref.range | object | start_ms/end_ms; up to 30,000 ms |
condition_strength | string | low, medium (default), high, or xhigh |
conditioning_ref on the first chunk influences every subsequent chunk in the plan.
Constraints
| Constraint | Limit |
|---|---|
| Chunks per plan | 30 |
| Chunk duration | 3,000–120,000 ms |
| Conditioning reference duration | up to 30,000 ms |
| Minimum time range | 50 ms |
Python
plan = {
"chunks": [
{"song_id": song_id, "range": {"start_ms": 0, "end_ms": 30000}},
{
"text": "[Chorus]\nWe're rising up tonight",
"duration_ms": 30000,
"positive_styles": ["bigger drums", "layered vocals", "anthemic"],
"negative_styles": ["sparse"],
"context_adherence": "high",
"conditioning_ref": {
"song_id": song_id,
"range": {"start_ms": 30000, "end_ms": 45000},
},
"condition_strength": "high",
},
]
}
audio = client.music.compose(composition_plan=plan, model_id="music_v2_5")TypeScript
const plan = {
chunks: [
{ songId, range: { startMs: 0, endMs: 30000 } },
{
text: "[Chorus]\nWe're rising up tonight",
durationMs: 30000,
positiveStyles: ["bigger drums", "layered vocals", "anthemic"],
negativeStyles: ["sparse"],
contextAdherence: "high",
conditioningRef: { songId, range: { startMs: 30000, endMs: 45000 } },
conditionStrength: "high",
},
],
};
const audio = await client.music.compose({ compositionPlan: plan, modelId: "music_v2_5" });Error Handling
bad_prompt
Occurs when the prompt references copyrighted material (specific artists, bands, or copyrighted lyrics). The error response includes a prompt_suggestion with alternative phrasing.
try:
audio = client.music.compose(
prompt="A song like Beatles",
music_length_ms=30000
)
except Exception as e:
print(f"Request failed: {e}")try {
const audio = await client.music.compose({
prompt: "A song like Beatles",
musicLengthMs: 30000,
});
} catch (err) {
console.error("Request failed:", err);
}bad_composition_plan
Returned when a composition plan contains copyrighted styles. The error includes a composition_plan_suggestion with corrected styles. No suggestion is provided for harmful content.
Common HTTP Errors
| Code | Meaning |
|---|---|
| 401 | Invalid API key |
| 422 | Invalid parameters |
| 429 | Rate limit exceeded |
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs an API key, Needs Python, Needs Node.js
The author says: Requires internet access and an ElevenLabs API key (ELEVENLABS_API_KEY).
Security
What our scanner noticed· Medium risk
- Instructions that use the network
- Downloads piped into a shell
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- ElevenLabs
- Publisher
- ElevenLabs (Official)
- Source
- elevenlabs/skills · music · commit 9763c39
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by ElevenLabs or ElevenLabs.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download music.zip