开放接口文档
聚合网易云、QQ、酷狗三大音源的标准化访问能力。本站设计的页面默认可用,外部网站经域名白名单授权后可调用。
接口概览
本服务对外提供三大音源(网易云、QQ、酷狗)的标准化访问能力,包含以下 6 项能力:
POST 表单提交(Content-Type: application/x-www-form-urlencoded),响应统一为 application/json。
鉴权与访问控制
本接口采用域名白名单鉴权,无需 API Key。调用方网站域名需由服务端管理员预先加入白名单,明明主页设计的网站(同源调用)默认放行,无需加入白名单。
服务端会自动读取请求中的 Origin 或 Referer HTTP 头来识别调用方域名,按以下优先级校验:
- 同源放行:调用方域名 = 本站域名(如明明主页设计的网站
/page/*调用本站接口),自动通过 - 本地放行:
localhost/127.0.0.1(本地开发环境)自动通过 - 白名单校验:其他外部域名必须在白名单内才能调用
/page/{id})与主站同域,无需任何配置即可直接调用本接口。
| 规则 | 说明 |
|---|---|
| 精确匹配 | 白名单填 example.com,则 example.com 可调用 |
| 子域名匹配 | 白名单填 example.com,则 sub.example.com、api.example.com 也可调用 |
| 端口无关 | 校验仅比较 hostname,不区分端口 |
| 大小写不敏感 | 域名统一转小写后比较 |
403:
{"code": -1, "error": "域名未授权: your-domain.com"}
请联系服务端管理员,将您的域名加入白名单(管理后台 → 接口菜单)。
服务端已开启 CORS,允许浏览器直接跨域调用。响应头包含:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: Content-Type
对于 OPTIONS 预检请求,服务端会直接返回 204 No Content。
频率限制
为保障服务稳定性,开放接口对每个调用方 IP 进行限流。注意:限流的是接口调用次数,不是播放歌曲数。正常播放一首歌仅需 2-4 次调用(搜索 + 获取地址 + 可选歌词/封面),实际听歌完全不受影响。
| 维度 | 限制 |
|---|---|
| 时间窗口 | 60 秒 |
| 最大请求数 | 60 次 / IP / 分钟 |
| 限流对象 | 仅 /api/open/music/* 接口调用 |
| 不限流 | 实际音频流播放(走 CDN 直连) |
429:
{"code": -1, "error": "请求过于频繁,请稍后再试"}
建议客户端实现请求队列和缓存(搜索结果可缓存 10-30 分钟,播放地址可缓存 1 小时),加了缓存后重复播放同一首歌不消耗调用次数。
搜索歌曲
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | string | 是 | 搜索关键词(歌曲名 / 歌手名 / 专辑名) |
| type | string | 是 | 音源:wy=网易云 · qq=QQ音乐 · kg=酷狗 |
| page | number | 否 | 页码,默认 1 |
| limit | number | 否 | 每页数量,默认 30,最大 100 |
| format | string | 否 | 返回格式,固定传 1(标准化格式) |
POST /api/open/music/search HTTP/1.1
Content-Type: application/x-www-form-urlencoded
name=周杰伦&type=wy&page=1&limit=30&format=1
{
"code": 1,
"data": [
{
"id": "186016",
"name": "晴天",
"artist": "周杰伦",
"album": "叶惠美",
"pic_id": "186016",
"url_id": "186016",
"lyric_id": "186016",
"sign": ""
}
]
}
| 字段 | 类型 | 说明 |
|---|---|---|
| code | number | 1 成功 · 其他失败 |
| data | array | 歌曲列表 |
| data[].id | string | 歌曲 ID(用于获取播放地址) |
| data[].name | string | 歌曲名 |
| data[].artist | string | 歌手名(多位歌手用 / 分隔) |
| data[].album | string | 专辑名 |
| data[].pic_id | string | 封面 ID(用于获取封面图片) |
| data[].url_id | string | 播放地址 ID(通常等于 id) |
| data[].lyric_id | string | 歌词 ID(通常等于 id) |
| data[].sign | string | 签名(部分音源需要,获取播放地址时回传) |
获取播放地址
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | string | 是 | 歌曲 ID(来自搜索结果的 url_id 或 id) |
| type | string | 是 | 音源:wy · qq · kg |
| sign | string | 否 | 签名(搜索结果中带 sign 字段时需回传) |
{
"code": 1,
"data": {
"url": "https://xxxcdn.com/xxx.mp3"
}
}
- 返回的 URL 通常为各音源官方 CDN 地址,可直接用于
<audio>播放 - 部分音源返回 HTTP 地址,建议在页面中升级为 HTTPS 后使用
- 播放地址有时效性(通常 30 分钟~数小时不等),过期后需重新获取
- 部分歌曲因版权原因可能返回空 URL(VIP / 下架歌曲)
获取歌词
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | string | 是 | 歌曲 ID(来自搜索结果的 lyric_id) |
| type | string | 是 | 音源:wy · qq · kg |
| song | string | 是 | 歌曲 ID(与 id 相同,部分音源需要) |
| sign | string | 否 | 签名 |
{
"code": 1,
"data": {
"lyric": "[00:12.00]故事的小黄花 [00:15.00]从出生那年就飘着...",
"tlyric": ""
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
| lyric | string | 原文歌词(LRC 格式) |
| tlyric | string | 翻译歌词(外文歌曲时返回,无翻译则为空) |
获取封面图片
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| pic | string | 是 | 封面 ID(来自搜索结果的 pic_id) |
| type | string | 是 | 音源:wy · qq · kg |
{
"code": 1,
"data": {
"url": "https://p1.music.126.net/xxx.jpg"
}
}
返回的 URL 可直接用于 <img> 标签的 src。
获取歌单详情
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | string | 是 | 歌单 ID |
| type | string | 是 | 音源:wy · qq · kg |
返回歌单内的全部歌曲列表,字段结构与搜索接口一致(含 songId、songName、artistName、albumName、albumCover 等并行数组)。
https://music.163.com/#/playlist?id=3778678 中,3778678 即为歌单 ID。
获取用户歌单
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| uid | string | 是 | 用户 UID(各音源平台的用户 ID) |
| type | string | 是 | 音源:wy · qq · kg |
{
"playlist": [
{
"id": "123456",
"name": "我喜欢的音乐",
"coverImgUrl": "https://xxx.jpg",
"creator": {
"nickname": "用户昵称",
"avatarUrl": "https://xxx.jpg"
}
}
]
}
错误码说明
| HTTP 状态码 | 业务 code | 含义 | 处理建议 |
|---|---|---|---|
| 200 | 1 | 成功 | — |
| 200 | 0 / -1 | 上游业务错误 | 检查参数 / 上游服务异常 |
| 400 | — | 参数缺失 | 检查必填参数 |
| 403 | -1 | 域名未授权 | 联系管理员加白名单 |
| 429 | -1 | 请求过频 | 降低频率,添加缓存 |
| 502 | -1 | 上游连接失败 | 稍后重试 |
| 504 | -1 | 上游超时 | 稍后重试 |
{
"code": -1,
"error": "错误描述信息"
}
完整调用示例
// 1. 搜索歌曲
async function searchSongs(keyword) {
const params = new URLSearchParams({
name: keyword,
type: 'wy', // wy=网易云 qq=QQ音乐 kg=酷狗
page: '1',
limit: '30',
format: '1'
})
const res = await fetch('https://your-domain.com/api/open/music/search', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: params.toString()
})
const data = await res.json()
return data.code === 1 ? data.data : []
}
// 2. 获取播放地址
async function getPlayUrl(songId, type, sign) {
const params = new URLSearchParams({ id: songId, type })
if (sign) params.append('sign', sign)
const res = await fetch('https://your-domain.com/api/open/music/url', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: params.toString()
})
const data = await res.json()
return data.code === 1 ? data.data.url : ''
}
// 3. 完整流程:搜索 → 播放
;async function playSong(keyword) {
const songs = await searchSongs(keyword)
if (songs.length === 0) return
const song = songs[0]
const url = await getPlayUrl(song.url_id, 'wy', song.sign)
if (url) {
const audio = new Audio(url)
audio.play()
}
}
<?php
function searchMusic($keyword, $type = 'wy') {
$url = 'https://your-domain.com/api/open/music/search';
$data = http_build_query([
'name' => $keyword,
'type' => $type,
'page' => 1,
'limit' => 30,
'format' => 1
]);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $data,
CURLOPT_HTTPHEADER => ['Content-Type: application/x-www-form-urlencoded'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10
]);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
$result = searchMusic('周杰伦');
print_r($result);
import requests
def search_songs(keyword, source='wy'):
url = 'https://your-domain.com/api/open/music/search'
data = {
'name': keyword,
'type': source,
'page': 1,
'limit': 30,
'format': 1
}
resp = requests.post(url, data=data, timeout=10)
return resp.json()
result = search_songs('周杰伦')
print(result)
常见问题
联系服务端管理员,在管理后台「接口」菜单中添加您的域名即可。添加后立即生效,无需重启服务。
可以。localhost / 127.0.0.1 已默认放行,无需加入白名单。但浏览器在 localhost 环境可能不发送 Origin 头,会改用 Referer 识别。
常见原因:① VIP 付费歌曲;② 因版权下架;③ 地区限制。这是上游音源的限制,非接口问题。
有。不同音源的 CDN 地址有效期不同,通常 30 分钟到数小时不等。建议每次播放时实时获取,不要长期缓存播放地址。
525 表示上游音乐服务暂时不可用(SSL 握手失败),通常是上游服务器临时故障,稍后重试即可。
在网易云/QQ/酷狗的网页版或客户端打开歌单,URL 中的数字 ID 即为歌单 ID。例如 music.163.com/#/playlist?id=3778678 的歌单 ID 是 3778678。