Rate Limiting

Entiende los límites de uso de la API según tu plan.

Rate Limiting

KipuDev implementa rate limiting para garantizar un servicio estable y justo para todos los usuarios.

Límites por plan

PlanConsultas/díaRequests/minuto
Free10010
Basic2,00060
Pro10,000100
EnterpriseIlimitado500

Los límites se reinician diariamente a las 00:00 UTC-5 (hora de Lima/Perú).

Headers de respuesta

Cada respuesta incluye headers que te permiten monitorear tu uso:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 2025-12-20T05:00:00Z
HeaderDescripción
X-RateLimit-LimitLímite total diario de tu plan
X-RateLimit-RemainingConsultas restantes hoy
X-RateLimit-ResetFecha/hora cuando se reinicia el límite (ISO 8601)

Respuesta al exceder el límite

Cuando excedes tu límite diario:

{
  "error": "Has excedido el límite diario de consultas",
  "code": "DAILY_LIMIT_EXCEEDED",
  "limit": 100,
  "reset": "2025-12-20T05:00:00Z"
}

Cuando haces demasiadas solicitudes por minuto:

{
  "error": "Demasiadas solicitudes por minuto",
  "code": "RATE_LIMITED",
  "retryAfter": 45
}

Consumo por endpoint

Todos los endpoints consumen 1 consulta de tu cuota diaria:

EndpointConsumo
/api/contribuyentes/{ruc}1 consulta
/api/contribuyentes/search1 consulta
/api/tipocambio1 consulta
/api/cpe/validar1 consulta

Buenas prácticas

1. Monitorea tu uso

async function apiRequest(endpoint: string) {
  const response = await fetch(`https://api.kipudev.com${endpoint}`, {
    headers: { "X-API-KEY": process.env.KIPUDEV_API_KEY },
  });

  // Monitorear uso
  const remaining = response.headers.get("X-RateLimit-Remaining");
  const limit = response.headers.get("X-RateLimit-Limit");
  
  console.log(`Uso: ${limit - remaining}/${limit}`);
  
  // Alertar cuando quede poco
  if (remaining && parseInt(remaining) < 10) {
    console.warn("⚠️ Pocas consultas restantes:", remaining);
  }

  return response.json();
}

2. Implementa caché

Cachea las respuestas que no cambian frecuentemente para reducir consultas innecesarias.

const cache = new Map<string, { data: any; expires: number }>();

async function consultarRucConCache(ruc: string) {
  const cacheKey = `ruc:${ruc}`;
  const cached = cache.get(cacheKey);
  
  // Retornar del caché si no ha expirado (1 hora)
  if (cached && cached.expires > Date.now()) {
    return cached.data;
  }

  // Consultar API
  const data = await apiRequest(`/api/contribuyentes/${ruc}`);
  
  // Guardar en caché por 1 hora
  cache.set(cacheKey, {
    data,
    expires: Date.now() + 60 * 60 * 1000,
  });

  return data;
}

3. Agrupa consultas cuando sea posible

Si necesitas consultar múltiples RUCs, hazlo de forma secuencial con pequeñas pausas:

async function consultarMultiplesRuc(rucs: string[]) {
  const results: any[] = [];
  
  for (const ruc of rucs) {
    const data = await consultarRuc(ruc);
    results.push(data);
    
    // Pausa de 100ms entre solicitudes
    await new Promise(r => setTimeout(r, 100));
  }
  
  return results;
}

4. Maneja el rate limiting gracefully

async function apiRequestWithRetry(endpoint: string) {
  const response = await fetch(`https://api.kipudev.com${endpoint}`, {
    headers: { "X-API-KEY": process.env.KIPUDEV_API_KEY },
  });

  if (response.status === 429) {
    const data = await response.json();
    
    if (data.code === "DAILY_LIMIT_EXCEEDED") {
      // Límite diario - notificar al usuario
      throw new Error("Has alcanzado el límite diario. Actualiza tu plan.");
    }
    
    // Rate limit por minuto - esperar y reintentar
    const waitTime = data.retryAfter * 1000 || 60000;
    await new Promise(r => setTimeout(r, waitTime));
    return apiRequestWithRetry(endpoint); // Reintentar
  }

  return response.json();
}

Actualizar plan

Si necesitas más consultas, puedes actualizar tu plan en cualquier momento desde el dashboard.

NecesitasPlan recomendado
< 100 consultas/díaFree
100-2,000 consultas/díaBasic ($29/mes)
2,000-10,000 consultas/díaPro ($99/mes)
> 10,000 consultas/díaEnterprise

El plan Enterprise incluye soporte prioritario y SLA personalizado. Contáctanos para más información.