Seedance 2.5 w Pythonie - wideo przez API krok po kroku
Ile kosztuje sekunda wideo z Seedance 2.5 przez API, jak wysłać zadanie w curl i Pythonie, odebrać plik MP4 i nie płacić za nieudane generacje.
Seedance 2.5 przez API Jantarisa kosztuje od 1,51 zł za sekundę i płacisz tylko za sekundy gotowego wideo. Wysyłasz POST /v1/generate z modelem seedance-2.5, dostajesz identyfikator zadania, a po minucie czy kilku odbierasz plik MP4 z GET /v1/tasks/{id}. Poniżej masz działające przykłady w curl i Pythonie, przeliczenie kosztów dla typowych długości i listę błędów, na które sam się nadziałem.
Czym jest Seedance 2.5 i co potrafi
Seedance 2.5 to model wideo od ByteDance Seed, pokazany 31 lipca 2026. Producent chwali się trzema rzeczami: do 30 sekund wideo w jednym przebiegu, dźwięk generowany razem z obrazem (efekty, mowa, muzyka) i bardzo szerokie wejście referencyjne. Według ogłoszenia ByteDance jedno zadanie może dostać do 30 obrazów, 10 klipów wideo i 10 ścieżek audio jako referencje. Do tego dochodzi edycja istniejącego wideo i przedłużanie klipu w kolejnych rundach.
Dla mnie najważniejsza zmiana względem 2.0 to długość. Wcześniej rolkę 25-sekundową trzeba było sklejać z kilku ujęć i pilnować, żeby postać nie zmieniała twarzy między cięciami. Teraz jedno ujęcie na całą długość rolki jest realne.
Czego nie obiecuję: rozdzielczości. Oficjalne materiały ByteDance jej nie podają, a różne platformy oferują 480p, 720p, czasem 1080p. W Jantarisie listę dozwolonych wartości zwraca schemat modelu:
curl https://jantaris.com/v1/models/seedance-2.5W odpowiedzi szukaj pola input_schema - tam są dozwolone resolution, aspect_ratio i zakres duration. Endpoint jest publiczny, klucz nie jest potrzebny.
Ile kosztuje Seedance 2.5 przez API
Cena Seedance 2.5 to od 1,51 zł za sekundę. Rozliczenie jest za sekundę wygenerowanego wideo, więc koszt klipu to po prostu cena za sekundę razy długość.
| Długość klipu | Jak liczyć | Typowe użycie |
|---|---|---|
| 5 s | 5 × od 1,51 zł za sekundę | test promptu, B-roll |
| 10 s | 10 × od 1,51 zł za sekundę | krótkie ujęcie reklamowe |
| 15 s | 15 × od 1,51 zł za sekundę | rolka z jednym ujęciem |
| 30 s | 30 × od 1,51 zł za sekundę | pełna rolka w jednym przebiegu |
Na koncie PL cena jest w złotówkach brutto, z 23% VAT, a fakturę dostajesz automatycznie po każdym doładowaniu. Aktualne stawki wszystkich modeli wideo są w cenniku.
Dwie rzeczy, które zmieniają realny koszt bardziej niż sama stawka:
- Nieudane generacje nie są płatne. Jeśli zadanie skończy się statusem
failed, blokada środków wraca w całości, acostwynosi 0. - Poprawki są płatne. Jeśli wideo się wygenerowało, ale ci się nie podoba, to jest udana generacja. Dlatego testuję prompty na 5 sekundach, a dopiero potem puszczam pełną długość.
Przed wysłaniem zadania wiesz, ile zapłacisz. Odpowiedź na POST /v1/generate zawiera estimated_cost, a ta kwota jest blokowana na saldzie do czasu zakończenia zadania.
Pierwsze wideo w curl
Potrzebujesz konta i klucza. Rejestracja zajmuje chwilę, minimalne doładowanie to 40 zł, a klucz (sk-jt-...) tworzysz w panelu. Szczegóły w szybkim starcie.
Klucz trzymam w zmiennej środowiskowej:
export JANTARIS_API_KEY="sk-jt-..."Wysłanie zadania:
curl https://jantaris.com/v1/generate \
-H "Authorization: Bearer $JANTARIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.5",
"input": {
"prompt": "A fisherman pulls a net onto a wooden boat at dawn, slow handheld camera, mist over the water, waves and seagulls",
"duration": 5,
"resolution": "720p",
"aspect_ratio": "16:9",
"generate_audio": true
}
}'Serwer odpowiada od razu kodem 202:
{
"id": "task_8f2k...",
"object": "task",
"status": "queued",
"model": "seedance-2.5",
"estimated_cost": { "amount": "...", "currency": "PLN" },
"poll_url": "https://jantaris.com/v1/tasks/task_8f2k..."
}Status sprawdzasz tak:
curl https://jantaris.com/v1/tasks/task_8f2k... \
-H "Authorization: Bearer $JANTARIS_API_KEY"Gdy status zmieni się na succeeded, w polu output jest link do pliku. Link jest ważny ograniczony czas, więc pobieraj od razu.
Seedance 2.5 w Pythonie: pełny skrypt
Ten skrypt wysyła zadanie, czeka na wynik z rosnącym odstępem między zapytaniami i zapisuje MP4 na dysku. Używam go jako bazy do większości swoich eksperymentów.
import os
import time
import pathlib
import requests
API = "https://jantaris.com/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['JANTARIS_API_KEY']}"}
def generate_video(prompt: str, duration: int = 5, aspect_ratio: str = "16:9",
resolution: str = "720p", image_url: str | None = None) -> dict:
payload = {
"model": "seedance-2.5",
"input": {
"prompt": prompt,
"duration": duration,
"resolution": resolution,
"aspect_ratio": aspect_ratio,
"generate_audio": True,
},
}
if image_url:
payload["input"]["image_url"] = image_url
r = requests.post(f"{API}/generate", headers=HEADERS, json=payload, timeout=30)
if r.status_code != 202:
raise RuntimeError(f"{r.status_code}: {r.json()['error']['message']}")
task = r.json()
print("zadanie:", task["id"], "szacowany koszt:", task["estimated_cost"])
return task
def wait_for_task(task_id: str, timeout: int = 900) -> dict:
delay, deadline = 3, time.time() + timeout
while time.time() < deadline:
task = requests.get(f"{API}/tasks/{task_id}", headers=HEADERS, timeout=30).json()
if task["status"] in ("succeeded", "failed"):
return task
time.sleep(delay)
delay = min(delay * 1.5, 20)
raise TimeoutError(task_id)
def download(task: dict, folder: str = "wideo") -> list[pathlib.Path]:
pathlib.Path(folder).mkdir(exist_ok=True)
saved = []
for i, item in enumerate(task["output"]):
path = pathlib.Path(folder) / f"{task['id']}_{i}.mp4"
with requests.get(item["url"], stream=True, timeout=180) as r:
r.raise_for_status()
with open(path, "wb") as f:
for chunk in r.iter_content(1 << 20):
f.write(chunk)
saved.append(path)
return saved
if __name__ == "__main__":
task = generate_video(
"Close-up of hands kneading dough on a floured table, warm kitchen light, "
"slow push-in, soft ambient sound",
duration=5,
)
done = wait_for_task(task["id"])
if done["status"] == "succeeded":
print("koszt:", done["cost"], "pliki:", download(done))
else:
print("nieudane, nic nie płacisz:", done["error"])Kilka uwag do kodu:
timeout=30przyPOSTwystarcza, bo serwer nie czeka na wideo, tylko przyjmuje zadanie.- Pętla odpytuje najpierw co 3 sekundy, potem rzadziej, maksymalnie co 20. Przy wideo nie ma sensu odpytywać częściej.
generate_audio: Truewłącza dźwięk generowany razem z obrazem. Jeśli podkład i tak dokładasz w montażu, ustawFalse.- Parametr
?wait=60działa też przy wideo, ale Seedance zwykle potrzebuje więcej niż minutę, więc przy wideo go nie używam. Przy obrazach to wygodny skrót, opisuję go w poradniku o obrazach w Pythonie.
Wideo z obrazu (image-to-video)
Kiedy zależy mi na konkretnym kadrze, na przykład produkt w określonym ustawieniu albo postać z wcześniej zrobionej grafiki, podaję pierwszą klatkę w image_url. Obraz musi być dostępny pod publicznym adresem HTTPS.
task = generate_video(
prompt="The camera slowly orbits the bottle, light reflections move across the glass, "
"condensation drops run down",
duration=5,
aspect_ratio="9:16",
image_url="https://twoja-domena.pl/pliki/butelka.png",
)Pierwszą klatkę robię najczęściej w Nano Banana Pro albo GPT Image 2.5, a dopiero potem animuję. Ta kolejność jest tańsza: obraz kosztuje ułamek sekundy wideo, więc kompozycję poprawiam na obrazach, a do Seedance idzie już gotowy kadr. Cały ten łańcuch z kosztami rozpisałem w tekście ile kosztuje rolka z AI.
Webhook zamiast odpytywania
Przy kilkunastu zadaniach naraz pętla z odpytywaniem robi się niewygodna. Wtedy dodaję webhook_url, a Jantaris wysyła POST z tym samym JSON-em, który zwraca GET /v1/tasks/{id}, kiedy zadanie się skończy.
curl https://jantaris.com/v1/generate \
-H "Authorization: Bearer $JANTARIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.5",
"input": { "prompt": "Rain on a neon street at night, slow dolly", "duration": 10, "aspect_ratio": "9:16" },
"webhook_url": "https://twoj-serwer.pl/jantaris-hook"
}'Każde powiadomienie ma nagłówek x-jantaris-signature z podpisem HMAC-SHA256 ciała żądania. Sekret webhooka bierzesz z panelu. Minimalny odbiornik we Flasku:
import hmac, hashlib, os
from flask import Flask, request, abort
app = Flask(__name__)
SECRET = os.environ["JANTARIS_WEBHOOK_SECRET"].encode()
@app.post("/jantaris-hook")
def hook():
expected = hmac.new(SECRET, request.get_data(), hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, request.headers.get("x-jantaris-signature", "")):
abort(401)
task = request.get_json()
if task["status"] == "succeeded":
print("gotowe:", task["output"][0]["url"])
return "", 204Dokładny format podpisu i zasady ponawiania są w dokumentacji webhooków.
Prompty do Seedance 2.5, które działają
Po kilkudziesięciu generacjach mam kilka zasad:
- Pisz po angielsku. Polskie prompty model rozumie, ale angielskie dają u mnie przewidywalniejszy ruch kamery.
- Opisuj ruch kamery wprost: "slow push-in", "handheld", "static tripod shot", "orbit". Bez tego model wymyśla ruch sam, często za dużo.
- Dźwięk też opisz. Przy
generate_audio: truedopisuję na końcu, co ma być słychać: "waves and seagulls", "quiet cafe chatter". - Kwestie mówione daj w cudzysłowie i po angielsku. Polską mowę w modelach wideo traktuję jako loterię, lektora nagrywam osobno.
- Jedno ujęcie, jedna akcja. Trzydzieści sekund kusi, żeby wcisnąć całą fabułę. Lepiej działa jedna czynność rozpisana dokładnie.
Błędy API i co z nimi robić
| Kod | Co znaczy | Co robię |
|---|---|---|
| 401 | zły albo brak klucza | sprawdzam zmienną JANTARIS_API_KEY |
| 402 | saldo niższe niż estimated_cost | doładowuję (BLIK działa od ręki) |
| 404 | literówka w identyfikatorze modelu | poprawiam na seedance-2.5 |
| 422 | parametr poza schematem, np. zła rozdzielczość | czytam error.message, porównuję z input_schema |
| 429 | za dużo zapytań | czekam i ponawiam z opóźnieniem |
| 502 | błąd po stronie dostawcy | ponawiam później |
Zadanie, które zostało przyjęte, a potem się nie udało, nie zwraca błędu HTTP. Ma po prostu status: "failed" i obiekt error. Pełna lista jest w dokumentacji błędów.
Seedance 2.5 czy inny model wideo
Seedance 2.5 wybieram, kiedy potrzebuję długiego ujęcia z dźwiękiem albo dużo referencji. Do krótkich, filmowych ujęć z bardzo dopracowanym światłem sprawdzam też Veo 3.1 (Quality), a przy ujęciach wielokadrowych Kling 3.0. Zestawienie z tabelą parametrów i cen jest w porównaniu API do wideo AI. Jeśli wolisz klikać zamiast pisać kod, ten sam model i to samo saldo są w Jantaris Studio.
FAQ
Ile kosztuje 10 sekund wideo z Seedance 2.5?
Dziesięciokrotność ceny za sekundę, czyli 10 × od 1,51 zł za sekundę. Dokładną kwotę dla konkretnego zadania zobaczysz w polu estimated_cost od razu po jego wysłaniu.
Jak długie wideo generuje Seedance 2.5?
Według ByteDance do 30 sekund w jednym przebiegu. Zakres parametru duration dostępny w Jantarisie sprawdzisz w schemacie modelu pod GET /v1/models/seedance-2.5.
Czy płacę za nieudane generacje?
Nie. Gdy zadanie kończy się statusem failed, zablokowane środki wracają na saldo w całości, a koszt wynosi 0.
Czy mogę dostać fakturę VAT za Seedance 2.5?
Tak. Na koncie PL faktura VAT z NIP-em wystawia się automatycznie po każdym doładowaniu, a płacić można BLIK-iem albo kartą.
Jak długo są dostępne wygenerowane pliki?
Linki z pola output są ważne ograniczony czas, więc pobieraj pliki od razu po zakończeniu zadania. W Studio historia generacji zostaje na koncie.












