CheaperGen

Guides

Erreurs

Tous les codes d’erreur et états HTTP de l’API CheaperGen — 400, 401, 402, 404, 409, 429, 502, 503 — avec leurs causes et la marche à suivre pour les traiter ou réessayer.

L’API utilise les codes d’état HTTP habituels : 2xx indique une réussite, 4xx que la requête doit être modifiée et 5xx qu’une erreur s’est produite de notre côté ou en amont. Toutes les réponses d’erreur ont la même structure JSON, ce qui permet de les traiter au même endroit.

Format des erreurs#

400 Bad Request
{
  "error": {
    "code": "invalid_request",
    "message": "\"resolution\" must be one of: 480p, 720p",
    "param": "resolution"
  }
}
  • code — une chaîne stable et lisible par machine. Utilisez-la dans vos conditions, pas le message.
  • message — une explication lisible par un humain, que vous pouvez enregistrer dans les logs. Sa formulation peut évoluer.
  • param — présent lorsqu’un champ précis de la requête est à l’origine de l’erreur.

Codes d’erreur#

HTTPcodeSignificationQue faire ?Réessayer ?
400invalid_requestLe corps de la requête n’est pas un JSON valide, un champ obligatoire manque, une valeur est hors limites ou non autorisée, le corps contient un paramètre inconnu, une mention du prompt ne correspond à rien, ou un fichier vidéo/audio de référence est illisible ou dépasse les limites du modèle (durée, taille, résolution ou fréquence d’images). param indique le champ concerné.Corrigez la requête. Le message indique précisément le problème.Après correction
401unauthorizedLa clé API est absente, mal formée ou révoquée.Vérifiez l’en-tête Authorization: Bearer et que la clé est active.Après correction
402insufficient_balanceVotre solde ne couvre pas le prix de cette génération. Aucun montant n’a été débité.Ajoutez des crédits ou activez le rechargement automatique dans Tableau de bord → Facturation. Voir Facturation.Après correction
404not_foundL’ID du point de terminaison, du modèle ou de la génération n’existe pas, ou la génération appartient à un autre compte.Vérifiez l’ID dans la liste des modèles.Non
409conflictLa requête est incompatible avec l’état de la ressource — généralement, il s’agit de l’annulation d’une génération déjà en cours ou terminée.Consultez l’état actuel de la génération.Non
410model_delistedCe modèle n’est plus proposé. Rien n’a été envoyé ni débité ; l’historique de ses générations reste consultable.Choisissez un autre modèle parmi ceux de la liste des modèles.Non
429rate_limitedTrop de requêtes par seconde, ou votre file de générations en attente de démarrage est pleine.Attendez un peu avant de réessayer. Voir Limites de débit.Réessayer avec un délai croissant
500internal_errorUne erreur s’est produite de notre côté.Réessayez en espaçant progressivement les tentatives. Si le problème persiste, contactez l’assistance en indiquant l’heure de la requête.Réessayer avec un délai croissant
501direct_upload_unavailableLes téléversements directs (avec URL pré-signée) ne sont pas disponibles sur ce déploiement.Importez plutôt le fichier avec multipart/form-data. Voir Téléversements.Non
502—Une erreur de passerelle ou de réseau s’est produite avant que la requête n’atteigne notre API (cas rare). Les défaillances du modèle ne génèrent jamais d’erreur HTTP : la génération échoue avec un motif d’erreur.Réessayez en espaçant progressivement les tentatives. Aucun montant n’a été débité.Réessayer avec un délai croissant
503model_unavailableLe modèle n’accepte temporairement plus de nouvelles générations.Réessayez plus tard ou changez de modèle. Consultez page d’état.Réessayer avec un délai croissant
503pricing_unavailableLa lecture des tarifs est momentanément indisponible : la requête n’a donc pas été tarifée. Rien n’a été envoyé ni facturé.Réessayez la même requête après quelques secondes (la réponse contient un en-tête Retry-After), avec le même Idempotency-Key.Réessayer avec un délai croissant
503fallback_price_declinedLa capacité habituelle est indisponible. Pour le moment, seul le tarif d’urgence (plafonné au prix officiel) est proposé, mais votre requête indiquait allow_fallback_price: false. Aucun montant n’a été débité ; le message précise les deux tarifs.Réessayez plus tard au tarif standard, ou envoyez allow_fallback_price: true (valeur par défaut) pour accepter le tarif d’urgence.Réessayer avec un délai croissant
400max_cost_exceededLe prix, tarif d’urgence compris, dépasse votre limite max_cost_usd. Aucun montant n’a été débité.Réduisez la résolution ou la durée, ou confirmez le prix et augmentez max_cost_usd.Après correction

