Comprenez les limites de débit de l'API Zenovay et optimisez votre intégration pour la fiabilité et les performances.
Aperçu des limites de débit
L'API REST est une fonctionnalité payante. Les clés API ne fonctionnent que sur les plans Pro, Scale et Enterprise — les clés du plan Free sont rejetées avec une réponse 403 API_PAID_PLAN_REQUIRED.
Limites de l'API par plan
Ces limites s'appliquent à l'API REST (endpoints sous /api/external/v1/) :
| Plan | Requêtes/minute | Requêtes/mois |
|---|---|---|
| Pro | 30 | 10 000 |
| Scale | 60 | 100 000 |
| Enterprise | 120 | 1 000 000 |
Les limites sont déterminées par l'abonnement de votre équipe. Si vous appartenez à plusieurs équipes, l'API utilise le plan le plus élevé dont vous êtes membre.
Qu'est-ce qui compte comme requête
Chaque appel API authentifié compte comme une requête par rapport à votre quota mensuel — les endpoints de lecture (GET) et l'endpoint de requête (POST /query/:websiteId). L'API REST est en lecture seule ; il n'y a pas d'endpoints PUT, PATCH ou DELETE.
Ce qui ne compte pas
Les requêtes qui échouent l'authentification (401, par exemple une clé manquante ou invalide) ne comptent pas par rapport à votre quota, car la clé n'est jamais validée.
Headers de limite de débit
Headers de réponse
Chaque réponse d'API inclut les headers d'utilisation :
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
| Header | Description |
|---|---|
| X-RateLimit-Limit | Votre limite de requêtes par minute |
| X-RateLimit-Remaining | Requêtes restantes cette minute (pas toujours présent — voir ci-dessous) |
| X-Usage-Monthly | Requêtes utilisées ce mois |
| X-Usage-Limit | Limite de requêtes mensuelles |
| X-Usage-Reset | Quand l'utilisation mensuelle se réinitialise (ISO 8601) |
| X-Usage-Total | Total des requêtes jamais effectuées avec cette clé |
X-RateLimit-Remaining n'est inclus que lorsqu'un nombre exact de requêtes restantes est disponible ; traitez son absence comme normale et appuyez-vous sur X-RateLimit-Limit plus votre propre décompte de requêtes pour votre budget.
Lire les headers
const response = await fetch(url, { headers });
const limit = response.headers.get('X-RateLimit-Limit');
const remaining = response.headers.get('X-RateLimit-Remaining'); // peut être null — voir la note ci-dessus
const monthlyReset = response.headers.get('X-Usage-Reset'); // horodatage ISO 8601
console.log(`${remaining ?? '?'}/${limit} requêtes restantes cette minute`);
console.log(`L'utilisation mensuelle se réinitialise à ${monthlyReset}`);
Limite de débit dépassée
Réponse
Quand la limite par minute est dépassée :
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"
}
}
Le 429 par minute inclut un header Retry-After (en secondes) vous indiquant combien de temps attendre avant de réessayer.
Quand le quota mensuel est dépassé, le corps d'erreur utilise la même forme avec "code": "MONTHLY_LIMIT_EXCEEDED". Cette réponse ne porte pas de header Retry-After — vérifiez plutôt le header X-Usage-Reset, qui vous indique quand votre allocation mensuelle se réinitialise (le premier du mois suivant).
Traiter les erreurs 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;
}
Meilleures pratiques
Mise en cache
Mettez en cache les réponses quand c'est possible :
const cache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes
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;
}
Demander uniquement ce dont vous avez besoin
Utilisez le filtre range pour limiter les données retournées :
# Filtrer sur une plage horaire spécifique:
GET /api/external/v1/analytics/WEBSITE_ID?range=7d
Utiliser les filtres de date
Limitez les données retournées à des périodes spécifiques (valeurs supportées : 24h, 7d, 30d, 90d, 1y) :
# Récupérer uniquement les 30 derniers jours :
GET /api/external/v1/analytics/WEBSITE_ID?range=30d
Pagination
L'endpoint des visiteurs pagine avec limit et offset (pas de numéros de page). limit vaut par défaut 100 et est limité à 1000.
Requête
GET /api/external/v1/analytics/WEBSITE_ID/visitors?range=30d&limit=100&offset=0
Réponse
{
"success": true,
"data": {
"visitors": [...],
"pagination": {
"limit": 100,
"offset": 0,
"has_more": true
}
},
"timestamp": "2026-06-13T12:00:00.000Z"
}
Pagination efficace
Continuez à demander des pages jusqu'à ce que has_more soit false, en augmentant offset de limit à chaque fois :
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;
// Respecter les limites de débit
await sleep(100);
}
return allVisitors;
}
Backoff exponentiel
Implémentation
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;
}
}
}
}
Calendrier de backoff
| Tentative | Temps d'attente |
|---|---|
| 1 | 1-2 secondes |
| 2 | 2-4 secondes |
| 3 | 4-8 secondes |
| 4 | 8-16 secondes |
| 5 | 16-32 secondes |
Surveillance de l'utilisation
Vérifier l'utilisation actuelle
curl https://api.zenovay.com/api/external/v1/usage \
-H "X-API-Key: zv_YOUR_API_KEY"
Cela retourne votre décompte de requêtes mensuelles actuel, votre quota restant, votre limite de débit par minute et votre niveau d'abonnement.
Chaque réponse d'API porte également votre utilisation en direct dans les headers (X-Usage-Monthly, X-Usage-Limit, X-Usage-Reset), vous permettant de suivre la consommation sans un appel séparé.
Dans le tableau de bord
Ouvrez Clés API (app.zenovay.com/api-keys) pour voir vos clés et les totaux de requêtes de chaque clé ainsi que l'activité récente. Utilisez l'endpoint GET /usage ci-dessus pour le décompte mensuel précis et le quota restant.
Optimisation pour une utilisation à grand volume
Utiliser les endpoints agrégés
Utilisez l'endpoint de vue d'ensemble des analyses pour obtenir les totaux des résumés en un seul appel au lieu de parcourir les enregistrements de visiteurs bruts :
# Un seul appel pour la vue d'ensemble des analyses:
GET /api/external/v1/analytics/WEBSITE_ID?range=30d
Cela retourne un bloc summary (total des visiteurs, pages vues, visiteurs uniques) plus daily_stats en une seule réponse. Pour les ventilations géographiques, par page ou par appareil, utilisez les endpoints dédiés /countries, /pages et /technology.
Limites de débit Enterprise
Enterprise PlanLes plans Enterprise commencent aux limites publiées les plus élevées (120 requêtes/minute, 1 000 000 requêtes/mois). Si vous avez besoin de limites plus élevées, envoyez un email à [email protected] avec :
- Vos modèles d'utilisation actuels
- Croissance attendue
- Détails de votre cas d'usage
Dépannage
Fréquemment limité par débit
Si vous atteignez souvent la limite par minute :
- Ajouter des délais entre les requêtes (ou une queue de requête)
- Utiliser le backoff exponentiel sur les 429s
- Mettre en cache les réponses que vous réutilisez
- Utiliser des endpoints agrégés au lieu de nombreux petits appels
- Améliorer votre plan pour une limite plus élevée
Quota mensuel épuisé
Un MONTHLY_LIMIT_EXCEEDED (429) signifie que vous avez utilisé votre allocation de requêtes mensuelles. Il se réinitialise le premier du mois suivant (voir le header X-Usage-Reset). Améliorez votre plan pour un quota mensuel plus élevé.
Limites étrangement basses
Si vos limites semblent incorrectes :
- Vérifiez votre niveau de plan — les limites sont basées sur l'abonnement de votre équipe
- Confirmez que vous utilisez une clé de la bonne équipe
- Contactez le support