Ir para o conteúdo principal

Entender e tratar os erros da API

A API pública CaptainDNS retorna todos os seus erros num envelope JSON padronizado. Esta página lista os códigos canónicos, o seu significado e a ação corretiva recomendada.

Envelope padrão

Todas as respostas de erro seguem este 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: string estável documentada aqui. Use-a para ramificar a sua lógica de tratamento de erros.
  • message: descrição legível em inglês. Não faça parse; ela pode evoluir.
  • details: objeto opcional com contexto específico do código. O seu esquema varia por código. A maioria dos códigos não expõe details: a informação é então carregada pelo message.
  • request_id: identificador CaptainDNS da requisição, útil para abrir um ticket de suporte. Presente somente se o header X-Request-Id foi propagado.
  • documentation_url: link para esta página.

O status HTTP acompanha sempre o código. Um cliente robusto ramifica no par (status, code) e trata code como prioridade.

Códigos de autenticação (401)

INVALID_API_KEY

Status: 401.

Causa: header Authorization em falta, prefixo em falta, chave malformada, segredo alterado ou chave não encontrada pelo CaptainDNS. Um HMAC mismatch e uma "chave desconhecida" retornam o mesmo código para não distinguir um do outro para um atacante.

Ação: verifique que o header é mesmo Authorization: Bearer cdns_live_.... Um espaço parasita, uma quebra de linha ou uma chave truncada são as causas mais frequentes.

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

Sem campo details; a informação está somente em message.

EXPIRED_API_KEY

Status: 401.

Causa: a chave ultrapassou o seu 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"
}

Sem campo details.

Ação: crie uma nova chave com uma data de expiração mais distante ou sem expiração. As chaves sem expires_at são válidas enquanto não forem revogadas.

REVOKED_API_KEY

Status: 401.

Causa: a chave foi revogada manualmente ou automaticamente (fim da grace period de rotação).

{
  "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"
}

Sem campo details.

Ação: use a chave ativa. Se não tiver nenhuma, crie uma no dashboard.

Códigos de autorização (403)

INSUFFICIENT_SCOPE

Status: 403.

Causa: a chave não tem o escopo necessário para o endpoint. O escopo em falta é concatenado em 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"
}

Sem campo details; o escopo necessário é lido a partir de message.

Ação: crie uma nova chave com o escopo em falta ou use uma chave que já o carregue. Os escopos não podem ser modificados após a criação.

IP_NOT_ALLOWED

Status: 403.

Causa: a chave tem uma allowlist de IP e o IP da requisição não faz parte dela. O IP do cliente é derivado de r.RemoteAddr no backend (nunca de um X-Forwarded-For enviado pelo cliente), após eventual reescrita pela camada TrustedProxyRealIP se o hop imediato for um proxy de confiança configurado do lado do 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"
}

Sem campo details; o IP detetado e a lista CIDR não são devolvidos ao cliente (são registados no servidor).

Ação: adicione o seu IP à allowlist da chave, ou encaminhe o seu tráfego por um egress autorizado (proxy, NAT).

QUOTA_EXCEEDED

Status: 403.

Causa: a cota mensal de créditos foi atingida e o plano não permite excedente (plano Free, hard cap).

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

Ação: aguarde o próximo período ou passe ao plano superior. O dashboard CaptainDNS permite trocar de plano num clique.

OVERAGE_BUDGET_EXCEEDED

Status: 403.

Causa: o perfil ativou o excedente mas atingiu o teto orçamental mensal configurado no dashboard. As chamadas seguintes são recusadas até o fim do período ou até que o teto seja elevado.

{
  "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"
}

Ação: eleve o teto orçamentário (um valor em euros, não um número de créditos) em Perfil > Subscrição > Excedente API, passe a um plano com envelope maior ou aguarde o próximo período mensal.

Códigos de requisição (400)

INVALID_REQUEST

Status: 400.

Causa: um componente da requisição não pode ser processado. Dois casos são emitidos pela API pública:

  • Header Idempotency-Key malformado (caracteres não ASCII, espaços, tamanho fora dos limites, valor vazio após trim).
  • Body da requisição ilegível ou excedendo o limite de idempotência (11 MiB).
{
  "code": "INVALID_REQUEST",
  "message": "Invalid Idempotency-Key header.",
  "request_id": "req_a1b2c3d4",
  "documentation_url": "https://www.captaindns.com/en/docs/api/errors"
}

Sem campo details; o motivo preciso está em message.

Ação: corrija o header ou o body e tente novamente. Para erros de validação específicos de um endpoint (domínio inválido, selector desconhecido, etc.), consulte a secção Códigos de validação (400).

