Face à une erreur de l'API Kimi, regardez d'abord trois éléments : le code de statut HTTP, error.type et request_id. Un même 429 peut venir d'une surcharge serveur, d'une limitation d'organisation ou d'un solde insuffisant ; un même 401 peut venir d'une clé erronée ou d'un mélange entre site chinois et site international. Classez d'abord, modifiez le code ensuite.

Cet article détaille quatre catégories — 401, 404, 429 et délais — avec les causes, les étapes de diagnostic et un code de retrait réutilisable. Modèles et prix sont ceux de la page Tarifs des modèles.

Remarque : Moonshot et Kimi sont des marques de leurs détenteurs respectifs. Les types d'erreur, règles de limitation et comportements d'interface peuvent évoluer ; cet article décrit la situation courante en octobre 2026 et la documentation officielle fait foi.

1. Aide-mémoire des codes de statut

Code Type d'erreur Signification courante Direction de traitement
400 invalid_request_error Paramètre erroné, contexte trop long, plafond de sortie dépassé Corriger la requête
400 content_filter Entrée ou sortie bloquée par la sécurité des contenus Ajuster le prompt
401 invalid_authentication_error Clé invalide, région incompatible Corriger les identifiants
401 incorrect_api_key_error Clé absente ou erronée Corriger les identifiants
403 permission_denied_error Interface non ouverte, liste blanche IP, solde ou droits Vérifier droits et solde
404 resource_not_found_error Nom de modèle ou chemin erroné Consulter la liste des modèles
429 engine_overloaded_error Surcharge serveur Retrait puis nouvelle tentative
429 rate_limit_reached_error Concurrence, RPM, TPM ou TPD dépassés Ralentir ou augmenter le quota
429 exceeded_current_quota_error Impayé, solde insuffisant, bon expiré Recharger
499 client_closed_request Client ou proxy déconnecté trop tôt Vérifier délais et flux
500 server_error Erreur interne du serveur Retrait puis nouvelle tentative
503 server_unavailable Service temporairement indisponible Retrait puis nouvelle tentative
504 Gateway Time-out Requête longue en attente excessive Passer en flux

Un solde insuffisant peut se manifester par un 403 ou un 429 selon le point d'entrée : ne vous fiez pas au seul code de statut, mais à error.type. Journalisez au minimum l'heure, le code, le type d'erreur, le nom du modèle et request_id ; ne journalisez jamais la clé complète ni le contenu sensible.

2. 401 : vérifier la région avant la clé

  1. Une clé du site chinois est-elle configurée avec l'adresse internationale, ou l'inverse ? Les comptes, soldes et clés des deux sites sont totalement indépendants.
  2. Des clés de lignes de produit différentes sont-elles mélangées, par exemple plateforme ouverte, Kimi Code et abonnement ?
  3. La clé contient-elle un espace, un saut de ligne ou des guillemets superflus au début ou à la fin ?
  4. La variable d'environnement est-elle réellement chargée ? Affichez uniquement son préfixe pour vérifier.
  5. La clé a-t-elle été supprimée, renouvelée ou dépourvue des droits sur le projet actuel ?
  6. L'en-tête est-il bien Authorization: Bearer <key> et le chemin /v1/chat/completions ?
export MOONSHOT_API_KEY="votre clé"

curl "https://api.moonshot.cn/v1/chat/completions" \
  -H "Authorization: Bearer $MOONSHOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "kimi-k2.6",
    "max_completion_tokens": 64,
    "messages": [{"role": "user", "content": "Réponds seulement OK"}]
  }'

Si cette commande renvoie 200, la clé, la région et le nom du modèle sont corrects. Si un 401 persiste, testez avec une clé dont le fonctionnement est connu afin de distinguer un problème de clé d'un problème de configuration de passerelle.

3. 404 : nom de modèle et base_url en cause

Un 404 ne signifie pas nécessairement que le modèle est retiré. Quatre causes sont fréquentes :

  • Avec le SDK OpenAI, base_url n'est pas défini : la requête part vers l'adresse OpenAI par défaut et renvoie un modèle inexistant.
  • Le nom du modèle est mal orthographié, ou le compte n'a pas accès à cette version.
  • Le chemin comporte un /v1 en trop ou manquant, ou l'interface de chat pointe vers un autre chemin.
  • Les noms de modèles et les droits diffèrent entre site chinois et site international.

Commencez par lister les modèles avec la même clé pour voir ce que le compte peut utiliser :

curl "https://api.moonshot.cn/v1/models" \
  -H "Authorization: Bearer $MOONSHOT_API_KEY"

Ne devinez pas les modèles absents de la liste. La disponibilité réelle est celle renvoyée par le compte et la page Tarifs des modèles. Si la liste fonctionne mais que le chat renvoie 404, vérifiez que le chemin contient bien /v1 et que le client ne duplique pas base_url et le chemin complet.

4. 429 : trois types, trois traitements

error.type Signification Nouvelle tentative possible Traitement
engine_overloaded_error Surcharge serveur Oui Retrait selon Retry-After, réduire la concurrence
rate_limit_reached_error Concurrence, RPM, TPM ou TPD d'organisation dépassés Partiellement Ralentir, séparer les clés, augmenter le palier
exceeded_current_quota_error Impayé, solde insuffisant, bon expiré Non Recharger ou vérifier la facturation

