Przejdź do treści głównej

Kontynuuj klip z Seedance 2.0 Mini: ostatnia klatka twojego wideo otwiera nowy fragment od 4 do 15 sekund z dźwiękiem, a w odpowiedzi dostajesz jeden plik z połączonym oryginałem i kontynuacją, w 480p lub 720p.

Od $0.025/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
# 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.0-mini/video-extend",
  "input": {
    "bitrate_mode": "standard",
    "duration_seconds": 5,
    "enable_web_search": false,
    "generate_audio": true,
    "resolution": "720p",
    "video_url": "https://example.com/reference.mp4"
  }
}'

# 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.

video_urlstringWymagane

Klip do kontynuowania: MP4, MOV lub WebM, do 60 sekund. Jego ostatnia klatka staje się klatką otwierającą nowego fragmentu, więc potnij go na czystej, ostrej klatce. Oryginał nie jest rozliczany.

Domyślnie
Nie określono
Ograniczenia
minLength:1
format:"uri"
contentMediaType:["video/mp4","video/webm","video/quicktime"]
watermarkbooleanOpcjonalne

Dodaje do nowego fragmentu własny, widoczny znak wodny modelu „AI generated”. Domyślnie wyłączone; włącz, gdy miejsce publikacji wymaga oznaczania materiału wytworzonego przez AI. Nie wpływa na cenę.

Domyślnie
false
bitrate_modestringOpcjonalne

Przepływność kodowania nowego fragmentu w takiej postaci, w jakiej dostarcza go model: `standard` (domyślnie) lub `high`. High utrzymuje ostrzejsze drobne faktury i szybki ruch, a plik fragmentu jest znacznie większy; połączony plik platforma koduje jeszcze raz. Nie wpływa na cenę.

Domyślnie
"standard"
Dozwolone wartości
"standard""high"
seedintegerOpcjonalne

Liczba całkowita od 0 do 2147483647; bez niej każde uruchomienie losuje własną. Zablokuj ją, żeby porównywać po jednym zmienionym polu naraz; to narzędzie do porównań, a nie obietnica powtórzeń identycznych klatka po klatce.

Domyślnie
Nie określono
Ograniczenia
minimum:0
maximum:2147483647
enable_web_searchbooleanOpcjonalneWpływa na cenę

Domyślnie wyłączone. Po włączeniu model może przed renderowaniem nowego fragmentu wyszukać w sieci informacje związane z twoim promptem. Żądania z włączonym wyszukiwaniem są rozliczane według stawki za wyszukiwanie w sieci, wyższej od standardowej; szacunek widoczny przed wysłaniem już ją uwzględnia.

Domyślnie
false
generate_audiobooleanOpcjonalne

Domyślnie włączone, więc nowy fragment dostaje wygenerowany dźwięk; wyłączenie nie obniża ceny w tym progu. Twój oryginał w każdym przypadku zachowuje własny dźwięk; gdy jedna strona jest niema, połączony plik jest uzupełniany ciszą.

Domyślnie
true
duration_secondsintegerOpcjonalneWpływa na cenę

Długość nowego fragmentu w pełnych sekundach: od 4 do 15 albo -1, żeby model sam wybrał; wtedy z góry rezerwowane jest 15 sekund, a opłata rozlicza się na długość faktycznie dostarczoną. Domyślnie 5. Twój oryginał jest dodawany z przodu i nie jest rozliczany.

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

Rozmiar nowego fragmentu: 480p lub 720p, domyślnie 720p. Dopasuj go do oryginału: określa tylko jakość nowego fragmentu, a niższe ustawienie sprawia, że nowa część wygląda miękciej niż oryginał. Połączony plik zachowuje kadr Twojego klipu bez czarnych pasów; aby dopasować łączenie, obraz może zostać przycięty lub skorygowany o kilka procent przy krawędziach. Jeśli model zwróci wyraźnie inne proporcje, nowy fragment zostanie przeskalowany tak, aby wypełnić Twój kadr, i wyśrodkowany, a to, co wystaje, zostanie przycięte. Ustala cenę.

Domyślnie
"720p"
Dozwolone wartości
"480p""720p"
last_image_urlstringOpcjonalne

Opcjonalna docelowa klatka końcowa: nowy fragment kończy się na tym obrazie, zamiast tam, gdzie zdecyduje model. Przydaje się do przejścia albo powrotu do znanej klatki. Nadaj jej te same proporcje co ostatniej klatce klipu, inaczej zostanie przycięta. Każdy bok musi mieć od 300 do 6000 pikseli; mniejszy obraz zostanie odrzucony przez kontrolę wejścia, zanim cokolwiek naliczymy.

Domyślnie
Nie określono
Ograniczenia
contentMediaType:["image/jpeg","image/png","image/webp","image/gif"]
promptstringOpcjonalne

Opcjonalny. Co dzieje się dalej: kolejna akcja, ruch kamery i dźwięk. Bez niego model sam zdecyduje o ruchu na podstawie ostatniej klatki. Klatka otwierająca już ustala bohatera i scenerię, więc słowa zostaw na ruch.

Domyślnie
Nie określono
Ograniczenia
minLength:1

Ś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.0-mini/video-extend",
    "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.0 Mini · Video Extend. 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