Generate original music compositions from text prompts with detailed metadata and stem separation capabilities. The Music client provides methods for composing, streaming, and separating audio stems.
Note: The client.music property uses an enhanced wrapper class that extends the base API client with automatic multipart response parsing for the composeDetailed() method, providing structured access to composition metadata and audio data.
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
const client = new ElevenLabsClient({ apiKey: "your-api-key" });
// Access this API via: client.musicimport {
// Wrapper-specific types
SongMetadata,
MultipartResponse
} from "@elevenlabs/elevenlabs-js";
// Or access API types via ElevenLabs namespace
import { ElevenLabs } from "@elevenlabs/elevenlabs-js";
type MusicPrompt = ElevenLabs.MusicPrompt;
type SongSection = ElevenLabs.SongSection;
type TimeRange = ElevenLabs.TimeRange;Generate music from a text prompt or composition plan.
/**
* @param request - Music composition prompt and settings
* @param requestOptions - Optional request configuration
* @returns ReadableStream of audio chunks
* @throws UnprocessableEntityError if request fails
*/
client.music.compose(
request?: BodyComposeMusicV1MusicPost,
requestOptions?: RequestOptions
): HttpResponsePromise<ReadableStream<Uint8Array>>;
interface BodyComposeMusicV1MusicPost {
/** Text prompt describing the music to generate */
prompt?: string;
/** Composition plan with detailed structure */
composition_plan?: MusicPrompt;
/** Duration in seconds (10-300) */
duration?: number;
/** Duration in milliseconds (3000-600000) */
musicLengthMs?: number;
/** Audio format */
outputFormat?: string;
/** Model selection */
modelId?: "music_v1";
/** Guarantee no vocals */
forceInstrumental?: boolean;
/** Store for inpainting (enterprise) */
storeForInpainting?: boolean;
/** C2PA signing (mp3 only) */
signWithC2Pa?: boolean;
/** Enforce section durations */
respectSectionsDurations?: boolean;
}
interface MusicPrompt {
/** The styles and musical directions that should be present in the entire song */
positiveGlobalStyles: string[];
/** The styles and musical directions that should not be present in the entire song */
negativeGlobalStyles: string[];
/** The sections of the song */
sections: SongSection[];
}
interface SongSection {
/** The name of the section (1-100 characters) */
sectionName: string;
/** The styles and musical directions that should be present in this section */
positiveLocalStyles: string[];
/** The styles and musical directions that should not be present in this section */
negativeLocalStyles: string[];
/** The duration of the section in milliseconds (3000-120000ms) */
durationMs: number;
/** The lyrics of the section (max 200 characters per line) */
lines: string[];
/** Optional source to extract the section from (inpainting, enterprise only) */
sourceFrom?: SectionSource;
}
interface SectionSource {
/** ID of the song to use as source */
songId: string;
/** Time range to use from the source song */
range: TimeRange;
/** Optional time ranges to exclude from the source */
negativeRanges?: TimeRange[];
}
interface TimeRange {
/** Start time in milliseconds */
startMs: number;
/** End time in milliseconds */
endMs: number;
}Generate music and receive detailed metadata including composition plan and song information.
/**
* @param request - Music composition request
* @param requestOptions - Optional request configuration
* @returns Multipart response with audio, metadata, and composition plan
* @throws UnprocessableEntityError if request fails
*/
client.music.composeDetailed(
request?: BodyComposeMusicWithADetailedResponseV1MusicDetailedPost,
requestOptions?: RequestOptions
): HttpResponsePromise<MultipartResponse>;
interface BodyComposeMusicWithADetailedResponseV1MusicDetailedPost {
/** Text prompt describing the music */
prompt?: string;
/** Composition plan */
composition_plan?: MusicPrompt;
/** Duration in seconds */
duration?: number;
/** Duration in milliseconds (3000-600000) */
musicLengthMs?: number;
/** Audio format */
outputFormat?: string;
/** Model selection */
modelId?: "music_v1";
/** Guarantee no vocals */
forceInstrumental?: boolean;
/** Store for inpainting (enterprise) */
storeForInpainting?: boolean;
/** C2PA signing (mp3 only) */
signWithC2Pa?: boolean;
/** Return word timestamps */
withTimestamps?: boolean;
}
interface MultipartResponse {
/** JSON metadata */
json: {
/** The composition plan used */
compositionPlan: MusicPrompt;
/** Song metadata including title, genres, etc. */
songMetadata: SongMetadata;
};
/** Audio data as Buffer */
audio: Buffer;
/** Suggested filename for the audio */
filename: string;
}
interface SongMetadata {
/** Generated song title */
title: string;
/** Song description */
description: string;
/** Array of genre tags */
genres: string[];
/** Array of language codes */
languages: string[];
/** Whether song contains explicit content */
is_explicit: boolean;
}Stream music composition in real-time.
/**
* @param request - Music streaming request
* @param requestOptions - Optional request configuration
* @returns ReadableStream of audio chunks
* @throws UnprocessableEntityError if request fails
*/
client.music.stream(
request?: BodyStreamComposedMusicV1MusicStreamPost,
requestOptions?: RequestOptions
): HttpResponsePromise<ReadableStream<Uint8Array>>;
interface BodyStreamComposedMusicV1MusicStreamPost {
/** Text prompt for music generation */
prompt?: string;
/** Composition plan */
composition_plan?: MusicPrompt;
/** Duration in seconds */
duration?: number;
/** Duration in milliseconds (3000-600000) */
musicLengthMs?: number;
/** Audio format */
outputFormat?: string;
/** Model selection */
modelId?: "music_v1";
/** Guarantee no vocals */
forceInstrumental?: boolean;
/** Store for inpainting (enterprise) */
storeForInpainting?: boolean;
/** C2PA signing (mp3 only) */
signWithC2Pa?: boolean;
}Separate an audio file into individual stems (vocals, drums, bass, other).
/**
* @param request - Audio file and separation options
* @param requestOptions - Optional request configuration
* @returns ReadableStream of separated stems (zip archive)
* @throws UnprocessableEntityError if request fails
*/
client.music.separateStems(
request: BodyStemSeparationV1MusicStemSeparationPost,
requestOptions?: RequestOptions
): HttpResponsePromise<ReadableStream<Uint8Array>>;
interface BodyStemSeparationV1MusicStemSeparationPost {
/** Audio file to separate into stems */
file: File | Blob;
/** Choose 2-stem or 6-stem separation */
stemVariationId: "two_stems_v1" | "six_stems_v1";
/** Audio format */
outputFormat?: string;
/** C2PA signing */
signWithC2Pa?: boolean;
}Create and manage composition plans for structured music generation.
/**
* Create a composition plan from a text prompt
*/
client.music.compositionPlan.create(
request: BodyCreateCompositionPlanV1MusicCompositionPlanPost,
requestOptions?: RequestOptions
): HttpResponsePromise<MusicPrompt>;
interface BodyCreateCompositionPlanV1MusicCompositionPlanPost {
/** Text prompt describing the desired composition */
prompt: string;
/** Optional duration in milliseconds */
musicLengthMs?: number;
/** Plan-to-plan generation */
sourceCompositionPlan?: MusicPrompt;
/** Model selection */
modelId?: "music_v1";
}import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
const client = new ElevenLabsClient({ apiKey: "your-api-key" });
// Generate music from prompt
const audio = await client.music.compose({
prompt: "An upbeat electronic dance track with energetic beats",
duration: 60,
});
// Process audio stream
for await (const chunk of audio) {
// Handle audio chunk
}// Get music with full metadata
const result = await client.music.composeDetailed({
prompt: "A relaxing acoustic guitar piece with gentle melodies",
duration: 120,
});
console.log("Title:", result.json.songMetadata.title);
console.log("Description:", result.json.songMetadata.description);
console.log("Genres:", result.json.songMetadata.genres.join(", "));
console.log("Languages:", result.json.songMetadata.languages);
console.log("Explicit:", result.json.songMetadata.is_explicit);
// Save audio to file
await writeFile("music.mp3", result.audio);// Stream music as it generates
const stream = await client.music.stream({
prompt: "Epic orchestral soundtrack with dramatic crescendos",
duration: 180,
});
// Stream to output
for await (const chunk of stream) {
// Process chunk in real-time
}// First, create a composition plan
const plan = await client.music.compositionPlan.create({
prompt: "A jazz fusion piece with piano and saxophone",
});
console.log("Composition plan:", plan);
// Then use the plan to generate music
const audio = await client.music.compose({
composition_plan: plan,
duration: 90,
});import { readFile } from "fs/promises";
// Load an existing audio file
const audioFile = await readFile("song.mp3");
// Separate into stems
const stemsZip = await client.music.separateStems({
file: new File([audioFile], "song.mp3"),
stemVariationId: "two_stems_v1",
});
// Save the zip file containing separated stems
const stemsBuffer = Buffer.concat(
await Array.fromAsync(stemsZip)
);
await writeFile("stems.zip", stemsBuffer);// Create a detailed composition plan first
const plan = await client.music.compositionPlan.create({
prompt: "A progressive rock song with complex time signatures, starting calm and building to an intense finale",
});
// Generate with detailed response
const result = await client.music.composeDetailed({
composition_plan: plan,
duration: 240,
});
console.log("Generated:", result.json.songMetadata.title);
console.log("Composition:", result.json.compositionPlan);
// Save the audio
await writeFile(`${result.filename}`, result.audio);