Un dépassement TPD ne se règle généralement qu'en attendant le lendemain ou en augmentant le quota ; réessayer n'a pas de sens. Une requête interrompue par un 429 n'est généralement pas facturée, mais elle l'est normalement si la nouvelle tentative aboutit ; ne réessayez pas sans fin par crainte du coût, et ne croyez pas non plus qu'un 429 signifie que le compte a déjà été débité. Le SDK OpenAI réessaie automatiquement par défaut, ce qui peut transformer un 429 en plusieurs requêtes ; en production, fixez explicitement max_retries et utilisez votre propre logique de retrait.

import random
import time
from openai import OpenAI, RateLimitError

client = OpenAI(
    api_key="votre clé",
    base_url="https://api.moonshot.cn/v1",
    max_retries=0,
)

def ask(prompt: str, retries: int = 4) -> str:
    for attempt in range(retries):
        try:
            resp = client.chat.completions.create(
                model="kimi-k2.6",
                messages=[{"role": "user", "content": prompt}],
                max_completion_tokens=1024,
            )
            return resp.choices[0].message.content
        except RateLimitError as exc:
            body = exc.body or {}
            etype = (body.get("error") or {}).get("type", "")
            if etype == "exceeded_current_quota_error":
                raise RuntimeError("Solde ou quota insuffisant, rechargez d'abord")
            wait = min(2 ** attempt, 20) + random.random()
            print(etype, "attente", round(wait, 1), "secondes")
            time.sleep(wait)
    raise RuntimeError("Nombre de tentatives épuisé")

Les nouvelles tentatives ne conviennent qu'aux erreurs transitoires. Pour une opération ayant déjà produit des effets de bord, vérifiez avec une clé d'idempotence ou un contrôle d'état si elle a été exécutée avant de décider de la renvoyer.

5. Délais et 504

La génération de texte long, l'analyse de documents longs et les agents de code sont les plus exposés aux délais. Ordre de traitement :

  1. Passer du non-streaming à stream=True pour maintenir un flux de données continu.
  2. Fixer des délais de connexion et de lecture raisonnables, sans conserver les valeurs par défaut du SDK.
  3. Vérifier que le proxy d'entreprise, la passerelle et les outils de routage local ne coupent pas la connexion trop tôt ; cela peut se manifester par un 499.
  4. Contrôler la longueur de sortie avec max_completion_tokens et découper les tâches très longues.
  5. Journaliser l'identifiant de requête et la durée de chaque délai dépassé pour distinguer modèle lent, réseau lent et passerelle lente.
stream = client.chat.completions.create(
    model="kimi-k2.6",
    messages=[{"role": "user", "content": "Rédige une checklist de déploiement"}],
    max_completion_tokens=2048,
    stream=True,
    stream_options={"include_usage": True},
)

for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="")

Le flux ne réduit pas le prix unitaire, mais diminue nettement le gaspillage lié à l'attente jusqu'au délai puis à la nouvelle tentative. Le délai de connexion peut être court ; le délai de lecture doit couvrir la durée maximale de génération. En flux, ne reprenez pas le délai de lecture du non-streaming, sinon le client coupe lui-même une génération normale.

6. Tableau d'ordre de diagnostic

  1. Relever le code de statut, error.type, request_id, le nom du modèle et l'heure.
  2. Pour 401 et 403 : vérifier région, clé, ligne de produit, droits et solde.
  3. Pour 404 : vérifier base_url, nom de modèle et droits du compte, puis valider avec la liste des modèles.
  4. Pour 400 : vérifier longueur de contexte, plafond de sortie, format de fichier et sécurité des contenus.
  5. Pour 429 : traiter selon error.type — surcharge, limitation ou impayé.
  6. Pour 499 et 504 : vérifier flux, délais, proxy et maintien de connexion.
  7. Pour 500 et 503 : retrait puis nouvelle tentative ; si le problème persiste, transmettre request_id au prestataire.
  8. Après chaque incident, compléter la supervision et les alertes, sans attendre le retour des utilisateurs.

Questions fréquentes

Quelle différence entre 429 et 503 ?

Un 429 peut venir d'une surcharge serveur, d'un quota de compte ou d'un solde ; examinez d'abord error.type. Un 503 indique un service temporairement indisponible, généralement après un retrait. Dans les deux cas, évitez les nouvelles tentatives à intervalle fixe et rapproché.

Toujours 401 après un rechargement ?

Vérifiez que le rechargement et la clé appartiennent à la même région et à la même ligne de produit. Testez avec une clé nouvellement créée pour écarter une clé supprimée ou un cache de variable d'environnement.

Quelle erreur pour un contexte trop long ?

Généralement un 400 invalid_request_error, avec un message indiquant que les tokens d'entrée sont trop nombreux. Raccourcissez l'entrée, élaguez l'historique ou utilisez un modèle à contexte plus large.

Faut-il activer les nouvelles tentatives automatiques du SDK ?

Elles peuvent être activées, mais avec une limite. Les tentatives par défaut peuvent amplifier un 429 ; en production, il est conseillé de désactiver les nouvelles tentatives automatiques du SDK et d'appliquer votre propre retrait exponentiel et vos alertes selon le type d'erreur.

Comment distinguer une erreur de passerelle d'une erreur officielle ?

Envoyez la même requête au canal direct et à la passerelle, puis comparez code de statut, error.type et request_id. Vous identifierez rapidement l'amont, le réseau, la clé ou la configuration de la passerelle.

Pour aller plus loin

Créez d'abord une clé de test sur ZSQH AI Gateway, reproduisez une fois chaque cas 401, 404, 429 et délai dépassé, puis branchez la supervision de production. La disponibilité des modèles et les prix sont ceux de la page Tarifs des modèles.

Lectures associées :