Límites de Tasa
Entiende los límites de tasa de la API de ReciGo y cómo manejarlos.
Límites Predeterminados
Solicitudes por minuto
Por API key
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: 1645456800X-RateLimit-LimitEl límite máximo de solicitudes por minuto para tu API key (normalmente 100).
X-RateLimit-RemainingCuántas solicitudes te quedan en la ventana actual. Cuando llega a 0, recibirás un error 429.
X-RateLimit-ResetTimestamp 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:
{
"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: 45Mejores 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
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
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
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:
- Contacta a partners@recigo.es
- Proporciona tu API key (prefijo)
- Explica tu caso de uso y volumen esperado
- 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.