Capire e gestire gli errori della API
La API pubblica CaptainDNS restituisce tutti gli errori in un involucro JSON standardizzato. Questa pagina elenca i codici canonici, il loro significato e l'azione correttiva raccomandata.
Involucro standard
Ogni risposta d'errore segue questo formato:
{
"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: stringa stabile documentata qui. Usala per diramare la logica di gestione degli errori.message: descrizione leggibile in inglese. Non parsarla; può evolvere.details: oggetto opzionale con contesto specifico al codice. Il suo schema varia in base al codice. La maggior parte dei codici non esponedetails: l'informazione è allora trasportata damessage.request_id: identificatore CaptainDNS della richiesta, utile per aprire un ticket al supporto. Presente solo se l'headerX-Request-Idè stato propagato.documentation_url: link a questa pagina.
Lo status HTTP accompagna sempre il code. Un client robusto dirama sulla coppia (status, code) e tratta code in via prioritaria.
Codici di autenticazione (401)
INVALID_API_KEY
Status: 401.
Causa: header Authorization mancante, prefisso assente, chiave malformata, segreto alterato, o chiave non trovata lato CaptainDNS. Un HMAC mismatch e una chiave sconosciuta restituiscono lo stesso codice per non distinguerli lato attaccante.
Azione: verifica che l'header sia Authorization: Bearer cdns_live_.... Uno spazio parassita, un ritorno a capo o una chiave troncata sono le cause più frequenti.
{
"code": "INVALID_API_KEY",
"message": "Invalid API key.",
"request_id": "req_a1b2c3d4",
"documentation_url": "https://www.captaindns.com/en/docs/api/errors"
}
Nessun campo details; l'informazione è solo in message.
EXPIRED_API_KEY
Status: 401.
Causa: la chiave ha superato il suo 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"
}
Nessun campo details.
Azione: crea una nuova chiave con una data di scadenza più lontana o senza scadenza. Le chiavi senza expires_at restano valide finché non vengono revocate.
REVOKED_API_KEY
Status: 401.
Causa: la chiave è stata revocata manualmente o automaticamente (fine della grace period di rotazione).
{
"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"
}
Nessun campo details.
Azione: usa la chiave attiva. Se non ne hai, creane una dalla dashboard.
Codici di autorizzazione (403)
INSUFFICIENT_SCOPE
Status: 403.
Causa: la chiave non ha lo scope richiesto dall'endpoint. Lo scope mancante è concatenato in 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"
}
Nessun campo details; lo scope richiesto si legge da message.
Azione: crea una nuova chiave con lo scope mancante o usa una chiave che lo porta già. Gli scope non sono modificabili dopo la creazione.
IP_NOT_ALLOWED
Status: 403.
Causa: la chiave ha una IP allowlist e l'IP della richiesta non vi compare. L'IP del client è derivato da r.RemoteAddr lato backend (mai da un X-Forwarded-For impostato dal client), dopo eventuale riscrittura da parte del layer TrustedProxyRealIP se il hop immediato è un proxy di fiducia configurato lato 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"
}
Nessun campo details; l'IP rilevato e la lista CIDR non vengono restituiti al client (sono loggati lato server).
Azione: aggiungi il tuo IP all'allowlist della chiave, oppure instrada il tuo traffico tramite un egress autorizzato (proxy, NAT).
QUOTA_EXCEEDED
Status: 403.
Causa: la quota mensile di crediti è raggiunta e il piano non ammette overage (piano 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"
}
Azione: attendi il prossimo periodo o passa a un piano superiore. La dashboard CaptainDNS permette di cambiare piano con un clic.
OVERAGE_BUDGET_EXCEEDED
Status: 403.
Causa: il profilo ha attivato l'overage ma ha raggiunto il tetto di budget mensile configurato lato dashboard. Le chiamate successive vengono rifiutate fino alla chiusura del periodo o al rialzo del tetto.
{
"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"
}
Azione: rialza il tetto da Account > API usage, passa a un piano con quota più ampia, oppure attendi il prossimo periodo mensile.
Codici di richiesta (400)
INVALID_REQUEST
Status: 400.
Causa: un componente della richiesta non è utilizzabile. Due casi vengono emessi dalla API pubblica:
- Header
Idempotency-Keymalformato (caratteri non-ASCII, spazi, lunghezza fuori limiti, valore vuoto dopo trim). - Body della richiesta illeggibile o che supera il limite di idempotenza (11 MiB).
{
"code": "INVALID_REQUEST",
"message": "Invalid Idempotency-Key header.",
"request_id": "req_a1b2c3d4",
"documentation_url": "https://www.captaindns.com/en/docs/api/errors"
}
Nessun campo details; il motivo preciso è in message.
Azione: correggi l'header o il body, poi riprova. Per gli errori di validazione specifici a un endpoint (dominio invalido, selector sconosciuto, ecc.), consulta la sezione Codici di validazione (400).
Codici di conflitto (409)
IDEMPOTENCY_CONFLICT
Status: 409.
Causa: una chiave Idempotency-Key viene riutilizzata con un body diverso dalla richiesta originale. Il confronto si fa sull'hash SHA-256 del body grezzo.
{
"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"
}
Nessun campo details; la chiave in conflitto è quella appena inviata.
Azione: genera una nuova chiave per la nuova richiesta, o correggi il client che modifica il body tra i retry.
Codici di rate limit (429)
RATE_LIMITED
Status: 429.
Causa: il token bucket per chiave è vuoto o il rate limit per IP è stato superato. Due varianti di message a seconda del livello raggiunto:
- Bucket IP pre-auth:
"Too many requests from this IP. Slow down.". - Bucket per chiave:
"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"
}
Nessun campo details. L'header Retry-After accompagna sempre questo codice, espresso in secondi. Attendi almeno questa durata prima di riprovare. Vedi la guida al rate limiting per le strategie di backoff.
Codici server (5xx)
INTERNAL_ERROR
Status: 500 o 503.
Causa: errore inaspettato lato CaptainDNS. Due varianti:
- 500: errore applicativo transitorio (panic dell'handler, dipendenza DB non disponibile, errore di lookup del tier, ecc.). Il
messageprecisa il sottosistema. - 503: la API pubblica non è configurata o il gruppo
/public/v1/*è esplicitamente disabilitato lato piattaforma (pepper assente, flagPUBLICAPI_ENABLED=false). Non esiste un codiceSERVICE_UNAVAILABLEdistinto: l'indisponibilità condivide il codiceINTERNAL_ERRORcon uno status 503.
{
"code": "INTERNAL_ERROR",
"message": "public api is not configured",
"request_id": "req_a1b2c3d4"
}
Nessun campo details.
Azione: conserva il request_id e apri un ticket di supporto. I 503 sono generalmente legati a una manutenzione pianificata o a un incident: consulta il canale di stato ufficiale prima di riprovare. Riprova dopo qualche minuto per i 500 transitori; se il tasso supera l'1 % su una finestra di cinque minuti, allerta il team CaptainDNS.
Codici di validazione (400)
L'API restituisce anche 400 BAD_REQUEST per errori di validazione specifici a ogni endpoint. Questi errori non seguono l'involucro standardizzato qui sopra perché la loro struttura varia in base all'endpoint.
Esempio per un DNS resolve con dominio invalido:
{
"error": "invalid domain: must be a valid FQDN",
"field": "domain"
}
Per gli endpoint che restituiscono errori di validazione, consulta il riferimento OpenAPI che documenta gli schemi esatti.
Tabella sintetica
| Status | Code | Descrizione | Azione |
|---|---|---|---|
| 400 | Variabile | Errore di validazione endpoint | Correggere il body della richiesta |
| 400 | INVALID_REQUEST | Idempotency-Key o body illeggibile | Correggere l'header o il body |
| 401 | INVALID_API_KEY | Chiave assente, malformata o sconosciuta | Verificare l'header Authorization |
| 401 | EXPIRED_API_KEY | Chiave scaduta | Creare una nuova chiave |
| 401 | REVOKED_API_KEY | Chiave revocata | Usare una chiave attiva |
| 403 | INSUFFICIENT_SCOPE | Scope mancante sulla chiave | Creare una chiave con lo scope corretto |
| 403 | IP_NOT_ALLOWED | IP fuori allowlist | Aggiungere l'IP o passare da un egress autorizzato |
| 403 | QUOTA_EXCEEDED | Quota mensile raggiunta (hard cap) | Attendere o fare upgrade |
| 403 | OVERAGE_BUDGET_EXCEEDED | Tetto di overage raggiunto | Rialzare il tetto o fare upgrade |
| 409 | IDEMPOTENCY_CONFLICT | Stessa chiave con body diverso | Generare una nuova chiave |
| 429 | RATE_LIMITED | Rate limit IP o per chiave superato | Attendere Retry-After |
| 500 | INTERNAL_ERROR | Errore server transitorio | Riprovare e aprire un ticket se persiste |
| 503 | INTERNAL_ERROR | API pubblica non configurata | Verificare lo stato, riprovare |
Buone pratiche di gestione
- Dirama sulla coppia (status, code). Lo status da solo non basta: due 403 possono venire da
INSUFFICIENT_SCOPEo daIP_NOT_ALLOWED, che meritano azioni diverse. - Registra il
request_id. È l'identificatore univoco della richiesta lato CaptainDNS ed è richiesto per ogni investigazione lato supporto. - Non riprovare ciecamente. I 4xx salvo 429 indicano un problema lato client: riprovare senza modifiche non risolverà.
- Rispetta
Retry-After. I 429 e i 503 lo includono sistematicamente. Non bypassarlo. - Allerta sui tassi d'errore. L'1 % di 5xx su una finestra di 5 minuti è un segnale di incident. Portalo nella tua osservabilità.
Passa al riferimento OpenAPI per esplorare gli schemi endpoint per endpoint, o torna al quickstart se vuoi ripartire dall'inizio.