Comprenda los límites de tasa de la API de Zenovay y optimice su integración para mayor confiabilidad y rendimiento.
Descripción general de los límites de tasa
La API REST es una función de pago. Las claves de API solo funcionan en los planes Pro, Scale y Enterprise — las claves del plan Free se rechazan con una respuesta 403 API_PAID_PLAN_REQUIRED.
Límites de la API por plan
Estos límites se aplican a la API REST (endpoints bajo /api/external/v1/):
| Plan | Solicitudes/Minuto | Solicitudes/Mes |
|---|---|---|
| Pro | 30 | 10 000 |
| Scale | 60 | 100 000 |
| Enterprise | 120 | 1 000 000 |
Los límites se resuelven en función de la suscripción de su equipo. Si pertenece a varios equipos, la API usa el plan más alto del que es miembro.
Qué cuenta como solicitud
Cada llamada de API autenticada cuenta como una solicitud contra su cuota mensual — los endpoints de lectura (GET) y el endpoint de consulta (POST /query/:websiteId). La API REST es de solo lectura; no hay endpoints PUT, PATCH o DELETE.
Qué no cuenta
Las solicitudes que fallan en la autenticación (401, por ejemplo, una clave faltante o inválida) no cuentan contra su cuota, ya que la clave nunca se valida.
Encabezados de límite de tasa
Encabezados de respuesta
Cada respuesta de la API incluye encabezados de uso:
X-RateLimit-Limit: 30
X-Usage-Monthly: 4521
X-Usage-Limit: 10000
X-Usage-Reset: 2026-07-01T00:00:00.000Z
X-Usage-Total: 89234
| Encabezado | Descripción |
|---|---|
| X-RateLimit-Limit | Su límite de solicitudes por minuto |
| X-RateLimit-Remaining | Solicitudes restantes este minuto (no siempre presentes — ver abajo) |
| X-Usage-Monthly | Solicitudes usadas este mes |
| X-Usage-Limit | Límite mensual de solicitudes |
| X-Usage-Reset | Cuándo se reinicia el uso mensual (ISO 8601) |
| X-Usage-Total | Total de solicitudes jamás realizadas con esta clave |
X-RateLimit-Remaining solo se incluye cuando hay un conteo exacto de solicitudes restantes; trate su ausencia como normal y confíe en X-RateLimit-Limit más su propio conteo de solicitudes para presupuestar.
Leer los encabezados
const response = await fetch(url, { headers });
const limit = response.headers.get('X-RateLimit-Limit');
const remaining = response.headers.get('X-RateLimit-Remaining'); // puede ser null — ver nota arriba
const monthlyReset = response.headers.get('X-Usage-Reset'); // marca de tiempo ISO 8601
console.log(`${remaining ?? '?'}/${limit} solicitudes restantes este minuto`);
console.log(`El uso mensual se reinicia en ${monthlyReset}`);
Límite de tasa excedido
Respuesta
Cuando se excede el límite por minuto:
HTTP/1.1 429 Too Many Requests
Retry-After: 42
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded (30 requests/minute). Try again in 42 seconds",
"timestamp": "2026-06-13T12:00:00.000Z"
}
}
El 429 por minuto incluye un encabezado Retry-After (en segundos) que le indica cuánto tiempo esperar antes de reintentar.
Cuando se supera el monthly cuota, el cuerpo del error usa la misma forma con "code": "MONTHLY_LIMIT_EXCEEDED". Esta respuesta no lleva un encabezado Retry-After — en su lugar, verifique el encabezado X-Usage-Reset, que le dice cuándo se reinicia su asignación mensual (el primer día del mes siguiente).
Manejo de errores 429
async function apiRequest(url, options, retries = 3) {
const response = await fetch(url, options);
if (response.status === 429 && retries > 0) {
const retryAfter = response.headers.get('Retry-After') || 60;
console.log(`Rate limited. Waiting ${retryAfter}s...`);
await sleep(retryAfter * 1000);
return apiRequest(url, options, retries - 1);
}
return response;
}
Mejores prácticas
Caché
Almacene en caché las respuestas cuando sea posible:
const cache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5 minutos
async function getWithCache(endpoint) {
const cached = cache.get(endpoint);
if (cached && Date.now() - cached.time < CACHE_TTL) {
return cached.data;
}
const response = await api.get(endpoint);
cache.set(endpoint, { data: response, time: Date.now() });
return response;
}
Solicite solo lo que necesita
Use el filtro range para limitar los datos devueltos:
# Filtrar a un rango de tiempo específico:
GET /api/external/v1/analytics/WEBSITE_ID?range=7d
Use filtros de fecha
Limite los datos devueltos a períodos específicos (valores soportados: 24h, 7d, 30d, 90d, 1y):
# Obtener solo los últimos 30 días:
GET /api/external/v1/analytics/WEBSITE_ID?range=30d
Paginación
El endpoint de visitantes pagina con limit y offset (no números de página). limit tiene un valor por defecto de 100 y está limitado a 1000.
Solicitud
GET /api/external/v1/analytics/WEBSITE_ID/visitors?range=30d&limit=100&offset=0
Respuesta
{
"success": true,
"data": {
"visitors": [...],
"pagination": {
"limit": 100,
"offset": 0,
"has_more": true
}
},
"timestamp": "2026-06-13T12:00:00.000Z"
}
Paginación eficiente
Continúe solicitando páginas hasta que has_more sea false, incrementando offset por limit cada vez:
async function getAllVisitors(websiteId) {
let allVisitors = [];
let offset = 0;
const limit = 100;
let hasMore = true;
while (hasMore) {
const response = await api.get(
`/analytics/${websiteId}/visitors?limit=${limit}&offset=${offset}`
);
const { visitors, pagination } = response.data;
allVisitors = allVisitors.concat(visitors);
hasMore = pagination.has_more;
offset += limit;
// Respetar los límites de tasa
await sleep(100);
}
return allVisitors;
}
Retroceso exponencial
Implementación
async function requestWithBackoff(fn, maxRetries = 5) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await fn();
} catch (error) {
if (error.status === 429 && attempt < maxRetries - 1) {
const delay = Math.pow(2, attempt) * 1000 + Math.random() * 1000;
console.log(`Retry ${attempt + 1} after ${delay}ms`);
await sleep(delay);
} else {
throw error;
}
}
}
}
Calendario de retroceso
| Intento | Tiempo de espera |
|---|---|
| 1 | 1-2 segundos |
| 2 | 2-4 segundos |
| 3 | 4-8 segundos |
| 4 | 8-16 segundos |
| 5 | 16-32 segundos |
Monitoreo del uso
Verificar el uso actual
curl https://api.zenovay.com/api/external/v1/usage \
-H "X-API-Key: zv_YOUR_API_KEY"
Esto devuelve su recuento de solicitudes mensuales actual, cuota restante, límite de tasa por minuto y nivel de suscripción.
Cada respuesta de la API también lleva su uso en vivo en los encabezados (X-Usage-Monthly, X-Usage-Limit, X-Usage-Reset), permitiéndole rastrear el consumo sin una llamada separada.
En el panel
Abra Claves de API (app.zenovay.com/api-keys) para ver sus claves y los totales de solicitudes de cada clave, así como la actividad reciente. Use el endpoint GET /usage anterior para el recuento mensual preciso y la cuota restante.
Optimización para uso de alto volumen
Use endpoints agregados
Use el endpoint de resumen de análisis para obtener los totales de resumen en una sola llamada en lugar de paginar a través de registros de visitantes brutos:
# Una sola solicitud para el resumen de análisis:
GET /api/external/v1/analytics/WEBSITE_ID?range=30d
Esto devuelve un bloque summary (visitantes totales, vistas de página, visitantes únicos) más daily_stats en una sola respuesta. Para desgloses geográficos, por página o por dispositivo, use los endpoints dedicados /countries, /pages y /technology.
Límites de tasa Enterprise
Enterprise PlanLos planes Enterprise comienzan en los límites publicados más altos (120 solicitudes/minuto, 1 000 000 solicitudes/mes). Si necesita límites más altos, envíe un correo a [email protected] con:
- Sus patrones de uso actuales
- Crecimiento esperado
- Detalles de su caso de uso
Solución de problemas
Frecuentemente con límite de tasa
Si alcanza el límite por minuto a menudo:
- Agregue retrasos entre solicitudes (o una cola de solicitudes)
- Use retroceso exponencial en 429s
- Almacene en caché las respuestas que reutiliza
- Use endpoints agregados en lugar de muchas llamadas pequeñas
- Actualice su plan para un límite más alto
Cuota mensual agotada
Un MONTHLY_LIMIT_EXCEEDED (429) significa que ha utilizado su asignación mensual de solicitudes. Se reinicia el primer día del mes siguiente (ver el encabezado X-Usage-Reset). Actualice su plan para una cuota mensual más alta.
Límites inesperadamente bajos
Si sus límites parecen incorrectos:
- Verifique su nivel de plan — los límites se basan en la suscripción de su equipo
- Confirme que está usando una clave del equipo correcto
- Contacte con soporte