# Límites de solicitudes

> Límites de solicitudes de la API y cómo gestionarlos

Source: https://docs.graph8.com/es/developers/rate-limits/

La API aplica límites de frecuencia por organización para garantizar un uso equitativo y la estabilidad de la plataforma.

> **Tip: Contexto de precios**
> El límite de frecuencia es el mismo en todos los planes. En el plan **Platform**, los endpoints respaldados por el índice de graph8 (búsqueda, consulta, validador de email interno) son ilimitados *dentro de este límite*: no existe un tope de volumen mensual. Consulte [Precios](https://docs.graph8.com/developers/pricing/) para ver el mapa completo de cuotas.

---

## Límites

| Ventana | Límite |
|--------|-------|
| Por segundo | 5 solicitudes |

Se aplica por organización en todos los endpoints de la API de datos. Al superar el límite, se devuelve `429 Too Many Requests`.

> **Note: Qué significa "ilimitado dentro del límite" en Platform**
> El plan Platform elimina el costo por registro en los endpoints respaldados por el índice de graph8, pero el tope de 5 solicitudes por segundo sigue vigente. No hay límite de volumen mensual: mientras se mantenga por debajo de 5 solicitudes por segundo, puede llamar a esos endpoints con la frecuencia que necesite.

---

## Encabezados de límite de frecuencia

Cuando una solicitud supera el límite de frecuencia, la respuesta incluye encabezados para facilitar el reintento:

| Encabezado | Descripción |
|--------|-------------|
| `Retry-After` | Segundos de espera antes de reintentar |
| `X-RateLimit-Limit-Second` | Límite por segundo (5) |

### Ejemplo de respuesta `429`

```
HTTP/1.1 429 Too Many Requests
Retry-After: 1
X-RateLimit-Limit-Second: 5
Content-Type: application/json

{"detail": "Rate limit exceeded. Please slow down."}
```

---

## Estrategia de reintento

Utilice retroceso exponencial con el encabezado `Retry-After`:

**Python**

```python
import time
import requests

def api_request(url, headers, max_retries=3):
    for attempt in range(max_retries):
        response = requests.get(url, headers=headers)

        if response.status_code != 429:
            return response

        retry_after = int(response.headers.get("Retry-After", 2 ** attempt))
        print(f"Rate limited. Retrying in {retry_after}s...")
        time.sleep(retry_after)

    return response  # Return last response if all retries exhausted
```

**TypeScript**

```typescript
async function apiRequest(url: string, headers: HeadersInit, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await fetch(url, { headers });

    if (response.status !== 429) return response;

    const retryAfter = parseInt(response.headers.get("Retry-After") || String(2 ** attempt));
    console.log(`Rate limited. Retrying in ${retryAfter}s...`);
    await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
  }
}
```

**cURL**

```bash
# Simple retry with backoff
for i in 1 2 3; do
  response=$(curl -s -w "\n%{http_code}" \
    "https://be.graph8.com/api/v1/contacts" \
    -H "Authorization: Bearer $API_KEY")

  status=$(echo "$response" | tail -1)

  if [ "$status" != "429" ]; then
    echo "$response" | head -n -1
    break
  fi

  echo "Rate limited, retrying in ${i}s..."
  sleep $i
done
```

---

## Buenas prácticas

- **Agrupe las lecturas por contacto** - en lugar de un `GET /contacts/{contact_id}/sequences` (o `/lists`) por contacto, envíe hasta 100 ids a `POST /contacts/related` con `{"contact_ids": [...], "include": ["sequences", "lists"]}`. Una solicitud, un solo cupo del límite de tasa; cada contacto vuelve con `found: true|false`.
- **Use paginación con límites altos**: obtenga 200 elementos por página en lugar de hacer 200 solicitudes individuales.
- **Espacie las solicitudes cada ~200 ms**: un intervalo de 200 ms lo mantiene con holgura por debajo de las 5 solicitudes por segundo, con margen para variaciones.
- **Almacene respuestas en caché**: si consulta los mismos datos de forma repetida, guárdelos en caché localmente para reducir las llamadas a la API.
- **Use retroceso exponencial, no bucles continuos**: cuando alcance el límite de frecuencia, respete siempre el encabezado `Retry-After` en lugar de reintentar de inmediato.

> **Tip:**
> A 5 solicitudes por segundo con un tamaño de página de 200, puede leer aproximadamente 60,000 registros por minuto: suficiente para exportar un espacio de trabajo completo en pocos minutos.
