API بارگذاری و سپس کاور در یک مرحله
توضیح نقطه پایانی
بارگذاری و سپس کاور در یک مرحله، یک فایل صوتی یا نشانی صوتی را میفرستد و بر پایه همان صدای منبع یک نسخه کاور تازه میسازد.
نقطه پایانی: POST /api/music/upload-cover
صورتحساب: پرداختی، فعلاً بهطور پیشفرض 0.6 یوان برای هر فراخوانی. این نقطه پایانی «بارگذاری و سپس کاور» است، نه بارگذاری تصویر جلد. مبلغی که واقعاً کسر میشود تابع پیکربندی فعلی قیمت در پنل مدیریت است.
Max Mode / Variety: این نقطه پایانی دو پارامتر اختیاری max_mode و variety (0-4) را پشتیبانی میکند. با
روشنبودن max_mode این فراخوانی با 2 برابر قیمت حساب میشود (0.6 → 1.2 یوان برای هر فراخوانی)؛ variety هزینه
اضافی ندارد. معنی و روش ارسال آنها در بخش «پارامترهای پیشرفته» در
مرور کلی API جدید آمده است.
زمانهای انتظار و مهلتها (مهم): این نقطه پایانی همزمان است — سفارش تنها زمانی پذیرفته و به تولید سپرده میشود که پاسخ برسد. بر پایه اندازهگیری، بیشتر درخواستها در 1-3 ثانیه پاسخ میدهند، حدود 10% بیش از 30 ثانیه طول میکشند و طولانیترین حدود 230 ثانیه است. مهلت سمت کلاینت را 300 ثانیه یا بیشتر بگذارید؛ نبود پاسخ به معنای تولید نشدن نیست، و بلافاصله پس از مهلت دوباره تلاش نکنید (سفارش را تکرار میکند و دوباره هزینه میگیرد). اگر اتصال قطع شد، بعداً با
GET /api/music/songsبررسی کنید. بخش «زمانهای انتظار و تنظیم مهلت» در مرور کلی API جدید را ببینید.
وقتی صدا بزرگ است، بهتر است «بارگذاری» و «کاور» را به دو مرحله جدا کنید (توصیهشده)
این نقطه پایانی میخواهد تمام صدا در بدنه درخواست قرار بگیرد: هرچه صدا بزرگتر، بدنه بزرگتر، و یک لرزش شبکه یا مهلت، انتقال را در میانه قطع میکند و پس از آن سرور
unexpected end of JSON inputبرمیگرداند (HTTP 400، بدون هزینه).وقتی صدا از حدود 8 مگابایت میگذرد، شبکه ناپایدار است یا همان مواد منبع چند بار استفاده میشود، به شکل دو مرحلهای بروید:
POST /api/music/upload-sourceنخست صدای منبع را بارگذاری میکند — رایگان، هر زمان قابل تکرار — وclip_idمیدهد؛POST /api/music/generate-from-sourceبا همانclip_idکاور را آغاز میکند — بدنه درخواست در مرحله هزینهدار فقط حدود 250 بایت است.API بارگذاری صدای منبع، API کاور از کلیپ منبع و بخش «فایلهای بزرگ و درخواستهای بریده» در پایان همین صفحه را ببینید.
پارامترهای درخواست
Headers
| پارامتر | نوع | الزامی | یادداشت |
|---|---|---|---|
| Authorization | string | بله | Bearer YOUR_API_KEY |
| Content-Type | string | بله | application/json |
پارامترهای بدنه
| پارامتر | نوع | الزامی | پیشفرض | یادداشت |
|---|---|---|---|---|
| model | string | خیر | suno-v6 | نام مدل برای مشتری: suno-v6، suno-v6-wild یا suno-v6-mini |
| file_url | string | خیر | - | نشانی صدای منبع |
| file_base64 | string | خیر | - | صدا بهصورت Base64 |
| file_name | string | خیر | - | نام فایل |
| prompt | string | خیر | - | متن تازه یا جهت اقتباس |
| style | string | خیر | - | برچسبهای سبک |
| title | string | خیر | - | عنوان |
| negativeTags | string | خیر | - | سبک منفی |
| instrumental | boolean | خیر | false | اینکه آهنگ بیکلام باشد یا نه |
| waitAudio | boolean | خیر | false | اینکه تا کاملشدن صدا صبر شود یا نه |
| cover_start_s | number | خیر | - | ثانیه آغاز بخشی که کاور میشود |
| cover_end_s | number | خیر | - | ثانیه پایان بخشی که کاور میشود |
| audio_weight | number | خیر | - | میزان وابستگی به صدای مرجع، بازه 0.0-1.0؛ تنها زمانی قابل ارسال است که صدای مرجع داده شده باشد |
واحد cover_start_s و cover_end_s ثانیه است و میتواند اعشاری باشد؛ زمان آغاز باید کوچکتر از زمان پایان باشد و از طول صدای منبع فراتر نرود. اگر هر دو فیلد حذف شوند، تمام صدا استفاده میشود. audio_weight به metadata.control_sliders.audio_weight در سونو نقشه میشود و میزان تکیه نتیجه بر صدای مرجع را کنترل میکند؛ مقدارش 0.0-1.0 است و تنها زمانی میتوان آن را فرستاد که درخواست صدای مرجع معتبر در file_url یا file_base64 داشته باشد. مقدار 0 معتبر است؛ حذف فیلد یعنی «مشخصنشده» و رفتار پیشفرض سونو حفظ میشود. instrumental و waitAudio باید مقدار منطقی JSON باشند، نه رشته.
نقطه پایانی بارگذاری بهطور پیشفرض ناهمگام پاسخ میدهد. تا وقتی clips[].status در پاسخ pending است، خالیبودن audio_url طبیعی است و به معنای شکست بارگذاری یا کاور نیست؛ song_id واقعی برگشتی را ذخیره کنید و با نقطه پایانی جستوجوی آهنگ تا کاملشدن پرسوجو کنید و سپس نشانی صدا را بخوانید.
نمونه درخواست
curl -X POST https://www.suno-api.io/api/music/upload-cover \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "suno-v6",
"file_url": "https://example.com/source.mp3",
"file_name": "source.mp3",
"prompt": "متن تازه یا جهت اقتباس",
"style": "Mandopop, acoustic guitar",
"title": "نسخه کاور",
"negativeTags": "noise, low quality",
"audio_weight": 0.5,
"instrumental": false,
"waitAudio": false,
"cover_start_s": 0,
"cover_end_s": 60
}'
پاسخ
{
"code": 200,
"message": "success",
"data": {
"upload": {
"clip_id": "uploaded_clip_id",
"status": "complete"
},
"clips": [
{
"song_id": "new_clip_id",
"song_title": "نسخه کاور",
"status": "pending"
}
]
}
}
فایلهای بزرگ و درخواستهای بریده
توصیهشده: جدا کردن بارگذاری و کاور به دو مرحله
نقطه پایانی یکمرحلهای (همین یکی) بارگذاری و تولید را در یک مرحله ادغام میکند: بدنه بزرگ در همان مرحله واحد قرار دارد، پس با قطعشدن معلوم نیست چیزی تولید شده یا هزینهای کسر شده است.
| مرحله 1 بارگذاری | مرحله 2 کاور | |
|---|---|---|
| نقطه پایانی | POST /api/music/upload-source |
POST /api/music/generate-from-source |
| صورتحساب | رایگان (فقط بارگذاری، بدون تولید) | 0.6 یوان برای هر فراخوانی؛ با Max Mode 1.2 یوان برای هر فراخوانی |
| بدنه درخواست | خودِ صدا (base64 / multipart) یا فقط یک پیوند با file_url |
حدود 250 بایت (فقط یک sourceClipId) |
| خروجی | clip_id (شناسه کلیپ صدای منبع) |
data.clips[].song_id (نتیجه تولید) |
| در صورت شکست | همان را دوباره امتحان کنید، بدون هزینه و بدون ساخت کار تولید | مهلت کلاینت را ≥300 ثانیه بگذارید؛ در مهلت ابتدا با /api/music/songs بررسی کنید و بلافاصله تکرار نکنید |
| بازاستفاده از مواد منبع | همان clip_id برای extend / replace / جداسازی هم کار میکند |
صدا باید هر بار دوباره بارگذاری شود |
نتیجه: صدای بیش از حدود 8 مگابایت، شبکه ناپایدار، یا استفاده چندباره از یک ماده → شکل دو مرحلهای؛ صدای بسیار کوچک در شبکه پایدار → همین نقطه پایانی سادهتر است.
400 unexpected end of JSON input یعنی چه
یعنی JSONی که سرور دریافت کرده ناقص است (نه پارامتر اشتباه، نه مشکل دسترسی یا موجودی). دلایل رایج به ترتیب احتمال:
- بریدهشدن بدنه بزرگ در میانه انتقال: لایه ورودی هم «چند بایت که کلاینت اعلام کرده» و هم «چند بایت که واقعاً رسیده» را ثبت میکند. مورد اندازهگیریشده: کلاینت 14.17 مگابایت اعلام کرد اما فقط 11.8–12.4 مگابایت رسید و هر سه درخواست حدود 1.6–1.7 ثانیه متوقف شدند؛ تعداد بایتهای کمشده هر بار متفاوت بود، که نشاندهنده قطع انتقال است نه سقف ثابت (سرور اندازه بدنه درخواست را محدود نمیکند).
- ناسازگاری
Content-Lengthبا بایتهای واقعاً ارسالشده: در Node.js استفاده از.lengthرشته (تعداد نویسههای UTF-16) بهعنوان طول، وقتی محتوا چینی یا متن چندبایتی دارد اشتباه محاسبه میکند. - نوشتن بدنه بهصورت رشته بهجای Buffer، که بایتهای نوشتهشده با اعلامشده نمیخواند.
هر سه مورد پیش از هزینهکردن رخ میدهند، پس هزینهای ایجاد نمیشود.
چکلیست خودبررسی سمت کلاینت
- مقدار
Content-LengthازBuffer.byteLength(json, 'utf8')(یاBuffer.from(json).length) گرفته میشود — هرگز ازjson.length؛ - بدنه درخواست بهصورت Buffer نوشته میشود، نه رشته؛
- مهلت سوکت / درخواست ≥ 300 ثانیه؛
- وقتی صدا بیش از حدود 8 مگابایت است: از
file_urlاستفاده کنید (بدنه فقط چند صد بایت است)، یا بارگذاری multipart درupload-source، یا مستقیماً شکل دو مرحلهای؛ - در درخواستهای multipart
Content-Typeرا دستی تنظیم نکنید (boundary را کلاینت اضافه میکند)؛ - «بایتهای واقعاً ارسالشده» را چاپ کنید و با
Content-Lengthمقایسه کنید؛ - در شکل دو مرحلهای، پیش از فرستادن مرحله 2 مطمئن شوید مرحله 1
clip_idوstatusدر وضعیت کامل برگردانده است.
خطاهای رایج
| خطا | معنا | کار لازم |
|---|---|---|
unexpected end of JSON input |
بدنه درخواست ناقص (بریده) | چکلیست بالا را انجام دهید یا به شکل دو مرحلهای بروید |
invalid character '-' in numeric literal |
بدنه multipart به نقطه پایانی JSON فرستاده شده | در نقاط پایانی JSON از multipart استفاده نکنید و Content-Type را دستی تنظیم نکنید |
one of file_path, file_base64, file_url, or multipart file is required |
صدایی پیوست نشده | file_base64 / file_url / file بهصورت multipart اضافه کنید |
model is required |
بدنه JSON معتبر اما خالی بود (مثلاً {}) |
دستکم model را بفرستید |
Invalid request: Invalid request, ... |
پیام پوششی خطای تجزیه بدنه | نیمه دوم را برای علت مشخص بخوانید (معمولاً یکی از موارد بالا) |
نقاط پایانی مرتبط: API بارگذاری صدای منبع (مرحله 1)، API کاور از کلیپ منبع (مرحله 2).
دریافت کلید API
پس از ثبتنام از کنسول یک کلید API بسازید. هر تولید ۰٫۶ یوان هزینه دارد و ۲ قطعه برمیگرداند، دانلودها نامحدود است و به شماره تلفن نیازی نیست.
دریافت کلید API بازگشت به مرور کلی