Errores y límites
Esta página describe cómo informa errores la API pública de NORA, qué códigos HTTP devuelve y cuáles son los límites de tasa (rate limits) reales por endpoint. La URL base de producción es https://nora.valisoftconsulting.com y todos los endpoints públicos cuelgan del prefijo /api/v1.
Forma del cuerpo de error
Sección titulada «Forma del cuerpo de error»Todas las respuestas de la API van envueltas. Las correctas usan {"success": true, "data": ...} (ver autenticación) y las de error siguen una forma uniforme con un objeto error:
{ "success": false, "error": { "code": "NOT_FOUND", "message": "Recurso no encontrado", "details": { }, "request_id": "b3c1e2a4-..." }}Campos del objeto error:
| Campo | Tipo | Presencia | Descripción |
|---|---|---|---|
code | string | siempre | Código estable de error legible por máquina (ver tablas abajo). |
message | string | siempre | Mensaje descriptivo en español, pensado para humanos. |
details | objeto o lista | opcional | Información adicional. Solo aparece cuando hay detalles que aportar. |
request_id | string | cuando hay traza | Identificador de la petición; inclúyelo al reportar incidencias. |
Errores de validación (422)
Sección titulada «Errores de validación (422)»Cuando el cuerpo enviado no pasa la validación, details es una lista de errores por campo. Cada elemento tiene field (ruta del campo, separada por →) y message:
{ "success": false, "error": { "code": "VALIDATION_ERROR", "message": "Error de validación en los datos enviados", "details": [ { "field": "name", "message": "Field required" } ] }}Códigos HTTP
Sección titulada «Códigos HTTP»NORA usa el código HTTP de forma consistente con el code del cuerpo. Estos son los códigos que puedes encontrar:
| HTTP | code típico | Significado en NORA |
|---|---|---|
401 | UNAUTHORIZED | Falta la credencial o es inválida (API key ausente/incorrecta, token expirado). |
403 | FORBIDDEN | Autenticado, pero sin permisos para el recurso o la operación (incluye aislamiento entre organizaciones y funciones no incluidas en tu plan). |
404 | NOT_FOUND | El recurso no existe o no pertenece a tu organización. |
409 | CONFLICT | Conflicto de estado: el recurso ya existe o choca con otro. |
413 | PAYLOAD_TOO_LARGE | El cuerpo de la petición supera el límite (2 MiB para endpoints JSON ordinarios). |
422 | VALIDATION_ERROR | Los datos enviados no superan la validación de esquema. |
429 | RATE_LIMIT_EXCEEDED | Se superó el límite de tasa del endpoint (ver tabla más abajo). |
500 | INTERNAL_ERROR | Error interno no controlado del servidor. |
Catálogo de excepciones de negocio
Sección titulada «Catálogo de excepciones de negocio»La lógica de negocio de NORA lanza un conjunto acotado de excepciones, cada una con su par fijo de HTTP + code:
| Excepción | HTTP | code | Mensaje por defecto |
|---|---|---|---|
NotFoundException | 404 | NOT_FOUND | ”Recurso no encontrado” |
ConflictException | 409 | CONFLICT | ”El recurso ya existe” |
UnauthorizedException | 401 | UNAUTHORIZED | ”Credenciales inválidas” |
ForbiddenException | 403 | FORBIDDEN | ”Permisos insuficientes” |
ValidationException | 422 | VALIDATION_ERROR | ”Error de validación” |
RateLimitException | 429 | RATE_LIMIT_EXCEEDED | ”Límite de solicitudes excedido” |
Cada excepción puede llevar un message y details propios según el caso; los de la tabla son los valores por defecto cuando no se especifica nada.
Además, hay dos códigos que no provienen de la lógica de negocio sino de manejadores genéricos:
HTTP_ERROR: errores HTTP de bajo nivel (por ejemplo, método no permitido) que no encajan en una excepción de negocio.INTERNAL_ERROR: cualquier excepción no controlada (HTTP500). El detalle real se registra del lado del servidor; el cliente solo recibe un mensaje genérico.
Límites de tasa (rate limits)
Sección titulada «Límites de tasa (rate limits)»NORA aplica límites de tasa por endpoint con una ventana de un minuto. Al superarlos, recibes 429 con code RATE_LIMIT_EXCEEDED.
Clave de límite (bucket)
Sección titulada «Clave de límite (bucket)»En los endpoints de la API pública (los que se autentican con X-API-Key), el límite se contabiliza por API key, no por IP: la clave se identifica por un hash SHA-256 del valor de la cabecera X-API-Key. Si no hay API key, se cae a la IP de origen. Esto evita que una misma key esquive su cuota rotando IPs, o que su cuota se diluya tras un NAT compartido.
Límites por endpoint público
Sección titulada «Límites por endpoint público»Estos son los límites reales de los endpoints de la superficie pública (X-API-Key):
| Método y ruta | Límite |
|---|---|
GET /api/v1/jobs/{job_id} | 60/min |
POST /api/v1/jobs/trigger | 30/min |
POST /api/v1/jobs/{job_id}/stop | 30/min |
GET /api/v1/processes/list | 60/min |
GET /api/v1/machines/list | 60/min |
GET /api/v1/assets/by-name/{name} | 30/min |
POST /api/v1/queues/by-name/{name}/items | 60/min |
GET /api/v1/queues/by-name/{name}/items | 60/min |
POST /api/v1/queues/by-name/{name}/items/bulk | 20/min |
POST /api/v1/webhooks/trigger/{process_id} | 60/min |
Más allá de estos límites por endpoint, se aplica un límite global por defecto de 120/min a las rutas que no declaran uno propio.
Flujo de decisión
Sección titulada «Flujo de decisión»flowchart TD
A[Petición a /api/v1] --> B{X-API-Key válida?}
B -- No --> E1[401 UNAUTHORIZED]
B -- Sí --> C{Dentro del límite del endpoint?}
C -- No --> E2[429 RATE_LIMIT_EXCEEDED]
C -- Sí --> D{Permisos y plan para el recurso?}
D -- No --> E3[403 FORBIDDEN]
D -- Sí --> F{Recurso existe en tu organización?}
F -- No --> E4[404 NOT_FOUND]
F -- Sí --> G{Datos válidos?}
G -- No --> E5[422 VALIDATION_ERROR]
G -- Sí --> H[200/201 success: true]
Ejemplo de manejo
Sección titulada «Ejemplo de manejo»import httpx
BASE = "https://nora-api.valisoftconsulting.com/api/v1"headers = {"X-API-Key": "nora_ak_..."}
resp = httpx.post(f"{BASE}/jobs/trigger", headers=headers, json={...})
if resp.status_code == 429: # Límite excedido: espera y reintenta con retroceso ...elif not resp.is_success: err = resp.json()["error"] print(err["code"], err["message"], err.get("request_id"))else: data = resp.json()["data"]Consulta también autenticación para obtener y usar tu API key, y la guía de jobs para los flujos de ejecución.