Docs/API y webhooks/Límites de tasa

Límites de tasa

SecureCodingHub aplica un límite por minuto y por hora sobre cada API key. Los límites están pensados para ser invisibles durante el uso normal y para frenar scripts descontrolados antes de que saturen la plataforma.

Límites por defecto

VentanaLímiteHeader
Por minuto60 solicitudesX-RateLimit-Window: per_minute
Por hora1.000 solicitudesX-RateLimit-Window: per_hour

Ambas ventanas se evalúan en cada solicitud. La ventana más estrecha (60/minuto) gobierna los picos cortos; la ventana de hora gobierna la carga sostenida. Si se excede cualquiera de las dos, la solicitud se rechaza con 429 Too Many Requests: no necesitas inspeccionar qué ventana ha saltado, solo respetar el header Retry-After.

Respuesta al rechazo

HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-RateLimit-Window: per_minute
X-RateLimit-Limit: 60

{ "error": "rate_limited" }

Retry-After es siempre un número entero de segundos: el menor retraso seguro antes de que la próxima solicitud tenga éxito. X-RateLimit-Limit refleja el tope de la ventana que ha saltado.

Ventanas deslizantes vs. fijas

La ventana por minuto se fija al minuto del calendario (UTC). Una solicitud en 13:42:59 y otra en 13:43:01 caen en buckets distintos. La ventana por hora es un agregado deslizante real sobre los últimos 60 minutos. Esto significa que, durante el uso normal, nunca saltarás el tope horario salvo que también estés saltando el de minuto repetidamente.

Comportamiento recomendado del cliente

  • Ante un 429, duerme al menos Retry-After segundos y reintenta una vez.
  • Usa jitter: retryAfter + random(0, 5) segundos para evitar el thundering herd cuando muchos workers tocan el límite a la vez.
  • Si controlas el tamaño de lote, no superes 50 solicitudes/minuto por clave: te mantiene cómodamente por debajo del tope.
  • Para trabajos de alto volumen (exportación de datos, aprovisionamiento masivo de usuarios), emite una clave por worker en vez de compartir una sola.
  • No trates 429 como un error sobre el que alertar. Alerta solo ante fallos repetidos tras backoff exponencial.

Patrón de reintento

Un ejemplo mínimo en Node que respeta Retry-After con jitter:

async function call(path) {
  for (let attempt = 0; attempt < 4; attempt++) {
    const res = await fetch(`https://api.limeplate.com${path}`, {
      headers: { Authorization: `Bearer ${process.env.SCH_API_KEY}` },
    });
    if (res.status !== 429) return res;
    const wait = parseInt(res.headers.get('Retry-After') || '60', 10);
    const jitter = Math.floor(Math.random() * 5);
    await new Promise(r => setTimeout(r, (wait + jitter) * 1000));
  }
  throw new Error('exhausted retries on 429');
}

Solicitar una cuota mayor

La mayoría de integraciones encajan cómodamente dentro de los límites por defecto. Si tu carga de trabajo realmente necesita un tope mayor —por ejemplo, una actualización nocturna en Looker que descarga el progreso de 10.000 usuarios— escribe a support@securecodinghub.com indicando el nombre de la API key, el propósito de la integración y el pico de solicitudes/minuto que esperas. Podemos elevar los límites por clave sin rotar el token.

Qué no está limitado por tasa

Las entregas entrantes de webhooks que aceptas de SecureCodingHub no están limitadas por tasa desde nuestro lado. Las entregas salientes que enviamos a tu endpoint siguen un calendario de reintentos aparte, documentado en Webhooks.