L'API de génération vidéo Kling n'est pas une interface synchrone qui renvoie une vidéo en une requête : elle crée d'abord une tâche, permet d'en consulter l'état, puis de télécharger le résultat. La traiter comme un endpoint Chat Completions bloque généralement dès la première étape : la requête réussit, mais aucune vidéo n'est renvoyée, seulement un enregistrement de tâche.
Cet article suit l'ordre réel d'intégration et couvre, pour 2026, les générations d'interface, l'authentification, la soumission, le polling, les callbacks, le téléchargement, l'idempotence et la migration. Les chemins et champs peuvent changer selon la version : consultez la documentation officielle avant l'intégration.
Remarque : Kling et Kuaishou sont des marques de leurs détenteurs respectifs. Cet article est purement technique et n'implique aucune affiliation ni relation d'agence avec les sociétés concernées.
1. Distinguer les deux générations d'interface
Deux formes d'API coexistent chez Kling, et les mélanger est une source d'erreur fréquente.
L'interface récente place la version du modèle dans le chemin, par exemple POST /text-to-video/kling-3.0-turbo ou POST /text-to-video/kling-2.6. Le corps de requête n'a plus besoin de model_name, l'authentification utilise une clé API en en-tête Bearer, et la réponse expose data.id et data.status.
L'ancienne interface se trouve généralement sous /v1/videos/..., le corps précise le modèle via model_name, l'authentification génère un JWT à partir d'AccessKey/SecretKey, et la réponse expose task_id et task_status. Elle reste utilisable, mais un nouveau projet ne devrait pas partir de là.
Les exemples ci-dessous privilégient l'interface récente ; la liste de migration des deux générations figure en fin d'article.
2. URL de base et authentification
La documentation Kling indique notamment :
https://api-singapore.klingai.com: destiné aux serveurs hors Chine continentale, ce domaine remplaçant l'ancienapi.klingai.comselon la documentation.https://api-beijing.klingai.com: adresse de Pékin citée dans les exemples, adaptée à un déploiement national.
Les régions réellement disponibles, le périmètre du compte et la disponibilité des modèles sont à vérifier dans la console. Ne changez pas de région sans raison : les tâches et résultats appartiennent généralement à la région de soumission.
L'en-tête d'authentification est Authorization: Bearer <API_KEY>, avec un espace entre Bearer et la clé. Un détail facile à oublier : l'interface récente exige aussi Content-Type: application/json sur les requêtes d'interrogation, même en GET.
La clé ne doit vivre que côté serveur. Un appel direct depuis un navigateur, une application mobile ou un mini-programme expose les identifiants et rencontre des problèmes de CORS et de callbacks inaccessibles. Faites soumettre les tâches par le backend et ne transmettez au front que l'état de la tâche.
3. Soumettre une première tâche vidéo
Validez d'abord la chaîne avec la durée la plus courte et la résolution la plus basse, puis ajoutez les paramètres progressivement.
export KLING_API_KEY="votre-cle"
export KLING_BASE_URL="https://api-singapore.klingai.com"
curl -sS -X POST "$KLING_BASE_URL/text-to-video/kling-3.0-turbo" \
-H "Authorization: Bearer $KLING_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "Rue urbaine après la pluie, mouvement de caméra lent, rendu cinématographique, 16:9",
"settings": {
"resolution": "720p",
"aspect_ratio": "16:9",
"duration": 5
},
"options": {
"external_task_id": "demo-20261019-001",
"callback_url": "https://example.com/kling/callback"
}
}'
Une réponse réussie renvoie le code métier 0, l'identifiant de tâche dans data.id, et un état initial généralement submitted :
{
"code": 0,
"message": "",
"request_id": "…",
"data": {
"id": "…",
"status": "submitted",
"create_time": 0,
"update_time": 0,
"external_id": "demo-20261019-001"
}
}
Quelques limites à connaître : pour 3.0 Turbo, duration accepte 3 à 15 secondes, avec 5 secondes par défaut ; pour 2.6, on rencontre souvent 5 ou 10 secondes ; prompt est limité à environ 3072 caractères, la documentation recommandant de rester sous 2500. Résolution, ratio et audio varient selon le modèle : ne transposez pas directement les paramètres d'un modèle à un autre.
4. Interroger l'état d'une tâche
Une fois l'identifiant obtenu, interrogez l'état :
GET /tasks?task_ids=<ID_de_tache>
GET /tasks?external_task_ids=<ID_personnalise>
task_ids et external_task_ids sont exclusifs, plusieurs identifiants se séparant par des virgules. Le champ data de la réponse est un tableau de tâches, chacune contenant id, status, message, create_time, update_time, external_id, outputs et billing.
Quatre états existent :
submitted: reçue, pas encore commencée.processing: génération en cours.succeeded: réussie,outputsest lisible.failed: échouée, consultezmessageet le motif de modération.
N'interrogez pas à fréquence fixe et élevée. Partez de 5 secondes, reculez progressivement jusqu'à 15 à 30 secondes, et fixez un délai global. Une tâche vidéo peut être mise en file : si elle dépasse le délai attendu, vérifiez la concurrence et les packs plutôt que de soumettre immédiatement une deuxième fois.
Pour un rapprochement ou une reprise, utilisez la requête à curseur POST /tasks, avec filtres start_time, end_time, status et product_type, dans la limite de 500 éléments par page.
5. Callbacks et vérification de signature
En passant callback_url à la soumission, la plateforme pousse une notification à chaque changement d'état. Le callback économise des ressources par rapport au polling, mais exige une URL accessible publiquement, une réponse 200 rapide et un traitement réel placé dans une file.
Le corps du callback récent contient id, status, message, outputs, external_id et billing ; l'ancienne interface renvoie task_id, task_status et task_result, avec l'état de réussite orthographié succeed. Ne partagez pas le même parseur entre les deux formats.
Côté sécurité, créez un Webhook Secret dans la console (préfixe whsec_). Le callback porte trois en-têtes webhook-id, webhook-timestamp et webhook-signature ; la signature couvre {webhook-id}.{webhook-timestamp}.{rawBody}, en HMAC-SHA256 puis Base64. Trois points de contrôle : l'horodatage doit rester dans une fenêtre de plus ou moins 5 minutes, la signature se calcule sur le corps brut, et la comparaison doit utiliser une fonction à temps constant. La documentation officielle permet la coexistence de l'ancien et du nouveau secret pendant 7 jours, ce qui facilite une rotation progressive.
Les callbacks peuvent être répétés ou arriver dans le désordre : rendez le traitement idempotent par identifiant de tâche, et ne faites avancer l'état que dans un sens, sans réécrire processing en submitted.
6. Télécharger et conserver le résultat
Les vidéos des tâches réussies se trouvent dans le tableau outputs ; l'élément de type video contient url, watermark_url, duration et id. L'URL est protégée contre le hotlinking : l'intégrer directement dans une page ou un système tiers peut être refusé.
Deux contraintes fermes :
- Les liens de résultat sont nettoyés environ 30 jours après la génération ; ce ne sont pas des adresses CDN permanentes.
- La protection anti-hotlinking impose de télécharger côté serveur, puis de recopier le fichier dans votre propre stockage objet.
Le flux de persistance recommandé : télécharger dès la réussite, vérifier le Content-Type et la taille, calculer une somme de contrôle, écrire dans le stockage objet, puis associer l'adresse interne et l'identifiant de tâche. Pour la diffusion externe, utilisez vos propres URL signées avec expiration.
7. Idempotence, tentatives et concurrence
L'erreur la plus coûteuse sur une tâche vidéo est la « nouvelle soumission après timeout ». Un timeout de requête ne signifie pas que la tâche n'a pas été créée : la réponse a peut-être simplement été perdue.
external_task_id est le principal levier d'idempotence : générez un identifiant stable avant la soumission, enregistrez-le, puis après un timeout interrogez GET /tasks?external_task_ids=... avant de réessayer. Cet identifiant doit être unique au sein du compte. N'utilisez pas un UUID aléatoire comme clé de retry, sinon chaque tentative crée une nouvelle tâche.
Côté concurrence, la documentation précise que seule la création de tâche compte ; les interrogations ne consomment pas de slot. La plateforme ne met pas en file à votre place : au-delà des slots du pack, elle renvoie 1303. Toutes les clés API partagent le pool de concurrence du même compte. La stratégie recommandée est un backoff exponentiel d'au moins 1 seconde, avec une file de soumission côté application libérant les requêtes selon les slots disponibles.
8. Correspondance des erreurs courantes
| Code métier | HTTP | Signification | Traitement conseillé |
|---|---|---|---|
| 1002 | 401 | Identifiants invalides | Vérifier la clé, la région et les en-têtes |
| 1103 | 403 | Aucun droit sur l'interface ou le modèle | Confirmer l'activation du modèle sur le compte et le pack |
| 1101 | 429 | Impayé en post-paiement | Recharger puis réessayer |
| 1102 | 429 | Pack épuisé ou expiré | Acheter un pack ou changer de mode de facturation |
| 1201 | 400 | Valeur de paramètre invalide | Lire message, vérifier durée, ratio, résolution |
| 1301 | 400 | Modération du contenu refusée | Modifier le prompt ou le matériel, ne pas réessayer à l'identique |
| 1302 | 429 | Requêtes trop fréquentes | Réduire la fréquence, backoff exponentiel |
| 1303 | 429 | Concurrence dépassée | Mettre en file et attendre la libération d'un slot |
| 1203 | 404 | Ressource ou modèle inexistant | Vérifier le chemin et la version du modèle |
| 5002 | 500 | Timeout interne du service | Conserver l'identifiant, interroger plus tard plutôt que resoumettre |
En diagnostic, lisez d'abord le statut HTTP, puis le code métier, enfin request_id. Consignez les trois ensemble dans les journaux : cela raccourcit nettement la localisation avec le support.
9. Liste de contrôle pour migrer depuis l'ancienne interface
- Passer de l'authentification JWT AccessKey/SecretKey à la clé API Bearer ; l'ancienne interface conserve la compatibilité JWT.
- Remplacer les chemins
/v1/videos/...par des chemins par modèle du type/text-to-video/kling-3.0-turbo. - Retirer
model_namedu corps : le modèle est déterminé par le chemin. - Remplacer les champs
task_idettask_statusparidetstatus. - Remplacer l'état de réussite
succeedparsucceeded. - Remplacer l'interrogation par tâche par
GET /tasks?task_ids=.... - Lire les résultats dans les éléments
type=videodeoutputsau lieu detask_result.videos. - Séparer les parseurs de callback ancien et récent pour éviter les erreurs de champs.
- Ajouter la logique de nettoyage à 30 jours et de recopie anti-hotlinking.
- Compléter l'idempotence avec
external_task_idet répéter les scénarios timeout, callback dupliqué et échec de modération.
Pour la migration, faites coexister ancien et nouveau : dirigez un trafic progressif vers la nouvelle interface, gardez une fenêtre de retour arrière, puis retirez l'ancienne une fois le taux de réussite, la latence et la facturation conformes.
10. Points de contrôle via une passerelle
Si vous passez par ZSQH AI Gateway, vérifiez, en plus de la clé et de l'URL de base, que le canal vidéo est activé, que les tâches asynchrones sont transmises telles quelles, que external_task_id et les callbacks sont conservés, et comment les URL de résultat sont livrées. Une interface compatible OpenAI pour modèles texte ne convient pas directement aux tâches vidéo.
Consultez d'abord les modèles et tarifs, puis inscrivez-vous et créez une clé de test. Validez toute la chaîne avec une tâche de 5 secondes avant de décider comment basculer le trafic de production.
Questions fréquentes
L'API Kling est-elle synchrone ou asynchrone ?
Asynchrone. La soumission ne renvoie qu'un identifiant de tâche ; il faut interroger GET /tasks ou recevoir un callback, puis télécharger la vidéo depuis outputs en cas de réussite.
Faut-il utiliser l'URL de base de Singapour ou de Pékin ?
Cela dépend de l'emplacement du serveur, du compte et des régions où le modèle est disponible. La documentation cite les deux adresses : vérifiez dans la console avant l'intégration et gardez la même région pour la soumission et l'interrogation.
Que faire si une tâche reste bloquée en processing ?
Vérifiez d'abord les slots de concurrence et le pack, puis si la tâche est en file. Au-delà du délai attendu, interrogez par identifiant plutôt que de resoumettre ; contactez le support avec le request_id si nécessaire.
Peut-on intégrer directement l'URL du résultat dans un site ou un mini-programme ?
Ce n'est pas conseillé. Le lien est protégé contre le hotlinking et nettoyé au bout d'environ 30 jours. Téléchargez côté serveur, recopiez dans votre stockage objet, puis servez via vos propres URL signées.
Un nouvel essai après échec est-il facturé deux fois ?
Cela dépend du motif d'échec et des règles de facturation. Un refus de modération ne doit généralement pas être réessayé à l'identique ; après un timeout réseau, interrogez d'abord par external_task_id pour vérifier que la tâche n'existe pas. Lisez la facturation et testez avec de petites tâches avant la mise en production.
Lectures associées :
