Przejdź do treści głównej

Seedance 2.5 reference-to-video od ByteDance buduje jedno ujęcie z Twoich materiałów: do 30 obrazów, 10 klipów wideo i 10 ścieżek audio, bez pierwszej klatki. Wynik 4–30 sekund w 480p, 720p lub 1080p, z natywnym dźwiękiem.

Od $0.074/s

Obszar roboczy

Wyślij żądanie

Szybki start

Przykłady korzystają z publicznych definicji parametrów wybranego endpointu. Podmień klucz API i przykładowe media, a potem wyślij żądanie ze swojego serwera.

SDK i integracje
POSThttps://api.spicyapi.ai/api/v1/jobs/createTask

Uwierzytelnianie API

Klucz API trzymaj w zmiennej środowiskowej serwera SPICY_API_KEY. Dla żądań JSON używaj uwierzytelniania Bearer i Content-Type: application/json.

Authorization: Bearer $SPICY_API_KEY
Przykładowy wynikUżyj tego przykładu
# Generate the idempotency key once; reuse it when retrying after a lost response.
export SPICY_IDEMPOTENCY_KEY="${SPICY_IDEMPOTENCY_KEY:-$(uuidgen)}"
curl -X POST https://api.spicyapi.ai/api/v1/jobs/createTask \
  -H "Authorization: Bearer $SPICY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $SPICY_IDEMPOTENCY_KEY" \
  -d '{
  "model": "bytedance/seedance-2.5/reference-to-video",
  "input": {
    "aspect_ratio": "adaptive",
    "duration_seconds": 5,
    "generate_audio": true,
    "output_format": "mp4",
    "prompt": "A slow aerial shot drifting over a misty pine forest at sunrise",
    "resolution": "720p",
    "reference_image_urls": [
      "https://example.com/reference.png"
    ]
  }
}'

# Copy data.taskId from the response into TASK_ID, then poll the status.
TASK_ID="TASK_ID_FROM_RESPONSE"
curl "https://api.spicyapi.ai/api/v1/jobs/recordInfo?taskId=$TASK_ID" \
  -H "Authorization: Bearer $SPICY_API_KEY"

Wygenerowane ze schematu wejścia tego modelu – tego samego, względem którego API waliduje każde żądanie.

Parametry wejściowe

Te pola umieść w obiekcie input w ciele żądania. Nazwy i typy odpowiadają API. Gdy wartości domyślnej nie podano, nie zakładaj żadnej.

Ten model ma zależności między polami. Pola oznaczone jako wymagane warunkowo zależą od innych danych wejściowych; reguły znajdziesz w pełnym JSON Schema poniżej.

promptstringWymagane

Pole wymagane, a tutaj odpowiada też za obsadę. Referencje przywoływane są w kolejności wysyłki, więc napisz, który obraz jest którą postacią, co wnosi każdy klip i po co jest audio. Briefy przyjmujemy bez weryfikacji po naszej stronie; tam, gdzie sformułowanie odrzuca własna warstwa Seedance, klatka otwierająca w image-to-video wciąż doprowadza do celu.

Domyślnie
Nie określono
watermarkbooleanOpcjonalne

Prosi model o oznaczenie wideo znakiem wodnym treści wygenerowanej przez AI, zgodnie z dokumentacją samego modelu. Domyślnie wyłączone; włącz, gdy miejsce publikacji wymaga oznaczania materiałów wygenerowanych przez AI. Nie wpływa na cenę.

Domyślnie
false
return_last_framebooleanOpcjonalne

Oprócz wideo zwraca ostatnią klatkę klipu jako osobny obraz. Wyślij ją do image-to-video jako kolejną klatkę początkową, żeby łączyć ujęcia bez samodzielnego eksportowania kadru. Domyślnie wyłączone; nie wpływa na cenę.

Domyślnie
false
seedintegerOpcjonalne

Całkowity seed; pominięty – każdy przebieg losuje własny. Ustal go przy wszystkim innym bez zmian, żeby ocenić, co naprawdę zmieniła poprawka w prompcie. To narzędzie do porównań, a nie obietnica powtórzeń identycznych klatka w klatkę.

Domyślnie
Nie określono
Ograniczenia
minimum:0
maximum:2147483647
enable_web_searchbooleanOpcjonalne

Domyślnie wyłączone. Po włączeniu model może przed renderem wyszukać w sieci informacje związane z promptem. Nie zmienia ceny.

Domyślnie
false
output_formatstringOpcjonalne

Kontener zwracanego wideo: mp4 (domyślnie) albo mov. Obraz jest w obu taki sam; mov zapisuje ścieżkę dźwiękową jako nieskompresowany PCM, więc plik jest nieco większy i trafia bezpośrednio do programów montażowych, które wolą QuickTime. Nie zmienia ceny.

Domyślnie
"mp4"
Dozwolone wartości
"mp4""mov"
generate_audiobooleanOpcjonalne

Domyślnie włączone. Tworzy własną ścieżkę dźwiękową zsynchronizowaną z obrazem. Nawet przy podanym `reference_audio_urls` wyłączenie tej opcji oznacza, że żadna ścieżka nie powstanie – audio referencyjne kształtuje tempo i sposób gry, a nie jest ścieżką wynikową. Wyłącz je, gdy montaż dostanie dźwięk w postprodukcji.

