API تولید در حالت ساده
توضیح نقطه پایانی
تولید در حالت ساده یک توصیف یکجملهای را به آهنگ کامل تبدیل میکند. سرویس متن، ملودی، تنظیم و خوانندگی را از روی توصیف شما مینویسد.
نقطه پایانی: POST /api/music/create
صورتحساب: پرداختی، فعلاً بهطور پیشفرض 0.6 یوان برای هر فراخوانی. هر فراخوانی معمولاً 2 آهنگ برمیگرداند؛ مبلغی که واقعاً کسر میشود تابع پیکربندی فعلی قیمت در پنل مدیریت است.
Max Mode / Variety: این نقطه پایانی دو پارامتر اختیاری max_mode و variety (0-4) را پشتیبانی میکند. با
روشنبودن max_mode این فراخوانی با 2 برابر قیمت حساب میشود (0.6 → 1.2 یوان برای هر فراخوانی)؛ variety هزینه
اضافی ندارد. معنی و روش ارسال آنها در بخش «پارامترهای پیشرفته» در
مرور کلی API جدید آمده است.
مدل پیشنهادی: suno-v6
زمانهای انتظار و مهلتها (مهم): این نقطه پایانی همزمان است — سفارش تنها زمانی پذیرفته و به تولید سپرده میشود که پاسخ برسد. بر پایه اندازهگیری، بیشتر درخواستها در 1-3 ثانیه پاسخ میدهند، حدود 10% بیش از 30 ثانیه طول میکشند و طولانیترین حدود 230 ثانیه است. مهلت سمت کلاینت را 300 ثانیه یا بیشتر بگذارید؛ نبود پاسخ به معنای تولید نشدن نیست، و بلافاصله پس از مهلت دوباره تلاش نکنید (سفارش را تکرار میکند و دوباره هزینه میگیرد). اگر اتصال قطع شد، بعداً با
GET /api/music/songsبررسی کنید. بخش «زمانهای انتظار و تنظیم مهلت» در مرور کلی API جدید را ببینید.
پارامترهای درخواست
Headers
| پارامتر | نوع | الزامی | یادداشت |
|---|---|---|---|
| Authorization | string | بله | Bearer YOUR_API_KEY |
| Content-Type | string | بله | application/json |
پارامترهای بدنه
| پارامتر | نوع | الزامی | پیشفرض | یادداشت |
|---|---|---|---|---|
| description | string | بله | - | توصیف آهنگ، به هر زبانی؛ حداکثر 3000 نویسه (بیشتر از آن 400 برمیگرداند و هزینهای ندارد) |
| model | string | خیر | suno-v6 | نام مدل برای مشتری: suno-v6، suno-v6-wild یا suno-v6-mini |
| instrumental | boolean | خیر | false | اینکه آهنگ تنها بیکلام باشد |
| wait_completion | boolean | خیر | false | اینکه پیش از پاسخ منتظر پایان تولید بماند |
| references | array | خیر | - | فهرست مواد مرجع: آهنگهای مرجع / صداهای قدیمی / تصاویر مرجع؛ حداکثر 5 آهنگ، 1 صدا و 1 تصویر. بخش «مواد مرجع references (اختیاری)» در پایین را ببینید |
نمونه درخواست
curl -X POST https://www.suno-api.io/api/music/create \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "suno-v6",
"description": "یک ترانه پاپ ماندارین شاد درباره تابستان کنار دریا",
"instrumental": false,
"wait_completion": false
}'
مواد مرجع references (اختیاری)
references آرایهای است که به این تولید «مواد مرجع» میچسباند. کاملاً اختیاری است (حذف آن رفتار را دقیقاً مانند قبل نگه میدارد) و میتوانید فقط یک نوع یا هر ترکیبی را بچسبانید.
انواع عنصر
| type | فیلد الزامی | فیلدهای اختیاری | حداکثر | یادداشت |
|---|---|---|---|---|
song |
song_id |
style_prompt، lyrics، duration_s |
5 | آهنگ مرجع؛ song_id از API پرسوجوی آهنگ و تاریخچه گرفته میشود و آهنگ باید پیشتر کامل شده باشد |
voice |
voice_id |
- | 1 | صدای قدیمی؛ voice_id از API استنساخ صدا و تولید با صدا گرفته میشود |
image |
base64 |
- | 1 | تصویر مرجع؛ محتوای base64 را به شکل data:image/jpeg;base64,... بفرستید |
قواعد
- ترتیب آهنگهای مرجع همان ترتیب معنایی آنهاست: به همان ترتیبی که میخواهید بفرستید (مثلاً «ملودی از اولی، خوانندگی از دومی»).
style_prompt/lyrics/duration_sهمه میتوانند حذف شوند؛ پلتفرم آنها را از اطلاعات آهنگ پر میکند و آنچه شما فرستادهاید معتبر است.- در آهنگهای کاملاً بیکلام،
lyricsمیتواند""یا"[Instrumental]"باشد. - تصاویر مرجع از
jpeg/png/webpپشتیبانی میکنند، هر کدام تا 10 مگابایت، همراه بدنه بهصورت base64 ارسال میشوند. - هنگام چسباندن چند آهنگ مرجع، از
accept_mode=asyncهم استفاده کنید (بخش «حالت رسید پذیرش» در بالا): سرویس باید نخست مواد را آماده کند، پس انتظار همزمان میتواند طولانی باشد.
نمونه: دو آهنگ مرجع
curl -X POST https://www.suno-api.io/api/music/create \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "suno-v6",
"description": "این ایدهها را در یک آهنگ ترکیب کن",
"references": [
{ "type": "song", "song_id": "43eb711d-81f8-4e72-a68e-b2498bac88f9" },
{ "type": "song", "song_id": "a90438d2-35fc-4443-88f4-56531e6e5d24" }
]
}'
نمونه: آهنگ مرجع + صدای قدیمی
{
"model": "suno-v6",
"description": "این ایدهها را با این صدا بخوان",
"references": [
{ "type": "song", "song_id": "43eb711d-81f8-4e72-a68e-b2498bac88f9" },
{ "type": "voice", "voice_id": "5813cbe1-36f1-414a-a9a8-4d399dfeb292" }
]
}
نمونه: آهنگ مرجع + تصویر مرجع
{
"model": "suno-v6",
"description": "حالوهوای این تصویر را بگیر",
"references": [
{ "type": "song", "song_id": "43eb711d-81f8-4e72-a68e-b2498bac88f9" },
{ "type": "image", "base64": "data:image/jpeg;base64,/9j/4AAQ..." }
]
}
خطاهای پارامتر
این موارد HTTP 400 برمیگردانند و پیش از هر صورتحساب متوقف میشوند، پس هزینهای ندارند:
| مورد | پیام خطا |
|---|---|
| بیش از 5 آهنگ مرجع | references supports at most 5 song references |
| بیش از 1 صدا | references supports at most 1 voice reference |
| بیش از 1 تصویر مرجع | references supports at most 1 image reference |
مقدار نادرست type |
references[0].type must be one of song, voice, image |
آهنگ بدون song_id |
references[0].song_id is required |
| آهنگ هنوز کامل نشده | references[0].song_id must be a real completed clip |
| آهنگ تکراری | references[0].song_id is duplicated |
عدد در
references[0]نمایهٔ آن عنصر در آرایه است، پس یافتن عنصر خطادار آسان است.
پاسخ
آرایهای از آهنگها، معمولاً شامل 2 کار یا 2 آهنگ.
[
{
"song_id": "clip_id",
"song_title": "نسیم دریای تابستان",
"status": "pending",
"description": "یک ترانه پاپ ماندارین شاد درباره تابستان کنار دریا",
"audio_url": "",
"cover_url": "",
"video_url": "",
"model_version": "suno-v6",
"generation_type": "generate",
"created_at": "2026-05-21T10:00:00Z"
}
]
حالت رسید پذیرش (اختیاری، پیشنهادی برای کلاینتهایی که نباید اتصال طولانی نگه دارند)
بهطور پیشفرض این نقطه پایانی همزمان است: رسیدن پاسخ یعنی سفارش پذیرفته شده و انتظارهای اندازهگیریشده میتواند به حدود 230 ثانیه برسد. اگر کلاینت شما برای اتصال طولانی مناسب نیست، حالت رسید پذیرش را روشن کنید — هر یک از دو راه کافی است:
- افزودن
"accept_mode": "async"به بدنه درخواست - افزودن هدر
X-Accept-Mode: async
با روشنبودن آن، نقطه پایانی بیدرنگ HTTP 202 برمیگرداند که فقط یعنی «پذیرفته و در صف تولید قرار گرفت»، و تولید در پسزمینه ادامه مییابد:
{
"success": true,
"data": {
"request_id": "ac_20260920092714315816800d76fv3nq",
"status": "queued",
"accepted_at": 1789896434,
"pre_consumed_quota": 300000,
"tasks": [
{ "index": 0, "status": "queued" },
{ "index": 1, "status": "queued" }
]
}
}
مرحله پذیرش
song_idبرنمیگرداند. هنوز شناسه واقعی آهنگ وجود ندارد و نهrequest_idو نهtasks[].indexشناسه آهنگ نیستند — آنها را بهعنوانsong_idذخیره نکنید.song_idواقعی در پرسوجوی پیشرفت در پایین ظاهر میشود.
پرسوجوی پیشرفت پذیرش
نقطه پایانی: GET /api/music/requests/{request_id} (رایگان، با همان کلید API احراز هویت میشود)
curl "https://www.suno-api.io/api/music/requests/ac_20260920092714315816800d76fv3nq" \
-H "Authorization: Bearer YOUR_API_KEY"
{
"success": true,
"data": {
"request_id": "ac_20260920092714315816800d76fv3nq",
"status": "processing",
"tasks": [
{ "index": 0, "status": "processing", "song_id": "f3fa09f5-3d55-4953-826c-0d23f043ec57" },
{ "index": 1, "status": "processing", "song_id": "5fcafe3e-3fae-4d64-8f66-c01bc027b0c3" }
]
}
}
معنی هر مقدار status:
| status | معنی |
|---|---|
queued |
پذیرفته شده، هنوز به آهنگ مشخصی گره نخورده (tasks میتواند آرایه خالی باشد) |
processing |
به تولید سپرده شده |
partial |
یکی از دو آهنگ کامل شده |
completed |
هر دو کامل شدهاند و tasks[].song_id خوانده میشود |
failed |
ارسال ناموفق بود، مبلغ کاملاً بازگردانده شده و error_message علت را میگوید |
هر کار tasks[].status خودش را هم دارد، با همان مقادیر API پرسوجوی آهنگ:
pending (سپرده شده و در حال تولید)، processing، completed، failed. عناصر کار ممکن است title
و duration و audio_url ثبتشده هم داشته باشند؛ نبودشان یعنی هنوز تولید نشده است.
پس از گرفتن song_id واقعی، با API پرسوجوی آهنگ یا نقاط پایانی دانلود ادامه دهید.
نمونه پایتون
import time
import requests
BASE = "https://www.suno-api.io"
HEADERS = {"Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json"}
accepted = requests.post(
f"{BASE}/api/music/create",
headers={**HEADERS, "Idempotency-Key": "your-own-unique-key"},
json={"description": "یک ترانه پاپ شاد", "model": "suno-v6", "accept_mode": "async"},
timeout=300,
).json()["data"]
request_id = accepted["request_id"]
while True:
time.sleep(5)
progress = requests.get(
f"{BASE}/api/music/requests/{request_id}", headers=HEADERS, timeout=60
).json()["data"]
if progress["status"] in ("completed", "failed"):
print(progress)
break
سازگاری و نکات
- بدون
accept_modeرفتار دقیقاً مانند قبل است: انتظار همزمان، بازگشت200و آرایه آهنگها. اتصالهای موجود نیازی به تغییر کد ندارند. - این کلید فعلاً فقط روی
POST /api/music/createوPOST /api/music/create/customکار میکند؛ سایر نقاط پایانی تولید هنوز آن را پشتیبانی نمیکنند. Idempotency-Keyهم بفرستید (رشته یکتای خودتان، حداکثر 128 نویسه): همان کلید فقط یک بار پذیرفته میشود، ارسال دوباره همان رسید را برمیگرداند و هزینه دوباره گرفته نمیشود. در حالت ناهمزمان این نکته مهمتر است.- با
accept_mode=asyncمقدارwait_completionنادیده گرفته میشود (رسید بیدرنگ برمیگردد و منتظر آهنگ نمیماند). - هزینه همچنان هنگام پذیرش سفارش پیشکسر میشود؛ تولید ناموفق بهطور خودکار کاملاً بازگردانده میشود.
- سقف فیلد متنی:
descriptionحداکثر 3000 نویسه را میپذیرد (شمارش بر پایه نویسه یونیکد، یک نویسه چینی 1 حساب میشود). متن بلندتر بیدرنگ HTTP400برمیگرداند، وارد تولید نمیشود و هزینهای ندارد، و پیام خطا طول اندازهگیریشده را میآورد، مثلاًdescription must not exceed 3000 characters; received 4120. این نقطه پایانی فیلد متن/سبک ندارد؛ برای آن بخش «سقف فیلد متنی» در API تولید در حالت سفارشی را ببینید. قواعد کلی در «سقف فیلدهای متنی» مرور کلی API جدید آمده است. - بدون
referencesرفتار، قیمت و پاسخ دقیقاً مانند قبل است: اتصالهای موجود نیازی به تغییر کد ندارند. - وقتی مواد مرجع (خصوصاً چند آهنگ) پیوست شده، بهجای انتظار همزمان طولانی از حالت رسید
accept_mode=asyncاستفاده کنید؛ زمان آمادهسازی مواد به تعداد و منبع آن بستگی دارد.
گامهای بعدی
اگر هنگام رسیدن پاسخ آهنگها کامل نشدهاند، نتیجه نهایی را با API پرسوجوی آهنگ بگیرید.
نمونه اتصال در Node/Electron
اگر تولید استاندارد را در فرایند اصلی Electron، سرور Node.js یا کلاینت دسکتاپ ادغام میکنید، این جریان پیشنهادی است:
- برای ساخت کار تولید
POST /api/music/createرا فراخوانی کنید. - مقدار
song_idیاidرا از پاسخ بخوانید. - هر 2 ثانیه
POST /api/music/queryرا برای بررسی وضعیت فراخوانی کنید. - بهمحض ظاهر شدن
audio_urlدر نتیجه، تولید را تمامشده بدانید.
از مسیرهای قدیمی POST /api/generate یا GET /api/clip?id=... دیگر استفاده نکنید؛ اینها بخشی از سطح اتصال عمومی پیشنهادی امروز نیستند.
const http = require('http');
const https = require('https');
const BASE_URL = 'https://www.suno-api.io';
const MODEL = 'suno-v6';
const POLL_INTERVAL_MS = 2000;
const MAX_POLL_ATTEMPTS = 60;
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
function requestJson(urlString, apiKey, body) {
const url = new URL(urlString);
const transport = url.protocol === 'https:' ? https : http;
const payload = JSON.stringify(body);
return new Promise((resolve, reject) => {
const req = transport.request(
{
method: 'POST',
hostname: url.hostname,
port: url.port || undefined,
path: `${url.pathname}${url.search}`,
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(payload),
},
},
(res) => {
let raw = '';
res.setEncoding('utf8');
res.on('data', (chunk) => {
raw += chunk;
});
res.on('end', () => {
const data = raw ? JSON.parse(raw) : {};
if (!res.statusCode || res.statusCode < 200 || res.statusCode >= 300) {
reject(new Error(`Suno API request failed: HTTP ${res.statusCode} ${raw}`));
return;
}
resolve(data);
});
}
);
req.on('error', reject);
req.write(payload);
req.end();
});
}
function getPayload(response) {
return response && response.data !== undefined ? response.data : response;
}
function toSongList(payload) {
if (Array.isArray(payload)) return payload;
if (Array.isArray(payload?.songs)) return payload.songs;
if (Array.isArray(payload?.clips)) return payload.clips;
return payload ? [payload] : [];
}
function collectSongIds(createResponse) {
return toSongList(getPayload(createResponse))
.map((song) => song.song_id || song.id)
.filter(Boolean);
}
async function generateSunoSong({ apiKey, description, instrumental = false }) {
const createResponse = await requestJson(`${BASE_URL}/api/music/create`, apiKey, {
description,
model: MODEL,
instrumental,
wait_completion: false,
});
const songIds = collectSongIds(createResponse);
if (songIds.length === 0) {
throw new Error(`Suno API did not return song ids: ${JSON.stringify(createResponse)}`);
}
for (let attempt = 0; attempt < MAX_POLL_ATTEMPTS; attempt += 1) {
await sleep(POLL_INTERVAL_MS);
const queryResponse = await requestJson(`${BASE_URL}/api/music/query`, apiKey, {
song_ids: songIds,
model: MODEL,
});
const songs = toSongList(getPayload(queryResponse));
const completed = songs.find((song) => song.audio_url);
if (completed) {
return {
audioUrl: completed.audio_url,
title: completed.song_title || completed.title || 'Suno Song',
duration: completed.duration,
};
}
const allFailed = songs.length > 0 && songs.every((song) =>
['failed', 'error', 'rejected'].includes(String(song.status || '').toLowerCase())
);
if (allFailed) {
throw new Error(`Suno generation failed: ${JSON.stringify(songs)}`);
}
}
throw new Error('Suno generation timed out after 120 seconds. Please query again later.');
}
// Usage:
// generateSunoSong({
// apiKey: process.env.SUNO_API_KEY,
// description: 'A bright pop song about the ocean in summer',
// }).then(console.log).catch(console.error);
در پروژههای واقعی کلید API را در متغیر محیطی سرور، تنظیمات کلاینت دسکتاپ یا مخزن امن نگه دارید — هرگز در کد فرانتاند و هرگز در مخزن کد.
دریافت کلید API
پس از ثبتنام از کنسول یک کلید API بسازید. هر تولید ۰٫۶ یوان هزینه دارد و ۲ قطعه برمیگرداند، دانلودها نامحدود است و به شماره تلفن نیازی نیست.
دریافت کلید API بازگشت به مرور کلی