spicyapiDocumentation
Guides
Contenu principal

Tutoriel : transformer une image en vidéo

Partez d’une image enregistrée sur votre ordinateur et repartez avec un fichier vidéo téléchargé. Chaque étape montre la CLI, le SDK TypeScript et le HTTP simple.

Ce tutoriel part d’une image de votre ordinateur et la transforme en un court clip vidéo que vous téléchargez et conservez. Il suit tout le parcours, dans l’ordre : choisir un modèle, téléverser l’image, vérifier le prix, lancer la génération, l’attendre, télécharger le résultat et réagir si quelque chose se passe mal. Vous n’avez pas à reconstituer le tout à partir des pages de référence.

Chaque étape montre trois façons de faire la même chose. Choisissez-en une et gardez-la jusqu’au bout :

MéthodeChoisissez-la siIl vous faut
CLIVous voulez taper des commandes sans écrire la moindre ligne de codeNode.js 22.13 ou plus récent
SDK TypeScriptVous construisez un programme Node.js et voulez voir les appels qu’il effectueNode.js 22.13 ou plus récent
HTTP (curl)Vous voulez voir l’API brute, par exemple pour utiliser plus tard un autre langage de programmationUn terminal bash avec curl et jq (macOS, Linux, ou WSL sous Windows)

Vous préférez tout simplement demander à un assistant IA de s’en charger ? Voir Passer plutôt par un assistant IA.

Ce que vous allez obtenir

  • Le résultat : un court fichier vidéo, généralement au format MP4, qui part de votre image et s’anime comme le décrit votre phrase.
  • Votre temps : comptez une vingtaine de minutes la première fois, surtout de la lecture. La génération elle-même prend en général quelques minutes ; certains modèles et réglages demandent plus longtemps.
  • Où tout se passe : sur SpicyAPI. Votre ordinateur se contente d’envoyer l’image et les instructions, puis de télécharger le fichier terminé.

Ce que cela coûte, et comment le savoir avant de payer

Les prix sont en dollars américains. Ils dépendent du modèle que vous choisissez et de vos réglages, comme la durée et la résolution de la vidéo : cette page n’avance donc aucun chiffre. Vous pouvez voir le prix à trois endroits, et aucun d’eux ne coûte quoi que ce soit :

  1. Le catalogue en direct (étape 1) liste chaque modèle que votre compte peut utiliser, aux prix de votre compte. Les vidéos sont généralement facturées per_second, c’est-à-dire par seconde de vidéo produite. Quand un modèle affiche plusieurs prix, chacun correspond à un réglage, par exemple une résolution.
  2. Un devis (étape 3) donne le prix exact de votre requête exacte. Il ne lance rien et ne met aucun argent de côté.
  3. La confirmation : la CLI affiche de nouveau le prix et attend votre y avant de lancer quoi que ce soit.

Ce qu’il advient de votre argent :

  • Seule l’étape 4 coûte de l’argent, tout comme la relance d’une tâche échouée. Lister les modèles, téléverser, demander un devis, attendre et télécharger sont gratuits.
  • Quand une génération démarre, le montant du devis est mis de côté sur votre solde (une réservation). Ce montant est aussi le maximum que la vidéo peut coûter.
  • Si la vidéo réussit, vous êtes facturé pour ce qui a été produit, jamais plus que la réservation, et le reliquat revient sur votre solde.
  • Les tâches échouées ou expirées libèrent normalement toute la réservation. Certains refus de contenu sont facturés au devis accepté, uniquement si la page du modèle indique explicitement cette exception. Consultez settled et cost pour connaître le montant final.
  • Les nouveaux comptes démarrent sans aucune somme offerte : il vous faut donc d’abord un solde. Voir Facturation.

Comment ça marche

votre image ──téléversement──▶ adresse spicy:// (utilisable pendant un jour)
                                         │
votre phrase + réglages ─────────────────┴──▶ devis (gratuit) ──▶ lancer la tâche (argent mis de côté)
                                                                              │
                                                     queued ──▶ running ──▶ succeeded / failed / expired
                                                                              │
                                                 lien de téléchargement (environ 20 minutes) ──▶ votre fichier

Une tâche est un travail de génération. SpicyAPI s’en occupe en arrière-plan : la lancer et récupérer le résultat sont donc deux actions distinctes. Chaque tâche a un identifiant qui commence par job_ ; gardez-le, car c’est lui qui permet de retrouver la tâche. Les autres termes employés sur cette page sont expliqués dans le Glossaire.

Avant de commencer

Avoir un compte, un solde et une clé API

