Volver a Inicio

Límites de Tasa

Entiende los límites de tasa de la API de ReciGo y cómo manejarlos.

Límites Predeterminados

100

Solicitudes por minuto

Por API key

60

Segundos de ventana

Ventana deslizante

Nota: El límite de 100 solicitudes por minuto se aplica por API key. Si necesitas un límite mayor, contacta a partners@recigo.es

Cómo Funciona

ReciGo utiliza un algoritmo de ventana deslizante para limitar las solicitudes:

Ventana Deslizante de 60 Segundos

El límite de tasa rastrea las solicitudes en los últimos 60 segundos (no por minuto calendario).

09:00:00 → Solicitud 1
09:00:15 → Solicitud 2
09:00:30 → Solicitud 3
...
09:00:59 → Solicitud 100 ✅
09:01:00 → Solicitud 101 ❌ (límite excedido)
09:01:01 → Solicitud 102 ✅ (solicitud 1 ya no cuenta)

Por API Key

Cada API key tiene su propio límite independiente. Si tienes múltiples API keys (por ejemplo, una para producción y otra para pruebas), cada una tiene su límite de 100 solicitudes por minuto.

Todos los Endpoints Cuentan

Todas las solicitudes a cualquier endpoint cuentan hacia el límite:

  • POST /v1/pricing/estimate
  • POST /v1/jobs
  • GET /v1/jobs/{job_id}

Headers de Respuesta

Cada respuesta incluye headers que te informan sobre el estado de tu límite de tasa:

HTTP/1.1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1645456800
X-RateLimit-Limit

El límite máximo de solicitudes por minuto para tu API key (normalmente 100).

X-RateLimit-Remaining

Cuántas solicitudes te quedan en la ventana actual. Cuando llega a 0, recibirás un error 429.

X-RateLimit-Reset

Timestamp Unix (en segundos) de cuándo se restablecerá la ventana. Úsalo para calcular cuánto tiempo debes esperar.

Error 429: Too Many Requests

Si excedes el límite de tasa, recibirás un error HTTP 429:

HTTP 429 Too Many Requests
{
  "error": "rate_limit_exceeded",
  "message": "Has excedido el límite de solicitudes",
  "retry_after_seconds": 45
}

Importante: El campo retry_after_seconds te indica cuántos segundos debes esperar antes de hacer otra solicitud.

Headers Adicionales

HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1645456845
Retry-After: 45

Mejores Prácticas

1. Monitorea los headers de límite de tasa

Revisa X-RateLimit-Remaining en cada respuesta. Si se está acercando a 0, reduce la frecuencia de solicitudes.

2. Implementa reintentos con backoff exponencial

Cuando recibas un error 429, espera el tiempo indicado en retry_after_seconds antes de reintentar.

3. Usa caché cuando sea posible

Si consultas el estado de trabajos frecuentemente, considera implementar caché local para reducir solicitudes innecesarias.

4. Distribuye las solicitudes en el tiempo

En lugar de hacer 100 solicitudes en ráfaga, distribúyelas uniformemente a lo largo del minuto (por ejemplo, 1-2 solicitudes por segundo).

5. Evita polling agresivo

No consultes el estado de trabajos cada segundo. Para la mayoría de casos, consultar cada 5-10 minutos es suficiente. Recuerda: ReciGo usa un modelo fire-and-forget.

6. Usa batch operations cuando sea posible

Si necesitas crear múltiples trabajos, considera hacerlo en lotes con pausas entre ellos en lugar de crear todos simultáneamente.

Ejemplos de Código

Ejemplo 1: Verificar Límite de Tasa

check-rate-limit.ts
async function makeRequest() {
  const response = await fetch('https://api.recigo.es/v1/jobs', {
    method: 'POST',
    headers: {
      'X-API-Key': process.env.RECIGO_API_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      // ... job data
    }),
  });

  // Verificar headers de límite de tasa
  const rateLimit = {
    limit: parseInt(response.headers.get('X-RateLimit-Limit') || '100'),
    remaining: parseInt(response.headers.get('X-RateLimit-Remaining') || '0'),
    reset: parseInt(response.headers.get('X-RateLimit-Reset') || '0'),
  };

  console.log(`Límite: ${rateLimit.limit}`);
  console.log(`Restante: ${rateLimit.remaining}`);
  console.log(`Reset: ${new Date(rateLimit.reset * 1000).toISOString()}`);

  // Advertir si quedan pocas solicitudes
  if (rateLimit.remaining < 10) {
    console.warn('⚠️ Quedan pocas solicitudes disponibles');
  }

  return response.json();
}

