Elige el código
Los cinco que cubren el 95 % de los casos de prueba: el camino feliz, el error del cliente, la falta de credenciales, el recurso inexistente y el fallo del servidor.
Respuestas de ejemplo para los códigos que de verdad se prueban, con cabeceras verosímiles y cuerpo editable. Como respuesta cruda para un mock server o como bloque de documentación.
100 % privado. No hay servidor: los datos se generan en tu navegador y no se envían ni se guardan en ninguna parte.
Cómo funciona
Los cinco que cubren el 95 % de los casos de prueba: el camino feliz, el error del cliente, la falta de credenciales, el recurso inexistente y el fallo del servidor.
Escribe el endpoint y el JSON que quieras devolver. Todo es editable.
Cruda para pegarla en un mock server, o como bloque para el README y la especificación de tu API.
Elegir el código de estado es la mitad del trabajo; la otra mitad es qué devuelves en el cuerpo. Y ahí casi todo el mundo improvisa, con el resultado de que cada endpoint de la misma API devuelve los errores de una forma distinta.
Existe un estándar para esto: el RFC 9457 —antes 7807—, que define un formato
común llamado problem details con el tipo de contenido
application/problem+json:
HTTP/1.1 400 Bad Request
Content-Type: application/problem+json
{
"type": "https://api.ejemplo.com/errores/ruc-invalido",
"title": "El RUC no es válido",
"status": 400,
"detail": "El dígito verificador de 20481234560 no corresponde.",
"instance": "/clientes/alta/8f3e",
"errores": [
{ "campo": "ruc", "mensaje": "Dígito verificador incorrecto" }
]
}
Los cinco campos tienen un papel claro: type identifica la clase de
error de forma estable —es lo que tu cliente debe mirar, no el texto—, title es
un resumen legible, status repite el código, detail explica
este caso concreto, e instance identifica la ocurrencia para poder
buscarla en los registros.
La regla que se deriva: tu cliente nunca debe decidir en función del texto del
mensaje. Los textos cambian, se traducen, se corrigen. El type —o un
código propio— es lo estable.
// MAL: el código dice que todo fue bien
HTTP/1.1 200 OK
{ "exito": false, "error": "Usuario no encontrado" }
// BIEN: el código ya lo dice
HTTP/1.1 404 Not Found
{ "type": "...", "title": "Usuario no encontrado", "status": 404 }
Con el primero, todo lo que hay entre tu servidor y tu cliente se equivoca: el reintento automático no reintenta porque cree que funcionó, la caché guarda la respuesta de error, los paneles de monitorización muestran cero errores mientras los usuarios se quejan, y cada cliente tiene que aprender a mirar dentro del cuerpo. Es el antipatrón más extendido en API internas.
| Código | Significa | Qué debe hacer el cliente |
|---|---|---|
| 401 Unauthorized | «No sé quién eres»: faltan credenciales o son inválidas | Renovar el token o pedir que inicie sesión |
| 403 Forbidden | «Sé quién eres y no puedes» | Mostrar que no tiene permiso. Reintentar no sirve |
Confundirlos tiene un efecto muy concreto y muy molesto: si devuelves 401 cuando querías decir 403, la aplicación intentará renovar el token, lo conseguirá, reintentará, volverá a recibir 401… y acabará cerrando la sesión del usuario por un problema de permisos que no tenía nada que ver con su identidad.
Cuando el 401 es porque el token expiró, ayuda mucho añadir la cabecera
WWW-Authenticate: Bearer error="invalid_token": así el cliente sabe que debe
renovar y no que debe pedir la contraseña otra vez.
Un 500 significa que algo se rompió en tu servidor, y el cuerpo debe decir exactamente eso y nada más. Lo que no puede llevar:
Lo correcto es un mensaje genérico más un identificador de incidencia: «Error interno. Referencia: 7f3a9c». Ese identificador va también a tus registros, así que el usuario te lo puede dar y tú encuentras el detalle sin haberlo publicado.
Preguntas frecuentes
El estándar que define un formato común para los cuerpos de error en API HTTP, con el tipo de contenido application/problem+json y los campos type, title, status, detail e instance. Antes era el RFC 7807. Usarlo evita que cada endpoint de tu API devuelva los errores de una forma distinta.
Porque todo lo que hay entre tu servidor y tu cliente se equivoca: los reintentos no reintentan, la caché guarda la respuesta de error, la monitorización no ve nada y cada cliente tiene que aprender a mirar dentro del cuerpo. El código de estado existe precisamente para eso.
El 401 significa «no sé quién eres»: faltan credenciales o son inválidas, y el cliente debe renovar el token. El 403 significa «sé quién eres y no puedes»: reintentar no sirve de nada. Confundirlos hace que la aplicación cierre la sesión del usuario por un problema de permisos.
Un mensaje genérico y un identificador de incidencia que también vaya a tus registros. Nunca la traza de la excepción, consultas SQL ni datos que estuvieran en memoria: eso es información valiosa para quien quiera atacarte.
Sí, es su uso principal. Copia la respuesta cruda y pégala en tu mock server, o usa el formato de documentación para el README y la especificación de tu API.
Sí, el cuerpo JSON, la ruta del endpoint y el método son editables. El generador te da una base verosímil y tú la ajustas a tu caso.
Sigue probando