Suivez d’abord Préparer votre compte. À la fin, vous devez avoir :

  • un compte SpicyAPI dont le solde est approvisionné ;
  • une clé API, qui commence par sk-spicy- ;
  • cette clé enregistrée dans une variable d’environnement nommée SPICY_API_KEY. Une variable d’environnement est une valeur nommée que votre terminal transmet aux programmes qu’il lance : la clé n’a ainsi jamais besoin d’apparaître dans une commande ni dans votre code.

Vérifiez que la clé est bien définie dans la fenêtre de terminal que vous utilisez, sans afficher la clé entière :

echo "${SPICY_API_KEY:0:9}"

Ce que vous devez voir : sk-spicy-. Si rien ne s’affiche ou si une erreur apparaît, la clé n’est pas définie dans cette fenêtre ; revenez à Préparer votre compte.

Placer votre image dans un dossier de travail

Créez un dossier pour ce tutoriel et ouvrez votre terminal dedans. Toutes les commandes de cette page s’exécutent depuis ce dossier, et tous les fichiers qu’elles créent y atterrissent.

mkdir -p ~/spicy-video
cd ~/spicy-video

Copiez votre image dans ce dossier et nommez-la start-frame.jpg (ou start-frame.png s’il s’agit d’un PNG ; utilisez alors ce nom partout où cette page écrit start-frame.jpg).

Ce qui fait une bonne image de départ :

  • Format et taille : JPEG, PNG, WebP ou GIF, jusqu’à 10 MiB (environ 10 mégaoctets). Un modèle peut fixer ses propres limites, plus strictes ; vous les verrez à l’étape 1.
  • Le fichier doit vraiment être dans ce format. SpicyAPI examine le contenu du fichier, pas seulement son nom. Les photos prises au téléphone sont souvent en HEIC ; renommer l’une d’elles en .jpg ne la convertit pas. Ouvrez-la d’abord et exportez-la ou enregistrez-la en JPEG.
  • Cadrage : l’image devient la première image de la vidéo. Prenez une image large pour une vidéo large et une image en hauteur pour une vidéo verticale ; certains modèles proposent aussi un réglage aspect_ratio.
  • Droits : utilisez une image que vous avez le droit d’utiliser.

Installer l’outil choisi

La CLI est un programme appelé spicyapi que vous lancez dans le terminal. Installez-la une fois pour toutes (instructions complètes, Node.js compris : CLI : avant de commencer) :

npm install -g @spicyapi/cli
spicyapi --version

Si l’installation échoue avec EACCES, passez-vous-en et tapez npx @spicyapi/cli partout où cette page tape spicyapi.

Vérifiez ensuite que votre clé fonctionne et que vous avez un solde :

spicyapi balance

Ce que vous devez voir : available, held et total en dollars américains. available doit être supérieur à zéro.

Les sept étapes

Remplacez MODEL_ID_FROM_CATALOG par un vrai identifiant de modèle

MODEL_ID_FROM_CATALOG est un espace réservé, pas un modèle. À l’étape 1, vous choisissez un vrai identifiant de modèle dans le catalogue en direct (spicyapi models list, listModels() dans le SDK, ou GET /api/v1/models). Collez-le partout où cette page affiche l’espace réservé. Envoyer l’espace réservé tel quel ne renvoie qu’une erreur « introuvable ».

Sous Windows ? Choisissez l’onglet CLI ou SDK

L’onglet HTTP est écrit pour bash. Windows PowerShell traite différemment les guillemets, les retours à la ligne (\) et $(...) : ces commandes n’y fonctionneront donc pas telles quelles. Sous Windows, utilisez l’onglet CLI ou SDK, ou lancez les commandes HTTP dans WSL (Sous-système Windows pour Linux, Windows Subsystem for Linux en anglais).

1. Choisir un modèle et lire ses réglages

À faire : listez les modèles image vers vidéo que votre compte peut utiliser, choisissez-en un, puis lisez les réglages qu’il accepte.

Listez les modèles :

spicyapi models list --modality video --task image-to-video --json

Ce que vous devez voir : une liste JSON. Celle-ci est abrégée, et les montants sont remplacés par … :

{
  "total": 1,
  "items": [
    {
      "model": "MODEL_ID_FROM_CATALOG",
      "displayName": "Example video model",
      "modality": "video",
      "tasks": ["image-to-video"],
      "enabled": true,
      "available": true,
      "quantityField": "duration_seconds",
      "maxOutputDurationSeconds": 10,
      "taskTimeoutSeconds": 1800,
      "pricing": [
        { "variant": "720p", "unit": "per_second", "price": "…", "currency": "USD" },
        { "variant": "1080p", "unit": "per_second", "price": "…", "currency": "USD" }
      ]
    }
  ]
}

