Uma resposta 500 para input inválido é sempre um bug: o servidor deveria retornar 4xx, não travar. Um 403 ausente é um bypass de autorização. Se um usuário comum acessa um endpoint de admin e recebe 200 em vez de 403, o controle de acesso não está funcionando.

Como os status codes são organizados

Os status codes HTTP são números de três dígitos organizados em cinco classes:

FaixaClasseSignificado
1xxInformativoRequisição recebida, processamento em andamento
2xxSucessoRequisição concluída com êxito
3xxRedirecionamentoO cliente precisa tomar outra ação (geralmente seguir o redirect)
4xxErro do clienteA requisição tem um problema: o cliente enviou algo errado
5xxErro do servidorA requisição era válida: o servidor falhou em processá-la

O primeiro dígito diz a categoria. 4xx = sua requisição estava errada. 5xx = o servidor quebrou.

2xx: códigos de sucesso

200 OK

O código de sucesso mais comum. A requisição funcionou e há conteúdo na resposta.

Usado para:

  • Requisições GET que retornam dados
  • Requisições POST que não criam um novo recurso (como uma busca)
  • Atualizações via PUT/PATCH

O que verificar nos testes:

  • O corpo da resposta contém os dados esperados
  • A resposta está no formato correto (JSON, XML)
  • Os campos obrigatórios estão presentes

201 Created

Um recurso foi criado com sucesso. Deve ser retornado para requisições POST que criam novos itens.

O que verificar:

  • A resposta inclui o recurso criado com seu novo ID
  • O header Location frequentemente aponta para a URL do novo recurso
  • POST /users → 201 com { id: 123, email: "...", ... }

Bug comum a capturar: a API retorna 200 em vez de 201 para endpoints de criação. Tecnicamente funciona, mas está semanticamente errado e pode confundir os consumidores da API.

204 No Content

Sucesso, mas nada a retornar. Usado para requisições DELETE e algumas respostas de PUT/PATCH.

O que verificar:

  • O corpo da resposta está vazio (algumas APIs retornam corpo incorretamente com 204)
  • O recurso foi de fato deletado (faça um GET para confirmar)

206 Partial Content

Retornado quando apenas parte de um recurso é enviada (downloads em partes, streaming de vídeo). Relevante principalmente para testar downloads de arquivo e streaming de mídia.

3xx: códigos de redirecionamento

301 Moved Permanently

O recurso foi movido permanentemente para uma nova URL. Buscadores atualizam seus índices para 301.

Relevância para testes: verifique se URLs antigas redirecionam corretamente, se redirects de HTTP para HTTPS são 301 (não 302), e se os destinos dos redirects carregam corretamente.

302 Found (Redirect Temporário)

O recurso está temporariamente em outra URL. Usado para redirects de login ("vá aqui agora, a URL original ainda é válida").

304 Not Modified

O cliente tem uma versão em cache e ela ainda é atual: nenhum conteúdo é enviado, use o cache. Você vai ver isso na aba Network do navegador para assets estáticos.

Relevância para testes: se você está testando comportamento de cache, 304 significa que o cache está funcionando. Se você está vendo 304 para dados que deveriam ter mudado, há um bug de cache.

4xx: códigos de erro do cliente

Esses significam que a sua requisição tinha um problema: dados ruins, auth ausente, URL errada.

400 Bad Request

O servidor não conseguiu entender a requisição. Geralmente significa sintaxe malformada, JSON inválido ou erro de validação.

Quando você deve ver 400:

  • JSON inválido no corpo da requisição
  • Header obrigatório ausente
  • URL malformada

O que verificar nos testes:

  • Retorna mensagem de erro útil explicando o problema
  • Não revela detalhes internos (stack traces)
  • Retorna 400, não 500 (500 para input inválido é um bug do servidor)

401 Unauthorized

A requisição não tem credenciais de autenticação válidas. "Você não está logado" ou "seu token expirou."

Diferença do 403: 401 = não autenticado (quem é você?). 403 = autenticado mas sem permissão (sei quem você é, mas você não pode fazer isso).

O que testar:

  • Requisição sem token algum → 401
  • Requisição com token expirado → 401
  • Requisição com token inválido ou forjado → 401
  • A resposta de erro não revela informações sobre tokens válidos

403 Forbidden

Autenticado, mas sem permissão. "Você está logado, mas não tem autorização para isso."

O que testar:

  • Usuário comum acessando endpoint de admin → 403
  • Usuário acessando dados privados de outro usuário → 403
  • A resposta não expõe nenhum dado que o usuário não deveria ver

Relevância para segurança: um check de 403 ausente significa que acesso não autorizado funciona, um bug de segurança real.

404 Not Found

O recurso solicitado não existe naquela URL.

O que testar:

  • Solicitar um recurso deletado → 404
  • Solicitar com um ID que nunca foi criado → 404
  • Para recursos sensíveis, não deve revelar se o recurso existe (contas de usuário: retornar 404 "user not found" vs 403 "forbidden" pode revelar a existência da conta)
  • É 404 ou 410? (410 = deletado permanentemente, algumas APIs fazem essa distinção)

405 Method Not Allowed

Você usou o método HTTP errado. GET em um endpoint que só aceita POST.

Relevância para testes: tente métodos errados intencionalmente. DELETE /users quando só deveria aceitar GET. Deve retornar 405, não 500 ou falha silenciosa.

