# Sarutobi > Sarutobi est une plateforme de Product Analytics auto-hébergée, écrite en TypeScript (Next.js, PostgreSQL, Drizzle, Better Auth). Elle relie collecte d'événements, identité persistante, exploration et décision : pages vues, visites, sessions, personnes, groupes, funnels, rétention, cohortes, parcours, feature flags, expériences, Web Vitals et erreurs JavaScript. Les SDK navigateur pèsent moins de 5 ko gzip, n'ont aucune dépendance runtime et ne peuvent jamais faire échouer le site instrumenté. Un serveur MCP expose les mêmes mesures aux agents. Le produit et sa documentation sont en **français** ; le code, les routes et les noms d'API sont en **anglais**. Instance officielle : `https://sarutobi.ascencia.re`. Dépôt : `https://github.com/pedrokarim/sarutobi` (MIT). Repères pour intégrer sans rien lire d'autre : - **La clé d'un site s'appelle `siteId`.** Elle ressemble à `st_live_8f3a1c9d2e4b6071` et s'obtient sur la page **Installation** du site, dans le dashboard. Elle **n'est pas un secret** : elle transite en clair dans le JavaScript. Ce qui protège les chiffres, c'est la liste des domaines autorisés déclarée sur le site. Ne jamais l'appeler « token » ni « clé d'API ». - **La clé serveur `st_secret_…`** est réservée à `@ascencia/sarutobi-node` et ne doit jamais atteindre un bundle client. - **Installer** : `bun add @ascencia/sarutobi-react@next` (React, Next.js) ou `@ascencia/sarutobi-js@next` (vanilla, Vue, Svelte). Sans bundler : ``. - **Brancher** : `` en React, `sarutobi.init({ siteId })` ailleurs. Pages vues, visites, referrers, UTM, pays, appareil, Core Web Vitals et erreurs JavaScript sont collectés sans autre instrumentation. - **API** : `capture(name, props?)`, `identify(id, props?)`, `reset()`, `setConsent(state)`, `pageview(path?)`, `setContext(props)`, `group(type, key, props?)`, `groupIdentify(type, key, props)`, `isFeatureEnabled(key)`, `getFeatureFlag(key)`, `flush()`. Aucune méthode ne renvoie de promesse ; aucune ne fait attendre l'appelant. - **Ingestion** : `POST /api/collect`, corps JSON envoyé en `text/plain;charset=UTF-8` pour éviter le pré-vol CORS, 1 à 20 events par lot, 32 ko maximum. Réponse `202` au corps toujours vide. - **En développement, rien n'est envoyé** : le SDK se désactive seul sur `localhost`, `127.0.0.1` et les domaines en `.localhost`. Passer `enabled: true` pour tester en local. - **Un `202` veut dire « accepté », pas « visible »** : le temps réel lit les visites brutes, les courbes lisent des agrégats recalculés toutes les dix minutes par un cron. - **Nommer un event** : verbe au passé en `snake_case`, jamais d'identifiant dans le nom, propriétés à faible cardinalité, jamais de donnée personnelle. Trente-deux clés par event, cinq cent douze caractères par valeur ; chaînes, nombres, booléens et `null` uniquement. - **Consentement** : le SDK démarre en `consent: "pending"` et ne crée aucun identifiant avant `setConsent("granted")`. ## Démarrer - [Démarrage rapide](https://sarutobi.ascencia.re/docs) : récupérer la clé du site, installer le paquet, brancher le provider, vérifier la réception du premier event. - [Comment ça fonctionne](https://sarutobi.ascencia.re/docs/fonctionnement) : le trajet d'un event du SDK au dashboard, la latence des rollups, ce que répond chaque écran, et pourquoi visite, session et personne sont trois choses distinctes. - [Next.js](https://sarutobi.ascencia.re/docs/nextjs) : App Router et Pages Router, `disabled` réévalué à chaque rendu, Content Security Policy, `NEXT_PUBLIC_SARUTOBI_SITE_ID`. - [React et autres frameworks](https://sarutobi.ascencia.re/docs/react) : le hook `useSarutobi()`, l'usage hors composant, Vue, Svelte, vanilla, SPA et rendu côté serveur. - [Sans bundler](https://sarutobi.ascencia.re/docs/script) : la balise `