Ao chamar uma API, 401 Unauthorized, 403 Forbidden e 429 Too Many Requests são os três tipos de erro mais comuns.

Todos pertencem aos erros de cliente 4xx, mas os métodos de resolução são completamente diferentes:

  • 401: falha de autenticação — o servidor não consegue confirmar “quem você é”
  • 403: acesso recusado — o servidor entende a solicitação, mas não permite sua execução
  • 429: solicitações em excesso — a velocidade de chamada ou o uso excede o limite

Se você não distinguir os tipos de erro e tentar novamente diretamente, isso não apenas não resolverá o problema, como também poderá criar uma tempestade de tentativas, podendo até levar a restrições adicionais na API.

Este artigo explicará, por meio de uma lista de verificação de diagnóstico, comandos curl e código Node.js, como lidar com esses três tipos de erro.

Entenda 401, 403 e 429 em uma tabela

Código de status Significado principal Causas comuns Deve tentar novamente imediatamente?
401 Unauthorized Ausência de credenciais de autenticação válidas API Key incorreta, Token expirado, formato incorreto do cabeçalho de autenticação Não deve tentar novamente da mesma forma
403 Forbidden O servidor recusa processar a solicitação Permissões insuficientes, restrições de IP ou região, políticas de recurso, bloqueio de WAF Normalmente não
429 Too Many Requests As solicitações excedem os limites de taxa ou cota Concorrência alta demais, limite de QPS excedido, cota esgotada Tentar novamente após aguardar

É importante observar que, embora o nome em inglês de 401 seja Unauthorized, em diagnósticos práticos é mais adequado entendê-lo como “não autenticado”; o 403 é que normalmente está relacionado à autorização ou às políticas de acesso.

I. 401 Unauthorized: verifique primeiro as credenciais de autenticação

HTTP 401: credenciais de API ausentes, inválidas ou expiradas

HTTP 401 Unauthorized indica que a solicitação não possui as credenciais de autenticação válidas necessárias para o recurso de destino. Uma resposta 401 padrão normalmente informa ao cliente, por meio do cabeçalho de resposta WWW-Authenticate, o esquema de autenticação que o servidor espera usar.

Causas comuns

  1. O cabeçalho de solicitação Authorization não foi enviado
  2. A API Key ou o Access Token foi preenchido incorretamente
  3. O Token expirou ou foi revogado
  4. O esquema de autenticação está incorreto, por exemplo, ausência de Bearer
  5. As variáveis de ambiente não foram carregadas corretamente
  6. Foi usada uma chave do ambiente incorreto
  7. O cabeçalho de autenticação foi perdido quando a solicitação foi encaminhada por proxy ou gateway
  8. A diferença de horário entre o cliente e o servidor é grande demais, causando a invalidação da assinatura

Erros comuns

A API exige um Bearer Token:

Authorization: Bearer YOUR_ACCESS_TOKEN

Mas o cliente o enviou como:

Authorization: YOUR_ACCESS_TOKEN

Ou o escreveu incorretamente como:

Authentication: Bearer YOUR_ACCESS_TOKEN

Ambas as situações podem retornar 401.

Diagnóstico com curl

Não comece visualizando apenas o corpo da resposta. Adicione -i para verificar simultaneamente o código de status e os cabeçalhos de resposta:

curl -i "https://api.example.com/v1/profile" \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Accept: application/json"

Verifique principalmente:

  • Se Authorization foi realmente enviado
  • Se o esquema de autenticação está correto
  • Se há espaços ou quebras de linha antes ou depois do Token
  • O que WWW-Authenticate retorna
  • Se há informações de erro como invalid_token, expired_token etc. no corpo da resposta

Se precisar visualizar um processo de solicitação mais detalhado, você pode usar:

curl -v "https://api.example.com/v1/profile" \
  -H "Authorization: Bearer $API_TOKEN"

Observação: os logs de depuração podem conter Tokens. Não envie logs completos diretamente para Issues públicos, conversas em grupo ou tickets.

O 401 deve ser tentado novamente?

Não tente repetidamente com as mesmas credenciais inválidas.