Códigos de conflito (409)

IDEMPOTENCY_CONFLICT

Status: 409.

Causa: uma chave Idempotency-Key é reutilizada com um body diferente da requisição original. A comparação é feita no hash SHA-256 do body bruto.

{
  "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"
}

Sem campo details; a chave conflitante é aquela que acabou de enviar.

Ação: gere uma nova chave para a nova requisição, ou corrija o cliente que modifica o body entre os retries.

Códigos de rate limit (429)

RATE_LIMITED

Status: 429.

Causa: o token bucket por chave está vazio ou o limite por IP foi ultrapassado. Duas variantes de message conforme a camada atingida:

  • Bucket IP pré-auth: "Too many requests from this IP. Slow down.".
  • Bucket por chave: "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"
}

Sem campo details. O header Retry-After acompanha sempre este código, expresso em segundos. Aguarde pelo menos essa duração antes de tentar novamente. Veja o guia de rate limiting para as estratégias de backoff.

Códigos de servidor (5xx)

INTERNAL_ERROR

Status: 500 ou 503.

Causa: erro inesperado do lado do CaptainDNS. Duas variantes:

  • 500: erro aplicacional transitório (panic em handler, dependência de DB indisponível, erro de lookup de tier, etc.). A message detalha o subsistema.
  • 503: a API pública não está configurada ou o group /public/v1/* foi explicitamente desativado na plataforma (pepper em falta, flag PUBLICAPI_ENABLED=false). Não existe código SERVICE_UNAVAILABLE distinto: a indisponibilidade partilha o código INTERNAL_ERROR com status 503.
{
  "code": "INTERNAL_ERROR",
  "message": "public api is not configured",
  "request_id": "req_a1b2c3d4"
}

Sem campo details.

Ação: guarde o request_id e abra um ticket de suporte. Os 503 geralmente estão ligados a uma manutenção planeada ou a um incidente: consulte o canal de status oficial antes de tentar novamente. Tente novamente após alguns minutos para os 500 transitórios; se a taxa ultrapassar 1 % numa janela de cinco minutos, alerte a equipa CaptainDNS.

Códigos de validação (400)

A API também retorna 400 BAD_REQUEST para erros de validação específicos de cada endpoint. Esses erros não são cobertos pelo envelope padronizado acima pois a sua estrutura varia por endpoint.

Exemplo para um DNS resolve com domínio inválido:

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

Para os endpoints que retornam erros de validação, consulte a referência OpenAPI que documenta os esquemas exatos.

Tabela sintética

StatusCodeDescriçãoAção
400VariávelErro de validação de endpointCorrigir o body da requisição
400INVALID_REQUESTIdempotency-Key ou body ilegívelCorrigir o header ou o body
401INVALID_API_KEYChave em falta, malformada ou desconhecidaVerificar o header Authorization
401EXPIRED_API_KEYChave expiradaCriar nova chave
401REVOKED_API_KEYChave revogadaUsar chave ativa
403INSUFFICIENT_SCOPEEscopo em falta na chaveCriar chave com o escopo correto
403IP_NOT_ALLOWEDIP fora da allowlistAdicionar o IP ou passar por um egress autorizado
403QUOTA_EXCEEDEDCota mensal atingida (hard cap)Aguardar ou fazer upgrade de plano
403OVERAGE_BUDGET_EXCEEDEDTeto de excedente atingidoElevar o teto ou fazer upgrade
409IDEMPOTENCY_CONFLICTMesma chave com body diferenteGerar nova chave
429RATE_LIMITEDRate limit IP ou por chave ultrapassadoAguardar Retry-After
500INTERNAL_ERRORErro de servidor transitórioTentar novamente e abrir ticket se persistente
503INTERNAL_ERRORAPI pública não configuradaVerificar o status, tentar novamente

Boas práticas de tratamento

  • Ramifique no par (status, code). O status sozinho não basta: dois 403 podem vir de INSUFFICIENT_SCOPE ou de IP_NOT_ALLOWED, que merecem ações diferentes.
  • Registe o request_id. É o identificador único da requisição do lado do CaptainDNS e é necessário para qualquer investigação no suporte.
  • Não tente novamente cegamente. Os 4xx exceto 429 indicam um problema no cliente: tentar sem mudar nada não vai funcionar.
  • Respeite Retry-After. Os 429 e 503 incluem-no sempre. Não o ignore.
  • Alerte sobre taxas de erro. 1 % de 5xx numa janela de 5 minutos é um sinal de incidente. Eleve isso na sua observabilidade.

Siga para a referência OpenAPI para explorar os esquemas endpoint por endpoint, ou volte ao quickstart se quiser recomeçar do início.