Ejemplo 2: Reintento con Backoff Exponencial

retry-with-backoff.ts
async function makeRequestWithRetry(
  maxRetries = 3,
  baseDelay = 1000
): Promise<any> {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      const response = await fetch('https://api.recigo.es/v1/jobs', {
        method: 'POST',
        headers: {
          'X-API-Key': process.env.RECIGO_API_KEY,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          // ... job data
        }),
      });

      const data = await response.json();

      // Éxito
      if (response.ok) {
        return data;
      }

      // Error 429: Too Many Requests
      if (response.status === 429) {
        const retryAfter = data.retry_after_seconds || 60;
        console.log(`⏳ Límite excedido. Esperando ${retryAfter}s...`);
        await sleep(retryAfter * 1000);
        continue; // Reintentar
      }

      // Error 5xx: Server Error
      if (response.status >= 500) {
        const delay = baseDelay * Math.pow(2, attempt); // Backoff exponencial
        console.log(`⏳ Error del servidor. Esperando ${delay}ms...`);
        await sleep(delay);
        continue; // Reintentar
      }

      // Otros errores (4xx): No reintentar
      throw new Error(`API Error: ${data.message}`);

    } catch (error) {
      if (attempt === maxRetries - 1) {
        throw error; // Último intento fallido
      }
      console.log(`Intento ${attempt + 1} fallido, reintentando...`);
    }
  }

  throw new Error('Máximo de reintentos alcanzado');
}

function sleep(ms: number) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

Ejemplo 3: Rate Limiter Cliente

rate-limiter.ts
class RateLimiter {
  private queue: Array<() => Promise<any>> = [];
  private processing = false;
  private requestsPerMinute: number;
  private minInterval: number;

  constructor(requestsPerMinute = 90) { // 90 para estar seguro (límite es 100)
    this.requestsPerMinute = requestsPerMinute;
    this.minInterval = 60000 / requestsPerMinute; // ms entre solicitudes
  }

  async add<T>(fn: () => Promise<T>): Promise<T> {
    return new Promise((resolve, reject) => {
      this.queue.push(async () => {
        try {
          const result = await fn();
          resolve(result);
        } catch (error) {
          reject(error);
        }
      });

      if (!this.processing) {
        this.process();
      }
    });
  }

  private async process() {
    this.processing = true;

    while (this.queue.length > 0) {
      const fn = this.queue.shift();
      if (fn) {
        await fn();
        await this.sleep(this.minInterval);
      }
    }

    this.processing = false;
  }

  private sleep(ms: number) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }
}

// Uso
const limiter = new RateLimiter(90); // 90 solicitudes por minuto

async function createJob(jobData: any) {
  return limiter.add(async () => {
    const response = await fetch('https://api.recigo.es/v1/jobs', {
      method: 'POST',
      headers: {
        'X-API-Key': process.env.RECIGO_API_KEY,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(jobData),
    });
    return response.json();
  });
}

// Crear múltiples trabajos respetando el límite
const jobs = [job1Data, job2Data, job3Data];
const results = await Promise.all(jobs.map(createJob));

Solicitar Límites Mayores

Si tu caso de uso requiere más de 100 solicitudes por minuto, podemos aumentar tu límite.

Para solicitar un aumento:

  1. Contacta a partners@recigo.es
  2. Proporciona tu API key (prefijo)
  3. Explica tu caso de uso y volumen esperado
  4. Describe las medidas que has tomado para optimizar solicitudes

Nota: Los límites aumentados se revisan caso por caso. Asegúrate de haber implementado las mejores prácticas antes de solicitar un aumento.

Explorar Más