API Seedance 2.0 : texte-vidéo et image-vidéo en Python
Un seul script crée la tâche, interroge son état et enregistre le MP4. Voici les champs, les limites et deux clips de 5 secondes produits le 30 octobre 2026.
Sur cette page
- Réponse courte
- De quoi avez-vous besoin avant le premier appel ?
- Quels champs prend une requête Seedance 2.0 ?
- Le script Python
- Comment envoyer une première image pour l'image vers vidéo ?
- Deux clips que nous avons produits
- Ce que les fichiers contiennent
- Quelles erreurs et quelles limites allez-vous rencontrer ?
- Seedance 2.0, Fast, Mini ou 2.5 ?
- FAQ
- Existe-t-il une API Seedance 2.0 officielle ?
- Puis-je envoyer une URL d'image au lieu du base64 ?
- Comment couper le son ?
- Pourquoi ma requête a-t-elle expiré ?
- Combien de temps les liens vidéo restent-ils valides ?
- Sources vérifiées
Seedance 2.0 tourne sur l'API média d'OmniaKey sous l'identifiant de modèle dreamina-seedance-2-0-260128. Vous envoyez une tâche en POST vers https://api.omniakey.com/v1/media/tasks, vous interrogez l'identifiant de tâche, puis vous téléchargez le MP4. Nos deux clips de 5 secondes en 720p, l'un à partir de texte et l'autre à partir d'une image fixe, ont pris 159 et 139 secondes le 30 octobre 2026.
Réponse courte
- Identifiant de modèle
dreamina-seedance-2-0-260128, avec trois opérations :text_to_video,image_to_videoetreference_to_video(la documentation de l'API vidéo d'OmniaKey, vérifiée le 30 octobre 2026). - Créer, interroger, télécharger : l'appel de création répond 202 avec un identifiant, puis vous appelez
GET /v1/media/tasks/{id}toutes les quelques secondes jusqu'à ce que le statut soitsucceeded(la vue d'ensemble de l'API média d'OmniaKey, vérifiée le 30 octobre 2026). - La durée va de 4 à 15 secondes entières, et l'identifiant complet 2.0 rend en 480P, 720P et 1080P.
- Le corps de la requête reste sous 1 MiB, base64 intégré compris.
- Nos deux rendus de 5 secondes en 720p ont pris 159 secondes (texte vers vidéo) et 139 secondes (première image).
De quoi avez-vous besoin avant le premier appel ?
D'une clé API OmniaKey, de Python 3 et de l'identifiant de modèle exact. Le script n'importe que la bibliothèque standard : il tourne sans environnement virtuel et sans installer de paquet.
Exportez la clé dans OMNIAKEY_API_KEY avant le premier appel. Le script la lit une fois et l'envoie en jeton Bearer à chaque requête, la clé reste donc hors du fichier et hors de votre historique Git.
Créez avec POST https://api.omniakey.com/v1/media/tasks et interrogez avec GET https://api.omniakey.com/v1/media/tasks/{id}. Ces deux appels plus POST /v1/media/tasks/{id}/cancel constituent toute l'API média (vue d'ensemble de l'API média, vérifiée le 30 octobre 2026).
Écrivez les identifiants de modèle en entier. OmniaKey ne sert pas les alias courts seedance-2 et seedance-2-5, ils répondent 503 no_available_channel (documentation de l'API vidéo, vérifiée le 30 octobre 2026).
Les tâches vidéo sont facturées d'avance à la seconde de sortie générée, et le montant revient automatiquement quand une tâche se termine en failed ou canceled (vue d'ensemble de l'API média, vérifiée le 30 octobre 2026). Pour le prix actuel d'une seconde, voir les tarifs en cours sur la page du modèle Seedance 2.0.
Quels champs prend une requête Seedance 2.0 ?
Quatre champs de premier niveau portent la tâche, et un objet parameters porte les réglages de sortie. Seul duration n'a pas de valeur par défaut raisonnable : envoyez-le toujours.
model: l'identifiant complet du modèle (les alias courts échouent)type:video(le type de média)operation:text_to_video,image_to_video,reference_to_video(nom seul, sans préfixe)input.prompt: une chaîne (scène, action et caméra, jusqu'à 12 000 caractères)input.media[]:{"type": "first_frame", "url": …}(une première image, oureference_image)
Dans parameters :
duration: 4 à 15, secondes entières (décide du prix)resolution:480P,720P,1080P(Fast et Mini s'arrêtent à 720P)ratio:16:9,9:16,1:1,4:3,3:4,21:9,adaptive(adaptivesuit l'image)generate_audio:truepar défaut, oufalse(falsedonne un MP4 muet)n:1(doit valoir 1)
Les deux listes suivent la documentation de l'API vidéo et la vue d'ensemble de l'API média d'OmniaKey (vérifiées le 30 octobre 2026), la limite de prompt vient de la page du modèle.
Envoyez le nom d'opération seul ; OmniaKey ajoute lui-même le préfixe du type de média (documentation de l'API vidéo, vérifiée le 30 octobre 2026). Les paramètres qu'il ne connaît pas partent vers le fournisseur tels quels (vue d'ensemble de l'API média, vérifiée le 30 octobre 2026).
Un piège attend ceux qui partent de la documentation du fournisseur : l'API de création de tâche de BytePlus place des champs dans content[] et au premier niveau, donc du code tiré d'un tutoriel BytePlus ne tourne pas tel quel contre /v1/media/tasks (API de création de tâche de BytePlus, vérifiée le 30 octobre 2026).
Le script Python
Un seul fichier fait les deux opérations, et la seule différence est le corps qu'il construit. Enregistrez-le sous seedance_video.py et lancez python3 seedance_video.py.
import base64
import json
import os
import time
import urllib.error
import urllib.request
import uuid
API = "https://api.omniakey.com/v1/media/tasks"
KEY = os.environ["OMNIAKEY_API_KEY"]
MODEL = "dreamina-seedance-2-0-260128"
def request(method, url, body=None, extra_headers=None):
headers = {"Authorization": f"Bearer {KEY}", "User-Agent": "omniakey-example/1"}
data = None
if body is not None:
headers["Content-Type"] = "application/json"
data = json.dumps(body).encode()
headers.update(extra_headers or {})
req = urllib.request.Request(url, data=data, headers=headers, method=method)
with urllib.request.urlopen(req, timeout=120) as resp:
return json.load(resp)
def poll(url, attempts=5):
for attempt in range(attempts):
try:
return request("GET", url)
except urllib.error.HTTPError as err:
if err.code < 500 or attempt == attempts - 1:
raise
except urllib.error.URLError:
if attempt == attempts - 1:
raise
time.sleep(5 * (attempt + 1))
def run_task(body, out_path):
task = request("POST", API, body, {"Idempotency-Key": str(uuid.uuid4())})["id"]
print("task", task, flush=True)
for _ in range(180): # 5-second polls, up to 15 minutes
time.sleep(5)
state = poll(f"{API}/{task}")
if state["status"] not in ("queued", "processing"):
break
else:
raise TimeoutError(f"{task} is still {state['status']}: poll it again later, do not resubmit")
if state["status"] != "succeeded":
raise RuntimeError(state.get("error") or state["status"])
asset_url = state["assets"][0]["url"] # signed link: short-lived, so download now
req = urllib.request.Request(asset_url, headers={"User-Agent": "omniakey-example/1"})
with urllib.request.urlopen(req, timeout=300) as resp, open(out_path, "wb") as f:
f.write(resp.read())
return task
def text_to_video(prompt, out_path, duration=5, resolution="720P", ratio="16:9"):
body = {
"model": MODEL,
"type": "video",
"operation": "text_to_video",
"input": {"prompt": prompt},
"parameters": {"duration": duration, "resolution": resolution, "ratio": ratio},
}
return run_task(body, out_path)
def image_to_video(prompt, image_path, out_path, duration=5, resolution="720P", audio=False):
with open(image_path, "rb") as f:
raw = f.read()
if len(raw) > 700_000: # base64 adds a third, and the whole body must stay under 1 MiB
raise ValueError("first frame too large: save it as a JPEG about 1024 px wide")
frame = "data:image/jpeg;base64," + base64.b64encode(raw).decode()
body = {
"model": MODEL,
"type": "video",
"operation": "image_to_video",
"input": {"prompt": prompt, "media": [{"type": "first_frame", "url": frame}]},
"parameters": {"duration": duration, "resolution": resolution, "ratio": "adaptive",
"generate_audio": audio},
}
return run_task(body, out_path)
if __name__ == "__main__":
print("done", text_to_video(
"Close-up of a tall glass on a wooden bar counter. Sparkling water is poured over ice; bubbles "
"rise and the ice cubes clink and shift. Warm evening light from the left. The camera slowly "
"pushes in. Sound of pouring, fizzing and clinking ice. No people, no text.",
"sparkling-glass.mp4",
))
print("done", image_to_video(
"The cat slowly wakes, stretches its front paws and yawns, then looks toward the window. "
"Raindrops keep running down the glass. The camera stays still.",
"cat.jpg",
"cat-wakes.mp4",
))
Six points de ce fichier comptent avant de changer quoi que ce soit.
- Chaque requête de création porte un
Idempotency-Keyaléatoire ; rejouer cette clé avec le même corps renvoie la tâche d'origine en HTTP 200 et ne facture jamais deux fois (vue d'ensemble de l'API média, vérifiée le 30 octobre 2026). - La boucle attend 5 secondes entre deux interrogations et s'arrête après 180 essais, soit 15 minutes.
- Un timeout signifie que la tâche rend encore. Interrogez le même identifiant de tâche plus tard et ne renvoyez jamais la tâche, sinon vous payez un second clip.
assets[0].urlest un lien signé valable environ une heure : le script télécharge donc dès que la tâche réussit (vue d'ensemble de l'API média, vérifiée le 30 octobre 2026).progress.percentpeut rester à 0 pendant que la tâche tourne, la boucle suit donc uniquementstatus(documentation de l'API vidéo, vérifiée le 30 octobre 2026).- La fonction image refuse un fichier de plus de 700 000 octets, parce que le base64 ajoute un tiers et que le corps doit rester sous 1 MiB.
La forme de la requête correspond à Kling 3.0 sur la même API : changer de modèle change l'identifiant et les paramètres, pas le code autour.
Comment envoyer une première image pour l'image vers vidéo ?
Placez l'image dans input.media[] avec "type": "first_frame", en ligne sous forme d'URI data:image/jpeg;base64,..., comme dans notre clip du chat.
input.media[] accepte une URL HTTPS publique ou une URI de données en ligne, et le corps entier est plafonné à 1 MiB (documentation de l'API vidéo, vérifiée le 30 octobre 2026). Le test interne d'OmniaKey a vu un lien HTTPS ordinaire pour la première image rejeté avec provider_submit_rejected, c'est pourquoi l'exemple envoie une URI de données (documentation de l'API vidéo, vérifiée le 30 octobre 2026).
Le base64 ajoute un tiers : partez d'un JPEG d'environ 1024 pixels de large. Notre première image faisait 134 356 octets, un PNG de 4 Mo serait refusé.
Laissez parameters.ratio sur adaptive ici : la valeur suit la forme de l'image envoyée, et c'est ainsi qu'une image fixe de 1024×571 est devenue un clip de 1280×720. Pour reference_to_video, le même tableau prend "type": "reference_image" (documentation de l'API vidéo, vérifiée le 30 octobre 2026).
Deux clips que nous avons produits
Les deux tâches sont parties le 30 octobre 2026 avec le fichier ci-dessus, inchangé. La première est du texte vers vidéo, tâche task_uF2QUtbeAAUW11lXEaLxNw1ZnBUoqvNk, créée à 01:39:43 UTC et réussie à 01:42:22 UTC. Le prompt demandait le bruit du service, l'audio est donc resté activé.
Close-up of a tall glass on a wooden bar counter. Sparkling water is poured over ice; bubbles rise and the ice cubes clink and shift. Warm evening light from the left. The camera slowly pushes in. Sound of pouring, fizzing and clinking ice. No people, no text.

Les images montrent un verre avec des glaçons sur un comptoir en bois, des bouteilles et des lumières chaudes floues derrière. Le verre grossit de la première à la dernière image, le travelling avant demandé dans le prompt, et finit plein avec des bulles près du fond.
La seconde est de l'image vers vidéo, tâche task_u85W0jn1sQLkrszJlxqXF1hxJYhsndxK, créée à 01:42:33 UTC et réussie à 01:44:52 UTC. La première image est une photo d'un chat roux endormi sur une pile de vieux livres près d'une fenêtre sous la pluie (1024×571 pixels), envoyée en URI de données avec "type": "first_frame".
The cat slowly wakes, stretches its front paws and yawns, then looks toward the window. Raindrops keep running down the glass. The camera stays still.

Le chat lève la tête, ouvre les yeux, étire ses deux pattes avant au-delà du bord des livres, bâille largement et tourne la tête vers la fenêtre, dans l'ordre donné par le prompt. La pluie continue de couler sur la vitre et le cadrage reste fixe, comme demandé.

Ces deux exécutions couvrent le texte vers vidéo et une première image en 720P sur 5 secondes. Nous n'avons pas testé le 1080P, Fast, Mini, 2.5, reference_to_video, un lien HTTPS pour la première image, ni d'autres durées.
Ce que les fichiers contiennent
Les deux téléchargements sont des MP4 H.264 en 1280×720 à 24 fps : 121 images, 5.04 secondes.
| Clip | Verre | Chat |
|---|---|---|
| Opération | texte vers vidéo | image vers vidéo |
| Durée jusqu'à la fin | 159 s | 139 s |
| Taille du fichier | 2 070 248 octets | 1 352 027 octets |
| Vidéo | 1280×720, 24 fps, 121 images | 1280×720, 24 fps, 121 images |
| Audio | piste AAC | aucune |
La piste du clip du verre contient le service, le pétillement et les glaçons qui tintent, sans voix ni musique. Le clip du chat n'a aucune piste, parce que la requête envoyait generate_audio: false.
Les deux enregistrements de tâche indiquaient usage.completion_tokens: 108900, soit 121 × 1280 × 720 ÷ 1024, la formule de tokens que BytePlus utilise pour estimer la facturation vidéo (page tarifs de BytePlus, vérifiée le 30 octobre 2026).
La documentation d'OmniaKey annonce qu'un clip de 6 secondes en 720p se termine généralement en une minute environ (documentation de l'API vidéo, vérifiée le 30 octobre 2026). Les nôtres ont pris 159 et 139 secondes, et trois clips de 5 secondes en 720p de notre comparatif du 26 octobre ont pris 144.8, 319.0 et 184.7 secondes. Prévoyez 2 à 5 minutes et interrogez la tâche au lieu de garder une requête ouverte.
Quelles erreurs et quelles limites allez-vous rencontrer ?
Vérifiez d'abord trois réglages : l'identifiant de modèle, une durée de 4 à 15 et l'audio, que le filtre du fournisseur peut refuser.
| Statut / Code | Ce qu'il faut changer |
|---|---|
400 invalid_request | corps ou input.prompt |
400 model_price_error | durée de 4–15 s |
403 model_not_allowed | accès du modèle pour la clé |
409 idempotency_key_reused | une nouvelle clé par corps |
503 no_available_channel | identifiant complet, opération seule |
| tâche en échec, erreur du fournisseur | lire error, puis réessayer |
Ces codes viennent de la vue d'ensemble de l'API média et de la documentation de l'API vidéo (vérifiées le 30 octobre 2026). Une tâche qui finit en failed rembourse sa facturation d'avance : un rendu refusé ne coûte que du temps.
Attention au réglage audio. Seedance rend une piste par défaut, et en la laissant active le fournisseur a refusé une requête de 4 secondes en 480P avec OutputAudioSensitiveContentDetected.PolicyViolation ; envoyez parameters.generate_audio: false sauf si la scène a besoin de son (documentation de l'API vidéo, vérifiée le 30 octobre 2026).
BytePlus indique que la série 2.0 n'accepte pas d'images ou de vidéos de référence contenant de vrais visages humains (page Seedance 2.0 de BytePlus, vérifiée le 30 octobre 2026). Seedance 2.0 n'a pas non plus de seed ni de camera_fixed, alors que ce sont deux champs de l'API de création de tâche du fournisseur (API de création de tâche de BytePlus, vérifiée le 30 octobre 2026).
Quinze secondes sont le plafond de cette famille, et duration: -1 n'achète rien de plus ; une prise de 20 ou 30 secondes relève de Seedance 2.5 (page du modèle Seedance 2.0, vérifiée le 30 octobre 2026).
OmniaKey ne publie pas de limites de débit fixes ; traitez un HTTP 429 comme réessayable avec un backoff exponentiel (page des erreurs d'API d'OmniaKey, vérifiée le 30 octobre 2026).
Seedance 2.0, Fast, Mini ou 2.5 ?
Quatre niveaux prennent le même corps de requête : changer coûte un identifiant de modèle et, sur Fast et Mini, un plafond de résolution plus bas.
- Seedance 2.0,
dreamina-seedance-2-0-260128: 480P, 720P et 1080P, 4 à 15 secondes. Le tarif catalogue de BytePlus pour un clip de 5 secondes est de $0.76 en 720p et de $0.35 en 480p (page tarifs de BytePlus, vérifiée le 30 octobre 2026). - Seedance 2.0 Fast,
dreamina-seedance-2-0-fast-260128: 480P et 720P, 4 à 15 secondes. Le tarif catalogue de BytePlus pour un clip de 5 secondes est de $0.60 en 720p et de $0.28 en 480p. - Seedance 2.0 Mini,
dreamina-seedance-2-0-mini-260615: 480P et 720P, 4 à 15 secondes. Le tarif catalogue de BytePlus pour un clip de 5 secondes est de $0.38 en 720p et de $0.18 en 480p. - Seedance 2.5,
dreamina-seedance-2-5-260628: le seul identifiant de la famille qui accepte une prise de 20 ou 30 secondes, et le plus lent, environ quatre minutes pour un clip de 4 secondes en 480P (documentation de l'API vidéo, vérifiée le 30 octobre 2026). Notre test de Seedance 2.5 couvre le rendu image.
Les pages de modèles d'OmniaKey annoncent un clip de 4 secondes en 480P en une minute environ sur 2.0, deux minutes sur Fast et 100 secondes sur Mini (vérifiées le 30 octobre 2026).
Prenez l'identifiant complet 2.0 quand il vous faut un master 1080P, car Fast et Mini s'arrêtent à 720P (documentation de l'API vidéo, vérifiée le 30 octobre 2026). OmniaKey fixe ses propres tarifs pour ces identifiants : les tarifs en cours sont sur la page du modèle Seedance 2.0.
FAQ
Existe-t-il une API Seedance 2.0 officielle ?
Oui. BytePlus ModelArk la vend, et l'activer là-bas demande un solde de compte supérieur à USD 30, un Savings Plan ou un pack de ressources Seedance (page Seedance 2.0 de BytePlus, vérifiée le 30 octobre 2026). Le script ci-dessus appelle le même identifiant de modèle via l'API média d'OmniaKey.
Puis-je envoyer une URL d'image au lieu du base64 ?
La documentation d'OmniaKey liste une URL HTTPS publique à côté de l'URI de données en ligne (documentation de l'API vidéo, vérifiée le 30 octobre 2026). Nos exécutions sont passées en ligne parce qu'un lien HTTPS pour la première image est revenu en provider_submit_rejected dans le test interne d'OmniaKey ; essayez une URL sur un clip de test d'abord.
Comment couper le son ?
Envoyez parameters.generate_audio: false : le MP4 arrive sans aucune piste audio, comme le clip du chat. L'audio est actif par défaut sur ce modèle.
Pourquoi ma requête a-t-elle expiré ?
Le clip rend généralement encore, puisque des tâches de 5 secondes en 720p ont pris de 139 à 319 secondes dans nos exécutions. Interrogez le même identifiant de tâche, ne renvoyez jamais la tâche, et augmentez la limite de 15 minutes de la boucle pour des clips de 15 secondes.
Combien de temps les liens vidéo restent-ils valides ?
Le lien signé dans assets[0].url reste valable environ une heure, et l'enregistrement de la tâche est conservé 24 heures après sa création (vue d'ensemble de l'API média, vérifiée le 30 octobre 2026). Téléchargez à la première réussite, ou interrogez la tâche à nouveau pour obtenir un lien frais.
Sources vérifiées
- BytePlus ModelArk : guide Seedance 2.0, vérifié le 30 octobre 2026
- BytePlus ModelArk : API de création de tâche de génération vidéo, vérifié le 30 octobre 2026
- BytePlus ModelArk : tarifs des modèles et formule de tokens, vérifié le 30 octobre 2026
La documentation d'OmniaKey, vérifiée le 30 octobre 2026 : API vidéo, vue d'ensemble de l'API média et erreurs d'API.
Modèles cités dans cet article
Articles similaires
Avis Seedance 2.5
La mise à niveau significative réside dans la narration et le contrôle de la production en une seconde 30, et non dans les gros titres non vérifiés de 4K qui circulent autour de lui.
HappyHorse 1.1 vs Seedance 2.0 : test avec le même prompt et prix
Trois prompts identiques, le même jour : Seedance 2.0 a fait les meilleurs clips, HappyHorse 1.1 les a faits deux fois plus vite.
API Kling 3.0 : code de requête texte-vidéo et clips réels
Une tâche texte-vidéo tient en un seul POST avec le modèle kling-3.0. Voici le code de la requête, les champs attendus et deux clips de 5 secondes que nous avons créés et mesurés le 29 octobre 2026.
Articles récents
- Codex : générer des images avec imagegen et un relais
- Modèles personnalisés Factory Droid : utiliser Claude et GPT avec votre clé API
- Gemini 4 Carbon : date de sortie, prix et accès à l'API
- API GPT Image 2.5 : générer et modifier des images en Python
- Test de MiniMax M3.1 Flash : benchmarks, vitesse et comparaison avec M3
