# Límites de uso

Cuántas peticiones por minuto admite la API y cómo reaccionar a un 429.

## Los límites

| Límite                                         | Valor              |
| ---------------------------------------------- | ------------------ |
| Peticiones por API key                         | **300 por minuto** |
| Peticiones por cuenta (sumando todas sus keys) | **600 por minuto** |
| Escrituras (`POST` y `PATCH`) por API key      | **60 por minuto**  |

Las ventanas son de un minuto y empiezan con la primera petición. Si superas cualquiera de los tres, la respuesta es `429 RATE_LIMITED`.

Estos valores pueden ajustarse con el tiempo: en vez de fijarlos en tu código, guíate por los headers de cada respuesta.

## Headers

Las respuestas a peticiones autenticadas traen:

| Header                | Qué dice                                                          |
| --------------------- | ----------------------------------------------------------------- |
| `RateLimit-Limit`     | El límite que aplica (normalmente, el de tu key).                 |
| `RateLimit-Remaining` | Cuántas peticiones te quedan en la ventana actual.                |
| `RateLimit-Reset`     | Segundos hasta que la ventana se reinicia.                        |
| `Retry-After`         | Solo en un `429`: segundos que debes esperar antes de reintentar. |

Cuando el `429` lo causa el límite de la cuenta o el de escrituras, los headers `RateLimit-*` de esa respuesta describen ese límite. El cuerpo del error trae también `retry_after`.

```json
{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Superaste 60 escrituras por minuto con esta key. Espera y reintenta.",
    "retry_after": 23,
    "request_id": "req_…"
  }
}
```

## Cómo reaccionar

- Ante un `429`, **espera lo que indica `Retry-After`** y reintenta. No reintentes antes: seguirás recibiendo `429`.
- Para `500` y errores de red, usa **espera exponencial con variación aleatoria** (por ejemplo 1 s, 2 s, 4 s, 8 s… con ±20 % al azar) y un máximo de intentos.
- Si reintentas un `POST`, usa el **mismo** `Idempotency-Key`.
- Si importas muchos datos, reparte las escrituras: 60 por minuto son una por segundo.
- Prefiere los [webhooks](https://developers.posdata.so/webhooks/) y la [sincronización incremental](https://developers.posdata.so/paginacion/#receta-sincronizaci%C3%B3n-incremental) a consultar lo mismo cada pocos segundos.

```js
// Node.js 20+ — retry with Retry-After and exponential backoff (sketch)
async function posdataFetch(url, options = {}, attempt = 0) {
  const res = await fetch(url, options);
  if (res.status !== 429 && res.status < 500) return res;
  if (attempt >= 5) return res;

  const retryAfter = Number(res.headers.get('Retry-After'));
  const backoff = 1000 * 2 ** attempt * (0.8 + Math.random() * 0.4);
  const waitMs = Number.isFinite(retryAfter) && retryAfter > 0 ? retryAfter * 1000 : backoff;
  await new Promise((resolve) => setTimeout(resolve, waitMs));
  // Same options → same Idempotency-Key on POST retries.
  return posdataFetch(url, options, attempt + 1);
}
```

---

Fuente: https://developers.posdata.so/limites/ · Índice para agentes: https://developers.posdata.so/llms.txt