Choisissez un modèle dont enabled et available valent tous deux true, et copiez sa valeur model. Lisez ensuite ses réglages :

spicyapi models get MODEL_ID_FROM_CATALOG --json

La réponse contient les mêmes champs, plus inputSchema (les réglages) et examples (des entrées déjà validées par le serveur).

Ce qu’il faut regarder dans la liste :

ChampCe qu’il vous apprend
modelL’identifiant de modèle que vous utiliserez à chaque étape suivante
enabled, availableN’utilisez un modèle que si les deux valent true
pricingUne entrée par niveau de prix : variant (le réglage concerné, souvent une résolution), unit (en général per_second pour la vidéo) et price en dollars américains. regularPrice et offerLabel apparaissent quand une remise s’applique
quantityFieldLe réglage qui détermine le nombre d’unités payées, en général duration_seconds. Vide, il signifie une unité par vidéo
maxOutputDurationSecondsLa durée de vidéo la plus longue que le modèle autorise
taskTimeoutSecondsCombien de temps une génération peut tourner avant de s’arrêter en expired (sans être facturée)

Comment lire les réglages. inputSchema est la liste des réglages du modèle, écrite en JSON Schema :

  • required liste les réglages que vous devez obligatoirement envoyer. Pour ce type de modèle, image_url en fait toujours partie, et la plupart exigent aussi prompt.
  • properties liste tous les réglages que le modèle accepte, chacun avec un type, une description en anglais courant et, souvent, enum (les seules valeurs autorisées), minimum et maximum, et default (la valeur utilisée si vous omettez le réglage).
  • Dans chaque réglage, x-ui contient des indications d’affichage. x-ui.affects_price: true signifie que modifier ce réglage modifie le prix.
  • Quelques modèles ajoutent des conditions au niveau supérieur, comme « si vous envoyez A, vous devez aussi envoyer B ». Spicy Schema explique comment les lire.
  • examples contient des entrées complètes déjà validées par le serveur : un point de départ sûr.

Les réglages que vous croiserez le plus souvent. Les noms sont les mêmes pour tous les modèles, mais chaque modèle n’en accepte qu’une partie, avec ses propres valeurs autorisées :

RéglageCe qu’il faitModifie le prix ?
image_urlL’image de départ, utilisée comme première image de la vidéo. Accepte l’adresse spicy:// de l’étape 2 ou un lien https:// publicNon
promptCe qui doit se passer : le mouvement, la caméra, l’ambiance. Décrivez le mouvement plutôt que de répéter ce que l’image montre déjàEn général, non
duration_secondsLa durée de la vidéo en secondes. Les valeurs autorisées figurent dans enum ou entre minimum et maximum ; certains modèles acceptent une valeur spéciale, expliquée dans la description du réglageOui pour la plupart des modèles : la vidéo est généralement facturée à la seconde, un clip plus long coûte donc plus cher
resolutionLa taille de sortie, comme 720p ou 1080pEn général : les résolutions plus élevées ont souvent leur propre prix, plus élevé
aspect_ratioLa forme de la vidéo, comme 16:9, 9:16 ou 1:1. Certains modèles proposent adaptive, qui suit la forme de l’imageVoir x-ui.affects_price
generate_audioGénère aussi une bande sonore assortie à l’imageSur certains modèles
last_image_urlUne image pour la dernière image de la vidéo ; voir Première et dernière imageDemandez un devis pour le savoir
negative_promptCe que la vidéo doit éviterEn général, non
seedUn nombre qui rend les résultats plus faciles à comparer d’une exécution à l’autre ; il ne garantit pas des vidéos identiquesNon

N’envoyez que les réglages listés par ce modèle

Chaque modèle a sa propre liste. Un réglage absent des properties de ce modèle, un nom mal orthographié ou une valeur hors de enum fait refuser toute la requête avec 400. Rien n’est facturé, mais ne recopiez pas l’entrée d’un autre modèle sans vérifier.

Ce qui s’est passé : vous avez lu le catalogue en direct de votre compte, avec vos prix. Rien n’a été facturé. La lecture du catalogue compte dans la limite de débit de votre compte : inutile donc de la refaire avant chaque vidéo ; recommencez quand vous changez de modèle ou recevez un 400.

2. Téléverser votre image

À faire : téléversez start-frame.jpg et copiez l’adresse spicy:// que vous recevez en retour. Le téléversement est gratuit.

spicyapi files upload start-frame.jpg

Ce que vous devez voir :