Fluxo recomendado:

  1. Verifique se a solicitação contém informações de autenticação
  2. Verifique se o Token expirou, foi revogado ou foi copiado incorretamente
  3. Se houver suporte a Refresh Token, atualize uma vez o token de acesso
  4. Tente novamente uma vez usando o novo Token
  5. Se ainda retornar 401, pare de tentar novamente e registre o erro

Se você usa uma API Key fixa, deve verificar o status da chave ou substituí-la por uma chave válida, em vez de tentar novamente em um loop.

II. 403 Forbidden: a autenticação pode ter sido bem-sucedida, mas a solicitação ainda é recusada

HTTP 403: a solicitação é recusada devido a permissões ou políticas de acesso

403 Forbidden indica que o servidor já entendeu a solicitação, mas se recusa a processá-la. Para erros típicos de permissão, mesmo uma nova autenticação não resolverá o problema automaticamente; se a solicitação ou a configuração de permissões não for alterada, solicitações repetidas normalmente continuarão falhando.

Causas comuns

  • A conta ou chave atual não possui as permissões necessárias
  • O Scope do Token é insuficiente
  • Foi acessado um recurso que não pertence ao projeto ou locatário atual
  • O IP de origem não está na lista de permissões
  • A região de origem da solicitação está sujeita a restrições
  • WAF, firewall ou sistema antiabuso bloqueou a solicitação
  • A conta, o projeto ou o recurso foi desativado
  • A API está disponível apenas para planos ou funções específicos
  • A assinatura é válida, mas o escopo de recurso na assinatura não corresponde
  • Em cenários de navegador, há restrições de política de CSRF, Origin ou Referer

Diferença entre 401 e 403

Você pode fazer uma distinção rápida com duas frases:

  • 401: o servidor não consegue confirmar quem você é
  • 403: o servidor conhece ou entende sua identidade e solicitação, mas não permite que você faça isso

Por exemplo, um membro comum usa um Token válido para chamar a API de “excluir organização”:

curl -i -X DELETE \
  "https://api.example.com/v1/organizations/org_123" \
  -H "Authorization: Bearer $API_TOKEN"

Se o Token for válido, mas a conta não for administradora da organização, o servidor poderá retornar:

HTTP/1.1 403 Forbidden
Content-Type: application/json

{
  "error": "insufficient_permissions",
  "message": "Administrator role is required."
}

Ordem de diagnóstico do 403

1. Leia o corpo da resposta

Priorize a busca por códigos de erro, funções ou permissões ausentes, Scopes necessários, o ID do recurso recusado e avisos sobre IP, região ou políticas de segurança.

2. Verifique o Scope do Token

Por exemplo, ler dados pode exigir apenas data:read, mas criar dados pode exigir data:write. Um Token válido não significa que ele possui todas as permissões.

3. Verifique a propriedade do recurso

Confirme se o ID do projeto, ID da organização, ID do locatário, ID do usuário, região ou ambiente pertence à mesma conta ou ao mesmo escopo de autorização das credenciais atuais.

4. Verifique as políticas de rede e segurança

Se o código funciona normalmente localmente, mas retorna 403 após a implantação, deve-se verificar principalmente o IP de saída do servidor, a lista de permissões de IP, a configuração de proxy, CDN, WAF, a região de origem da solicitação e os cabeçalhos de solicitação relacionados.

Não tire conclusões apenas com base no código de status

As implementações de API no mundo real não são necessariamente completamente consistentes. Algumas plataformas podem retornar 403 ao acionar a limitação de taxa, em vez de 429. Por exemplo, a API REST do GitHub pode retornar 403 ou 429 ao exceder o limite de taxa e indicar o status da limitação por meio de cabeçalhos de resposta como x-ratelimit-remaining, x-ratelimit-reset ou retry-after.

Portanto, ao encontrar 403, também é necessário verificar de forma abrangente:

  • O código de erro de negócio no corpo da resposta
  • Retry-After
  • X-RateLimit-Remaining
  • X-RateLimit-Reset
  • A documentação oficial da plataforma

O 403 deve ser repetido?

