Skip to main content
placeanalyzerAPI ReferenceGuías

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

PlanPeticiones/minutoPeticiones/díaAvalúos simultáneos
Sandbox601,0005
Starter12010,00020
Professional30050,000100
EnterprisePersonalizadoPersonalizadoPersonalizado

Headers de Rate Limit

Cada respuesta de la API incluye headers informativos sobre tu uso actual:

HeaderDescripciónEjemplo
X-RateLimit-LimitLímite máximo de peticiones120
X-RateLimit-RemainingPeticiones restantes en la ventana95
X-RateLimit-ResetTimestamp Unix cuando se reinicia1704067200
Retry-AfterSegundos 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ácticaDescripción
Cachear respuestasGuarda resultados de avalúos completados localmente
Usar requestCodeReutiliza el requestCode en lugar de crear nuevos avalúos
Polling inteligenteUsa intervalos de 5-10 segundos, no más frecuente
Batch cuando sea posiblePara múltiples propiedades, usa el procesamiento en lote
Monitorear headersRevisa X-RateLimit-Remaining proactivamente

❌ Evitar

PrácticaPor qué
Polling muy frecuente< 5 segundos consume tu límite rápidamente
Reintentos inmediatosSin backoff, saturarás la API
Ignorar errores 429Puede resultar en bloqueo temporal
Crear avalúos duplicadosReutiliza requestCode existentes

Endpoints y su Impacto

No todos los endpoints consumen el rate limit de la misma manera:

EndpointPesoNotas
POST /valuation-request5xCrear avalúo consume más recursos
GET /valuation-request/{code}1xConsulta estándar
GET /valuation-request/{code}/result1xConsulta estándar
GET /near-properties1xConsulta estándar

Aumentar tu Límite

Si necesitas más capacidad:

  1. Contacta a ventas: Para planes Enterprise personalizados
  2. Optimiza tu uso: Revisa si estás haciendo peticiones innecesarias
  3. Usa caché: Reduce peticiones repetidas
  4. Procesamiento batch: Para grandes volúmenes, usa la API de lotes