fileId: fil_01k3m8x9q2z4v7n5p6r8s0t1w3
status: ready
bytes: 402118
contentType: image/jpeg
sha256: a91f4c2e5b7d16809e3f2a4c8d0b61e7c4a890e5d2f71b3c609ae8427d15f0c6
uri: spicy://f/fil_01k3m8x9q2z4v7n5p6r8s0t1w3
expiresAt: 2026-09-18T09:12:11Z

Copiez la valeur uri exactement telle qu’elle s’affiche.

Ce qui s’est passé : votre image a été stockée de façon privée pour votre compte, vérifiée (son format réel doit correspondre au type déclaré) et dotée d’une adresse spicy://. Cette adresse n’est pas un lien web : seul votre compte peut l’utiliser, et uniquement dans l’entrée d’une tâche. Elle est utilisable pendant un jour (voir expiresAt) ; passé ce délai, téléversez l’image de nouveau.

L’image est déjà en ligne ?

Si l’image se trouve déjà à une adresse https:// publique qui s’ouvre sans connexion, vous pouvez sauter cette étape et mettre cette adresse dans image_url. Elle doit rester accessible pendant toute la génération de la vidéo.

Si le téléversement échoue :

Ce que vous voyezCe que cela signifieQue faire
Unsupported file type, ou la CLI ou le SDK indique ne pas pouvoir déterminer le typeLe fichier n’est ni un JPEG, ni un PNG, ni un WebP, ni un GIFConvertissez l’image, ou donnez-lui la bonne extension
File exceeds the 10 MB limitL’image dépasse 10 MiBExportez une version plus légère
The uploaded file does not match the upload ticketLe contenu du fichier ne correspond pas au type qu’indiquent son nom ou sa déclaration, par exemple une photo HEIC renommée en .jpgExportez-la en vrai JPEG ou PNG et téléversez-la de nouveau
The upload ticket has expiredPlus d’une vingtaine de minutes se sont écoulées entre le ticket et la validationRecommencez le téléversement

3. Décrire la vidéo et vérifier le prix

À faire : écrivez vos réglages dans un fichier nommé input.json, puis demandez un devis.

Écrire input.json. Commencez par les deux réglages que tout modèle image vers vidéo accepte. Mettez votre propre phrase dans prompt, et remplacez la valeur de image_url par l’uri copiée à l’étape 2 :

input.json
{
  "prompt": "The camera slowly pushes in while rain runs down the window and neon light flickers",
  "image_url": "spicy://f/fil_01k3m8x9q2z4v7n5p6r8s0t1w3"
}

Les réglages que vous omettez prennent la valeur default du modèle. Pour les choisir vous-même, ajoutez uniquement des réglages listés dans les properties de votre modèle, avec des valeurs qu’il autorise. Par exemple, si votre modèle liste duration_seconds et resolution et autorise ces valeurs :

{
  "prompt": "The camera slowly pushes in while rain runs down the window and neon light flickers",
  "image_url": "spicy://f/fil_01k3m8x9q2z4v7n5p6r8s0t1w3",
  "duration_seconds": 5,
  "resolution": "720p"
}

Enregistrez le fichier dans votre dossier de travail :

Collez toutes les lignes d’un coup, après y avoir mis votre propre texte et votre uri :

cat > input.json <<'EOF'
{
  "prompt": "The camera slowly pushes in while rain runs down the window and neon light flickers",
  "image_url": "spicy://f/fil_01k3m8x9q2z4v7n5p6r8s0t1w3"
}
EOF

