Aller au contenu principal

Comprendre et traiter les erreurs de l'API

L'API publique CaptainDNS retourne toutes ses erreurs dans une enveloppe JSON standardisée. Cette page liste les codes canoniques, leur signification et l'action corrective recommandée.

Enveloppe standard

Toute réponse d'erreur suit ce format :

{
  "code": "QUOTA_EXCEEDED",
  "message": "Monthly credits quota exceeded for plan 'starter'.",
  "details": {
    "tier": "starter",
    "credits_used": 50000,
    "credits_limit": 50000
  },
  "request_id": "req_a1b2c3d4",
  "documentation_url": "https://www.captaindns.com/en/docs/api/errors"
}
  • code : chaîne stable documentée ici. Utilisez-le pour brancher votre logique de traitement d'erreur.
  • message : description lisible en anglais. Ne la parsez pas ; elle peut évoluer.
  • details : objet optionnel avec contexte spécifique au code. Son schéma varie par code. La majorité des codes n'exposent pas de details : l'information est alors portée par message.
  • request_id : identifiant CaptainDNS de la requête, utile pour ouvrir un ticket support. Présent uniquement si le header X-Request-Id a été propagé.
  • documentation_url : lien vers cette page.

Le status HTTP accompagne toujours le code. Un client robuste branche sur le couple (status, code) et traite code en priorité.

Codes d'authentification (401)

INVALID_API_KEY

Status : 401.

Cause : header Authorization manquant, préfixe absent, clé malformée, secret altéré, ou clé non trouvée côté CaptainDNS. Un HMAC mismatch et un "clé inconnue" retournent le même code pour ne pas distinguer l'un de l'autre côté attaquant.

Action : vérifiez que le header est bien Authorization: Bearer cdns_live_.... Un espace parasite, un saut de ligne ou une clé tronquée sont les causes les plus fréquentes.

{
  "code": "INVALID_API_KEY",
  "message": "Invalid API key.",
  "request_id": "req_a1b2c3d4",
  "documentation_url": "https://www.captaindns.com/en/docs/api/errors"
}

Pas de champ details ; l'information est uniquement dans message.

EXPIRED_API_KEY

Status : 401.

Cause : la clé a dépassé son expires_at.

{
  "code": "EXPIRED_API_KEY",
  "message": "This API key has expired.",
  "request_id": "req_a1b2c3d4",
  "documentation_url": "https://www.captaindns.com/en/docs/api/errors"
}

Pas de champ details.

Action : créez une nouvelle clé avec une date d'expiration plus lointaine ou sans expiration. Les clés sans expires_at sont valables tant qu'elles ne sont pas révoquées.

REVOKED_API_KEY

Status : 401.

Cause : la clé a été révoquée manuellement ou automatiquement (fin de grace period de rotation).

{
  "code": "REVOKED_API_KEY",
  "message": "This API key has been revoked.",
  "request_id": "req_a1b2c3d4",
  "documentation_url": "https://www.captaindns.com/en/docs/api/errors"
}

Pas de champ details.

Action : utilisez la clé active. Si vous n'en avez pas, créez-en une depuis le dashboard.

Codes d'autorisation (403)

INSUFFICIENT_SCOPE

Status : 403.

Cause : la clé n'a pas le scope requis par l'endpoint. Le scope manquant est concaténé dans message.

{
  "code": "INSUFFICIENT_SCOPE",
  "message": "This API key does not have the required scope: web:read",
  "request_id": "req_a1b2c3d4",
  "documentation_url": "https://www.captaindns.com/en/docs/api/errors"
}

Pas de champ details ; le scope requis est lu depuis message.

Action : créez une nouvelle clé avec le scope manquant ou utilisez une clé qui le porte déjà. Les scopes ne sont pas modifiables après la création.

IP_NOT_ALLOWED

Status : 403.

Cause : la clé a une IP allowlist et l'IP de la requête n'en fait pas partie. L'IP cliente est dérivée de r.RemoteAddr côté backend (jamais d'un X-Forwarded-For posé par le client), après réécriture éventuelle par la couche TrustedProxyRealIP si le hop immédiat est un proxy de confiance configuré côté CaptainDNS.