Erreurs au cours d’une génération#

Une erreur HTTP signifie que la requête elle-même a été rejetée et qu’aucun montant n’a été débité. Le cas d’une génération acceptée qui échoue ensuite est différent : l’appel API a réussi (même si POST /run renvoie 202 lorsqu’une tâche échoue immédiatement), puis status de la génération passe à failed avec un objet error. Le montant réservé est automatiquement remboursé. Le même objet figure dans GET /generations, la charge utile notification webhook et les résultats des outils MCP.

Échec de génération
{
  "status": "failed",
  "error": {
    "code": "generation_failed",
    "message": "ByteDance's safety review for Seedance 2.0 Fast rejected this request (the prompt or an input file).",
    "reason": "content_blocked",
    "hint": "Describe the character's look instead of naming a copyrighted character or real person, keep it non-explicit, or try another model.",
    "retryable": false,
    "refunded": true,
    "detail": "Votre requête n’a pas passé le contrôle de sécurité du contenu. Modifiez votre prompt et réessayez."
  }
}

code désigne la catégorie générale (les quatre valeurs documentées depuis le lancement). reason précise la raison : utilisez-le dans vos conditions et affichez message et hint aux utilisateurs. retryable indique si un nouvel envoi de la même requête peut réussir ; param nomme le champ à modifier si nous pouvons l’identifier, et detail contient la formulation du fournisseur du modèle.

error.reasonerror.codeQue s’est-il passé ?Que faire ?Renvoyer tel quel ?
content_blockedgeneration_failedLe filtre de sécurité du fournisseur du modèle a rejeté le prompt, un fichier d’entrée ou le résultat généré (par exemple, un personnage protégé nommé, une personne réelle ou du contenu explicite). Le message indique à qui appartient le filtre.Reformulez le prompt (décrivez l’apparence au lieu de nommer un personnage, une marque ou une personne réelle), utilisez d’autres fichiers d’entrée ou essayez un modèle d’un autre fournisseur. Une requête identique échouera de la même façon.Non — à modifier d’abord
invalid_inputgeneration_failedLe modèle n’a pas accepté l’une des entrées ou des options : fichier trop volumineux, format non pris en charge, dimensions ou proportions incorrectes, durée excessive ou valeur incompatible. Lorsque nous pouvons l’identifier, param indique le champ concerné.Corrigez le champ indiqué (consultez les limites du modèle sur sa page API) et renvoyez la requête, ou essayez un autre modèle.Non — à modifier d’abord
input_unreachablegeneration_failedImpossible de télécharger une URL d’entrée : elle nécessite une connexion, le lien signé a expiré, ne pointe pas directement vers le fichier ou l’hébergeur a refusé la requête. Lorsque le fournisseur du modèle ne peut pas récupérer un fichier, nous le téléchargeons généralement nous-mêmes et relançons la tâche avec notre copie. Cela signifie le plus souvent que le fichier n’a pas pu être téléchargé du tout.Utilisez une URL publique qui pointe directement vers le fichier (ou importez-le avec POST /api/v1/uploads), puis renvoyez la requête.Non — à modifier d’abord
upstream_unavailableupstream_errorLe fournisseur du modèle était indisponible, surchargé ou à pleine capacité ; nous avons essayé toutes les routes disponibles.Réessayez dans une ou deux minutes ou utilisez un autre modèle.Oui
upstream_errorupstream_errorAprès avoir essayé toutes les routes disponibles, le fournisseur a rencontré une erreur interne pendant la génération.Réessayez ; ces erreurs sont généralement temporaires. Si le problème persiste, essayez un autre modèle.Oui
timeouttimeoutLa génération n’a pas abouti à temps (limite du fournisseur ou limite de 40 minutes imposée par nos soins).Réessayez. Les clips plus courts ou de résolution inférieure sont générés plus rapidement.Oui
output_unavailableupstream_errorLe modèle a terminé la génération, mais n’a renvoyé aucun fichier exploitable, ou le résultat n’a pas pu être téléchargé et enregistré.Retry.Oui
model_unavailablemodel_unavailableLe modèle, ou ce mode du modèle, a cessé d’être fourni pendant la génération.Choisissez un autre modèle ou réessayez plus tard.Non — à modifier d’abord
canceledupstream_errorLe fournisseur a annulé la tâche ou l’a laissée expirer avant son terme. (Une génération que vous annulez vous-même porte l’état canceled et n’a pas d’erreur.)Retry.Oui
generation_failedgeneration_failedLe modèle s’est arrêté sans résultat et sans indiquer de raison.Réessayez une fois ; en cas de nouvel échec, simplifiez le prompt ou les entrées, ou essayez un autre modèle.Oui

