# 音乐聚合 API 文档

- Base：`/api`
- 版本：`v1`
- 字符集：UTF-8
- 方法：GET / POST
- 返回格式：JSON
- 平台代码：`netease`（网易云音乐）、`tencent`（QQ音乐）

## 鉴权

```http
X-API-Key: msk_xxxxxxxxxxxx
```

```http
Authorization: Bearer msk_xxxx
```

```http
?api_key=msk_xxxx
```

所有接口均需 API Key（强制），缺少或无效返回 401。

每个 Key 有独立每日配额和有效期。超限返回 `429`；停用或过期返回 `403`；缺少或无效返回 `401`。

> 所有接口均强制鉴权，未携带 API Key 的请求一律返回 `401`。

## 统一响应结构

```json
{"code":0,"message":"ok","request_id":"...","data":{},"meta":{}}
```

- `code`：0 成功，非 0 为业务错误码
- `message`：成功为 ok，失败为错误描述
- `request_id`：请求标识
- `data`：业务数据，失败时为 null
- `meta`：meta.platform 平台代码；meta.platform_name 平台名称；meta.count 本页条数；meta.channel_id 渠道账号 ID；meta.mode 模式；meta.remaining_today 今日剩余，-1 不限

## 接口

### 1. 歌曲 `/song`

```text
GET /api/song?platform=netease&keyword=晴天&limit=20
GET /api/song?platform=netease&id=186016
```

参数：

| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `platform` | string | 是 | netease / tencent |
| `keyword` | string | 二选一 | 搜索关键词 |
| `id` | string | 二选一 | 唯一 ID，返回详情 |
| `page` | int | 否 | 页码，默认 1 |
| `limit` | int | 否 | 每页条数，默认 20 |

搜索模式 `data` 字段：

```text
keyword, page, limit, total, list[]
```

`list[]` 单条字段：

```text
id, name, artist[{id,name}], album_id, album, pic_id, url_id, lyric_id, cover, duration, duration_text
```

详情模式 `data` 字段：

```text
id, name, artist[{id,name}], album_id, album, pic_id, url_id, lyric_id, cover, duration, duration_text, qualities[{code,name,br,size}]
```

### 2. 歌单 `/playlist`

```text
GET /api/playlist?platform=netease&id=3778678
GET /api/playlist?platform=netease&keyword=周杰伦&limit=20
```

参数：

| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `platform` | string | 是 | netease / tencent |
| `keyword` | string | 二选一 | 搜索关键词 |
| `id` | string | 二选一 | 唯一 ID，返回详情 |
| `page` | int | 否 | 页码，默认 1 |
| `limit` | int | 否 | 每页条数，默认 20 |

搜索模式 `data` 字段：

```text
id, name, creator{id,name,avatar}, cover, pic_id, description, play_count
```

`list[]` 单条字段：

```text
id, name, creator{id,name,avatar}, cover, pic_id, description, play_count
```

详情模式 `data` 字段：

```text
id, name, cover, creator{id,name,avatar}, pic_id, description, play_count, song_count, songs[]
```

### 3. 歌手 `/artist`

```text
GET /api/artist?platform=netease&keyword=周杰伦&limit=20
GET /api/artist?platform=netease&id=6452&data_type=songs&page=1&limit=20
GET /api/artist?platform=netease&id=6452&data_type=albums&page=1&limit=20
```

参数：

| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `platform` | string | 是 | netease / tencent |
| `keyword` | string | 二选一 | 搜索关键词 |
| `id` | string | 二选一 | 唯一 ID，返回详情 |
| `page` | int | 否 | 页码，默认 1 |
| `limit` | int | 否 | 每页条数，默认 20 |
| `data_type` | string | 否 | 详情返回类型：songs（默认）或 albums，各自独立分页 |

搜索模式 `data` 字段：

```text
id, name, avatar, album_count, song_count, description
```

`list[]` 单条字段：

```text
id, name, avatar, album_count, song_count, description
```

详情模式 `data` 字段：

```text
id, name, avatar, description, data_type, songs[], song_count, albums[], page, limit, total
```

