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.

6 min de lectura

El modelo de dos capas

CapaAlcanceLímiteCódigo al exceder
Protección por IPPor IP de origen (IPv6: por bloque /64)35 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.

IPv6: se cuenta el bloque /64

Con IPv6, la protección por IP no cuenta la dirección exacta sino su bloque /64. A cada conexión IPv6 se le asigna un /64 entero, así que quien la usa puede estrenar dirección en cada petición sin cambiar de red: contar la dirección exacta no pondría ningún tope. Todas las direcciones de un mismo /64 comparten los 35 000 por minuto. Las IPv4 se cuentan una por una, como siempre.

El corte por API keys que no existen

La protección por IP tiene una segunda regla, para quien prueba keys al azar. Si desde una misma IP (o un mismo /64) llegan 60 API keys distintas que no autentican en un minuto —que no existen, o que fueron revocadas o vencieron—, esa IP queda cortada 15 minutos: toda petición recibe 429 RATE_DDOS_EXCEEDED con un Retry-After que dice cuánto le queda al corte, aunque la key que envíes sea válida.

  • Cuentan las keys distintas, no los intentos: una integración que sigue mandando la misma key revocada recibe 401 AUTH_INVALID_KEY cada vez, pero no llega al corte.
  • Solo cuentan las keys que no autentican. Una key válida sin permiso para el servicio, de una organización suspendida o usada desde una red que no permite no suma: existe, y no se fabrica al azar.
  • Si tu integración reparte el tráfico entre varias keys, revisa que ninguna esté mal copiada o revocada: detrás de una misma salida a internet, todas cuentan juntas.

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.