{
  "code": "IP_NOT_ALLOWED",
  "message": "Your IP is not in this key's allowlist.",
  "request_id": "req_a1b2c3d4",
  "documentation_url": "https://www.captaindns.com/en/docs/api/errors"
}

Pas de champ details ; l'IP détectée et la liste CIDR ne sont pas renvoyées au client (elles sont loguées côté serveur).

Action : ajoutez votre IP à l'allowlist de la clé, ou bien routez votre trafic via un egress autorisé (proxy, NAT).

QUOTA_EXCEEDED

Status : 403.

Cause : le quota mensuel de crédits est atteint et le plan n'autorise pas l'overage (plan Free, hard cap).

{
  "code": "QUOTA_EXCEEDED",
  "message": "Monthly credits quota exceeded for plan 'free'.",
  "details": {
    "tier": "free",
    "credits_used": 500,
    "credits_limit": 500
  },
  "request_id": "req_a1b2c3d4",
  "documentation_url": "https://www.captaindns.com/en/docs/api/errors"
}

Action : patientez jusqu'à la prochaine période ou passez au plan supérieur. Le dashboard CaptainDNS permet de changer de plan en un clic.

OVERAGE_BUDGET_EXCEEDED

Status : 403.

Cause : le profil a activé l'overage mais a atteint le plafond budgétaire mensuel configuré côté dashboard. Les appels suivants sont refusés jusqu'à la clôture de la période ou au relèvement du plafond.

{
  "code": "OVERAGE_BUDGET_EXCEEDED",
  "message": "Overage budget cap reached for plan 'starter'.",
  "details": {
    "tier": "starter",
    "credits_used": 68000,
    "credits_limit": 50000
  },
  "request_id": "req_a1b2c3d4",
  "documentation_url": "https://www.captaindns.com/en/docs/api/errors"
}

Action : relevez le plafond depuis Account > API usage, passez à un plan avec enveloppe plus large, ou attendez la prochaine période mensuelle.

Codes de requête (400)

INVALID_REQUEST

Status : 400.

Cause : un composant de la requête n'est pas exploitable. Deux cas sont émis par l'API publique :

  • Header Idempotency-Key malformé (caractères non-ASCII, espaces, longueur hors bornes, valeur vide après trim).
  • Body de requête illisible ou dépassant la limite d'idempotence (11 MiB).
{
  "code": "INVALID_REQUEST",
  "message": "Invalid Idempotency-Key header.",
  "request_id": "req_a1b2c3d4",
  "documentation_url": "https://www.captaindns.com/en/docs/api/errors"
}

Pas de champ details ; le motif précis est dans message.

Action : corrigez le header ou le body, puis retentez. Pour les erreurs de validation spécifiques à un endpoint (domaine invalide, selector inconnu, etc.), consultez la section Codes de validation (400).

Codes de conflit (409)

IDEMPOTENCY_CONFLICT

Status : 409.

Cause : une clé Idempotency-Key est réutilisée avec un body différent de la requête originale. La comparaison se fait sur le hash SHA-256 du body brut.

{
  "code": "IDEMPOTENCY_CONFLICT",
  "message": "Idempotency-Key reused with a different request body.",
  "request_id": "req_a1b2c3d4",
  "documentation_url": "https://www.captaindns.com/en/docs/api/errors"
}

Pas de champ details ; la clé conflictuelle est celle que vous venez d'envoyer.

Action : générez une nouvelle clé pour la nouvelle requête, ou corrigez le client qui modifie le body entre les retries.

Codes de rate limit (429)

RATE_LIMITED

Status : 429.

Cause : le token bucket per-clé est vide ou le rate limit par IP est dépassé. Deux variantes de message suivant l'étage atteint :

  • Bucket IP pré-auth : "Too many requests from this IP. Slow down.".
  • Bucket per-clé : "Rate limit exceeded for this API key.".
{
  "code": "RATE_LIMITED",
  "message": "Rate limit exceeded for this API key.",
  "request_id": "req_a1b2c3d4",
  "documentation_url": "https://www.captaindns.com/en/docs/api/errors"
}