> 详情用 data_type 选择返回 songs（默认）或 albums，各自独立分页。

### 4. 专辑 `/album`

```text
GET /api/album?platform=netease&id=32311
GET /api/album?platform=netease&keyword=周杰伦&limit=20
```

参数：

| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `platform` | string | 是 | netease / tencent |
| `keyword` | string | 二选一 | 搜索关键词 |
| `id` | string | 二选一 | 唯一 ID，返回详情 |
| `page` | int | 否 | 页码，默认 1 |
| `limit` | int | 否 | 每页条数，默认 20 |

搜索模式 `data` 字段：

```text
id, name, cover, pic_id, artists[{id,name}], publish_date, description
```

`list[]` 单条字段：

```text
id, name, cover, pic_id, artists[{id,name}], publish_date, description
```

详情模式 `data` 字段：

```text
id, name, cover, pic_id, artists[{id,name}], publish_date, description, song_count, songs[]
```

### 5. 歌词 `/lyric`

```text
GET /api/lyric?platform=netease&id=186016
```

参数：

| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `platform` | string | 是 | netease / tencent |
| `id` | string | 是 | 唯一 ID |

搜索模式 `data` 字段：

```text
keyword, page, limit, total, list[]
```

详情模式 `data` 字段：

```text
id, name, lyric, trans_lyric
```

### 6. 播放链接 `/playurl`

```text
GET /api/playurl?platform=netease&id=186016&quality=lossless
```

参数：

| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `platform` | string | 是 | netease / tencent |
| `id` | string | 是 | 唯一 ID |
| `quality` | string | 否 | 音质代码，缺省自动 |

搜索模式 `data` 字段：

```text
keyword, page, limit, total, list[]
```

详情模式 `data` 字段：

```text
song_id, name, available, url, quality, quality_name, size, format, bitrate, free, available_qualities[{code,name}], quality_unavailable, reason
```

> 只返回请求的那一档，不做降级；本曲或账号没有该档位时返回 available=false 与可用档位。

### 7. 封面图 `/pic`

```text
GET /api/pic?platform=netease&id=109951173569626660&size=500
```

参数：

| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `platform` | string | 是 | netease / tencent |
| `id` | string | 是 | 唯一 ID |
| `size` | int | 否 | 图片边长像素，默认 300 |

搜索模式 `data` 字段：

```text
keyword, page, limit, total, list[]
```

详情模式 `data` 字段：

```text
id, size, url
```

> id 取歌曲或歌单的 pic_id（封面 CDN 路径）。

### 8. 音质列表 `/quality`

```text
GET /api/quality?platform=netease
```

参数：

| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `platform` | string | 是 | netease / tencent |

详情模式 `data` 字段：

```text
platform, platform_name, total, qualities[{code,name}]
```

> 平台内置音质档位，不依赖歌曲，也不消耗上游请求。

## 音质代码顺序（由高到低）

### 网易云音乐

1. `jymaster` — 超清母带（jm）
2. `jyeffect` — 沉浸环绕（je）
3. `sky` — 空间音频（sk）
4. `hires` — Hi-Res
5. `lossless` — 无损 SQ
6. `exhigh` — 极高 320kbps
7. `higher` — 较高 192kbps
8. `standard` — 标准 128kbps

### QQ音乐

1. `master` — 臻品母带 24bit/192kHz
2. `flac` — 无损 FLAC
3. `320` — MP3 320kbps
4. `aac192` — AAC 192kbps
5. `128` — MP3 128kbps
6. `ogg192` — OGG 192kbps
7. `aac96` — AAC 96kbps
8. `ogg96` — OGG 96kbps

## 错误码

| HTTP | 含义 | 说明 |
|---|---|---|
| `400` | 参数错误 | 缺少 platform / keyword / id，或 keyword 与 id 同时传入 |
| `401` | 未授权 | 缺少或无效 API Key |
| `403` | 禁止访问 | API Key 已停用或已过期 |
| `429` | 超出配额 | 今日调用次数已达上限 |
| `500` | 服务异常 | 上游接口异常或内部错误 |
