Les échecs de l'API Kling se répartissent en trois couches : la requête (statut HTTP et code métier), la tâche (task failed) et le résultat (échec de téléchargement). L'ordre de diagnostic doit être : statut et code métier, puis request_id et reproduction minimale, et seulement ensuite modification des paramètres ou changement de modèle. Inverser l'ordre conduit facilement à prendre un problème de configuration pour une limite du modèle.

Cet article s'appuie sur les codes d'erreur et états de tâche de la documentation de la plateforme Kling d'octobre 2026 pour proposer un ordre de diagnostic, des règles de retry et d'idempotence. Interfaces et codes peuvent évoluer : la documentation officielle fait foi.

Remarque : Kling est une marque de Kuaishou et de ses sociétés affiliées. Cet article est purement technique et n'implique aucune affiliation ni caution. Les codes d'erreur, règles de concurrence et modes de facturation font foi dans la documentation officielle et sur la page de tarifs du site.

1. Distinguer d'abord les trois couches d'échec

Un échec de requête revient immédiatement : 401 authentification, 400 paramètres, 403 droits, 429 limitation ou solde, 5xx erreur serveur. Un échec de tâche survient après une soumission réussie et l'obtention d'un identifiant : l'état passe à failed, la raison figure dans message. Un échec de résultat signifie que la tâche est succeeded mais que le lien de téléchargement est inaccessible, expiré ou nettoyé.

Consignez les trois couches séparément. Prendre un échec de tâche pour un problème d'authentification et changer de clé en boucle, ou prendre un échec de téléchargement pour un échec de génération et resoumettre, gaspille du temps et de l'argent.

2. 401 : examiner les codes 1000 à 1004

Un 401 signifie que l'identité n'est pas validée, sans lien direct avec les capacités du modèle ou le solde. Les codes métier documentés sont : 1000 échec d'authentification, 1001 champ Authorization absent, 1002 jeton invalide, 1003 jeton pas encore valide, 1004 jeton expiré.

Les modèles actuels utilisent une clé API dans l'en-tête Authorization: Bearer ; l'ancienne interface signe un JWT AK/SK en HS256, valable environ 30 minutes. Les deux modes ne se mélangent pas. Procédez dans cet ordre :

  1. L'en-tête est-il Authorization: Bearer <identifiant>, avec un espace après Bearer ?
  2. L'identifiant contient-il un espace, un retour à la ligne ou des guillemets superflus ? Une copie depuis une fenêtre de chat en apporte facilement.
  3. La variable d'environnement est-elle réellement chargée ? Affichez seulement son préfixe, jamais la clé complète.
  4. La clé a-t-elle été supprimée, renouvelée ou désactivée ? L'ancien JWT a-t-il plus de 30 minutes, ou un décalage d'horloge le rend-il invalide ?
  5. L'URL de base, le domaine régional et la clé appartiennent-ils à la même plateforme ? Ne mélangez pas les adresses des serveurs internationaux et nationaux.
  6. Un proxy inverse écrase-t-il ou supprime-t-il l'en-tête Authorization ? La clé de signature des callbacks est-elle correctement configurée ?
  7. Testez une nouvelle clé sur une requête minimale pour distinguer un problème d'identifiant d'un problème de proxy ou de passerelle.

3. 429, solde et concurrence : identifier le type de limite

Un 429 ne signifie pas toujours « requêtes trop rapides ». Dans la documentation Kling, 1100 signale un compte anormal, 1101 un impayé en post-paiement et 1102 un pack prépayé épuisé ou expiré — tous sous 429 ; 1302 est la limite de débit, 1303 le dépassement de concurrence du pack, 1304 la restriction de liste blanche IP ; 1103 correspond à un 403 sans droit.

La concurrence se calcule par compte, version de modèle et type de pack ; toutes les clés d'un même compte partagent le quota. Une tâche occupe un slot dès submitted et le libère à la réussite ou à l'échec ; les interrogations ne consomment pas de concurrence. Multiplier les clés ne contourne donc pas la limite.

Traitement : lisez message et le code métier pour distinguer solde, concurrence et droits ; appliquez un backoff exponentiel sur 1302 et 1303, avec une première attente d'au moins 1 seconde, et placez les soumissions dans une file ; en cas de dépassement durable, réduisez la concurrence, décalez les pics ou ajustez le pack à l'usage réel. N'utilisez pas une tempête de retries sans backoff contre la limitation.

4. 400/404 paramètres et modèles : codes 1200 à 1203

