Rate Limiting
Para garantizar la estabilidad y disponibilidad de la API para todos los usuarios, Place Analyzer implementa límites de peticiones (rate limiting). Esta guía te ayudará a entender los límites y cómo manejarlos correctamente.
Límites por Plan
| Plan | Peticiones/minuto | Peticiones/día | Avalúos simultáneos |
|---|---|---|---|
| Sandbox | 60 | 1,000 | 5 |
| Starter | 120 | 10,000 | 20 |
| Professional | 300 | 50,000 | 100 |
| Enterprise | Personalizado | Personalizado | Personalizado |
Headers de Rate Limit
Cada respuesta de la API incluye headers informativos sobre tu uso actual:
| Header | Descripción | Ejemplo |
|---|---|---|
X-RateLimit-Limit | Límite máximo de peticiones | 120 |
X-RateLimit-Remaining | Peticiones restantes en la ventana | 95 |
X-RateLimit-Reset | Timestamp Unix cuando se reinicia | 1704067200 |
Retry-After | Segundos a esperar (solo en 429) | 30 |
Respuesta de Rate Limit Excedido
Cuando superas el límite, recibirás un error 429 Too Many Requests:
{ "error": { "code": "RATE_LIMIT_EXCEEDED", "message": "Has excedido el límite de peticiones. Intenta de nuevo en 30 segundos.", "retryAfter": 30 } }
Estrategias de Manejo
1. Exponential Backoff
La estrategia recomendada para reintentos automáticos:
async function fetchWithRetry(url, options, maxRetries = 3) { for (let attempt = 0; attempt < maxRetries; attempt++) { const response = await fetch(url, options); if (response.status === 429) { const retryAfter = response.headers.get('Retry-After') || Math.pow(2, attempt); console.log(`Rate limited. Esperando ${retryAfter} segundos...`); await new Promise(resolve => setTimeout(resolve, retryAfter * 1000)); continue; } return response; } throw new Error('Máximo de reintentos alcanzado'); }
import time import requests def fetch_with_retry(url, headers, max_retries=3): for attempt in range(max_retries): response = requests.get(url, headers=headers) if response.status_code == 429: retry_after = int(response.headers.get('Retry-After', 2 ** attempt)) print(f"Rate limited. Esperando {retry_after} segundos...") time.sleep(retry_after) continue return response raise Exception('Máximo de reintentos alcanzado')
2. Monitoreo Proactivo
Verifica los headers antes de quedarte sin peticiones:
function checkRateLimit(response) { const remaining = parseInt(response.headers.get('X-RateLimit-Remaining')); const limit = parseInt(response.headers.get('X-RateLimit-Limit')); const resetTime = parseInt(response.headers.get('X-RateLimit-Reset')); const usage = ((limit - remaining) / limit) * 100; if (usage > 80) { console.warn(`⚠️ Uso de rate limit alto: ${usage.toFixed(1)}%`); console.warn(` Reinicio en: ${new Date(resetTime * 1000).toISOString()}`); } return { remaining, limit, resetTime, usage }; }
3. Cola de Peticiones
Para aplicaciones con alto volumen, implementa una cola:
class RequestQueue { constructor(requestsPerMinute = 60) { this.queue = []; this.processing = false; this.interval = 60000 / requestsPerMinute; // ms entre peticiones } async add(requestFn) { return new Promise((resolve, reject) => { this.queue.push({ requestFn, resolve, reject }); this.process(); }); } async process() { if (this.processing || this.queue.length === 0) return; this.processing = true; const { requestFn, resolve, reject } = this.queue.shift(); try { const result = await requestFn(); resolve(result); } catch (error) { reject(error); } setTimeout(() => { this.processing = false; this.process(); }, this.interval); } } // Uso const queue = new RequestQueue(60); // 60 req/min const results = await Promise.all([ queue.add(() => fetch('/valuation-request/abc-123')), queue.add(() => fetch('/valuation-request/def-456')), queue.add(() => fetch('/valuation-request/ghi-789')), ]);
Mejores Prácticas
✅ Recomendado
| Práctica | Descripción |
|---|---|
| Cachear respuestas | Guarda resultados de avalúos completados localmente |
| Usar requestCode | Reutiliza el requestCode en lugar de crear nuevos avalúos |
| Polling inteligente | Usa intervalos de 5-10 segundos, no más frecuente |
| Batch cuando sea posible | Para múltiples propiedades, usa el procesamiento en lote |
| Monitorear headers | Revisa X-RateLimit-Remaining proactivamente |
❌ Evitar
| Práctica | Por qué |
|---|---|
| Polling muy frecuente | < 5 segundos consume tu límite rápidamente |
| Reintentos inmediatos | Sin backoff, saturarás la API |
| Ignorar errores 429 | Puede resultar en bloqueo temporal |
| Crear avalúos duplicados | Reutiliza requestCode existentes |
Endpoints y su Impacto
No todos los endpoints consumen el rate limit de la misma manera:
| Endpoint | Peso | Notas |
|---|---|---|
POST /valuation-request | 5x | Crear avalúo consume más recursos |
GET /valuation-request/{code} | 1x | Consulta estándar |
GET /valuation-request/{code}/result | 1x | Consulta estándar |
GET /near-properties | 1x | Consulta estándar |
Aumentar tu Límite
Si necesitas más capacidad:
- Contacta a ventas: Para planes Enterprise personalizados
- Optimiza tu uso: Revisa si estás haciendo peticiones innecesarias
- Usa caché: Reduce peticiones repetidas
- Procesamiento batch: Para grandes volúmenes, usa la API de lotes