API REST publique
Récupérer les statistiques de vos sites avec une clé API, pour les afficher dans votre propre dashboard.
L'API publique de Sessio donne accès, en lecture seule, aux données de vos sites : statistiques, visiteurs, sessions, événements, erreurs et heatmaps. Elle sert à intégrer vos chiffres dans votre propre dashboard, publier un widget de trafic, générer un rapport hebdomadaire ou piloter plusieurs outils depuis les mêmes données.
Toutes les routes sont préfixées /api/public/v1 et s'authentifient avec une simple clé API. Aucune route ne modifie vos données.
Base URL : https://api-sessio.flamme.work, suivie du préfixe /api/public/v1. Tous les exemples ci-dessous l'utilisent en préfixe complet.
#Créer une clé API
- Ouvrez le dashboard, page Clés API (
/app/api-keys). - Créez une clé : elle est affichée une seule fois, à la création. Copiez-la sur le moment.
- Donnez-lui uniquement les scopes dont vous avez besoin.
- Révoquez-la à tout moment depuis la même page : une clé révoquée cesse de fonctionner immédiatement.
Une clé API donne accès à vos données : elle reste côté serveur (voir Intégration côté serveur).
#Authentification
Deux en-têtes, équivalents, à placer sur chaque requête :
# En-tête recommandé
curl -H "Authorization: Bearer sk_live_VOTRE_CLE" \
"https://api-sessio.flamme.work/api/public/v1/sites"
# Variante
curl -H "X-Api-Key: sk_live_VOTRE_CLE" \
"https://api-sessio.flamme.work/api/public/v1/sites"Sans en-tête, la réponse est 401 avec le code missing_api_key ; une clé inconnue ou révoquée renvoie 401 invalid_api_key.
#Les scopes
Chaque clé porte des scopes, qui limitent ce qu'elle peut lire. Une route demandant un scope absent de la clé renvoie 403 insufficient_scope.
| Scope | Donne accès à |
|---|---|
stats:read |
Sites, statistiques, plan |
visitors:read |
Visiteurs |
sessions:read |
Sessions (métadonnées ; le replay reste réservé au dashboard) |
events:read |
Événements et erreurs |
heatmap:read |
Heatmaps |
Les adresses IP des visiteurs ne sont jamais renvoyées par l'API publique.
#Rate limiting
Chaque clé a le droit à 120 requêtes par minute (réglage serveur API_RATE_LIMIT). Chaque réponse porte les en-têtes RateLimit-* : quota, reste, remise à zéro. Au-delà, la réponse est 429 avec le code rate_limited.
#Les erreurs
Toute erreur a la même forme :
{
"error": {
"code": "invalid_period",
"message": "Période invalide."
}
}| Code | HTTP | Quand |
|---|---|---|
missing_api_key |
401 | Aucun en-tête d'authentification. |
invalid_api_key |
401 | Clé inconnue, révoquée ou appartenant à un autre compte. |
insufficient_scope |
403 | La clé n'a pas le scope exigé par la route. |
tenant_suspended |
403 | Le compte est suspendu. |
site_not_found |
404 | Site inconnu, ou hors du périmètre de la clé. |
not_found |
404 | Ressource inconnue (visiteur, session…). |
invalid_period |
422 | Période non reconnue, ou fenêtre de plus de 366 jours. |
invalid_param |
422 | Paramètre manquant ou invalide. |
rate_limited |
429 | Quota de 120 requêtes/min dépassé. |
internal_error |
500 | Erreur serveur. |
#Les périodes
Presque toutes les routes acceptent period :
| Valeur | Période |
|---|---|
today |
Aujourd'hui (valeur par défaut) |
weekly |
Cette semaine |
monthly |
Ce mois-ci |
yearly |
Cette année |
custom:YYYY-MM-DD:YYYY-MM-DD |
Une fenêtre libre, 366 jours au maximum |
Exemple : period=custom:2026-01-01:2026-03-31.
#La pagination
Les routes qui renvoient des listes acceptent limit (200 au maximum) et offset. La réponse porte le total et la fenêtre demandée :
{
"total": 1284,
"limit": 20,
"offset": 0,
"visitors": []
}Le nom de la collection (visitors, sessions, events…) suit la route appelée.
#Les routes
Toutes les routes sont en GET.
| Route | Scope | Params principaux |
|---|---|---|
/api/public/v1/openapi.json |
aucun (publique) | Spécification OpenAPI 3.1 complète |
/api/public/v1/sites |
stats:read |
— (les sites du compte de la clé) |
/api/public/v1/stats/overview |
stats:read |
site_id (requis), period |
/api/public/v1/stats/pages |
stats:read |
idem + limit, offset, sort |
/api/public/v1/stats/devices |
stats:read |
site_id, period |
/api/public/v1/stats/audience |
stats:read |
site_id, period |
/api/public/v1/stats/referrers |
stats:read |
site_id, period |
/api/public/v1/stats/countries |
stats:read |
site_id, period |
/api/public/v1/plan |
stats:read |
— (plan et usage du compte) |
/api/public/v1/visitors |
visitors:read |
site_id, period, limit, offset, search, url, device, referrer_type, sort |
/api/public/v1/visitors/:id |
visitors:read |
site_id |
/api/public/v1/sessions |
sessions:read |
site_id, period, limit, offset, visitor_id, has_replay |
/api/public/v1/events |
events:read |
site_id, period, limit, offset |
/api/public/v1/errors |
events:read |
site_id, period, kind, limit, offset |
/api/public/v1/heatmap/pages |
heatmap:read |
site_id, period |
/api/public/v1/heatmap/data |
heatmap:read |
site_id, url, type, device, period |
/api/public/v1/heatmap/scroll |
heatmap:read |
site_id, period |
Les définitions exactes de chaque indicateur se lisent dans Lire le tableau de bord ; les schémas de réponse complets, dans la spécification OpenAPI.
#Le champ identified_label
GET /visitors, GET /visitors/:id et GET /sessions renvoient identified_label : l'identifiant lisible du visiteur (prénom, email…), transmis par votre site grâce à Sessio.identify(). Il vaut null pour un visiteur qui n'a pas été identifié — c'est alors le jeton visiteur qui le désigne.
#Exemples
Les URL ci-dessous supposent site_id=1 : remplacez l'identifiant par celui renvoyé par /sites.
#Vue d'ensemble
curl -H "Authorization: Bearer sk_live_VOTRE_CLE" \
"https://api-sessio.flamme.work/api/public/v1/stats/overview?site_id=1&period=monthly"#Les sites, puis les statistiques d'un site
# 1. Les sites suivis par votre compte
curl -H "Authorization: Bearer sk_live_VOTRE_CLE" \
"https://api-sessio.flamme.work/api/public/v1/sites"
# 2. La vue d'ensemble d'un site (période = today par défaut)
curl -H "Authorization: Bearer sk_live_VOTRE_CLE" \
"https://api-sessio.flamme.work/api/public/v1/stats/overview?site_id=1"#Les visiteurs
curl -H "Authorization: Bearer sk_live_VOTRE_CLE" \
"https://api-sessio.flamme.work/api/public/v1/visitors?site_id=1&period=weekly&limit=20&offset=0"#Les sessions
curl -H "Authorization: Bearer sk_live_VOTRE_CLE" \
"https://api-sessio.flamme.work/api/public/v1/sessions?site_id=1&period=today&limit=10"Les paramètres visitor_id et has_replay restreignent la liste aux sessions d'un visiteur, ou aux sessions enregistrées.
#La heatmap d'une page
# 1. Les pages enregistrées, pour connaître l'url à demander
curl -H "Authorization: Bearer sk_live_VOTRE_CLE" \
"https://api-sessio.flamme.work/api/public/v1/heatmap/pages?site_id=1&period=monthly"
# 2. La chaleur d'une page (le chemin encodé : /pricing → %2Fpricing)
curl -H "Authorization: Bearer sk_live_VOTRE_CLE" \
"https://api-sessio.flamme.work/api/public/v1/heatmap/data?site_id=1&url=%2Fpricing&period=monthly"#Intégration côté serveur
Appelez l'API depuis votre backend — route API, fonction serverless, job planifié — et servez le résultat à vos utilisateurs :
const CLE = process.env.SESSIO_API_KEY;
export async function statsDuJour(siteId) {
const url = new URL('https://api-sessio.flamme.work/api/public/v1/stats/overview');
url.searchParams.set('site_id', siteId);
const res = await fetch(url, {
headers: { Authorization: `Bearer ${CLE}` },
});
if (!res.ok) {
const { error } = await res.json();
throw new Error(`Sessio ${error.code} : ${error.message}`);
}
return res.json();
}La clé sk_live_… ne quitte jamais votre serveur. Du code navigateur, un dépôt public ou un bundle embarqué, elle serait visible de tout le monde : vos données aussi. Si votre page doit afficher des chiffres, c'est votre serveur qui les demande à Sessio, puis les transmet.
#Spécification OpenAPI
GET /api/public/v1/openapi.json renvoie la spécification OpenAPI 3.1 complète de l'API : routes, paramètres, codes, schémas de réponse. Elle est publique, sans clé, et fait référence pour les formats exacts des réponses.
curl "https://api-sessio.flamme.work/api/public/v1/openapi.json"#Stabilité du contrat
Le contrat de /api/public/v1 est figé : routes, paramètres, codes d'erreur et formats documentés ici restent valables. Toute évolution cassante est publiée sur /api/public/v2, sans interrompre la v1 — vous pouvez intégrer v1 sans crainte de rupture.
/api/v1/* est l'API interne du dashboard : elle n'est pas documentée ici et n'est pas destinée à vos intégrations. Seule l'API publique /api/public/v1 est contractuelle.