409 Conflict

A requisição conflita com o estado atual do recurso.

Usos comuns:

  • Criar um usuário com e-mail que já existe
  • Editar um recurso que outra pessoa bloqueou
  • Conflito de versão (optimistic locking)

O que testar:

  • Criação duplicada → 409 (não 200 ou 500)
  • A resposta explica o conflito com clareza

422 Unprocessable Entity

O JSON da requisição é sintaticamente válido, mas semanticamente errado: a validação falhou.

Exemplo: corpo JSON válido, mas age: -5 viola a regra de que a idade deve ser positiva.

400 vs 422:

  • 400 = não consegue nem interpretar a requisição (JSON ruim, Content-Type errado)
  • 422 = interpretou, mas os valores falham na validação

Muitas APIs usam 400 para os dois casos. O que importa é consistência: escolha um e use corretamente em toda a API.

O que testar:

  • Cada campo obrigatório ausente → 422 com o nome do campo específico no erro
  • Valores fora do range válido → 422
  • Violações de regras de negócio → 422

429 Too Many Requests

Rate limiting: você enviou requisições demais em tempo curto demais.

O que testar:

  • Confirmar que headers de rate limit são retornados (X-RateLimit-Limit, X-RateLimit-Remaining, Retry-After)
  • Após atingir o limite, requisições são rejeitadas
  • Após a janela expirar, requisições voltam a funcionar

Relevância para segurança: endpoints de login devem ter rate limiting para prevenir ataques de força bruta. Teste que 429 é retornado após X tentativas de login com falha.

5xx: códigos de erro do servidor

Esses são sempre bugs. A requisição era válida: o servidor falhou em processá-la.

500 Internal Server Error

Crash genérico do servidor. Algo inesperado aconteceu.

Em testes: se você consegue reproduzir um 500 de forma confiável, é um bug, mesmo que o input fosse intencionalmente inválido. Bom design de API significa que input inválido retorna 4xx, não 500.

O que testar:

  • Input inválido nunca deve produzir 500: deve produzir 400/422
  • Campos opcionais nulos ou ausentes não devem produzir 500
  • Dados de edge case (arrays vazios, strings muito longas) não devem produzir 500

502 Bad Gateway

O servidor estava atuando como gateway/proxy e recebeu uma resposta ruim de um servidor upstream. Geralmente significa que uma dependência está fora.

503 Service Unavailable

O servidor está temporariamente indisponível: sobrecarregado ou em manutenção.

Relevância para testes: verifique como o frontend trata o 503. Mostra uma página de erro útil? Tenta novamente de forma inteligente? Degrada graciosamente?

504 Gateway Timeout

Similar ao 502: um gateway expirou aguardando por um servidor upstream. Aparece com frequência sob alta carga ou quando um serviço de terceiro está lento.

Tabela de referência rápida

CódigoSignificadoCausa comum em bugs
200OKRetornado para criações que deveriam ser 201
201CreatedAusente: API retorna 200 para POST
204No ContentCorpo retornado quando não deveria
301Redirect PermanenteTipo errado de redirect
304Not ModifiedCache stale exibindo dados desatualizados
400Bad RequestRetornado para input válido-mas-errado (deveria ser 422)
401UnauthorizedAusente: vulnerabilidade de bypass de autenticação
403ForbiddenAusente: vulnerabilidade de bypass de autorização
404Not Found500 retornado para recursos ausentes
409ConflictAusente: duplicatas criadas silenciosamente
422Unprocessable EntityConfundido com 400
429Too Many RequestsAusente: força bruta possível
500Internal Server ErrorDisparado por input inválido (deveria ser 4xx)
503Service UnavailableSem degradação graciosa no frontend

Testando status codes com Playwright

test('criar usuário retorna 201', async ({ request }) => {
  const response = await request.post('/api/users', {
    data: { email: 'novo@teste.com', password: 'SenhaValida1' },
  });
  expect(response.status()).toBe(201);
});

test('e-mail duplicado retorna 409', async ({ request }) => {
  // Criar usuário primeiro
  await request.post('/api/users', {
    data: { email: 'existente@teste.com', password: 'SenhaValida1' },
  });
  // Tentar novamente com o mesmo e-mail
  const response = await request.post('/api/users', {
    data: { email: 'existente@teste.com', password: 'SenhaValida1' },
  });
  expect(response.status()).toBe(409);
});

test('token ausente retorna 401', async ({ request }) => {
  const response = await request.get('/api/profile');
  expect(response.status()).toBe(401);
});

test('perfil errado retorna 403', async ({ request }) => {
  // Usar token de membro, tentar acessar endpoint de admin
  const response = await request.get('/api/admin/users', {
    headers: { Authorization: `Bearer ${memberToken}` },
  });
  expect(response.status()).toBe(403);
});

Assertions de status code são os testes de API mais rápidos e confiáveis que você pode escrever. Rodam em milissegundos e capturam bugs de autorização, validação ausente e design incorreto de API.

→ Veja também: Testes de API 101: Tudo que Todo Engenheiro QA Precisa Saber em 2026 | O que é uma API REST? Um Guia Prático para Engenheiros QA | Testes de API com Playwright: Além da Interface | Autenticação em Testes de API: Chaves API, Tokens Bearer, OAuth2, JWT