Límites de uso

Dos capas protegen la API: una protección por IP de origen que va al frente de cada petición, y un cupo por organización y por endpoint. Ambas exponen su estado en headers estándar: léelos y tu cliente se autorregula.

5 min de lectura

El modelo de dos capas

CapaAlcanceLímiteCódigo al exceder
Protección por IPPor IP de origen35 000 solicitudes por minutoRATE_DDOS_EXCEEDED
Cupo por endpointPor organización y por endpointEspecífico de cada endpoint (ping admite 20 por minuto)RATE_TPS_EXCEEDED

La protección por IP corre primero: es un piso de seguridad, no un compromiso comercial. Llegar ahí suele indicar una IP compartida mal configurada o un patrón de abuso claro; el umbral es generoso y el tráfico legítimo no se acerca. El cupo por endpoint es el que verás en operación normal, y cada endpoint declara el suyo en la referencia.

Las dos capas cuentan distinto: la capa de IP suma todas las peticiones que salen de una misma IP, sin importar el endpoint; la capa de cupo suma las de un solo endpoint. Rotar endpoints no multiplica el presupuesto por IP, y rotar IPs no multiplica el cupo por endpoint.

Ventana deslizante, no bloques fijos

Las dos capas usan una ventana deslizante de dos bloques con peso, la misma técnica que usan Cloudflare y Stripe. La intuición:

  • El bloque actual de 60 segundos cuenta a peso completo.
  • El bloque anterior cuenta con un peso que decrece de 1.0 (inicio del bloque actual) a 0.0 (final del bloque actual).
  • El total efectivo es actual + anterior × peso.

Con bloques fijos, un cliente podría mandar el límite completo en el segundo 59 y otro tanto en el segundo 0 del bloque siguiente: el doble del límite en dos segundos. La ventana deslizante atrapa eso.

Headers de respuesta

La API sigue el RFC 9598 (RateLimit Header Fields for HTTP). Cada respuesta protegida por cupo lleva:

HTTP
RateLimit-Limit:     20
RateLimit-Remaining: 18
RateLimit-Reset:     31
RateLimit-Policy:    20;w=60;name="endpoint"
RateLimit-Limit
Cupo de la ventana activa.
RateLimit-Remaining
Solicitudes restantes en la ventana activa.
RateLimit-Reset
Segundos hasta que la ventana activa se reinicia.
RateLimit-Policy
Cupo declarativo, en formato interpretable. 20;w=60 significa 20 solicitudes en una ventana deslizante de 60 segundos.

En un 429 además recibes Retry-After en segundos: espera al menos ese tiempo antes de reintentar.

Estrategia recomendada

  1. 01
    Regula de forma preventiva

    Lee RateLimit-Remaining en cada respuesta. Cuando baje del 20 % de RateLimit-Limit, reduce tu ritmo para llegar al próximo reinicio con margen.

  2. 02
    Respeta Retry-After

    Cuando recibes un 429, espera al menos los segundos que indica antes del próximo intento. Reintentar de inmediato solo vuelve a disparar el contador.

  3. 03
    Retroceso exponencial con variación

    Si los reintentos siguen fallando, suma un retraso exponencial (por ejemplo 2^n × 100 ms) con una variación aleatoria de ±50 %. La variación evita que miles de clientes se sincronicen en el mismo segundo.

Implementación de referencia
import time, random

def call_with_backoff(client, request, max_retries=5):
    for attempt in range(max_retries):
        r = client.send(request)
        if r.status_code != 429:
            return r
        wait = int(r.headers.get("Retry-After", "1"))
        # retroceso exponencial con techo en Retry-After * 4, mas variacion
        delay = min(wait * (2 ** attempt), wait * 4)
        delay += random.uniform(0, delay * 0.5)
        time.sleep(delay)
    return r  # quien llama decide que hacer al agotar los intentos

Si escribes tu propio cliente, interpretar la política es directo:

JavaScript
// RateLimit-Policy: 20;w=60;name="endpoint"
// -> limite 20, ventana 60 s, nombre "endpoint"
const [limit, ...params] = policy.split(';')
const window = Number(params.find((p) => p.startsWith('w='))?.slice(2))

Lo que ves cuando se dispara

Las dos capas devuelven HTTP 429 con la envoltura estándar. El error.code te dice cuál se disparó:

429 Too Many Requests
RateLimit-Limit:     20
RateLimit-Remaining: 0
RateLimit-Reset:     42
Retry-After:         42

{
  "success": false,
  "error": {
    "code": "RATE_TPS_EXCEEDED",
    "message": "You have exceeded the allowed request rate for this endpoint."
  }
}

Pedir un límite más alto

Si tu patrón de tráfico excede legítimamente el cupo de un endpoint (cargas masivas, campañas, altas por lotes), habla con tu asesor comercial. Podemos subir el límite de tu organización para un endpoint específico sin tocar el piso de protección por IP. Ten a mano:

  • Pico esperado y volumen diario total.
  • Si el pico es puntual (un lanzamiento) o sostenido.
  • Cómo haces el retroceso cuando te limitan, para saber que el aumento no solo desplaza el problema.