Pas de champ details. Le header Retry-After accompagne toujours ce code, exprimé en secondes. Attendez au moins cette durée avant de réessayer. Voir le guide rate limiting pour les stratégies de backoff.

Codes serveur (5xx)

INTERNAL_ERROR

Status : 500 ou 503.

Cause : erreur inattendue côté CaptainDNS. Deux variantes :

  • 500 : erreur applicative transitoire (panique handler, dépendance DB indisponible, erreur de lookup de tier, etc.). Le message précise le sous-système.
  • 503 : l'API publique n'est pas configurée ou le group /public/v1/* est explicitement désactivé côté plateforme (pepper absent, flag PUBLICAPI_ENABLED=false). Il n'existe pas de code SERVICE_UNAVAILABLE distinct : l'indisponibilité partage le code INTERNAL_ERROR avec un status 503.
{
  "code": "INTERNAL_ERROR",
  "message": "public api is not configured",
  "request_id": "req_a1b2c3d4"
}

Pas de champ details.

Action : retenez le request_id et ouvrez un ticket support. Les 503 sont généralement liés à une maintenance planifiée ou un incident : consultez le canal de statut officiel avant de réessayer. Retentez après quelques minutes pour les 500 transitoires ; si le taux dépasse 1 % sur une fenêtre de cinq minutes, alertez l'équipe CaptainDNS.

Codes de validation (400)

L'API retourne aussi des 400 BAD_REQUEST pour les erreurs de validation spécifiques à chaque endpoint. Ces erreurs ne sont pas couvertes par l'enveloppe standardisée ci-dessus car leur structure varie selon l'endpoint.

Exemple pour un DNS resolve avec domaine invalide :

{
  "error": "invalid domain: must be a valid FQDN",
  "field": "domain"
}

Pour les endpoints qui retournent des erreurs de validation, consultez la référence OpenAPI qui documente les schémas exacts.

Table synthétique

StatusCodeDescriptionAction
400VariesErreur de validation endpointCorriger le body de la requête
400INVALID_REQUESTIdempotency-Key ou body illisibleCorriger le header ou le body
401INVALID_API_KEYClé absente, malformée ou inconnueVérifier le header Authorization
401EXPIRED_API_KEYClé expiréeCréer une nouvelle clé
401REVOKED_API_KEYClé révoquéeUtiliser une clé active
403INSUFFICIENT_SCOPEScope manquant sur la cléCréer une clé avec le bon scope
403IP_NOT_ALLOWEDIP hors allowlistAjouter l'IP ou passer par un egress autorisé
403QUOTA_EXCEEDEDQuota mensuel atteint (hard cap)Attendre ou upgrader le plan
403OVERAGE_BUDGET_EXCEEDEDPlafond d'overage atteintRelever le plafond ou upgrader
409IDEMPOTENCY_CONFLICTMême clé avec body différentGénérer une nouvelle clé
429RATE_LIMITEDRate limit IP ou per-clé dépasséAttendre Retry-After
500INTERNAL_ERRORErreur serveur transitoireRetenter + ouvrir ticket si persistant
503INTERNAL_ERRORAPI publique non configuréeVérifier le statut, réessayer

Bonnes pratiques de handling

  • Branchez sur le couple (status, code). Le status seul ne suffit pas : deux 403 peuvent venir de INSUFFICIENT_SCOPE ou de IP_NOT_ALLOWED, qui méritent des actions différentes.
  • Journalisez le request_id. C'est l'identifiant unique de la requête côté CaptainDNS et il est requis pour toute investigation côté support.
  • Ne retentez pas aveuglément. Les 4xx à l'exception de 429 indiquent un problème côté client : retenter sans changement n'aboutira pas.
  • Respectez Retry-After. Les 429 et 503 l'incluent systématiquement. Ne le court-circuitez pas.
  • Alertez sur les taux d'erreur. 1 % de 5xx sur une fenêtre de 5 minutes est un signal d'incident. Remontez-le dans votre observabilité.

Passez à la référence OpenAPI pour explorer les schémas endpoint par endpoint, ou revenez au quickstart si vous voulez relancer depuis le début.