> ## Documentation Index
> Fetch the complete documentation index at: https://docs.snapgen.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Music composition

> Compose a song or an instrumental of 3 to 300 seconds with Eleven Music and receive the audio in the response.

`POST /v1/audio/music` composes a song or an instrumental from a text prompt, with optional lyrics, and returns the audio file as the response body. The request waits until the track is finished, so set a client timeout of several minutes.

| Model | Length | Price |
| - | - | - |
| [`eleven-music-v2.5`](/api-manual/audio/eleven-music-v2-5) | 3 to 300 seconds (default 30) | \$0.00375 per second (\$0.225 per minute) |

To extend, cover, remix, or split a song in later steps, use the task-based
[Music generation tasks](/api-reference/music-generations) endpoint with Suno or
Flow Music instead.

<ParamField body="model" type="string" required>
  Set to `eleven-music-v2.5`.
</ParamField>

<ParamField body="prompt" type="string" required>
  What the music should sound like, up to 4,100 characters: genre, mood,
  instruments, tempo, and structure.
</ParamField>

<ParamField body="lyrics" type="string">
  Lyrics to sing, up to 4,000 characters.
</ParamField>

<ParamField body="duration_seconds" type="integer" default="30">
  Length in whole seconds, from `3` to `300`. You're billed for the length you
  request.
</ParamField>

<ParamField body="instrumental" type="boolean">
  `true` guarantees an instrumental with no vocals.
</ParamField>

<ParamField body="response_format" type="string" default="mp3">
  `mp3`, `opus`, or `pcm`. WAV isn't offered for generated music. See
  [Output formats](/api-reference/audio-speech#output-formats).
</ParamField>

Fields that aren't listed here return `invalid_request`.

## Response

A successful request returns HTTP `200` with the audio as the body. The
`Content-Type` matches `response_format`: `audio/mpeg`, `audio/ogg`, or
`audio/pcm`. The response carries `x-gateway-execution-id`.

## Billing

The request is billed for `duration_seconds` at \$0.00375 per second, whatever
the finished file's exact length. The default 30 seconds costs \$0.1125, and
the 300-second maximum costs \$1.125. Failed requests aren't charged.

| Length | Price |
| - | - |
| 10 seconds | \$0.0375 |
| 30 seconds (default) | \$0.1125 |
| 60 seconds | \$0.225 |
| 300 seconds | \$1.125 |

This endpoint rejects `Idempotency-Key`. If a request times out, the track may
already have been generated: check your Console request logs before you retry.

## Errors

| Status | `error.code` | Cause |
| - | - | - |
| 400 | `invalid_request` | `prompt` is missing or blank, `duration_seconds` is out of range or not a whole number, or a field is unknown. |
| 400 | `idempotency_not_supported` | The request has an `Idempotency-Key` header. |
| 400 | `provider_rejected_request` | The provider refused the prompt or lyrics. |
| 402 | `insufficient_funds` | Your balance can't cover the request. |
| 404 | `model_not_available` | The model ID is unknown or disabled. A key whose allowlist excludes the model gets `api_key_model_not_allowed` (403). |
| 503 | `no_eligible_route` | The model doesn't run on this endpoint, or no route is available right now. |

See [Errors](/errors) for rate limits and provider failures.

<RequestExample>
  ```bash Curl theme={null}
  curl https://api.snapgen.org/v1/audio/music \
    -H "Authorization: Bearer $SNAPGEN_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "eleven-music-v2.5",
      "prompt": "Uplifting cinematic trailer score with strings and big drums",
      "duration_seconds": 30
    }' \
    --output music.mp3
  ```

  ```python Python theme={null}
  import json
  import os
  from urllib.request import Request, urlopen

  request = Request(
      "https://api.snapgen.org/v1/audio/music",
      data=json.dumps({
          "model": "eleven-music-v2.5",
          "prompt": "Uplifting cinematic trailer score with strings and big drums",
          "duration_seconds": 30,
      }).encode(),
      headers={
          "Authorization": f"Bearer {os.environ['SNAPGEN_API_KEY']}",
          "Content-Type": "application/json",
      },
  )

  with urlopen(request, timeout=600) as response, open("music.mp3", "wb") as file:
      file.write(response.read())
  ```

  ```javascript Node.js theme={null}
  import { writeFile } from "node:fs/promises";

  const response = await fetch("https://api.snapgen.org/v1/audio/music", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.SNAPGEN_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: "eleven-music-v2.5",
      prompt: "Uplifting cinematic trailer score with strings and big drums",
      duration_seconds: 30,
    }),
    signal: AbortSignal.timeout(600_000),
  });
  if (!response.ok) throw new Error(await response.text());
  await writeFile("music.mp3", Buffer.from(await response.arrayBuffer()));
  ```
</RequestExample>

<ResponseExample>
  ```text 200 theme={null}
  HTTP/1.1 200 OK
  content-type: audio/mpeg
  cache-control: no-store
  x-gateway-execution-id: 5b1e9f3a-2c4d-4e6f-8a7b-9c0d1e2f3a4b

  <binary MP3 audio>
  ```

  ```json 400 theme={null}
  {
    "error": {
      "message": "duration_seconds: Too big: expected number to be <=300",
      "type": "invalid_request_error",
      "param": null,
      "code": "invalid_request"
    }
  }
  ```
</ResponseExample>
