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

> ## Agent Instructions
> The Deepshi API is an OpenAI-compatible gateway. Base URL: https://api.deepshi.ai/v1. API keys start with sk-bf- and go in the Authorization: Bearer header. Prefer the official OpenAI SDKs pointed at the Deepshi base URL. Model ids are clean with no provider prefix (e.g. deepshi-3.0, claude-opus-4.8, gpt-5.5). Chat and image requests are synchronous; video and music requests are asynchronous job APIs (create, then poll). Every synchronous response carries usage.cost.total_cost in USD. Do not reference the internal /api/* admin plane or virtual keys.

# Audio generation

> Generate music and full songs from a style prompt and lyrics with the async audio API.

The audio API turns a style prompt and lyrics into a full song. Generation takes from several seconds to a few minutes, so the API is asynchronous: you create a job, poll it until it finishes, then read the result URL.

| Endpoint                                 | What it does                                |
| ---------------------------------------- | ------------------------------------------- |
| `POST /v1/audio/generations`             | Create a music job from a prompt and lyrics |
| `GET /v1/audio/generations/{id}`         | Poll a job for its status and result        |
| `GET /v1/audio/generations/{id}/content` | Redirect to the finished audio file         |

New here? The three steps below take you from a prompt to a saved `.mp3`.

## Step 1: Create a job

A request needs a **`model`** and a **`prompt`** that describes the style. Add **`lyrics_prompt`** with the words to sing on models that take lyrics. Browse the ids on the [music models](/models/audio-models) page.

```bash curl theme={null}
curl https://api.deepshi.ai/v1/audio/generations \
  -H "Authorization: Bearer $DEEPSHI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "minimax-music-v2",
    "prompt": "a warm lofi hip hop beat with mellow piano and vinyl crackle",
    "lyrics_prompt": "[Verse]\ncity lights fade slow\nin the quiet night we go\n[Chorus]\nhold on to the glow"
  }'
```

You get back a job object with `status: "in_progress"`. Save the `id` so you can poll it in Step 2.

```json theme={null}
{
  "id": "aud_a1b2c3...",
  "object": "audio",
  "model": "minimax-music-v2",
  "status": "in_progress",
  "created_at": 1783500700
}
```

| Field        | What it is                                                |
| ------------ | --------------------------------------------------------- |
| `id`         | The job id. Pass it to the poll and content endpoints.    |
| `object`     | Object type, always `audio`.                              |
| `status`     | Lifecycle state: `in_progress`, `completed`, or `failed`. |
| `created_at` | Unix timestamp when the job was created.                  |

## Step 2: Poll for completion

Call `GET /v1/audio/generations/{id}` on an interval (every few seconds is plenty) until `status` is `completed` or `failed`. A completed job carries the result under `audio[]`.

```json theme={null}
{
  "id": "aud_a1b2c3...",
  "object": "audio",
  "status": "completed",
  "seconds": "64",
  "created_at": 1783500700,
  "completed_at": 1783500701,
  "audio": [
    { "type": "url", "url": "https://media.cdn-deepshi.com/music/....mp3", "content_type": "audio/mpeg" }
  ]
}
```

| Field                  | What it is                                                                  |
| ---------------------- | --------------------------------------------------------------------------- |
| `audio[].url`          | A direct link to the finished `.mp3`.                                       |
| `audio[].content_type` | The media type, always `audio/mpeg`.                                        |
| `seconds`              | The length of the generated track, in seconds.                              |
| `status: "failed"`     | Generation failed. An `error` object explains why, and you are not charged. |

## Step 3: Get the file

Use `audio[].url` directly, or call `GET /v1/audio/generations/{id}/content` to be redirected to the same file. The full loop looks like this:

<CodeGroup>
  ```python Python theme={null}
  import time, requests

  BASE = "https://api.deepshi.ai/v1"
  headers = {"Authorization": "Bearer YOUR_DEEPSHI_API_KEY"}

  # 1. create
  job = requests.post(f"{BASE}/audio/generations", headers=headers, json={
      "model": "minimax-music-v2",
      "prompt": "a warm lofi hip hop beat with mellow piano and vinyl crackle",
      "lyrics_prompt": "[Verse]\ncity lights fade slow\nin the quiet night we go",
  }).json()

  # 2. poll
  while job["status"] not in ("completed", "failed"):
      time.sleep(5)
      job = requests.get(f"{BASE}/audio/generations/{job['id']}", headers=headers).json()

  if job["status"] == "failed":
      raise SystemExit(job.get("error"))

  # 3. download
  url = job["audio"][0]["url"]
  open("output.mp3", "wb").write(requests.get(url).content)
  print("saved output.mp3")
  ```

  ```javascript JavaScript theme={null}
  const BASE = "https://api.deepshi.ai/v1";
  const headers = {
    Authorization: "Bearer YOUR_DEEPSHI_API_KEY",
    "Content-Type": "application/json",
  };

  // 1. create
  let job = await (await fetch(`${BASE}/audio/generations`, {
    method: "POST",
    headers,
    body: JSON.stringify({
      model: "minimax-music-v2",
      prompt: "a warm lofi hip hop beat with mellow piano and vinyl crackle",
      lyrics_prompt: "[Verse]\ncity lights fade slow\nin the quiet night we go",
    }),
  })).json();

  // 2. poll
  while (!["completed", "failed"].includes(job.status)) {
    await new Promise((r) => setTimeout(r, 5000));
    job = await (await fetch(`${BASE}/audio/generations/${job.id}`, { headers })).json();
  }
  if (job.status === "failed") throw new Error(JSON.stringify(job.error));

  // 3. download
  const url = job.audio[0].url;
  const buf = Buffer.from(await (await fetch(url)).arrayBuffer());
  require("node:fs").writeFileSync("output.mp3", buf);
  console.log("saved output.mp3");
  ```

  ```bash curl theme={null}
  # 1. create -> capture the id
  ID=$(curl -s https://api.deepshi.ai/v1/audio/generations \
    -H "Authorization: Bearer $DEEPSHI_API_KEY" -H "Content-Type: application/json" \
    -d '{"model":"minimax-music-v2","prompt":"a warm lofi hip hop beat with mellow piano","lyrics_prompt":"[Verse]\ncity lights fade slow\nin the quiet night we go"}' \
    | python3 -c "import sys,json;print(json.load(sys.stdin)['id'])")

  # 2. poll until it is done
  while true; do
    STATUS=$(curl -s https://api.deepshi.ai/v1/audio/generations/$ID \
      -H "Authorization: Bearer $DEEPSHI_API_KEY" \
      | python3 -c "import sys,json;print(json.load(sys.stdin)['status'])")
    echo "status: $STATUS"; [ "$STATUS" = completed ] || [ "$STATUS" = failed ] && break
    sleep 5
  done

  # 3. follow the content redirect to the file
  curl -sL https://api.deepshi.ai/v1/audio/generations/$ID/content \
    -H "Authorization: Bearer $DEEPSHI_API_KEY" -o output.mp3
  ```
