GPT-6 Sol et Claude Opus 5.5 disponiblesGPT-6 Sol à moitié prix par rapport à 5.6 Sol

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.

Kiki, OmniaKey COO11 minutes de lecture
Sur cette page

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_video et reference_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 soit succeeded (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, ou reference_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 (adaptive suit l'image)
  • generate_audio : true par défaut, ou false (false donne 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.

python
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-Key alé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].url est 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.percent peut rester à 0 pendant que la tâche tourne, la boucle suit donc uniquement status (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é.

prompt
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.
Huit images d'un grand verre d'eau pétillante sur un comptoir en bois, du service à vide jusqu'au verre plein avec des bulles près du fond.
Huit images du clip du verre dans l'ordre chronologique, de 0.0 à 5.0 secondes. Seedance 2.0 via l'API OmniaKey, texte vers vidéo, 5 secondes, 720P, produit le 30 octobre 2026.

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

prompt
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.
Huit images d'un chat roux endormi sur une pile de livres près d'une fenêtre sous la pluie, qui se réveille, étire ses pattes et bâille.
Huit images du clip du chat dans l'ordre chronologique, de 0.0 à 5.0 secondes. Seedance 2.0 via l'API OmniaKey, image vers vidéo, 5 secondes, 720P, produit le 30 octobre 2026.

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

À gauche l'image fixe du chat roux envoyée comme première image, à droite la dernière image du clip, pattes étirées au-dessus des livres et tête tournée vers la fenêtre.
À gauche : l'image fixe envoyée comme première image. À droite : la dernière image du clip du chat. Seedance 2.0 via l'API OmniaKey, image vers vidéo, 5 secondes, 720P, produit le 30 octobre 2026.

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.

ClipVerreChat
Opérationtexte vers vidéoimage vers vidéo
Durée jusqu'à la fin159 s139 s
Taille du fichier2 070 248 octets1 352 027 octets
Vidéo1280×720, 24 fps, 121 images1280×720, 24 fps, 121 images
Audiopiste AACaucune

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 / CodeCe qu'il faut changer
400 invalid_requestcorps ou input.prompt
400 model_price_errordurée de 4–15 s
403 model_not_allowedaccès du modèle pour la clé
409 idempotency_key_reusedune nouvelle clé par corps
503 no_available_channelidentifiant complet, opération seule
tâche en échec, erreur du fournisseurlire 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

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

Seedance 2.0vidéo IAAPI vidéoimage-vidéoPython

Articles similaires

Articles récents