Suno AI API
使用API调用Suno.ai的音乐生成AI,并轻松将其集成到GPTs等代理中。
👉 我们更新很快,请给我们点个星。
英文 | 简体中文 | 演示 | 文档 | 使用Vercel部署
🔥 查看我们的新开源项目:Album AI - 使用自然语言与您的相册聊天!
简介
Suno.ai v3是一个令人惊叹的AI音乐服务。尽管官方API尚未发布,但我们迫不及待地想将其功能集成到某处。
我们发现一些用户有类似的需求,所以我们决定开源这个项目,希望你会喜欢。
演示
我们已经部署了一个绑定到免费Suno账户的示例,所以它有每日使用限制,但你可以看到它是如何运行的: suno.gcui.ai
特性
- 完美实现了app.suno.ai的创作API
- 自动保持账户活跃
- 兼容OpenAI的
/v1/chat/completions
API格式 - 支持自定义模式
- 一键部署到Vercel
- 除了标准API,还适配了GPTs和Coze等Agent平台的API Schema,因此你可以将其作为LLMs的工具/插件/Action,并将其集成到任何AI Agent中
- 宽松的开源许可证,允许你自由集成和修改
入门指南
1. 获取你的app.suno.ai账户的cookie
- 使用浏览器访问app.suno.ai。
- 打开浏览器控制台:按
F12
或访问开发者工具
。 - 导航到
网络
标签。 - 刷新页面。
- 找到包含关键词
client?_clerk_js_version
的请求。 - 点击它并切换到
Header
标签。 - 找到
Cookie
部分,将鼠标悬停在上面,并复制Cookie的值。
2. 克隆并部署此项目
你可以选择你喜欢的部署方法:
部署到Vercel
本地运行
git clone https://github.com/gcui-art/suno-api.git
cd suno-api
npm install
或者,你可以使用Docker Compose
docker compose build && docker compose up
3. 配置suno-api
-
如果部署到Vercel,请在Vercel仪表板中添加一个环境变量
SUNO_COOKIE
,值为第一步中获取的cookie。 -
如果你在本地运行,请确保在
.env
文件中添加以下内容:
SUNO_COOKIE=<your-cookie>
4. 运行suno api
- 如果你已部署到Vercel:
- 请在Vercel仪表板中点击部署,并等待部署成功。
- 访问
https://<vercel分配的域名>/api/get_limit
API进行测试。
- 如果在本地运行:
- 运行
npm run dev
。 - 访问
http://localhost:3000/api/get_limit
API进行测试。
- 运行
- 如果返回以下结果:
{
"credits_left": 50,
"period": "day",
"monthly_limit": 50,
"monthly_usage": 50
}
表示程序运行正常。
5. 使用Suno API
你可以在以下地址查看详细的API文档: suno.gcui.ai/docs
API参考
Suno API目前主要实现了以下API:
- `/api/generate`:生成音乐
- `/v1/chat/completions`:生成音乐 - 以与OpenAI API兼容的格式调用generate API
- `/api/custom_generate`:生成音乐(自定义模式,支持设置歌词、音乐风格、标题等)
- `/api/generate_lyrics`:根据提示生成歌词
- `/api/get`:根据id获取音乐信息。使用","分隔多个id。
如果未提供ID,将返回所有音乐。
- `/api/get_limit`:获取配额信息
- `/api/extend_audio`:延长音频长度
- `/api/clip`:根据作为查询参数`id`传递的ID获取剪辑信息
- `/api/concat`:从扩展生成完整歌曲
更详细的文档,请查看演示站点: suno.gcui.ai/docs
API集成代码示例
Python
import time
import requests
# 替换为你的vercel域名
base_url = 'http://localhost:3000'
def custom_generate_audio(payload):
url = f"{base_url}/api/custom_generate"
response = requests.post(url, json=payload, headers={'Content-Type': 'application/json'})
return response.json()
def extend_audio(payload):
url = f"{base_url}/api/extend_audio"
response = requests.post(url, json=payload, headers={'Content-Type': 'application/json'})
return response.json()
def generate_audio_by_prompt(payload):
url = f"{base_url}/api/generate"
response = requests.post(url, json=payload, headers={'Content-Type': 'application/json'})
return response.json()
def get_audio_information(audio_ids):
url = f"{base_url}/api/get?ids={audio_ids}"
response = requests.get(url)
return response.json()
def get_quota_information():
url = f"{base_url}/api/get_limit"
response = requests.get(url)
return response.json()
def get_clip(clip_id):
url = f"{base_url}/api/clip?id={clip_id}"
response = requests.get(url)
return response.json()
def generate_whole_song(clip_id):
payload = {"clip_id": clip_id}
url = f"{base_url}/api/concat"
response = requests.post(url, json=payload)
return response.json()
if __name__ == '__main__':
data = generate_audio_by_prompt({
"prompt": "一首关于战争的流行重金属歌曲,由深沉的男声歌手演唱,缓慢而富有旋律。歌词描绘了战后人们的悲伤。",
"make_instrumental": False,
"wait_audio": False
})
ids = f"{data[0]['id']},{data[1]['id']}"
print(f"ids: {ids}")
for _ in range(60):
data = get_audio_information(ids)
if data[0]["status"] == 'streaming':
print(f"{data[0]['id']} ==> {data[0]['audio_url']}")
print(f"{data[1]['id']} ==> {data[1]['audio_url']}")
break
# 休眠5秒
time.sleep(5)
Js
const axios = require("axios");
// 替换为你的 vercel 域名
const baseUrl = "http://localhost:3000";
async function customGenerateAudio(payload) {
const url = `${baseUrl}/api/custom_generate`;
const response = await axios.post(url, payload, {
headers: { "Content-Type": "application/json" },
});
return response.data;
}
async function generateAudioByPrompt(payload) {
const url = `${baseUrl}/api/generate`;
const response = await axios.post(url, payload, {
headers: { "Content-Type": "application/json" },
});
return response.data;
}
async function extendAudio(payload) {
const url = `${baseUrl}/api/extend_audio`;
const response = await axios.post(url, payload, {
headers: { "Content-Type": "application/json" },
});
return response.data;
}
async function getAudioInformation(audioIds) {
const url = `${baseUrl}/api/get?ids=${audioIds}`;
const response = await axios.get(url);
return response.data;
}
async function getQuotaInformation() {
const url = `${baseUrl}/api/get_limit`;
const response = await axios.get(url);
return response.data;
}
async function getClipInformation(clipId) {
const url = `${baseUrl}/api/clip?id=${clipId}`;
const response = await axios.get(url);
return response.data;
}
async function main() {
const data = await generateAudioByPrompt({
prompt:
"一首关于战争的流行重金属歌曲,由一位深沉男声歌手缓慢而富有旋律地演唱。歌词描述了战后人们的悲伤。",
make_instrumental: false,
wait_audio: false,
});
const ids = `${data[0].id},${data[1].id}`;
console.log(`ids: ${ids}`);
for (let i = 0; i < 60; i++) {
const data = await getAudioInformation(ids);
if (data[0].status === "streaming") {
console.log(`${data[0].id} ==> ${data[0].audio_url}`);
console.log(`${data[1].id} ==> ${data[1].audio_url}`);
break;
}
// 等待5秒
await new Promise((resolve) => setTimeout(resolve, 5000));
}
}
main();
与自定义代理的集成
您可以将 Suno AI 作为工具/插件/动作集成到您的 AI 代理中。
与 GPTs 集成
[即将推出...]
与 Coze 集成
[即将推出...]
与 LangChain 集成
[即将推出...]
贡献
有四种方式可以支持这个项目:
- 分叉并提交拉取请求:我们欢迎任何能够增强组件或编辑器的拉取请求。
- 提出问题:我们感谢合理的建议和错误报告。
- 捐赠:如果这个项目对您有帮助,可以考虑点击项目顶部的赞助按钮为我们买杯咖啡。干杯!☕
- 传播:向他人推荐这个项目,为仓库加星,或在使用项目后添加反向链接。
问题、建议、问题或错误?
我们使用 GitHub Issues 来管理反馈。随时提出问题,我们会及时处理。
许可证
LGPL-3.0 或更高版本
相关链接
- 项目仓库:github.com/gcui-art/suno-api
- Suno.ai 官方网站:suno.ai
- 演示:suno.gcui.ai
- 相册 AI:自动生成图像元数据并与相册聊天。RAG + 相册。
声明
suno-api 是一个非官方的开源项目,仅用于学习和研究目的。