Para 403 causados por permissões insuficientes, restrições de IP ou políticas de recursos, repetir exatamente da mesma forma não faz sentido.

A abordagem correta é modificar as permissões ou o Token Scope, usar a conta ou o projeto correto, ajustar a lista de permissões e as políticas de segurança, corrigir o ID do recurso e confirmar se o serviço ou plano oferece suporte a essa interface. Somente quando a plataforma declarar claramente que esse 403 na verdade representa uma limitação de taxa temporária é que se deve aguardar e tentar novamente de acordo com as regras de limitação de taxa.

III. 429 Too Many Requests: primeiro reduza a velocidade, depois tente novamente

HTTP 429: as solicitações de API estão sujeitas à limitação de taxa; é necessário aguardar e repetir com recuo

429 Too Many Requests indica que o cliente enviou solicitações demais em um período, ou seja, acionou a limitação de taxa. O servidor pode informar ao cliente, por meio de Retry-After, quanto tempo deve aguardar antes de tentar novamente.

Causas comuns

  • Excesso de solicitações em um curto período
  • Número de tarefas simultâneas muito alto
  • Vários serviços compartilham a mesma API Key
  • O código de repetição não possui um mecanismo de espera
  • Tarefas agendadas são executadas de forma concentrada no mesmo momento
  • As solicitações não possuem cache e obtêm repetidamente os mesmos dados
  • A cota de uma única conta, IP ou projeto foi esgotada
  • Limites de uso ou saldo do plano

Primeiro, verifique os cabeçalhos de resposta

curl -i "https://api.example.com/v1/resources" \
  -H "Authorization: Bearer $API_TOKEN"

Preste atenção principalmente a:

Retry-After: 30
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1710000000

Os nomes dos cabeçalhos de resposta podem ser diferentes entre plataformas; a documentação da plataforma deve prevalecer.

Tratamento correto de Retry-After

Os dois formatos comuns de Retry-After são número de segundos ou data HTTP:

Retry-After: 30
Retry-After: Wed, 21 Oct 2026 07:28:00 GMT

É melhor que o cliente seja compatível com ambos os formatos.

Por que não se pode tentar novamente imediatamente?

Se uma solicitação for repetida imediatamente após sofrer limitação de taxa, a nova solicitação continuará sendo limitada; vários clientes também podem tentar novamente ao mesmo tempo, formando um “efeito manada”. Um método mais seguro é:

  1. Priorizar o cumprimento de Retry-After
  2. Quando não houver um tempo de espera explícito, usar recuo exponencial
  3. Adicionar jitter aleatório ao tempo de espera
  4. Definir o número máximo de tentativas
  5. Retornar um erro claro após atingir o limite

Node.js: tratamento seguro de 429

O exemplo abaixo usa o fetch integrado do Node.js, prioriza a análise de Retry-After; se o servidor não fornecer esse cabeçalho de resposta, usa recuo exponencial com jitter aleatório.

const sleep = (ms) =>
  new Promise((resolve) => setTimeout(resolve, ms));

function parseRetryAfter(value) {
  if (!value) return null;

  const seconds = Number(value);
  if (Number.isFinite(seconds) && seconds >= 0) {
    return seconds * 1000;
  }

  const timestamp = Date.parse(value);
  if (!Number.isNaN(timestamp)) {
    return Math.max(0, timestamp - Date.now());
  }

  return null;
}

async function fetchWithRetry(url, options = {}, config = {}) {
  const {
    maxRetries = 3,
    baseDelayMs = 1000,
    maxDelayMs = 30_000,
  } = config;

  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    const response = await fetch(url, options);

    if (response.status !== 429) {
      return response;
    }

    if (attempt === maxRetries) {
      throw new Error(
        `请求持续受到限流,已达到最大重试次数:${maxRetries}`
      );
    }

    const retryAfterMs = parseRetryAfter(
      response.headers.get("retry-after")
    );

    const backoffCap = Math.min(
      maxDelayMs,
      baseDelayMs * 2 ** attempt
    );

    const jitterMs = Math.floor(Math.random() * backoffCap);
    const delayMs = retryAfterMs ?? jitterMs;

    console.warn(
      `收到 429,第 ${attempt + 1} 次等待 ${delayMs}ms 后重试`
    );

    await sleep(delayMs);
  }

  throw new Error("请求失败");
}

