> ## Documentation Index
> Fetch the complete documentation index at: https://docs.retailgrid.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Errores

> Códigos de estado que usa la API pública de Retailgrid y la forma de los errores de validación.

## Códigos de estado

| Estado | Significado | Cuándo lo ves |
| - | - | - |
| `200 OK` | Éxito | Respuestas de `GET`, `PATCH` y `/bulk` |
| `201 Created` | Recurso creado | `POST /v1/<entity>/{entity_id}` y `POST /v1/competitor_prices` |
| `202 Accepted` | Trabajo (job) en cola | `POST /v1/imports/*` que devuelve un `JobHandle` |
| `204 No Content` | Éxito, sin cuerpo | `DELETE /v1/<entity>/{entity_id}` |
| `401 Unauthorized` | Clave de API ausente, mal formada o rotada | Problema con la cabecera de autenticación - consulta [Autenticación](https://docs.retailgrid.io/es/api-reference/authentication.md) |
| `404 Not Found` | El `entity_id` de la ruta es desconocido | Modificar o eliminar una fila que no existe |
| `422 Unprocessable Entity` | La validación falló | Forma del payload incorrecta, campo obligatorio ausente, tipo no coincidente |
| `429 Too Many Requests` | Límite de uso por clave, o el presupuesto de uso de la organización está agotado | Espera y reintenta según `Retry-After`; si es un rechazo por presupuesto, lee el cuerpo (más abajo) |
| `503 Service Unavailable` | El control de uso no está disponible temporalmente (`usage_enforcement_unavailable`) | Reintenta tras una breve espera |
| `5xx` | Error del servidor | Reintenta con retroceso exponencial; si persiste, contacta con soporte |

## Límite de uso de la organización (429)

Cuando el presupuesto de uso compartido de la organización se agota, la solicitud se rechaza antes de procesarse con `429 Too Many Requests`, una cabecera `Retry-After` y un cuerpo cuyo `detail` indica exactamente qué límite se alcanzó y cuándo se libera:

```json theme={null}
{
  "detail": {
    "code": "organization_usage_limit_exceeded",
    "dimension": "transactions_read",
    "unit": "requests",
    "limit": 100000,
    "remaining": 0,
    "request_id": "0b3c1f4a-9c1d-4f2a-8a3b-2c3d4e5f6a7b",
    "reset_at": "2026-10-08T00:00:00Z",
    "retry_after": 3600
  }
}
```

* `unit` es uno de `requests`, `active_work`, `bytes` o `calls`.
* `reset_at` es el momento en que se repone el presupuesto; `retry_after` es la misma espera en segundos y coincide con la cabecera `Retry-After`.
* El presupuesto se comparte entre claves de API, usuarios y el conector MCP (consulta [Convenciones ▸ Límites de uso](https://docs.retailgrid.io/es/api-reference/conventions.md)), así que cambiar de clave no restaura el acceso: espera al reinicio.

Si el propio control de uso no está disponible temporalmente, la API devuelve `503` con `{ "detail": { "code": "usage_enforcement_unavailable" } }`; reintenta tras una breve espera.

## Forma de los errores de validación

Cuando una solicitud no supera la validación del esquema, la API devuelve un `422` con un cuerpo `HTTPValidationError`:

```json theme={null}
{
  "detail": [
    {
      "loc": ["body", "items", 0, "regular_price"],
      "msg": "field required",
      "type": "missing"
    },
    {
      "loc": ["body", "items", 1, "observed_at"],
      "msg": "input should be a valid datetime",
      "type": "datetime_parsing"
    }
  ]
}
```

Cada entrada de `detail` es un `ValidationError`:

* `loc` - ruta JSON al campo problemático, incluidos los índices de los arrays.
* `msg` - mensaje legible para personas.
* `type` - código de error legible por máquinas (por ejemplo, `missing`, `string_too_long`, `value_error`).

## Endpoints masivos: errores por elemento

Los endpoints `/bulk` devuelven `200 OK` incluso cuando fallan filas individuales. Los fallos por fila se informan dentro de `BulkResponse.results`, no como un error de nivel superior:

```json theme={null}
{
  "results": [
    { "index": 0, "ok": true,  "id": "1c2d..." },
    { "index": 1, "ok": false, "code": "validation_error", "message": "product_name too long" }
  ]
}
```

Recorre siempre `results` y comprueba `ok`. Un `200` **no** significa que se haya escrito cada fila.

## Casos 422 comunes por familia de endpoints

* **Products** - falta `item_id`, falta `sku`, o un campo decimal no se puede interpretar.
* **Product store** - falta `item_id`, `store_id` o `current_price`; `store_id` hace referencia a una tienda desconocida.
* **Transactions** - falta `item_id`, `transaction_timestamp` mal formado, campo decimal que no se puede interpretar.
* **Competitor prices** - falta uno de los cuatro campos obligatorios (`competitor_name`, `observed_at`, `regular_price`, `effective_price`).
* **Imports (CSV)** - archivo no adjunto, archivo vacío, archivo que no es UTF-8, fila de cabecera ausente.

## Estrategia de reintentos

* **Endpoints idempotentes** (`POST /v1/<entity>/{entity_id}`, `PATCH`, `DELETE`, `/bulk`) - reintenta ante 5xx y ante errores de transporte con retroceso exponencial (empieza en 1 s, tope de 30 s, máximo 5 intentos).
* **`POST /v1/competitor_prices`** - es una creación no idempotente (sin id en la ruta). Reintentar tras una respuesta exitosa creará una fila duplicada. Comprueba el resultado de la red antes de reintentar.
* **Importaciones asíncronas** - si `POST /v1/imports/*` falla, reintenta la carga. Si tiene éxito y el trabajo (job) posterior falla, corrige el CSV y envía un trabajo nuevo en lugar de reintentar la misma carga.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.