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 dedetails: l'information est alors portée parmessage.request_id: identifiant CaptainDNS de la requête, utile pour ouvrir un ticket support. Présent uniquement si le headerX-Request-Ida é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-Keymalformé (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
messagepré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, flagPUBLICAPI_ENABLED=false). Il n'existe pas de codeSERVICE_UNAVAILABLEdistinct : l'indisponibilité partage le codeINTERNAL_ERRORavec 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
| Status | Code | Description | Action |
|---|---|---|---|
| 400 | Varies | Erreur de validation endpoint | Corriger le body de la requête |
| 400 | INVALID_REQUEST | Idempotency-Key ou body illisible | Corriger le header ou le body |
| 401 | INVALID_API_KEY | Clé absente, malformée ou inconnue | Vérifier le header Authorization |
| 401 | EXPIRED_API_KEY | Clé expirée | Créer une nouvelle clé |
| 401 | REVOKED_API_KEY | Clé révoquée | Utiliser une clé active |
| 403 | INSUFFICIENT_SCOPE | Scope manquant sur la clé | Créer une clé avec le bon scope |
| 403 | IP_NOT_ALLOWED | IP hors allowlist | Ajouter l'IP ou passer par un egress autorisé |
| 403 | QUOTA_EXCEEDED | Quota mensuel atteint (hard cap) | Attendre ou upgrader le plan |
| 403 | OVERAGE_BUDGET_EXCEEDED | Plafond d'overage atteint | Relever le plafond ou upgrader |
| 409 | IDEMPOTENCY_CONFLICT | Même clé avec body différent | Générer une nouvelle clé |
| 429 | RATE_LIMITED | Rate limit IP ou per-clé dépassé | Attendre Retry-After |
| 500 | INTERNAL_ERROR | Erreur serveur transitoire | Retenter + ouvrir ticket si persistant |
| 503 | INTERNAL_ERROR | API publique non configurée | Vé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_SCOPEou deIP_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.