Errores de la API
Como informa de errores la API de Feedjolt: codigos HTTP, que reintentar con backoff, la cabecera X-Request-ID para informes, limites de tasa y errores de validacion.
La API usa códigos HTTP estándar para los resultados. Los cuerpos de respuesta de error siguen la forma por defecto de FastAPI (un campo detail con un string o payload estructurado). Los detalles de error por endpoint están en la referencia OpenAPI.
Códigos de estado HTTP
| Código | Significado | ¿Reintentar? |
|---|---|---|
| 200, 201, 204 | Éxito. | n/a |
| 400 | Error de validación. Cuerpo o query mal. | No - arregla la petición. |
| 401 | Auth ausente/inválida. | No - arregla la auth. |
| 403 | Auth OK pero le faltan scope o permisos. | No - ajusta scopes. |
| 404 | Recurso no encontrado, O no accesible para tu clave. | No - verifica el ID. |
| 409 | Conflicto (por ejemplo, slug ya tomado). | A veces - depende de la causa. |
| 410 | Gone - el recurso fue eliminado. | No. |
| 422 | Validación semántica. | No - arregla la petición. |
| 429 | Rate limited. | Sí, con backoff. |
| 500 | Nuestro bug. Por favor reporta. | Sí, con backoff. |
| 502, 503, 504 | Problema de infraestructura transitorio. | Sí, con backoff. |
IDs de petición
Cada respuesta de la API incluye:
X-Request-ID: <uuid>Cuando reportes un bug, incluye el ID de petición - nos permite tirar de la traza completa del servidor en segundos en lugar de adivinar desde una descripción.
Hola, recibí un 500 llamando a POST /posts con este cuerpo: {...}
X-Request-ID: 7e6f2b71-...404 vs. 403
Deliberadamente no diferenciamos entre "no existe" y "existe pero no puedes verlo" - eso filtraría información sobre recursos a los que tu clave no puede acceder. Si estás seguro de que el recurso existe y deberías tener acceso, revisa primero tus scopes, luego tu contexto de espacio.
Estrategia de reintento
Para códigos que deberías reintentar (429, 5xx), usa backoff exponencial:
async function callWithRetry(url: string, init: RequestInit) {
const delays = [200, 800, 2000, 5000, 10000]; // ms
for (const delay of [0, ...delays]) {
if (delay) await sleep(delay);
const res = await fetch(url, init);
if (res.status >= 500 || res.status === 429) continue;
return res;
}
throw new Error("retries exhausted");
}No reintentes 4xx (excepto 429) - la petición está rota; reintentar no la cambiará.
Rate limits (429)
Algunos endpoints están limitados por IP - actualmente los relacionados con auth (/auth/magic-link, /auth/google, etc.). Cuando excedes el límite, recibes un 429.
Los endpoints de la API a nivel de espacio (posts, comentarios, votos) no tienen rate limits publicados por clave hoy. Si haces una migración masiva que choca con muros, escribe a [email protected] - podemos subir límites temporalmente o recomendar un patrón más amable.
Validación
Los cuerpos que fallan la validación de Pydantic devuelven 422 con un array detail de los campos infractores. La forma es la estándar de FastAPI - ver el formato de respuesta de error de FastAPI o la referencia OpenAPI para ejemplos.