Domyślnie
true
duration_secondsintegerOpcjonalneWpływa na cenę

Od 4 do 30 sekund, domyślnie 5. Pamiętaj, że ta wartość i długość twoich klipów referencyjnych to dwa niezależne wkłady do rozliczanej wielkości, więc maksowanie obu jest momentem, w którym jedno żądanie robi się drogie. Sprawdź na krótkim czasie, czy referencje są czytane zgodnie z zamysłem, zanim ustalisz docelowy czas trwania.

Domyślnie
5
Dozwolone wartości
456789101112131415161718192021222324252627282930
resolutionstringOpcjonalneWpływa na cenę

480p, 720p lub 1080p, domyślnie 720p; wartość ta wprost zasila rozliczaną wielkość. Ustawia wyłącznie próg wyjściowy i nie wyostrzy referencji o niskiej rozdzielczości. Dopóki sprawdzasz, czy referencje się ze sobą składają, pracuj w 480p albo 720p, a próg podnieś, gdy relacja między nimi czyta się poprawnie. Nie ma tu progów z upscalingiem ani z poprawianiem obrazu.

Domyślnie
"720p"
Dozwolone wartości
"480p""720p""1080p"
aspect_ratiostringOpcjonalne

Domyślnie `adaptive`. Gdy materiały referencyjne nie mają wspólnego kształtu, adaptive pozwala modelowi znaleźć kadr mieszczący wszystkie tematy; zablokowanie jednej proporcji zwiększa ryzyko, że przywołana osoba albo produkt zostaną obcięte. Wskazuj kształt tylko przy twardym wymogu dostawy. Bez wpływu na rozliczenie.

Domyślnie
"adaptive"
Dozwolone wartości
"21:9""16:9""4:3""1:1""3:4""9:16""adaptive"
reference_audio_urlsarray<string>Wymagane warunkowo

Do 10 referencyjnych plików audio, każdy od 2 do 30 sekund, o łącznej długości nieprzekraczającej 30 sekund (poprzednia generacja dopuszczała 3 pliki i 15 sekund razem). Dają modelowi kotwicę dźwiękową – sposób mówienia, tempo, frazę muzyczną – do której dopasowuje się ruch i punkty cięcia. To co innego niż `generate_audio`: to, co podajesz tutaj, jest wejściem, a o tym, czy gotowy klip niesie ścieżkę dźwiękową, wciąż decyduje `generate_audio`.

Domyślnie
Nie określono
Ograniczenia
maxItems:10
reference_video_urlsarray<string>Wymagane warunkowoWpływa na cenę

Do 10 klipów referencyjnych wnoszących ruch, tempo albo język kamery. Każdy trwa od 2 do 30 sekund, a łączna długość nie przekracza 30 sekund – poprzednia generacja dopuszczała 3 klipy i 15 sekund razem, więc budżet referencji się podwoił i można przywołać cały ruch kamery w całości. Długość klipu referencyjnego nadal jednak wlicza się do rozliczanej wielkości: nie jako zmiana progu, lecz jako mnożnik liniowy tego samego rodzaju co `duration_seconds`, więc szerszy budżet nie jest powodem, by z przyzwyczajenia wrzucać całe ujęcie. Pisz prompt jako nowe ujęcie, które czerpie z tych klipów. Jeśli treść prosi o edycję samego materiału – usunięcie, podmianę albo zmianę stylu czegoś – Seedance traktuje zadanie jako edycję wideo, a ta wymaga ustawienia długości, którego ten endpoint nie przyjmuje, więc zadanie kończy się błędem. Prośba o kontynuację klipu też się nie powiedzie, chyba że `aspect_ratio` zostanie na `adaptive`.

Domyślnie
Nie określono
Ograniczenia
maxItems:10
reference_image_urlsarray<string>Wymagane warunkowo

Do 30 obrazów referencyjnych, służących do utrzymania postaci, stylu albo scenografii – poprzednia generacja dopuszczała tylko 9, więc miejsca jest tu naprawdę sporo. Dwa albo trzy ujęcia tej samej postaci zwykle działają lepiej niż dziesięć niemal identycznych kadrów. Pamiętaj, że ten endpoint nie ma parametru pierwszej ani ostatniej klatki: tryb referencyjny i tryb klatkowy wykluczają się, więc gdy klatka otwierająca ma być dokładna, przejdź do image-to-video. Własna kontrola wejścia Seedance może odrzucić zdjęcie albo klip referencyjny, na którym widać twarz prawdziwej, rozpoznawalnej osoby. Każdy bok musi mieć od 300 do 6000 pikseli; mniejsze pliki odrzuca kontrola wejściowa, zanim zostanie naliczona jakakolwiek opłata.

Domyślnie
Nie określono
Ograniczenia
maxItems:30

Śledź zadanie

HTTP 202 oznacza, że zadanie zostało przyjęte, a nie ukończone. Zapisz zwrócone taskId i odpytuj właśnie to zadanie. Nie twórz kolejnego zadania, czekając na jego wynik.

