Cada vez que tu navegador o app hace una solicitud HTTP (GET, POST, PUT, DELETE), el servidor responde con un código numérico de 3 dígitos. Este código comunica el resultado de la operación antes de procesar el cuerpo de la respuesta. Los códigos se agrupan en cinco clases según el primer dígito: 1xx (informacional), 2xx (éxito), 3xx (redirección), 4xx (error del cliente), 5xx (error del servidor).
Ejemplo: cuando cargás una página y ves contenido, el servidor probablemente respondió 200 OK. Si la URL cambió, quizás fue 301 Moved Permanently. Si intentás acceder sin permiso, 403 Forbidden. Si el servidor está caído, 503 Service Unavailable. Estos códigos son estándar HTTP definidos en RFC 7231 y extensiones posteriores.
Los códigos HTTP son fundamentales para debugging, SEO, monitoreo y UX. Un 404 bien manejado con página custom mejora la experiencia. Un 500 sin logging dificulta encontrar bugs. Google penaliza sitios con muchos errores 5xx. APIs REST usan códigos específicos (201 Created, 204 No Content, 409 Conflict) para comunicar resultados sin ambigüedad.
2xx: Éxito. 200 OK: solicitud exitosa, respuesta con contenido. 201 Created: recurso creado (típico en POST). 204 No Content: éxito pero sin cuerpo (útil en DELETE). 206 Partial Content: respuesta parcial, usado en streaming y descargas resumibles.
3xx: Redirección. 301 Moved Permanently: URL cambió para siempre, actualizar bookmarks (importante para SEO). 302 Found: redirección temporal, URL original sigue válida. 304 Not Modified: recurso no cambió desde última vez, usar caché (optimización clave). 307 Temporary Redirect: como 302 pero garantiza que el método HTTP no cambia (POST sigue siendo POST).
4xx: Error del cliente. 400 Bad Request: solicitud malformada (JSON inválido, parámetros faltantes). 401 Unauthorized: autenticación requerida o falló. 403 Forbidden: autenticado pero sin permisos. 404 Not Found: recurso no existe. 405 Method Not Allowed: GET en endpoint que solo acepta POST. 409 Conflict: conflicto de estado (crear recurso que ya existe). 429 Too Many Requests: rate limiting, reintentar después.
5xx: Error del servidor. 500 Internal Server Error: error genérico del servidor. 502 Bad Gateway: servidor intermedio (proxy, load balancer) recibió respuesta inválida. 503 Service Unavailable: servidor temporalmente sobrecargado o en mantenimiento. 504 Gateway Timeout: servidor intermedio no recibió respuesta a tiempo.
En frontend, siempre verificá el código antes de procesar la respuesta. No asumas que fetch() exitoso significa datos válidos: un 404 técnicamente no lanza error en fetch, necesitás if (!response.ok) throw new Error(). Mostrá mensajes específicos: 401 → "Por favor iniciá sesión", 403 → "No tenés permisos", 404 → "Página no encontrada", 500 → "Error del servidor, intentá de nuevo".
En backend/APIs, usá códigos semánticos. POST que crea recurso debe devolver 201 con header Location apuntando al nuevo recurso. DELETE exitoso puede ser 204 (sin contenido) o 200 con mensaje. Validación fallida es 400 con detalles del error, no 500. Autenticación fallida es 401, autorización fallida es 403. Para rate limiting, devolvé 429 con header Retry-After.
En SEO, los códigos correctos son críticos. Páginas eliminadas deben devolver 410 Gone o 404, no 200 con mensaje "no encontrado" (Google lo indexa como contenido real). Redirecciones permanentes (cambio de dominio, URLs deprecadas) deben ser 301 para transferir SEO juice. 302/307 solo para redirecciones realmente temporales. Errores 5xx dañan ranking si son frecuentes: monitoreá y fixeá rápido.
Herramientas de developer tools en navegadores muestran todos los códigos en la pestaña Network. Filtrá por rangos: ver solo 4xx revela problemas de cliente, 5xx problemas de servidor. La columna Status te da el código, la columna Time el tiempo de respuesta. Un 200 que tarda 10 segundos es problema aunque el código sea correcto.
En producción, configurá alertas sobre tasas de errores. Si >5% de requests son 5xx, algo está roto. Si ves picos de 429, tu rate limiting está funcionando o tenés tráfico anómalo (scrapers, ataques). Herramientas como Datadog, New Relic o Sentry trackean códigos HTTP y correlacionan con performance y logs.
Testing de APIs: escribí tests que validen códigos esperados. POST /users con datos válidos debe devolver 201, con email duplicado debe ser 409, sin auth debe ser 401. Esto evita regresiones donde cambios de código alteran contratos de la API sin darse cuenta.
Un error común es loggear solo errores 5xx. Loggeá también 4xx relevantes: muchos 404 en la misma URL sugieren links rotos, muchos 401 pueden indicar problema de integración. Analizá patrones: si 80% de 400 vienen del mismo campo de un form, la validación frontend no está funcionando.
Ejemplos
GET /api/users/123 → 200 OK (usuario encontrado y devuelto)POST /api/users → 201 Created (usuario creado exitosamente)GET /api/users/999 → 404 Not Found (usuario no existe)DELETE /api/users/123 sin auth → 401 Unauthorized (falta token)PUT /api/users/123 con datos inválidos → 400 Bad RequestGET /api/products cuando server caído → 503 Service Unavailable
Preguntas frecuentes
¿Cuál es la diferencia entre 401 y 403?
401 Unauthorized significa que no estás autenticado: falta token, sesión expiró, credenciales incorrectas. El servidor no sabe quién sos. 403 Forbidden significa que estás autenticado pero no autorizado: el servidor sabe quién sos pero no tenés permisos para ese recurso. Ejemplo: usuario regular intentando acceder a panel de admin es 403, usuario sin login es 401.
¿Por qué mi API devuelve 200 con error en el body en lugar de 4xx/5xx?
Esto es un antipatrón común llamado "envelope response". Algunas APIs viejas devuelven siempre 200 con <code>{"status":"error"}</code> en JSON. Esto rompe caching HTTP, complica manejo de errores en cliente y no es RESTful. El código HTTP debe reflejar el resultado: error de validación es 400, recurso no encontrado es 404, error de servidor es 500. Usá el body para detalles adicionales.
¿Qué código usar cuando un recurso ya no existe y nunca volverá?
410 Gone es el más apropiado: indica que el recurso existió pero fue eliminado permanentemente. Esto es útil para SEO (le dice a Google que deje de indexar) y APIs (cliente puede limpiar referencias). 404 Not Found también es aceptable y más común, pero no comunica la permanencia. Para páginas eliminadas intencionalmente (productos descontinuados, posts borrados), 410 es semánticamente mejor.