# Lai.vc 音乐生成 API — AI 开发文档

> 本文档面向 AI 编程助手(agent),由价目注册表实时生成,价格与能力永远是当前生效值。
> 固定地址:https://lai.vc/docs/api/music.md;结构化价目也可运行时 GET https://api.lai.vc/v1/music/models 获取。
> 图像见 images.md,视频见 videos.md。

## 认证

所有请求带 `Authorization: Bearer ak-你的密钥`(控制台「API 与 MCP → 密钥管理」创建)。
交给 AI agent 前请设**消费上限**。

## 关键约束

1. **异步**。提交返回 `202` + 任务号,音乐通常 **1~3 分钟**(含有界并发排队)。
   `?wait=true` 可同步等待。
2. **一次生成产出 2 首**(上游固定双版本),给用户挑。按次计费,与首数无关。
3. **成品仅保留 24 小时**,过期自动删除。返回的 URL 有效期不超过留存期,请及时转存。
4. **失败自动退款**。

## 端点

### 提交生成

```http
POST https://api.lai.vc/v1/music/generations
Content-Type: application/json
Authorization: Bearer ak-xxx

{
  "model": "lai-music-1.0",
  "prompt": "upbeat lo-fi hip hop, chill, warm piano",
  "action": "auto",
  "instrumental": true
}
```

返回 `202`:`{ "id": "…", "status": "queued", "cost_usd": 2, "songs_expected": 2, "queue": {"ahead":0,"eta_seconds":90} }`

| 参数 | 必填 | 说明 |
|---|---|---|
| `model` | ✅ | 模型 id,见下方价目 |
| `prompt` | ✅ | 风格描述,支持中文(≤500 字) |
| `action` | | `auto` 纯提示自动 / `custom` 带歌词精调 / `instrumental` 纯音乐 / `extend` 续写 / `artist_consistency` 音色一致 / `upload(_extend)` 参考音频。默认 `auto` |
| `lyrics` | | 歌词(`custom` 时用;≤3000 字;`instrumental` 会忽略) |
| `title` | | 标题(≤80 字)。**所有模式(含 auto)传了即生效**:成品 `songs[].title` 就是此值;不传才自动起名 |
| `instrumental` | | 纯音乐(无人声),默认 false |
| `gender` | | `male` / `female` 人声偏好 |

> `extend` / `artist_consistency` 需带源歌曲的 `continueSongId` / `sourceSongId`(取自此前任务返回的 `song_id`);
> `upload(_extend)` 需先调上传接口拿 `audioKey`。

### 查询结果

```http
GET https://api.lai.vc/v1/music/generations/{id}
```

```json
{
  "id": "…", "status": "succeeded", "model": "Lai 1.0",
  "requested_title": "你提交的标题",     // 传了标题,songs[].title 就是它
  "requested_lyrics": "你提交的歌词",     // 纯音乐为 null
  "songs": [
    { "title": "你提交的标题", "upstream_title": "晴天车票", "lyric": "[Verse 1]\n…", "duration": 204,
      "song_id": "…", "url": "https://…mp3", "cover_url": "https://…" },
    { "title": "你提交的标题", "upstream_title": "晴天车票", "lyric": "[Verse 1]\n…", "duration": 208,
      "song_id": "…", "url": "https://…mp3", "cover_url": "https://…" }
  ],
  "expires_at": "2026-07-23T…Z", "cost_usd": 2
}
```

`status`:`processing` / `succeeded` / `failed`(已退款)/ `expired`。
`song_id` 可用于后续 `extend`(续写)或 `artist_consistency`(音色一致)。

**标题**:你提交了 `title` 就以你的为准(`songs[].title` = 你传的标题);未提交时才用系统自动起的名。
自动起的名字始终在 `songs[].upstream_title` 供参考。
⚠️ **歌词以 `songs[].lyric` 为准**:生成时会自动润色歌词,可能与提交值不同;
你提交的原值另存在 `requested_title` / `requested_lyrics`。纯音乐 `lyric` 为 null。
**歌词请随音频一并转存**(直接把 `lyric` 文本落盘为 .txt/.lrc 即可):任务过期清理时歌词随任务一起删除,过期后无法找回。
`duration` 单位为秒。