Utilisez des guillemets droits ordinaires ("), pas des guillemets courbes, et ne mettez pas de virgule après le dernier réglage.

Obtenir le devis :

spicyapi tasks quote --model MODEL_ID_FROM_CATALOG --input-file input.json

Ce que vous devez voir (montants remplacés par …) :

quoteId: eyJ2IjoxLCJtIjoi…
model: MODEL_ID_FROM_CATALOG
estimatedCost: …
maxCharge: …
currency: USD
quantity: 5
unit: per_second
expiresAt: 2026-09-17T08:05:00Z

Ce qui s’est passé : SpicyAPI a contrôlé votre entrée par rapport aux réglages du modèle et calculé le prix de cette requête précise. Rien n’a été lancé et rien n’a été facturé. estimatedCost est le montant qui sera mis de côté si vous lancez la génération maintenant, et maxCharge le maximum qu’elle peut coûter. quantity et unit indiquent ce que vous payez, par exemple 5 secondes.

Un devis est valable cinq minutes, et uniquement pour cette entrée exacte. Changez la durée ou la résolution et redemandez un devis pour comparer les prix. Le devis effectue les mêmes contrôles que le lancement de la tâche : les problèmes apparaissent donc ici, gratuitement. Un 400 signifie que l’entrée ne correspond pas aux réglages du modèle (corrigez input.json à l’aide de l’étape 1), et un 40201 que votre solde ne suffirait pas. L’étape 7 liste les autres codes.

Un essai sans votre propre image ?

Les examples du modèle, vus à l’étape 1, sont des entrées complètes déjà validées par le serveur. Vous pouvez en placer une telle quelle dans input.json, demander son devis et la générer pour voir tout le parcours fonctionner avant d’utiliser votre propre image.

4. Lancer la génération

Cette étape coûte de l’argent

Lancer la génération met de côté le montant du devis sur votre solde. Une fois que SpicyAPI l’a acceptée, la tâche ne peut pas être annulée : elle va jusqu’au bout et elle est facturée si elle réussit. Les tâches échouées ou expirées libèrent normalement toute la réservation. Certains refus de contenu sont facturés au devis accepté, uniquement si la page du modèle indique explicitement cette exception. Consultez settled et cost pour connaître le montant final.

La clé d’idempotence, en termes simples. C’est une étiquette pour une vidéo, comme un numéro de commande. Si votre connexion coupe et que vous ne savez pas si la vidéo a démarré, renvoyez la même requête avec la même étiquette : SpicyAPI vous rend la tâche déjà lancée au lieu d’en lancer, et d’en facturer, une seconde. Une étiquette reste valable 24 heures avec la même clé API. Prenez une nouvelle étiquette pour une autre vidéo : la même étiquette avec une entrée différente est refusée avec 409. Pour en savoir plus : Idempotence.

À faire :

spicyapi tasks create --model MODEL_ID_FROM_CATALOG --input-file input.json

La CLI redemande un devis, affiche le prix et attend votre réponse :

Estimated charge: USD …; maximum charge: USD …. Quote expires: 2026-09-17T08:05:00Z.
Idempotency-Key: 4f6755a5-0d72-4420-9f6b-9faf0e2b0241
Create a billable task with model MODEL_ID_FROM_CATALOG? … Continue? [y/N]

Tapez y et appuyez sur Entrée. Toute autre réponse annule, et rien n’est facturé. Copiez la valeur Idempotency-Key quelque part avant de répondre : la CLI crée une nouvelle étiquette à chaque exécution, et c’est de celle-ci que vous aurez besoin si la connexion coupe.

Ce que vous devez voir :

idempotencyKey: 4f6755a5-0d72-4420-9f6b-9faf0e2b0241
taskId: job_01k3m8x9q2z4v7n5p6r8s0t1w3
state: queued
estimatedCost: …
deadlineAt: 2026-09-17T08:35:00Z

Copiez le taskId.

Ce qui s’est passé : SpicyAPI a accepté la génération, qui est désormais une tâche, et a mis estimatedCost de côté sur votre solde. C’est aussi le maximum que cette vidéo peut coûter. state: queued signifie qu’elle attend son tour. deadlineAt est l’heure limite à laquelle elle peut se terminer ; si elle n’est pas finie à ce moment-là, elle se termine en expired et rien n’est facturé. deadlineAt n’est pas la date d’expiration de vos fichiers.

Transmettre le devis revient à dire « n’accepte cette tâche qu’au prix qu’on m’a montré ». Si le prix ou l’entrée a changé entre-temps, la requête est refusée avec 40901 au lieu de mettre de côté un autre montant. La CLI s’en charge pour vous.

Si la connexion a coupé et que vous n’avez jamais vu d’identifiant de tâche, ne relancez pas simplement avec une nouvelle étiquette : cela créerait, et facturerait, une seconde vidéo. Renvoyez la requête avec la même étiquette :

  • CLI : spicyapi tasks create --model MODEL_ID_FROM_CATALOG --input-file input.json --idempotency-key <the value you copied>, en remplaçant <the value you copied> par la valeur Idempotency-Key que vous avez copiée. Voir Reprendre une tâche après une attente interrompue.
  • SDK : relancez node generate.mjs --yes ; il réutilise idempotency-key.txt.
  • HTTP : relancez le bloc « Lancer la vidéo » ; il réutilise idempotency-key.txt.

Si l’étape 4 a été refusée, rien n’a été créé et rien n’a été facturé ; la raison et la solution se trouvent à l’étape 7.

5. Attendre la vidéo

À faire : consultez la tâche jusqu’à ce qu’elle soit terminée. Une vidéo prend généralement quelques minutes.

spicyapi tasks wait job_01k3m8x9q2z4v7n5p6r8s0t1w3 --wait-timeout-ms 1800000 --json

Utilisez votre propre identifiant de tâche. --wait-timeout-ms 1800000 attend jusqu’à 30 minutes au lieu des 10 par défaut.

Ce que vous devez voir, une fois la tâche terminée (version abrégée) :

{
  "taskId": "job_01k3m8x9q2z4v7n5p6r8s0t1w3",
  "model": "MODEL_ID_FROM_CATALOG",
  "state": "succeeded",
  "output": {
    "assets": [
      {
        "key": "tasks/2026/09/17/job_01k3m8x9q2z4v7n5p6r8s0t1w3/result.mp4",
        "url": "https://…",
        "expiresAt": "2026-09-17T08:40:00Z",
        "mime": "video/mp4",
        "durationSeconds": 5,
        "width": 1280,
        "height": 720,
        "bytes": 4839211
      }
    ]
  },
  "cost": "…",
  "settled": true
}

La prochaine fois, vous pourrez réunir les étapes 4 et 5 en ajoutant --wait à tasks create.

Ce qui s’est passé : votre outil a interrogé SpicyAPI sur la tâche toutes les quelques secondes. Les états sont queued (en attente), running (en cours de génération), puis un état final : succeeded, failed ou expired. Après un succès, le fichier est copié dans le stockage propre à SpicyAPI, ce qui prend encore quelques secondes ; en attendant, le résultat affiche pending: true. cost est définitif une fois que settled vaut true.

  • Fermer le terminal ou appuyer sur Ctrl + C n’annule pas la tâche. Cela arrête seulement l’attente. Gardez l’identifiant de la tâche et refaites cette étape plus tard.
  • Ne vérifiez pas plus souvent que toutes les quelques secondes. Consulter une tâche utilise le quota de lecture du compte, indépendamment du lancement de tâches ; voir Limites de débit.
  • Pour une application ou un serveur, laissez SpicyAPI vous prévenir quand la tâche est terminée au lieu de poser la question : voir Être prévenu au lieu d’attendre.

6. Télécharger et conserver la vidéo

À faire : obtenez un lien de téléchargement récent et enregistrez le fichier sur votre ordinateur.

Obtenez un lien récent :

spicyapi files download-url job_01k3m8x9q2z4v7n5p6r8s0t1w3
key: tasks/2026/09/17/job_01k3m8x9q2z4v7n5p6r8s0t1w3/result.mp4
url: https://…
expiresAt: 2026-09-17T08:52:00Z

Collez l’url dans un navigateur pour télécharger le fichier, ou enregistrez-le depuis le terminal (gardez les guillemets, car le lien contient des caractères &) :

curl -L -o my-video.mp4 "PASTE_THE_URL_HERE"

Dans Windows PowerShell, tapez curl.exe au lieu de curl. Si une tâche a produit plusieurs fichiers, spicyapi tasks get <task-id> --json les liste, et --key permet d’en choisir un.

Ce qui s’est passé : chaque résultat est fourni avec un lien de téléchargement direct. Ce lien fonctionne environ 20 minutes et ne demande pas de clé API ; n’y ajoutez jamais votre clé. Quand il a expiré, redemandez la tâche (ou utilisez files download-url) pour en obtenir un nouveau.

Gardez votre propre copie

SpicyAPI conserve les fichiers générés environ 14 jours au plus, moins si le réglage de conservation de votre compte est plus court, puis les supprime définitivement. Votre image téléversée est utilisable pendant un jour, et le texte de votre prompt est effacé au bout de 30 jours par défaut. L’enregistrement de la tâche et de son coût est conservé. Pour supprimer plus tôt les fichiers et le prompt d’une tâche terminée, utilisez spicyapi tasks purge, purgeTask() ou POST /api/v1/jobs/purge ; cela supprime uniquement le contenu et ne constitue pas un remboursement. Voir Conservation et destruction.

7. En cas de problème

Les problèmes sont de deux sortes, et ils ne se traitent pas de la même façon.

Une requête est refusée. Votre commande ou votre appel reçoit immédiatement une erreur. Rien n’a été créé et rien n’a été facturé. Le message explique pourquoi, et l’erreur comporte un code et un identifiant de requête (req_…) à citer si vous contactez l’assistance.

CodeCe que cela signifieQue faire
400, ou un code plus précis commençant par 400L’entrée ne correspond pas aux réglages du modèle : un réglage obligatoire manquant, un réglage inconnu ou mal orthographié, une valeur non autorisée, une adresse spicy:// expirée ou appartenant à un autre compte, une combinaison de réglages que le modèle ne peut pas servir pour le moment, ou une adresse de callback invalideComparez input.json avec les réglages de l’étape 1 et corrigez-le. Pour une adresse expirée, téléversez l’image de nouveau
401La clé API est absente, mal saisie ou révoquéeVérifiez SPICY_API_KEY comme dans Avant de commencer
40201Votre solde ne couvre pas le montant à mettre de côtéAjoutez des fonds dans Facturation, dans la console
40202Un plafond de dépense de votre clé (quotidien, mensuel ou cumulé) est atteintRelevez-le sur la page Clés API, ou attendez qu’il soit remis à zéro
403, 40301Cette clé n’a pas le droit d’utiliser ce modèle, ou la requête vient d’un endroit depuis lequel elle n’est pas autoriséeVérifiez la liste des modèles et les adresses IP autorisées de la clé sur la page Clés API
404Aucun modèle avec cet identifiant pour votre compte (ou vous avez envoyé l’espace réservé), ou aucune tâche avec cet identifiant pour cette cléRecopiez l’identifiant exact ; utilisez la clé qui a créé la tâche
409Cette clé d’idempotence a déjà servi pour une requête différentePrenez une nouvelle étiquette pour une nouvelle vidéo
40901Le devis a expiré (cinq minutes) ou le prix a changéRedemandez un devis, puis relancez
429Trop de requêtes en peu de tempsAttendez le nombre de secondes indiqué dans l’erreur, puis continuez plus lentement
50301Le modèle ne peut pas accepter de nouveau travail pour le momentRéessayez plus tard, ou choisissez un autre modèle

La tâche échoue. La tâche a été acceptée, mais se termine en failed ou expired au lieu de succeeded. La tâche affiche un errorCode qui en donne la raison, et un errorMessage qui l’explique plus en détail. Les tâches échouées ou expirées libèrent normalement toute la réservation. Certains refus de contenu sont facturés au devis accepté, uniquement si la page du modèle indique explicitement cette exception. Consultez settled et cost pour connaître le montant final.

Pour le lire :

spicyapi tasks get job_01k3m8x9q2z4v7n5p6r8s0t1w3

Regardez state, errorCode et errorMessage.

Décidez ensuite quoi faire d’après l’errorCode, et non d’après la formulation du message :

errorCodeCe que cela signifieQue faire
rate_limited, upstream_unavailable, upstream_failedLa génération était saturée ou momentanément indisponibleRelancez-la après une courte pause
timeout (ou l’état est expired)La vidéo n’a pas été terminée à tempsRéessayez une fois ; si cela se reproduit, choisissez une durée plus courte ou une résolution plus basse et lancez une nouvelle tâche
generation_failedLa génération a tourné mais n’a rien produitLa même entrée échoue généralement de la même façon. Modifiez le prompt ou l’image et lancez une nouvelle tâche
invalid_assetL’image n’a pas pu être utilisée, par exemple parce que le téléversement avait expiré ou que le fichier était illisibleTéléversez l’image de nouveau et lancez une nouvelle tâche avec la nouvelle adresse
invalid_request, unsupported_combinationLes réglages n’ont pas été acceptésModifiez les réglages et lancez une nouvelle tâche
content_rejectedLe modèle choisi a décliné cette requête en vertu de sa propre politiqueModifiez le prompt ou l’image, ou choisissez un autre modèle

Traitez toute autre valeur comme upstream_failed. La liste complète se trouve dans Erreurs.

Relancer une tâche échouée. Une relance crée une nouvelle tâche avec le même modèle et la même entrée, au prix actuel du modèle. Elle coûte de l’argent, comme l’étape 4, et elle reprend l’entrée d’origine : si cette entrée utilisait un téléversement qui a expiré depuis, téléversez de nouveau et lancez plutôt une nouvelle tâche.

spicyapi tasks retry job_01k3m8x9q2z4v7n5p6r8s0t1w3 --wait --wait-timeout-ms 1800000

La commande vous demande de confirmer mais, contrairement à tasks create, n’affiche pas de prix au préalable. Pour voir le prix, lancez la commande tasks quote de l’étape 3.

Seules les tâches failed et expired peuvent être relancées. Pour obtenir une autre version d’une vidéo réussie, revenez à l’étape 3 avec une nouvelle étiquette. Une tâche acceptée ne peut en aucun cas être annulée. Pour en savoir plus : Engagement et relance.

Passer plutôt par un assistant IA

Si vous utilisez un assistant IA compatible MCP, comme Claude Code, Cursor ou Codex, le serveur MCP de SpicyAPI lui permet de réaliser les sept étapes à votre place. Configurez-le une fois avec Serveur MCP : configurer votre client, puis formulez votre demande avec vos propres mots, par exemple :

Téléverse sur SpicyAPI l’image qui se trouve dans /Users/me/spicy-video/start-frame.jpg. Trouve les modèles image vers vidéo que ma clé peut utiliser et demande un devis pour un clip de 5 secondes sur les deux moins chers. Ensuite, dès que j’ai confirmé, génère la vidéo avec le moins cher des deux, attends qu’elle soit prête et donne-moi le lien de téléchargement.

Sous Windows, indiquez le chemin sous la forme C:\Users\me\spicy-video\start-frame.jpg.

Ce qui se passe :

  1. spicyapi_upload_file téléverse l’image et obtient son adresse spicy://. C’est gratuit, mais le fichier est bel et bien envoyé : désignez précisément le fichier voulu. Par défaut, seuls les fichiers situés dans votre dossier personnel peuvent être lus ; voir Fichiers locaux.
  2. spicyapi_models_list et spicyapi_model_get trouvent un modèle et ses réglages, et spicyapi_task_quote calcule le prix des différentes options. Tout cela est gratuit.
  3. spicyapi_task_create s’arrête et vous demande votre accord, en affichant le modèle, le montant estimé et le montant maximal, ainsi que l’heure d’expiration du devis. Rien n’est facturé tant que vous n’avez pas confirmé, et l’assistant ne peut pas confirmer à votre place.
  4. spicyapi_task_wait attend jusqu’à cinq minutes à chaque appel : pour une vidéo plus longue, l’assistant peut donc devoir attendre plusieurs fois. Il vous donne ensuite le lien de téléchargement, valable environ 20 minutes.

D’autres exemples et la description de chaque outil : Serveur MCP.

Aller plus loin

Première et dernière image

Certains modèles image vers vidéo acceptent aussi last_image_url : une seconde image sur laquelle la vidéo se termine. Pour savoir si le vôtre l’accepte, cherchez last_image_url dans les properties de l’étape 1. S’il n’y figure pas, le modèle ne le prend pas en charge et l’envoyer provoque un refus avec 400.

Téléversez les deux images comme à l’étape 2, puis mettez les deux adresses dans input.json :

{
  "prompt": "The flower slowly opens as morning light spreads across the table",
  "image_url": "spicy://f/fil_01k3m8x9q2z4v7n5p6r8s0t1w3",
  "last_image_url": "spicy://f/fil_01k3m8x9q2z4v7n5p6r8s0t1w4"
}

La description du réglage explique comment ce modèle utilise l’image finale. Redemandez un devis avant de lancer la génération, pour voir si la seconde image modifie le prix.

Plusieurs vidéos

  • Réutilisez le téléversement. Une même adresse spicy:// peut servir dans plusieurs tâches jusqu’à son expiresAt, sauf si la conservation des téléversements de votre compte est réglée pour les supprimer dès qu’une tâche se termine.
  • Une étiquette par vidéo. Donnez à chaque vidéo sa propre clé d’idempotence, comme campaign-clip-1, campaign-clip-2. Si vous relancez votre script, il récupère alors les vidéos déjà lancées au lieu de les payer deux fois.
  • Ne lancez pas tout en même temps. Chaque tâche en cours immobilise de l’argent mis de côté, un plafond de dépense refuse avec 40202 les tâches qui le dépasseraient, et chaque vérification d’état compte dans votre limite de débit. Commencez par deux à la fois.

Scripts prêts à l’emploi : Lancer un lot en limitant la concurrence (SDK) et Lancer la CLI depuis un script.

Être prévenu au lieu d’attendre

Pour un site web ou un service en arrière-plan, garder un programme en marche uniquement pour demander « c’est fini ? » est du gaspillage. Donnez plutôt à la tâche une adresse de callback : une adresse web publique sur votre propre serveur, que SpicyAPI appelle une seule fois, quand la tâche se termine, avec les mêmes informations sur la tâche que celles affichées à l’étape 5.

Ce qu’il vous faut :

  • un serveur joignable depuis Internet à une adresse https://, sur le port standard (localhost est refusé) ;
  • votre clé de signature des webhooks, récupérée dans la console, pour que votre serveur puisse vérifier que chaque appel vient bien de SpicyAPI ;
  • du code qui vérifie la signature, répond rapidement et gère le cas où la même notification arrive deux fois.

Webhooks explique le format, la signature et le calendrier des nouvelles tentatives, et le SDK propose un récepteur minimal. Prévoyez une solution de secours : de temps en temps, vérifiez les tâches dont le deadlineAt est largement dépassé sans qu’aucune notification soit arrivée.

Ajoutez l’adresse de callback quand vous demandez le devis et quand vous lancez la tâche :

spicyapi tasks create --model MODEL_ID_FROM_CATALOG --input-file input.json --callback-url https://your-app.example.com/hooks/spicy

La CLI inclut l’adresse dans son propre devis : la vérification du prix correspond donc toujours.

Étapes suivantes

Sur cette page