Odpowiedź o przyjęciu
HTTP/1.1 202 Accepted
Location: /api/v1/jobs/recordInfo?taskId=job_01k3m8x9q2z4v7n5p6r8s0t1w3

{
  "code": 200,
  "msg": "success",
  "request_id": "req_example_create",
  "data": {
    "taskId": "job_01k3m8x9q2z4v7n5p6r8s0t1w3",
    "state": "queued",
    "estimatedCost": "0.750000"
  }
}

Odpowiedź o przyjęciu zawiera szacunek, dzięki czemu twoja aplikacja pokaże tę samą kwotę w historii zadań i w rozliczeniach.

Odczytaj zadanie
curl --get "https://api.spicyapi.ai/api/v1/jobs/recordInfo" \
  --data-urlencode "taskId=$TASK_ID" \
  -H "Authorization: Bearer $SPICY_API_KEY"

Zacznij odpytywać mniej więcej co 2 sekundy i stopniowo wydłużaj odstęp. Zatrzymaj się na stanie końcowym. Po zerwaniu połączenia odpytaj pierwotne taskId. Tworzenie ponawiaj wyłącznie z pierwotnym kluczem idempotentności i pierwotnym ciałem żądania.

Albo odbierz wynik przez callback
import { verifyWebhook } from "@spicyapi/sdk";

// express.raw keeps the bytes we signed; express.json never matches.
app.post("/hooks/spicy", express.raw({ type: "application/json" }), (req, res) => {
  const { payload } = verifyWebhook({
    rawBody: req.body,
    timestamp: req.header("X-Webhook-Timestamp"),
    signature: req.header("X-Webhook-Signature"),
    payloadVersion: Number(req.header("X-Webhook-Payload-Version")),
    secret: process.env.SPICY_WEBHOOK_SECRET,
  });
  res.status(200).end();
  void handleFinishedTask(payload);
});

Podaj callBackUrl przy tworzeniu zadania, a gotowy rekord przyjdzie do ciebie metodą POST – bez żadnej pętli odpytywania. Każda dostawa niesie X-Webhook-Timestamp, X-Webhook-Signature i X-Webhook-Payload-Version. Podpis to HMAC-SHA256 w base64 z taskId.timestamp.sha256(body), więc trzeba go sprawdzać na surowych bajtach: sparsowanie JSON-a i ponowne zserializowanie zmienia je i weryfikacja się nie powiedzie. Nieudane dostawy są ponawiane, więc to samo taskId może przyjść dwa razy – zrób obsługę idempotentną. Najpierw odpowiedz kodem 2xx, a pracę wykonaj potem; wolna obsługa jest traktowana jak nieudana dostawa.

Odczytaj wynik

Wynik wykorzystuj dopiero przy stanie succeeded. Przy niepowodzeniu skorzystaj z errorCode, errorMessage i request_id. Przykładowe koszty i stany nie odpowiadają rzeczywistemu rozliczeniu.

Przykład odpowiedzi po zakończeniu
{
  "code": 200,
  "msg": "success",
  "request_id": "req_example_record",
  "data": {
    "taskId": "job_01k3m8x9q2z4v7n5p6r8s0t1w3",
    "model": "bytedance/seedance-2.5/reference-to-video",
    "state": "succeeded",
    "output": {
      "assets": [
        {
          "key": "tasks/2026/08/28/job_01k3m8x9q2z4v7n5p6r8s0t1w3/3f7a1c9e5b2d48f0a6c1e3d5b7f9a1c3.mp4",
          "mime": "video/mp4",
          "url": "https://example.r2.cloudflarestorage.com/results/job_01k3m8x9q2z4v7n5p6r8s0t1w3/result.mp4?X-Amz-Signature=SIGNATURE_FROM_RESPONSE",
          "expiresAt": "2026-08-28T12:20:08.000Z"
        }
      ]
    },
    "cost": "0.750000",
    "settled": true,
    "createdAt": "2026-08-28T12:00:00Z",
    "completedAt": "2026-08-28T12:00:30Z"
  }
}

Każdy dostępny materiał otwieraj lub pobieraj bezpośrednio spod assets[].url, bez nagłówka Authorization. Podpisany adres wygasa o expiresAt; odpytaj zadanie ponownie, żeby go odświeżyć, dopóki materiał mieści się w okresie przechowywania. Materiał oczekujący lub niedostępny nie ma adresu. Podpisane adresy traktuj jako prywatne.

SDK i integracje

Korzystaj ze SpicyAPI w aplikacji, terminalu, asystencie AI lub wizualnym przepływie pracy. Wybierz instrukcję konfiguracji.

Użyj w ComfyUI

Zainstaluj węzły SpicyAPI przez ComfyUI Manager albo poleceniem poniżej, a potem wyszukaj na płótnie Seedance 2.5 · Reference to Video. Węzeł ma te same opcje co ta strona i pokazuje cenę, zanim ruszy.

cd ComfyUI/custom_nodes
git clone https://github.com/spicyapi-ai/comfyui-spicyapi