Cómo se organizan los códigos de estado
Los códigos de estado HTTP son números de tres cifras agrupados en cinco clases según su primer dígito:
- **1xx, informativos:** la petición se ha recibido y se sigue procesando
- **2xx, éxito:** la petición se ha recibido, entendido y aceptado
- **3xx, redirección:** hace falta algo más para completar la petición
- **4xx, error del cliente:** la petición está mal formada o no se puede atender
- **5xx, error del servidor:** el servidor no ha podido atender una petición válida
Los códigos que necesitas conocer
2xx, éxito
**200 OK**: la respuesta de éxito de toda la vida. En una petición GET, el cuerpo lleva el recurso solicitado; en un POST, el resultado.
**201 Created**: se ha creado un recurso. Se devuelve tras un POST correcto a un punto de creación y debería incluir una cabecera Location que apunte al recurso nuevo.
**204 No Content**: la petición ha ido bien pero no hay nada que devolver. Habitual en peticiones DELETE y en PUT que actualizan sin devolver el resultado.
**206 Partial Content**: se usa en las peticiones por rangos (vídeo en streaming, descargas que se reanudan). La cabecera Content-Range indica qué fragmento se devuelve.
3xx, redirección
**301 Moved Permanently**: el recurso se ha movido para siempre. Los navegadores y los buscadores lo guardan en caché y actualizan sus enlaces. Úsalo para cambios de URL definitivos.
**302 Found**: redirección temporal. Los navegadores la siguen pero no la cachean, y la URL original sigue siendo "válida". Úsalo con moderación: muchas veces se emplea donde lo correcto sería un 301.
**303 See Other**: tras una petición POST, redirige a una petición GET. Es la forma estándar de implementar el patrón Post/Redirect/Get y evitar que se reenvíe un formulario.
**304 Not Modified**: el cliente tiene una copia en caché y el contenido no ha cambiado. El servidor envía esto en lugar de retransmitir la respuesta completa.
**307 Temporary Redirect**: como el 302, pero garantizando explícitamente que la redirección mantiene el mismo método HTTP. Un POST a un 307 se redirige como POST, no como GET.
**308 Permanent Redirect**: como el 301, pero conservando el método. Úsalo al mover definitivamente un punto de acceso que recibe POST.
4xx, errores del cliente
**400 Bad Request**: la petición está mal formada. Un error de sintaxis en el cuerpo, un JSON inválido o un campo obligatorio que falta. El cliente no debería reintentar sin corregirla.
**401 Unauthorized**: hace falta autenticarse (el nombre confunde, porque en realidad significa "sin autenticar"). El cliente debería enviar sus credenciales.
**403 Forbidden**: está autenticado pero no autorizado. El servidor ha entendido la petición y se niega a autorizarla. No conviene revelar si el recurso existe.
**404 Not Found**: el recurso no existe en esa dirección. También se puede usar para disimular un 403: devolver 404 ante un acceso no autorizado evita los ataques de enumeración.
**405 Method Not Allowed**: ese método HTTP no está admitido. Por ejemplo, un GET en un punto que solo acepta POST.
**409 Conflict**: la petición choca con el estado actual. Crear un usuario con un correo duplicado o intentar bloquear un archivo que ya está bloqueado.
**410 Gone**: como el 404, pero el recurso existió y se ha eliminado para siempre. Les dice a los rastreadores que lo quiten de su índice.
**422 Unprocessable Entity**: la sintaxis es válida pero la semántica no. El JSON se ha analizado bien, pero los valores no pasan la validación. Es más concreto que un 400.
**429 Too Many Requests**: se ha superado el límite de peticiones. La respuesta debería incluir una cabecera Retry-After que indique cuándo se puede reintentar.
5xx, errores del servidor
**500 Internal Server Error**: un fallo genérico del servidor. Una excepción sin controlar, un proceso caído o una mala configuración. Toca mirar los registros.
**502 Bad Gateway**: el servidor, actuando como pasarela o proxy, ha recibido una respuesta inválida de otro servidor. Muy habitual cuando tu aplicación está caída pero el proxy inverso (Nginx, Cloudflare) sigue en pie.
**503 Service Unavailable**: el servidor no puede atender la petición temporalmente. Modo mantenimiento, sobrecarga o un despliegue en marcha. Incluye Retry-After si sabes cuándo volverá.
**504 Gateway Timeout**: el servidor de destino ha tardado demasiado en responder. Tu balanceador de carga o tu red de distribución no ha llegado a tiempo a tu aplicación.
Lista de comprobación práctica
- No devuelvas nunca un 200 con un error en el cuerpo ("200 OK" junto a
{"error": "not found"}es un antipatrón) - Usa 4xx para los errores del cliente y 5xx para los del servidor
- El 404 vale tanto para "no existe" como para "no tienes permiso", y así evitas la enumeración de recursos
- Incluye detalles útiles en las respuestas 4xx: qué ha fallado y qué debería hacer el cliente
- Un 503 durante un despliegue es mejor que dejar las peticiones colgadas o que fallen con un 502