API بارگذاری و سپس کاور در یک مرحله

به‌روزرسانی 2026-09-18 · تیم Suno-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 مگابایت می‌گذرد، شبکه ناپایدار است یا همان مواد منبع چند بار استفاده می‌شود، به شکل دو مرحله‌ای بروید:

  1. POST /api/music/upload-source نخست صدای منبع را بارگذاری می‌کند — رایگان، هر زمان قابل تکرار — و clip_id می‌دهد؛
  2. 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ی که سرور دریافت کرده ناقص است (نه پارامتر اشتباه، نه مشکل دسترسی یا موجودی). دلایل رایج به ترتیب احتمال:

  1. بریده‌شدن بدنه بزرگ در میانه انتقال: لایه ورودی هم «چند بایت که کلاینت اعلام کرده» و هم «چند بایت که واقعاً رسیده» را ثبت می‌کند. مورد اندازه‌گیری‌شده: کلاینت 14.17 مگابایت اعلام کرد اما فقط 11.8–12.4 مگابایت رسید و هر سه درخواست حدود 1.6–1.7 ثانیه متوقف شدند؛ تعداد بایت‌های کم‌شده هر بار متفاوت بود، که نشان‌دهنده قطع انتقال است نه سقف ثابت (سرور اندازه بدنه درخواست را محدود نمی‌کند).
  2. ناسازگاری Content-Length با بایت‌های واقعاً ارسال‌شده: در Node.js استفاده از .length رشته (تعداد نویسه‌های UTF-16) به‌عنوان طول، وقتی محتوا چینی یا متن چندبایتی دارد اشتباه محاسبه می‌کند.
  3. نوشتن بدنه به‌صورت رشته به‌جای Buffer، که بایت‌های نوشته‌شده با اعلام‌شده نمی‌خواند.

هر سه مورد پیش از هزینه‌کردن رخ می‌دهند، پس هزینه‌ای ایجاد نمی‌شود.

چک‌لیست خودبررسی سمت کلاینت

خطاهای رایج

خطا معنا کار لازم
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 بسازید. هر تولید ۰٫۶ یوان هزینه دارد و ۲ قطعه برمی‌گرداند، دانلودها نامحدود است و به شماره تلفن نیازی نیست.

دریافت کلید API بازگشت به مرور کلی