</CodeGroup>

<Note>
  An audio id is scoped to the key that created it. Another key cannot poll or download it.
  Download anything you want to keep as soon as the job completes.
</Note>

## Writing the prompt and lyrics

A song comes from two fields that do different jobs:

* **`prompt`** describes the **style**: genre, mood, instruments, tempo. Up to the model's `prompt_max_length`.
* **`lyrics_prompt`** is the **words to sing**, with structure tags like `[Verse]`, `[Chorus]`, `[Bridge]`, `[Intro]`, and `[Outro]` on their own lines. Separate lines with `\n`. On `minimax-music-v2` the lyrics run from 10 to 3000 characters.

```json theme={null}
{
  "model": "minimax-music-v2",
  "prompt": "upbeat synth-pop, bright and driving, female vocal",
  "lyrics_prompt": "[Verse]\nwe run through the neon rain\n[Chorus]\nnever coming down again\n[Bridge]\nhold the night, hold the light"
}
```

<Note>
  Lyrics support is model-specific: some models require lyrics for vocal songs, some can generate
  instrumental-only tracks, and some write their own lyrics from the prompt. See the
  [music models](/models/audio-models) page. A failed job is not charged.
</Note>

## Choosing a model

Each music model accepts a style `prompt` plus its own set of options, such as lyrics, instrumental toggles, duration, and output format. There are two ways to see what a model supports:

* The [music models](/models/audio-models) page, with a card per model showing its prompt limit and output options.
* `GET /v1/models`, the same facts as JSON, scoped to your key.

```bash theme={null}
curl https://api.deepshi.ai/v1/models \
  -H "Authorization: Bearer $DEEPSHI_API_KEY"
```

Each audio entry lists the `parameters` it accepts (with `type`, allowed `values`, and `default`), plus `prompt_max_length` and its modalities:

```json Example music model entry theme={null}
{
  "id": "minimax-music-v2",
  "object": "model",
  "output_modalities": ["audio"],
  "input_modalities": ["text"],
  "prompt_max_length": 300,
  "parameters": {
    "sample_rate": { "type": "enum", "values": [8000, 16000, 22050, 24000, 32000, 44100], "default": 44100 },
    "bitrate":     { "type": "enum", "values": [32000, 64000, 128000, 256000], "default": 256000 },
    "format":      { "type": "enum", "values": ["mp3"], "default": "mp3" }
  }
}
```

### Common parameters

Availability of each option is model-specific; call `GET /v1/models` for the exact set a model accepts.

<ParamField body="model" type="string" required>
  The music model id. Take it from `GET /v1/models`.
</ParamField>

<ParamField body="prompt" type="string" required>
  The music style: genre, mood, instruments. Over the model's `prompt_max_length` returns `400`.
</ParamField>

<ParamField body="lyrics_prompt" type="string">
  The lyrics to sing, with `[Verse]` / `[Chorus]` structure tags. Required by some models (for example `minimax-music-v2`).
</ParamField>

<ParamField body="is_instrumental, force_instrumental" type="boolean">
  Generate a vocal-free track, where supported.
</ParamField>

<ParamField body="music_length_ms, seconds_total, duration" type="integer">
  Output length, where the model supports duration control.
</ParamField>

<ParamField body="sample_rate, bitrate, format" type="enum">
  Output options, where supported. `format` is `mp3` on `minimax-music-v2`; `minimax-music-v2.5` and
  `minimax-music-v2.6` also accept `wav` and `pcm`.
</ParamField>

## Pricing

Music is priced **per track** (a flat rate per song) or **per minute of output**, depending on the model. Per-model rates are on [deepshi.ai](https://deepshi.ai/).

You are billed only for **delivered output**. A job is charged once, when it completes. A job that fails is not charged. Like video, music responses do not carry an inline `usage.cost`; check your balance and per-model rates on [deepshi.ai](https://deepshi.ai/).

## Next steps

<CardGroup cols={2}>
  <Card title="Audio models" icon="music" href="/models/audio-models">
    Browse audio models, their prompt limits, and output options.
  </Card>

  <Card title="Credits & billing" icon="coins" href="/get-started/pricing-credits">
    How billing and your prepaid balance work.
  </Card>
</CardGroup>
