# Errores

Cuando una API de Inovacc rechaza o no puede completar una llamada, responde con un estado HTTP y un envoltorio de error JSON. Esta guía describe el envoltorio, los tipos de error, los códigos que comparten todas las API, y qué hacer para cada estado: corregir la solicitud, esperar o reintentar.

## El envoltorio

```json
{ "error": { "message": "Human-readable explanation", "type": "validation_error", "code": "invalid_body" } }
```

- **`code`** es sobre lo que debe bifurcar tu programa. Los códigos son parte del contrato de cada API: dentro de una ruta de versión como `/v1`, se pueden agregar códigos nuevos, y un código existente conserva su significado.
- **`type`** agrupa los códigos en familias, útiles para el registro y el manejo general.
- **`message`** es una oración fija en inglés para las personas. Nunca repite un valor de tu solicitud (como máximo el nombre de un campo rechazado) y nunca describe qué falló dentro de Inovacc. No la analices.

Algunas respuestas agregan un campo al envoltorio: un archivo rechazado lleva `reason` (por ejemplo `executable` o `password_protected`), y una conversión de esquema que no encaja lleva `failing_documents`, un conteo. Ignora los campos que no conozcas.

Dos respuestas no usan el envoltorio. En la API de IA, una ruta que no existe responde `404 {"error":"not_found"}`. Un WebSocket (una transmisión de Eventos o un oyente de Datos) rechazado antes de la actualización responde un error HTTP ordinario; una vez abierto, termina con un código de cierre.

## Tipos

| `type` | Significa | Estado típico |
|---|---|---|
| `validation_error` | La solicitud está mal formada: un encabezado, un campo o un valor incumple las reglas. | 400 |
| `invalid_request_error` | La solicitud está bien formada pero no se puede atender tal como se envió: demasiado grande, un tipo de archivo no admitido, una URL que no se puede obtener. | 400, 413, 415, 422 |
| `authentication_error` | No hay credencial, o no es válida. | 401 |
| `authorization_error`, `permission_error`, `forbidden` | La credencial es válida pero no puede hacer esto. | 403 |
| `not_found_error`, `not_found` | La cosa no existe, o no se te permite saber que existe. | 404, 410 |
| `conflict_error`, `conflict` | La solicitud entra en conflicto con el estado actual: una versión, un modo, un límite de una colección. | 409 |
| `idempotency_error` | Un id de operación está en uso o se usó para otra cosa. | 409 |
| `rate_limit_error`, `rate_limited` | Demasiadas llamadas, o se agotó una asignación o un presupuesto. | 429 |
| `api_error`, `service_error`, `service_unavailable`, `internal_error` | Algo del lado de Inovacc, o una fuente a la que llamó por ti, falló. | 500, 502, 503, 504 |

Las API de Datos, de IA y de Eventos usan las familias anteriores; la cadena exacta de `type` puede diferir entre API para la misma familia, así que maneja el `code`, y recurre al estado HTTP como respaldo.

## Códigos que comparten todas las API

| Estado | Código | Significado | Qué hacer |
|---|---|---|---|
| 401 | `missing_credentials`, `invalid_credentials` | No hay clave, o una clave que no es válida, venció o fue revocada. | Corrige la credencial; no reintentes sin cambios. |
| 403 | `forbidden`, `route_forbidden`, `key_disabled`, `capability_not_enabled` | La credencial no puede hacer esto. | Solicita el permiso, la ruta o la capacidad. |
| 403 | `origin_not_allowed`, `secret_key_in_browser` | Una llamada desde un navegador con un origen no listado, o una clave secreta en un navegador. | Lista el origen; usa una clave publicable. |
| 400 | `missing_operation_id`, `invalid_operation_id` | IA: un `POST`, `PUT` o `DELETE` sin un `X-Operation-Id` válido. | Envía de 8 a 128 letras, dígitos, `_` o `-`. |
| 400 | `invalid_body`, `unsupported_field`, `invalid_field` | El cuerpo o un parámetro no es válido para este endpoint. | Corrige la solicitud. |
| 404 | `*_not_found` | No existe, o no es tuyo. | Revisa el id. |
| 409 | `operation_in_progress` | El mismo id de operación sigue en ejecución. | Espera y luego reintenta con el mismo id. |
| 409 | `operation_id_reused` | IA: un id de operación ya usado para otro archivo en una colección. | Usa un nuevo id de operación para una nueva operación. |
| 409 | `version_conflict` | Datos: el registro cambió desde que lo leíste. | Vuelve a leerlo y luego reintenta. |
| 413 | `request_too_large`, `payload_too_large` | El cuerpo supera el límite de tamaño. | Hazlo más pequeño, o carga por partes. |
| 429 | `rate_limited` | Demasiadas solicitudes en la ventana. | Espera `Retry-After` segundos, cuando se indique. |
| 429 | `quota_exceeded`, `concurrency_limited` | IA: se agotó una asignación de tokens, costo o concurrencia. | Reduce el ritmo; pide a Inovacc que aumente la asignación. |
| 429 | `budget_exhausted` | IA: se gastó un presupuesto diario. | Espera hasta las 00:00 UTC (`Retry-After`). |
| 502 | `upstream_error` | Falló una fuente a la que se llamó por ti. | Reintenta con espera creciente. |
| 503 | `service_unavailable` | No se pudo acceder a una dependencia; no se hizo ni se adivinó nada. | Reintenta con espera creciente. |
| 504 | `timeout_error` | IA: el modelo no empezó a responder a tiempo. | Reintenta con espera creciente. |

Cada página de producto lista todos los códigos que puede devolver, con lo que hay que hacer.

## Política de reintentos

| Estado | ¿Reintentar? | Cómo |
|---|---|---|
| 400, 401, 403, 404, 410, 413, 415, 422 | No | La misma solicitud fallará de la misma manera. Corrígela primero. |
| 409 `operation_in_progress` | Sí | Tras una breve espera, con el **mismo** id de operación. |
| 409 `version_conflict` | Sí, tras volver a leer | Lee el registro, aplica tu cambio a la nueva versión, envía su `If-Match`. |
| 409, otros códigos | No | El estado debe cambiar primero (crea la base de datos, espera los elementos, vacía la carpeta). |
| 429 con `Retry-After` | Sí | No antes del número de segundos que indica. |
| 429 sin `Retry-After` | Más tarde | Se agotó una asignación: espera minutos, no segundos, o auméntala. |
| 500, 502, 503, 504 | Sí | Con espera exponencial y variación aleatoria (por ejemplo 1, 2, 4, 8 segundos), unas pocas veces como máximo. |
| Error de red, sin respuesta | Sí | Igual que para 503. |

**Reintenta con seguridad.** En la API de IA, reintenta una llamada que modifica con el **mismo** `X-Operation-Id`: si el primer intento sí tuvo éxito, recibes su respuesta almacenada en lugar de una segunda ejecución. En Datos, reintenta una creación con tu propio id de registro o `If-None-Match: *`, y una actualización con el mismo `If-Match`. En Eventos, reintenta una publicación con el mismo `idempotency_key`: regresa el `event_id` original con `duplicate: true`.

## Ver también

- [Autenticación](/es/guides/authentication/): credenciales e idempotencia.
- [Límites](/es/guides/limits/): los tamaños y tasas detrás de `413` y `429`.
- [Webhooks](/es/guides/webhooks/): cómo se reintentan las entregas fallidas.
