> ## 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.

# Score an image with music

> Read the mood of an image with a vision model, then generate a matching song.

This recipe chains three capabilities: a [vision model](/capabilities/text-and-chat#image-input) reads the mood of an image, [structured outputs](/capabilities/structured-outputs) turn that into a style and lyrics, and the [music API](/capabilities/audio-generation) turns those into a song. You end up with an `.mp3` that fits the picture.

The connection between them is plain JSON: the vision model returns a `style` and `lyrics`, and the music API takes exactly those two fields.

## The plan

<Steps>
  <Step title="Read the image">
    `POST /v1/chat/completions` with a vision model and the image, asking for JSON with a `style` prompt and `lyrics`.
  </Step>

  <Step title="Generate the song">
    `POST /v1/audio/generations` with `prompt` set to the style and `lyrics_prompt` set to the lyrics.
  </Step>

  <Step title="Poll and download">
    Poll `GET /v1/audio/generations/{id}` until `completed`, then download `audio[0].url`.
  </Step>
</Steps>

## Full script

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

  BASE = "https://api.deepshi.ai/v1"
  headers = {"Authorization": "Bearer YOUR_DEEPSHI_API_KEY"}
  IMAGE_URL = "https://example.com/photo.jpg"

  # 1. read the image's mood as a song brief
  brief = requests.post(f"{BASE}/chat/completions", headers=headers, json={
      "model": "deepshi-3.0",
      "messages": [{
          "role": "user",
          "content": [
              {"type": "text", "text": (
                  "Turn this image into a song. Reply with JSON "
                  '{"style": "...", "lyrics": "..."} where style is a short '
                  "music-style prompt and lyrics use [Verse] / [Chorus] tags."
              )},
              {"type": "image_url", "image_url": {"url": IMAGE_URL}},
          ],
      }],
      "response_format": {"type": "json_object"},
  }).json()

  song = json.loads(brief["choices"][0]["message"]["content"])
  print("style:", song["style"])

  # 2. generate the song
  job = requests.post(f"{BASE}/audio/generations", headers=headers, json={
      "model": "minimax-music-v2",
      "prompt": song["style"],
      "lyrics_prompt": song["lyrics"],
  }).json()

  # 3. poll, then download
  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"))

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

  ```javascript JavaScript theme={null}
  import { writeFileSync } from "node:fs";

  const BASE = "https://api.deepshi.ai/v1";
  const headers = {
    Authorization: "Bearer YOUR_DEEPSHI_API_KEY",
    "Content-Type": "application/json",
  };
  const IMAGE_URL = "https://example.com/photo.jpg";

  // 1. read the image's mood as a song brief
  const brief = await (await fetch(`${BASE}/chat/completions`, {
    method: "POST",
    headers,
    body: JSON.stringify({
      model: "deepshi-3.0",
      messages: [{
        role: "user",
        content: [
          { type: "text", text:
            'Turn this image into a song. Reply with JSON {"style": "...", "lyrics": "..."} ' +
            "where style is a short music-style prompt and lyrics use [Verse] / [Chorus] tags." },
          { type: "image_url", image_url: { url: IMAGE_URL } },
        ],
      }],
      response_format: { type: "json_object" },
    }),
  })).json();

  const song = JSON.parse(brief.choices[0].message.content);
  console.log("style:", song.style);

  // 2. generate the song
  let job = await (await fetch(`${BASE}/audio/generations`, {
    method: "POST",
    headers,
    body: JSON.stringify({
      model: "minimax-music-v2",
      prompt: song.style,
      lyrics_prompt: song.lyrics,
    }),
  })).json();

  // 3. poll, then download
  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));

  const buf = Buffer.from(await (await fetch(job.audio[0].url)).arrayBuffer());
  writeFileSync("song.mp3", buf);
  console.log("saved song.mp3");
  ```
</CodeGroup>

## Notes

* **Use a vision-capable model** for step 1. `deepshi-3.0` reads images and returns JSON. Send the image as a URL or a base64 `data:` URI.
* **`minimax-music-v2` is a vocal model**, so it needs `lyrics_prompt`. Asking the vision model to write the lyrics keeps the whole chain in one pass.
* **Cost:** the chat call reports its cost inline in `usage.cost`. The song is billed once on completion; see [music pricing](/capabilities/audio-generation#pricing).

## Next steps

<CardGroup cols={2}>
  <Card title="Music generation" icon="music" href="/capabilities/audio-generation">
    All music parameters, models, and pricing.
  </Card>

  <Card title="Animate an image" icon="wand-magic-sparkles" href="/guides/cookbook/animate-an-image">
    Chain image generation into a video clip.
  </Card>
</CardGroup>