Les échecs dus à votre requête — content_blocked, un fichier refusé dans invalid_input, input_unreachable — ne sont pas réessayés auprès d’autres fournisseurs, car ils seraient de nouveau rejetés. Les pannes et erreurs des fournisseurs sont d’abord réessayées sur toutes les routes disponibles, au même prix. Voir Échecs et remboursements.

Lorsqu’un fournisseur indique qu’il ne peut pas télécharger l’un de vos fichiers d’entrée, nous essayons généralement de le télécharger nous-mêmes. Si nous y parvenons, la tâche est relancée avec une copie hébergée chez nous — au même prix, sans rien changer de votre côté ; la génération affiche toujours les URL que vous avez envoyées, et la copie est supprimée avec la génération conformément à sa retention. Ainsi, input_unreachable signifie le plus souvent que le fichier n’a pas pu être téléchargé : il nécessite une connexion, son lien signé a expiré, ne pointe pas directement vers le fichier ou son hébergeur a refusé la requête. Nous copions les images jusqu’à 30 MB, les vidéos jusqu’à 200 MB et l’audio jusqu’à 50 MB ; un fichier plus volumineux ou illisible échoue avec le statut invalid_input.

Réessayer sans risque#

Réessayez 429, 500, 502 et 503 avec un délai exponentiel et une part d’aléatoire. Ne réessayez pas les autres erreurs 4xx sans modifier la requête : elle échouerait de la même façon.

Les envois ne sont pas idempotents

Chaque appel réussi à POST /run/{endpoint} crée et facture une nouvelle génération. Si l’envoi expire à cause du réseau et que vous ignorez si la requête a été acceptée, consultez vos générations récentes avant de la renvoyer.

const RETRYABLE = new Set([429, 500, 502, 503]);

export async function postWithRetry(url, headers, body, attempts = 5) {
  let resp;
  for (let attempt = 0; attempt < attempts; attempt++) {
    resp = await fetch(url, { method: "POST", headers, body: JSON.stringify(body) });
    if (!RETRYABLE.has(resp.status)) break;
    // exponential backoff with jitter: ~1s, 2s, 4s, 8s…
    await new Promise((r) => setTimeout(r, Math.min(2 ** attempt, 30) * 1000 + Math.random() * 1000));
  }
  const data = await resp.json();
  if (!resp.ok) throw new Error(`${resp.status} ${data.error.code}: ${data.error.message}`);
  return data;
}

Exemples de validation#

Les messages de validation indiquent le champ et les valeurs autorisées ; vous pouvez les afficher tels quels aux développeurs :

[
  {
    "error": {
      "code": "invalid_request",
      "message": "\"prompt\" is required",
      "param": "prompt"
    }
  },
  {
    "error": {
      "code": "invalid_request",
      "message": "Unknown parameter \"resoluton\"",
      "param": "resoluton"
    }
  },
  {
    "error": {
      "code": "not_found",
      "message": "Unknown endpoint \"bytedance/seedance-2.0-fast/text-to-gif\". See GET /api/v1/models."
    }
  }
]

Vous pouvez aussi calculer le prix d’une requête sans lancer de génération : POST /api/v1/quote/{endpoint} valide les champs qui déterminent le prix et renvoie le coût. Voir Référence de l’API.

Quelque chose n’est pas clair ou manque ? Écrivez à support@cheapergen.com : nous lisons tous les messages.