1200 est une erreur de paramètre générique, 1201 désigne un champ ou une valeur précise, 1202 une méthode HTTP incorrecte, 1203 une ressource ou un modèle inexistant. 1300 signale un conflit avec la politique de la plateforme, 1301 un contenu bloqué par la sécurité, généralement en 400.

Causes fréquentes : durée hors plage du modèle (2.5 Turbo accepte seulement 5 ou 10 secondes, la série 3.0 va de 3 à 15 secondes) ; résolution non prise en charge (la 4K n'existe que sur certains modèles) ; ratio, première et dernière frame ou nombre d'images de référence incompatibles avec le modèle ; URL d'image inaccessible pour la plateforme ; version de modèle absente du chemin ou de model_name ; prompt au-delà de la limite.

Diagnostiquez avec une requête minimale, puis rajoutez les paramètres un par un. Un refus de modération n'est pas une panne technique : ne cherchez pas à le contourner en changeant des mots-clés.

5. Tâche failed : état, message et callback

Les états courants sont submitted, processing, succeeded, failed ; l'ancienne interface peut renvoyer succeed au lieu de succeeded, et la couche d'adaptation doit gérer les deux. En cas de failed, examinez message, request_id et les paramètres soumis.

Causes fréquentes : échec de téléchargement de l'image ou de la vidéo d'entrée, modération, anomalie de rendu amont, timeout de tâche, indisponibilité temporaire du modèle. Conservez l'enregistrement des tâches échouées au lieu de les supprimer immédiatement, sinon tout retour d'expérience devient impossible.

Si vous utilisez callback_url, vérifiez webhook-id, webhook-timestamp et webhook-signature, la signature étant en HMAC-SHA256 ; les callbacks de test sont limités à un toutes les 6 secondes, et un traitement réussi doit répondre HTTP 200. La documentation ne promet pas de rejeu systématique en cas d'échec : conservez le polling comme filet de sécurité en production, sans dépendre uniquement du callback.

6. Timeouts et polling : ne pas écrire un appel asynchrone comme un appel synchrone

Une tâche vidéo dure souvent de quelques dizaines de secondes à plusieurs minutes, avec de l'attente en file aux heures de pointe. Réglez séparément le timeout de connexion, le timeout de lecture et le timeout global de tâche : le premier peut être court, le deuxième suit l'interface d'interrogation, le troisième correspond au délai métier acceptable.

Pour le polling, partez de 5 secondes, reculez progressivement jusqu'à 15–30 secondes, avec un jitter aléatoire ; fixez un nombre maximal de tentatives et une échéance globale, puis marquez la tâche « à confirmer » au lieu d'attendre indéfiniment. Dans les 5xx, 5000, 5001 et 5002 désignent respectivement une erreur interne, un service temporairement indisponible et un timeout amont ; ils peuvent être réessayés avec backoff. Les 401, 403 et 1301 ne doivent pas être réessayés aveuglément.

Voici un exemple Python simplifié qui enchaîne soumission, polling, classification des erreurs et téléchargement :

import time
import random
import requests

API_KEY = "votre-identifiant-kling"
BASE = "https://votre-adresse-api-kling"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

def create_task(payload, external_id):
    payload = {**payload, "external_task_id": external_id}
    resp = requests.post(f"{BASE}/text-to-video/chemin-de-votre-modele",
                         json=payload, headers=HEADERS, timeout=(5, 30))
    if resp.status_code == 401:
        raise RuntimeError("Authentification échouée : vérifier la clé, Bearer et la région")
    if resp.status_code == 429:
        raise RuntimeError(f"Limite, solde ou concurrence : {resp.text}")
    resp.raise_for_status()
    return resp.json()["data"]["id"]

def wait_and_download(task_id, timeout=900):
    deadline = time.time() + timeout
    delay = 5
    while time.time() < deadline:
        r = requests.get(f"{BASE}/tasks", params={"task_ids": task_id},
                         headers=HEADERS, timeout=(5, 30))
        if r.status_code in (500, 503, 504):
            time.sleep(delay + random.random())
            delay = min(delay * 1.5, 30)
            continue
        r.raise_for_status()
        task = r.json()["data"][0]
        status = task["status"].lower()
        if status in ("succeeded", "succeed"):
            url = task["outputs"][0]["url"]
            video = requests.get(url, timeout=(5, 120))
            video.raise_for_status()
            return video.content  # en production, écrire en flux dans le stockage objet
        if status == "failed":
            raise RuntimeError(task.get("message") or "task failed")
        time.sleep(delay)
        delay = min(delay * 1.5, 30)
    raise TimeoutError(task_id)

# Avant de resoumettre, interroger external_task_ids pour vérifier si la tâche existe déjà

7. Échec de téléchargement : validité du lien et recopie

Après une réussite, le résultat se trouve dans outputs, avec url, watermark_url et duration. La documentation indique un nettoyage 30 jours après la génération, et la validité réelle du lien peut être plus courte. Les échecs de téléchargement viennent souvent d'un lien expiré, d'un résultat nettoyé, d'un timeout réseau, de droits sur le stockage objet ou d'un blocage par un proxy.

Recommandations : télécharger et recopier immédiatement dans votre stockage objet ; réessayer séparément le téléchargement et la génération, sans resoumettre la génération en cas d'échec de téléchargement ; consigner content-type, content-length et la somme de contrôle ; ne jamais écrire l'URL signée complète dans des journaux publics. Si le résultat a été nettoyé, il faut généralement régénérer : la recopie doit donc être la première étape après un callback ou un polling réussi.

8. Retry et idempotence : éviter une double facturation

Classez avant de réessayer : 429, 5xx et timeouts réseau peuvent être réessayés avec backoff ; 400, 401, 403 et 1301 exigent d'abord une correction ; une tâche failed demande de lire message, de corriger la cause puis de soumettre une nouvelle tâche.

Kling prend en charge external_task_id, unique au sein d'un compte. Fournissez le numéro métier ou la clé d'idempotence à la soumission ; après un timeout réseau, interrogez external_task_ids pour vérifier si la tâche existe avant de renvoyer. Sinon, un simple « timeout de requête » peut devenir deux tâches et deux facturations.

La table des tâches doit au minimum consigner : numéro métier, task_id, external_id, modèle et paramètres, état, message, request_id, coût et nombre de tentatives. Pour le rapprochement, dédupliquez par task_id, pas par nombre de soumissions.

9. Tableau d'ordre de diagnostic

Symptôme À vérifier d'abord Cause fréquente Traitement
401 Authorization, clé, région 1000–1004, JWT expiré ou pas encore valide Corriger l'identifiant, requête minimale
429 Code métier et message 1101/1102 solde, 1302 débit, 1303 concurrence Recharger, backoff, réduire la concurrence
400 Paramètres et contenu 1200/1201/1300/1301 Corriger selon message, ne pas contourner la modération
404 Chemin, méthode, modèle 1202/1203 Aligner chemin et nom de modèle sur la documentation
failed message, matériel d'entrée Téléchargement, modération, rendu Corriger matériel ou paramètres, conserver la trace
Timeout Timeouts connexion/lecture/tâche File d'attente, tâche longue, 5xx amont Régler les timeouts par couche, polling avec backoff
Téléchargement État et validité du lien Expiration, nettoyage, réseau Recopier immédiatement, réessayer le téléchargement seul

Questions fréquentes

Un 429 signifie-t-il toujours un solde insuffisant ?

Non. Un 429 peut être 1101 impayé, 1102 pack épuisé, 1302 limite de débit, 1303 concurrence dépassée ou 1304 restriction IP. Lisez le code métier et message avant de choisir entre recharge, backoff et réduction de concurrence.

Une tâche échouée est-elle facturée ?

Cela dépend des règles de la plateforme et du motif. Vérifiez avant l'intégration comment sont facturés les échecs, les refus de modération et les annulations pour timeout, et fiez-vous à la facture. Ne supposez pas qu'un échec est toujours gratuit.

À quelle fréquence interroger une tâche ?

Partez de 5 secondes, reculez jusqu'à 15–30 secondes, avec jitter. Fixez une échéance globale et un nombre maximal de tentatives pour éviter l'attente infinie et la pression sur l'interface d'interrogation.

Que faire si le callback n'arrive pas ?

Vérifiez d'abord que l'URL est accessible publiquement, renvoie HTTP 200 et que la signature est valide, puis que l'horodatage est dans la fenêtre autorisée. La documentation ne promet pas de rejeu systématique : conservez le polling comme solution de repli en production.

Le lien de résultat est inaccessible : pourquoi ?

Vérifiez l'état de la tâche, l'expiration du lien et un éventuel nettoyage du résultat. Recopiez dans le stockage objet dès la réussite ; une fois le lien invalide, il faut généralement régénérer.

Prochaines étapes

Créez une clé de test sur ZSQH AI Gateway, puis entraînez-vous sur chaque cas : 401, 429, erreur de paramètre, tâche échouée et timeout, avant de brancher la supervision de production. Les modèles disponibles et la facturation figurent sur la page Tarifs des modèles.

Lectures associées :