> ## 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.

# Convenciones

> Patrones que sigue cada endpoint de la API de Retailgrid: respuestas masivas, trabajos asíncronos, identificadores, decimales y marcas de tiempo.

Lee esto una vez y podrás usar cualquier endpoint de la API sin sorpresas.

## Identificadores

En la API aparecen dos tipos de ids:

* **`item_id` / `sku` / `competitor_name` / etc.** - tu identificador de negocio estable. Lo proporcionas tú. Úsalo para los upserts. `item_id` es la clave única a nivel de SKU para productos y transacciones; `product_id` es un código opcional a nivel de producto que agrupa ítems relacionados.
* **`id` / `entity_id`** - el id interno de fila de Retailgrid, devuelto en las respuestas. Úsalo en los parámetros de ruta al modificar o eliminar (`PATCH /v1/products/{entity_id}`).

`entity_id` es un UUID para productos, variantes de producto y transacciones. **Para los precios de competidores es un entero** - el único lugar de la API donde esto varía.

## Endpoints masivos

Cada entidad tiene un endpoint `POST /v1/<entity>/bulk` que acepta un array `items` y devuelve resultados por ítem.

**Solicitud:**

```json theme={null}
{
  "items": [
    { "item_id": "SKU-001", "product_name": "Item one" },
    { "item_id": "SKU-002", "product_name": "Item two" }
  ]
}
```

**Respuesta (`BulkResponse`):**

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

Una solicitud masiva **nunca** es de todo o nada. Las filas correctas se escriben aunque otras filas fallen. Revisa siempre cada `BulkItemResult.ok` antes de dar el proceso por terminado.

Tamaño de lote recomendado: **de 500 a 2.000 ítems por solicitud**, según el ancho de las filas. Los payloads más grandes funcionan, pero aumentan la latencia y la probabilidad de un reintento a nivel de transporte.

## Trabajos asíncronos

Los endpoints `POST /v1/imports/*` aceptan un CSV multipart y devuelven de inmediato un `JobHandle`:

```json theme={null}
{ "job_id": "0b3c1f4a-9c1d-4f2a-8a3b-2c3d4e5f6a7b" }
```

Consulta el estado con `GET /v1/jobs/{job_id}`:

```json theme={null}
{
  "job_id": "0b3c1f4a-9c1d-4f2a-8a3b-2c3d4e5f6a7b",
  "job_type": "import_products",
  "status": "running",
  "progress": 47,
  "created_at": "2026-05-04T10:00:00Z",
  "started_at": "2026-05-04T10:00:01Z"
}
```

`status` es uno de `queued`, `running`, `completed`, `failed`. Una cadencia de sondeo razonable es cada **5-10 segundos** para trabajos activos y cada **30-60 segundos** para trabajos en cola.

## Síncrono vs asíncrono

| Quieres... | Usa | Familia de endpoints |
| - | - | - |
| Enviar unos pocos registros ahora mismo | Síncrono, JSON | `POST /v1/<entity>/{entity_id}` o `/bulk` |
| Refrescar un catálogo completo desde un CSV | Asíncrono, multipart | `POST /v1/imports/<entity>` y luego consultar `/v1/jobs/{id}` |

Consulta [Importaciones vs masivo](https://docs.retailgrid.io/es/api-reference/imports-vs-bulk.md) para ver el árbol de decisión completo.

## Decimales

Los importes, cantidades y tasas se devuelven como **cadenas de texto**, no como números de punto flotante. Esto evita las sorpresas de redondeo que tendrías con IEEE-754:

```json theme={null}
{ "regular_price": "19.99", "tax_rate": "0.20" }
```

Puedes enviarlos como números o como cadenas, pero espera cadenas en las respuestas. Analízalos con una biblioteca de decimales en el lado del cliente.

## Marcas de tiempo

Todas las marcas de tiempo están en **ISO 8601 en UTC**:

```text theme={null}
2026-05-04T10:00:00Z
```

Los campos de solo fecha usan `YYYY-MM-DD`. La API no realiza conversión de zona horaria - envía UTC, recibe UTC.

## Idempotencia

`POST /v1/<entity>/{entity_id}` es un **upsert con clave en el `entity_id` de la ruta**, lo que hace que sea seguro reintentarlo. `PATCH` también es idempotente a nivel de campo. `DELETE` es idempotente (eliminar una fila ya eliminada devuelve `204`).

Los endpoints `/bulk` son idempotentes por ítem, con clave en el identificador de negocio dentro de cada ítem (`item_id`, `sku`, etc.).

Hoy no existe la cabecera `Idempotency-Key` - la añadiremos antes de recomendar esta API para flujos cercanos a pagos.

## Paginación

Los endpoints de listado (productos, transacciones, Grids, trabajos, precios aprobados) usan **paginación basada en cursor**. Pasa `limit` para definir el tamaño de página y, para obtener la siguiente página, pasa el valor `cursor` devuelto como `next_cursor` en la respuesta anterior. Un `next_cursor` con valor `null` significa que no hay más filas.

## Límites de uso

El uso se mide **por organización** - el presupuesto se comparte entre todas las claves de API, todos los usuarios y el conector MCP, así que añadir más claves o repartir las llamadas entre endpoints no eleva tu límite. Cuando el presupuesto de uso de la organización se agota, la API rechaza la solicitud **antes** de realizar cualquier procesamiento costoso y devuelve `429 Too Many Requests`, una cabecera `Retry-After` y un cuerpo JSON que indica el límite, el margen restante y cuándo se restablece (consulta [Errores](https://docs.retailgrid.io/es/api-reference/errors.md)).

También se aplica un límite de uso independiente por clave, que igualmente devuelve `429` con una cabecera `Retry-After`. Los límites actuales son lo bastante amplios como para que los pipelines de sincronización bien diseñados no los alcancen; publicaremos aquí las cifras concretas cuando tengamos datos de producción estables. La única regla que importa para el diseño del pipeline: ante un `429`, espera y respeta `Retry-After` en lugar de reintentar de inmediato.


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