API przesyłania i coveru w jednym kroku
Opis punktu końcowego
Przesyłanie i cover w jednym kroku wysyła plik dźwiękowy lub URL dźwięku i tworzy na podstawie tego źródłowego dźwięku nową wersję coveru.
Punkt końcowy: POST /api/music/upload-cover
Rozliczenie: Płatne, obecnie domyślnie 0,6 ¥ za wywołanie. Ten punkt końcowy to „prześlij i zrób cover” — nie chodzi o przesyłanie okładki graficznej. Faktycznie pobierana kwota zależy od bieżącej konfiguracji cen w panelu administracyjnym.
Max Mode / Variety: ten punkt końcowy obsługuje opcjonalne parametry max_mode i variety (0-4). Przy włączonym
max_mode to wywołanie jest rozliczane po podwójnej cenie (0,6 → 1,2 ¥ za wywołanie); variety nie kosztuje
nic dodatkowo. Znaczenie i sposób wysyłania opisano w sekcji „Parametry zaawansowane”
Przeglądu nowego API.
Czasy oczekiwania i limity czasu (ważne): to punkt końcowy synchroniczny — zamówienie zostaje przyjęte i przekazane do generowania dopiero, gdy przyjdzie odpowiedź. Z pomiarów: większość żądań odpowiada w 1-3 sekundy, około 10% przekracza 30 sekund, a najdłuższe trwa około 230 sekund. Ustaw limit czasu klienta na 300 sekund lub więcej; brak odpowiedzi nie oznacza, że nic nie zostało wygenerowane, a ponawianie od razu po limicie czasu duplikuje zamówienie i pobiera opłatę ponownie. Jeśli połączenie się zerwało, sprawdź później przez
GET /api/music/songs. Zobacz „Czasy oczekiwania i ustawienia limitu czasu” w Przeglądzie nowego API.
Przy dużym pliku dźwiękowym warto rozdzielić „przesyłanie” i „cover” na dwa kroki (zalecane)
Ten punkt końcowy wymaga umieszczenia całego dźwięku w treści żądania: im większy dźwięk, tym większa treść, a jedno drgnięcie sieci lub limit czasu przerywają transfer w połowie, po czym serwer zwraca
unexpected end of JSON input(HTTP 400, bez opłaty).Gdy dźwięk przekracza około 8 MB, sieć jest niestabilna albo ten sam materiał źródłowy będzie używany wielokrotnie, przejdź na formę dwuetapową:
POST /api/music/upload-sourcenajpierw przesyła dźwięk źródłowy — bezpłatnie, można ponawiać w każdej chwili — i zwracaclip_id;POST /api/music/generate-from-sourcerozpoczyna cover tymclip_id— treść żądania w płatnym kroku to tylko około 250 bajtów.Zobacz API przesyłania dźwięku źródłowego, API coveru na podstawie clipu źródłowego oraz „Duże pliki i obcięte żądania” na końcu tej strony.
Parametry żądania
Headers
| Parametr | Typ | Wymagany | Uwagi |
|---|---|---|---|
| Authorization | string | tak | Bearer YOUR_API_KEY |
| Content-Type | string | tak | application/json |
Parametry treści
| Parametr | Typ | Wymagany | Domyślnie | Uwagi |
|---|---|---|---|---|
| model | string | nie | suno-v6 | Nazwa modelu dla klienta: suno-v6, suno-v6-wild lub suno-v6-mini |
| file_url | string | nie | - | URL dźwięku źródłowego |
| file_base64 | string | nie | - | Dźwięk w Base64 |
| file_name | string | nie | - | Nazwa pliku |
| prompt | string | nie | - | Nowy tekst lub kierunek adaptacji |
| style | string | nie | - | Tagi stylu |
| title | string | nie | - | Tytuł |
| negativeTags | string | nie | - | Styl negatywny |
| instrumental | boolean | nie | false | Czy utwór jest instrumentalny |
| waitAudio | boolean | nie | false | Czy czekać na ukończenie dźwięku |
| cover_start_s | number | nie | - | Sekunda początku fragmentu do przerobienia |
| cover_end_s | number | nie | - | Sekunda końca fragmentu do przerobienia |
| audio_weight | number | nie | - | Zależność od dźwięku referencyjnego, zakres 0.0-1.0; można wysłać tylko wtedy, gdy podano dźwięk referencyjny |
cover_start_s i cover_end_s podaje się w sekundach i mogą być ułamkowe; czas początku musi być mniejszy niż końca i nie może przekraczać długości dźwięku źródłowego. Gdy oba pola zostaną pominięte, używany jest cały dźwięk. audio_weight odpowiada polu metadata.control_sliders.audio_weight w Suno i steruje tym, jak mocno wynik opiera się na dźwięku referencyjnym; przyjmuje 0.0-1.0 i można je dołączyć tylko wtedy, gdy żądanie zawiera poprawny dźwięk referencyjny w file_url lub file_base64. 0 jest poprawną wartością; pominięcie pola oznacza „nie określono” i zachowuje domyślne zachowanie Suno. instrumental i waitAudio muszą być wartościami logicznymi JSON, nie ciągami znaków.
Punkt końcowy przesyłania domyślnie odpowiada asynchronicznie. Dopóki clips[].status w odpowiedzi to pending, pusty audio_url jest normalny i nie oznacza, że przesyłanie lub cover się nie udały; zapisz zwrócony prawdziwy song_id i odpytuj punkt końcowy wyszukiwania utworów do zakończenia, zanim odczytasz adres dźwięku.
Przykład żądania
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": "Nowy tekst lub kierunek adaptacji",
"style": "Mandopop, acoustic guitar",
"title": "Wersja cover",
"negativeTags": "noise, low quality",
"audio_weight": 0.5,
"instrumental": false,
"waitAudio": false,
"cover_start_s": 0,
"cover_end_s": 60
}'
Odpowiedź
{
"code": 200,
"message": "success",
"data": {
"upload": {
"clip_id": "uploaded_clip_id",
"status": "complete"
},
"clips": [
{
"song_id": "new_clip_id",
"song_title": "Wersja cover",
"status": "pending"
}
]
}
}
Duże pliki i obcięte żądania
Zalecane: rozdziel przesyłanie i cover na dwa kroki
Jednorazowy punkt końcowy (ten) łączy przesyłanie i generowanie w jeden krok: duża treść występuje w tym jedynym kroku, więc przy przerwaniu nie wiadomo, czy coś zostało wygenerowane, ani czy pobrano opłatę.
| Krok 1 przesyłanie | Krok 2 cover | |
|---|---|---|
| Punkt końcowy | POST /api/music/upload-source |
POST /api/music/generate-from-source |
| Rozliczenie | Bezpłatnie (tylko przesyłanie, bez generowania) | 0,6 ¥ za wywołanie; 1,2 ¥ za wywołanie z Max Mode |
| Treść żądania | Sam dźwięk (base64 / multipart) albo tylko link przez file_url |
Około 250 bajtów (tylko jeden sourceClipId) |
| Zwraca | clip_id (ID clipu dźwięku źródłowego) |
data.clips[].song_id (wygenerowany wynik) |
| Gdy się nie uda | Po prostu ponów — bez opłaty i bez zadania generowania | Ustaw limit czasu klienta na ≥300 s; przy przekroczeniu najpierw sprawdź przez /api/music/songs i nie ponawiaj od razu |
| Ponowne użycie materiału źródłowego | Ten sam clip_id działa też dla extend / replace / rozdzielania |
Dźwięk trzeba przesłać za każdym razem |
Wniosek: dźwięk powyżej około 8 MB, niestabilna sieć albo ten sam materiał używany kilka razy → forma dwuetapowa; maleńki dźwięk w stabilnej sieci → ten punkt końcowy jest wygodniejszy.
Co oznacza 400 unexpected end of JSON input
Oznacza to, że JSON odebrany przez serwer jest niekompletny (to nie błędny parametr ani problem z uprawnieniami czy saldem). Typowe przyczyny, od najbardziej prawdopodobnej:
- Duża treść obcięta w połowie transferu: warstwa wejściowa rejestruje zarówno „ile bajtów zadeklarował klient”, jak i „ile faktycznie dotarło”. Zmierzony przypadek: klient zadeklarował 14,17 MB, a dotarło tylko 11,8–12,4 MB, a wszystkie trzy żądania zatrzymały się około 1,6–1,7 s; brakująca liczba bajtów była za każdym razem inna, co wskazuje na przerwanie transferu, a nie stały limit (serwer nie ogranicza rozmiaru treści żądania).
Content-Lengthniezgodny z faktycznie wysłanymi bajtami: w Node.js użycie.lengthciągu znaków (liczba znaków UTF-16) jako długości daje błąd, gdy treść zawiera chiński lub inny wielobajtowy tekst.- Zapisanie treści jako ciągu znaków zamiast Buffer, przez co zapisane bajty nie zgadzają się z deklaracją.
Wszystkie trzy zdarzają się przed pobraniem opłaty, więc nie powstaje żaden koszt.
Lista samodzielnej kontroli po stronie klienta
-
Content-Lengthpochodzi zBuffer.byteLength(json, 'utf8')(alboBuffer.from(json).length) — nigdy zjson.length; - Treść żądania jest zapisywana jako Buffer, nie jako ciąg znaków;
- Limit czasu gniazda / żądania wynosi ≥ 300 sekund;
- Gdy dźwięk przekracza około 8 MB: użyj
file_url(treść to tylko kilkaset bajtów) albo przesyłania multipart zupload-source, albo od razu formy dwuetapowej; - W żądaniach multipart nie ustawiaj
Content-Typeręcznie (boundary ma dodać klient); - Wypisz „faktycznie wysłane bajty” i porównaj z
Content-Length; - W formie dwuetapowej upewnij się, że krok 1 zwrócił
clip_idze stanem zakończonym, zanim wyślesz krok 2.
Częste błędy
| Błąd | Znaczenie | Co zrobić |
|---|---|---|
unexpected end of JSON input |
Treść żądania niekompletna (obcięta) | Przejdź samodzielną kontrolę powyżej albo zmień na formę dwuetapową |
invalid character '-' in numeric literal |
Treść multipart wysłano do punktu końcowego JSON | Nie używaj multipart w punktach końcowych JSON i nie ustawiaj Content-Type ręcznie |
one of file_path, file_base64, file_url, or multipart file is required |
Nie dołączono dźwięku | Dodaj file_base64 / file_url / multipart file |
model is required |
Treść to pusty poprawny JSON (np. {}) |
Wyślij co najmniej model |
Invalid request: Invalid request, ... |
Komunikat opakowujący błąd analizy treści | Przeczytaj drugą połowę, aby poznać konkretną przyczynę (zwykle jedną z powyższych) |
Powiązane punkty końcowe: API przesyłania dźwięku źródłowego (krok 1), API coveru na podstawie clipu źródłowego (krok 2).
Uzyskaj klucz API
Po rejestracji utwórz klucz API w konsoli. Każde generowanie kosztuje 0,6 ¥ i zwraca 2 utwory, pobierania są nieograniczone, a numer telefonu nie jest wymagany.
Pobierz klucz API Powrót do przeglądu