Exemplo de chamada:

const response = await fetchWithRetry(
  "https://api.example.com/v1/resources",
  {
    headers: {
      Authorization: `Bearer ${process.env.API_TOKEN}`,
      Accept: "application/json",
    },
  },
  {
    maxRetries: 3,
    baseDelayMs: 1000,
    maxDelayMs: 30_000,
  }
);

if (!response.ok) {
  const errorBody = await response.text();
  throw new Error(`API 请求失败:${response.status} ${errorBody}`);
}

const data = await response.json();
console.log(data);

Ao repetir solicitações POST, também é necessário considerar a idempotência

Nem todas as solicitações são adequadas para repetição automática. Solicitações de leitura como GET e HEAD geralmente podem ser repetidas com mais segurança. Para solicitações POST, como criar pedidos, realizar cobranças ou enviar mensagens, o cliente pode já ter enviado com sucesso, mas não recebeu a resposta devido a uma interrupção de rede. Nesse caso, repetir diretamente pode causar operações duplicadas.

Se a plataforma oferecer suporte, deve-se definir uma chave de idempotência para operações de escrita:

curl -i -X POST "https://api.example.com/v1/orders" \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-20260331-0001" \
  -d '{
    "product_id": "prod_123",
    "quantity": 1
  }'

O nome do cabeçalho de solicitação e o período de validade da chave de idempotência são determinados pela plataforma específica; consulte a documentação da API correspondente.

Lista de verificação para solução de problemas em produção

Ao receber 401

  • A solicitação contém um cabeçalho de autenticação
  • O esquema de autenticação, como Bearer, está correto
  • O Token expirou, foi revogado ou foi copiado incorretamente
  • A chave do ambiente correto está sendo usada
  • O proxy ou gateway removeu o cabeçalho de autenticação
  • A hora do cliente está precisa
  • É possível atualizar um Token uma vez com segurança

Ao receber 403

  • O Token possui o Scope necessário
  • A conta atual possui a função necessária
  • O recurso pertence ao projeto ou locatário atual
  • O IP de saída está na lista de permissões
  • Está sujeito a restrições de região, WAF ou políticas de segurança
  • O corpo da resposta indica claramente permissão ou limitação de taxa
  • Existem informações de limitação de taxa nos cabeçalhos da resposta

Recebeu 429

  • Foi lido o Retry-After
  • Foram verificados os cabeçalhos de resposta relacionados à limitação de taxa
  • São usados recuo exponencial e jitter aleatório
  • Foi definido o número máximo de tentativas
  • A concorrência é limitada
  • Os resultados de consultas repetidas são armazenados em cache
  • É possível combinar ou enviar solicitações em lote
  • Foi atingida a cota do plano ou o limite de uso da conta

Quais informações de diagnóstico são recomendadas para registrar?

Recomenda-se registrar nos logs o horário da solicitação, o nome do host e o caminho da API, o método HTTP, o código de status, o código de erro de negócio, o request-id ou trace-id, o Retry-After, a cota restante de limitação de taxa e o horário de redefinição, o número de tentativas e o tempo de espera real.

Mas não registre a API Key completa, o Access Token completo, o Refresh Token, a senha do usuário ou informações pessoais sensíveis no corpo da solicitação.

A regra mnemônica final

401: primeiro corrija as credenciais, não tente novamente com o Token antigo.
403: primeiro corrija as permissões ou políticas, não repita a solicitação exatamente como está.
429: respeite o tempo de espera, recue, reduza a velocidade e limite a concorrência.

O código de status é apenas o ponto de entrada para a solução de problemas, não é toda a resposta. Uma forma confiável de tratamento é combinar simultaneamente o código de status HTTP, o código de erro de negócio no corpo da resposta, os cabeçalhos de resposta relevantes, a documentação da plataforma, o ID da solicitação e os logs do servidor, transformando “erro de interface” em um mecanismo de engenharia observável, recuperável e sustentável.

Referências