@jichio/shared-types — la source de vérité
TypeScript, dupliquée en Pydantic côté API.
Envelope batch
{
"events": [
{ /* Event */ }
]
}
Type Event
type Event = {
eventId: string; // UUID
eventName: string; // "pageview" | "click" | "identify" | custom
source: string; // ex. "sdk-react"
anonymousId: string; // UUID anonyme (localStorage)
userId?: string; // présent après identify
sessionId: string; // UUID session (sessionStorage)
timestamp: string; // ISO-8601
properties: EventProperties;
};
EventProperties (schemaVersion 1)
type EventProperties = {
schemaVersion: 1;
sdk: {
version: string;
coreVersion: string;
adapter: string; // source / adapter, ex. "sdk-react"
adapterVersion?: string;
autoCapture: boolean;
debug: boolean;
sentAt: string; // ISO
queueSeq: number;
};
session: {
id: string;
startedAt: string;
eventIndex: number;
isFirstEvent: boolean;
referrerDomain?: string;
entryUrl?: string;
entryPath?: string;
};
user?: {
id?: string;
[trait: string]: unknown; // traits passés à identify()
};
page?: {
url: string;
path: string; // pathname + search + hash
pathname: string;
search: string;
hash: string;
title: string;
referrer?: string;
referrerPath?: string;
documentVisibility: string;
loadType: string; // "initial" | "manual" | "spa-navigation"
};
campaign?: {
utmSource?: string | null;
utmMedium?: string | null;
utmCampaign?: string | null;
utmTerm?: string | null;
utmContent?: string | null;
};
custom?: Record<string, unknown>; // payload de track()
viewport?: {
width: number; height: number; devicePixelRatio: number;
scrollX: number; scrollY: number;
documentWidth: number; documentHeight: number;
};
device?: Record<string, unknown>;
locale?: {
language: string; languages: string[];
timezone: string; timezoneOffset: number;
};
network?: Record<string, unknown>;
screen?: Record<string, unknown>; // pageview
acquisition?: Record<string, unknown>; // pageview
element?: Record<string, unknown>; // click
pointer?: Record<string, unknown>;
};
Les clés présentes dépendent du type d’événement : voir
Modèle d’événement.
Les clés sensibles (
password, token, secret…) sont retirées avant
l’envoi : voir Vie privée & données.
L’API ajoute properties.server à la réception : voir
Modèle d’événement.Exemple — batch réel (extrait)
{
"events": [
{
"eventId": "11c9185b-9f88-43c2-80c4-8b764ef385c9",
"eventName": "pageview",
"source": "sdk-react",
"anonymousId": "7bac4caf-c18d-406e-830d-9187b03c188f",
"userId": "user_123",
"sessionId": "9e1d9f79-9e06-42d8-a00d-a4f492cb2fde",
"timestamp": "2026-07-28T08:45:41.396Z",
"properties": {
"schemaVersion": 1,
"sdk": { "version": "0.1.1", "adapter": "sdk-react", "queueSeq": 3, "debug": true },
"session": { "id": "9e1d9f79-9e06-42d8-a00d-a4f492cb2fde", "eventIndex": 3, "isFirstEvent": false },
"user": { "id": "user_123", "email": "you@example.com", "role": "admin" },
"page": {
"url": "http://localhost:3000/dashboard?utm_source=docs",
"path": "/dashboard?utm_source=docs",
"pathname": "/dashboard",
"search": "?utm_source=docs",
"hash": "",
"title": "Dashboard",
"documentVisibility": "visible",
"loadType": "manual"
},
"campaign": { "utmSource": "docs" },
"viewport": { "width": 1024, "height": 768, "devicePixelRatio": 1, "scrollX": 0, "scrollY": 0 },
"locale": { "language": "fr-FR", "languages": ["fr-FR"], "timezone": "Africa/Lagos", "timezoneOffset": -60 }
}
}
]
}