### 上传参考音频(upload / upload_extend)

```http
POST https://api.lai.vc/v1/music/uploads
Content-Type: multipart/form-data;  file=@ref.mp3    # MP3/WAV/M4A,≤30MB
```

返回 `{ "audio_key": "music-src/…" }`,提交时放进 `audioKey` 字段。

### 配方:翻唱 / 原歌换伴奏(三步曲)

把一首已有歌曲用同样的嗓音、同样的歌词、全新的伴奏重唱一遍(AI 重唱,非保留原始录音人声):

```text
① 原曲入站   POST /v1/music/uploads (multipart file=@原曲.mp3) → audio_key
             POST /v1/music/generations {"action":"upload","audioKey":"…","model":"lai-music-2.0"}
             → 轮询到 succeeded,记下 songs[0] 的 song_id 与 lyric(上游会自动识别出歌词)
② 提取声线   无需显式调用 —— 直接进第 ③ 步,平台自动从源歌提取
③ 换伴奏重唱 POST /v1/music/generations {
               "action": "artist_consistency",
               "sourceSongId": "<第①步的 song_id>",
               "lyrics":  "<第①步返回的 lyric,原词照抄>",
               "prompt":  "<新伴奏风格,如 slow acoustic guitar ballad>",
               "model":   "lai-music-2.0"
             }
```

- 每步都是一次正常计费的生成(价目见下),失败自动退款。
- 想直接给已生成的站内歌换伴奏,跳过第①步,直接用它的 `song_id`。
- 第①步的音频转换偶发上游拉取失败(自动退款),重试一次即可。

### 模型与价目

```http
GET https://api.lai.vc/v1/music/models
```

## 价目表(每次生成 = 2 首,美元)

| 模型 | id | 单价($/次) | 支持 action | 说明 |
|---|---|---|---|---|
| Suno 6(旗舰) | `suno6` | $3 | auto / custom | Suno 官方 V6 引擎,完整结构长曲,人声与编曲最佳 |

## 查询余额

```http
GET https://api.lai.vc/v1/account/balance
```

任何有效 AutoKey 都能查(不要求特定能力域)。生成前不确定余额是否充足,先查它比撞 402 更省事。

```json
{
  "account": { "balance_usd": 62.72, "used_total_usd": 1.04 },
  "key": { "name": "…", "limit_usd": 5, "used_usd": 0.1, "remaining_usd": 4.9, "expires_at": null }
}
```

- `account.balance_usd`:账户可用余额,**生成实际扣这里**(所有密钥共享)。
- `key.remaining_usd`:本密钥消费上限的剩余($limit − $used);`null` = 该密钥不限额。

## 错误码

| HTTP | code | 含义 |
|---|---|---|
| 401 | `invalid_api_key` | 密钥无效 |
| 403 | `key_disabled` / `key_expired` / `ip_denied` / `scope_denied` | 密钥停用 / 过期 / IP 不在白名单 / 未开通音乐能力 |
| 402 | `key_quota_exceeded` / `insufficient_quota` | 密钥上限用尽 / 账户余额不足 |
| 400 | `invalid_request` | 参数不合法 |
| 404 | `not_found` | 任务不存在 |

遇到 401/403/402 **不要重试**。

## MCP

```bash
claude mcp add laivc --env LAIVC_API_KEY=ak-xxx -- npx -y @laivc/mcp
```

提供 `list_music_models` / `generate_music` / `get_music`(需 @laivc/mcp ≥ 0.3.0)。

> action 取值(全集):auto / custom / extend / artist_consistency / upload / upload_extend;**各模型实际支持的子集见上方价目表**,传不支持的 action 会被拒绝。
