Référence API
Cette fiche donne une vue d'ensemble de l'API REST de TimePick, organisée par familles d'endpoints. Elle sert de point d'entrée pour un développeur ou un intégrateur qui doit appeler l'API depuis un script ou un outil externe — elle ne documente pas chaque endpoint en détail. Pour la liste exhaustive, chaque route est déclarée dans un fichier de server/src/routes/ sur GitHub.
API interne, sans garantie de stabilité
Cette API a été conçue pour l'interface web de TimePick elle-même, pas comme une API publique versionnée. Tant que le projet est en pré-V1 (état au 2026-07-13), ses chemins, ses formats de payload et ses codes d'erreur peuvent changer sans préavis ni période de dépréciation. Un usage en intégration externe reste possible mais doit être revalidé à chaque mise à jour de l'instance.
Base et authentification
URL de base : https://<votre-domaine.tld>/api (ou http://localhost:3000/api en développement).
La quasi-totalité des endpoints hors /setup, /public (lecture) et /health requièrent l'en-tête :
Authorization: Bearer <token>Le <token> est un JWT de session, obtenu via le flux magic link :
POST /api/auth/loginavec{ "email": "alice@example.org" }— envoie un email contenant un lien de connexion. La réponse est volontairement générique (anti-énumération), qu'un compte corresponde ou non à l'email :json{ "data": { "message": "Si cet email est enregistré, vous recevrez un lien de connexion." } }Le lien reçu par email contient un
tokenen paramètre. Le client appelle ensuitePOST /api/auth/verifyavec{ "token": "<token>" }, qui ouvre la session et renvoie le JWT à utiliser dans l'en-têteAuthorizationpour tous les appels suivants.
Deux rôles distincts sont portés par le JWT : admin (accès à /api/admin/*) et user (accès à /api/me/* et aux réservations, si hasMemberAccess est vrai — c'est-à-dire si l'utilisateur est invité sur au moins un événement).
Détail des durées de vie de session/token, du rate limiting et des autres protections : voir Sécurité.
Enveloppe de réponse
Toutes les réponses de succès sont enveloppées dans un objet data. Exemple réel, réponse de POST /api/auth/verify :
{
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…",
"sessionTTL": 7200,
"user": {
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"email": "alice@example.org",
"firstName": "Alice",
"lastName": "Dupont",
"role": "user",
"hasMemberAccess": true
}
}
}Les réponses d'erreur suivent le même principe avec la clé error :
{
"error": {
"code": "INVALID_TOKEN",
"message": "Lien de connexion invalide."
}
}Conversion snake_case → camelCase
La base de données stocke ses colonnes en snake_case (first_name, is_published…). Un middleware global (snakeToCamelMiddleware, monté avant toutes les routes dans server/src/app.ts) convertit automatiquement chaque réponse JSON de succès en camelCase (firstName, isPublished…) avant l'envoi au client. Les corps de requête envoyés par le client, eux, restent en camelCase — la conversion inverse est gérée côté requêtes SQL, pas au niveau de l'API.
Familles d'endpoints
| Préfixe | Rôle | Authentification |
|---|---|---|
/api/auth | Connexion par magic link (demande, vérification), rafraîchissement de session, connexion de secours, renvoi d'invitation | Public pour la demande/vérification/secours ; user/admin pour le rafraîchissement |
/api/setup | Configuration initiale (création du premier admin, test SMTP de démarrage) | Public — se ferme dès qu'un administrateur existe |
/api/public | Consultation d'un événement publié par UUID et de ses créneaux, gestion de ses propres réservations | Auth optionnelle en lecture (mode consultation sans session) ; user requis pour réserver/annuler |
/api/me | Profil et données de l'utilisateur connecté (événements, créneaux réservés, créneaux disponibles) | user (accès à un membre admin également) |
/api/admin | Administration : dashboard/analytics, utilisateurs, événements, créneaux, invitations, paramètres SMTP/emails/identité visuelle, configuration (polling, TTL), enveloppes d'email (shell-parts), codes de secours, notifications d'annulation | admin |
/api/admin/uploads | Upload d'image pour l'éditeur d'emails (max 5 Mo, retourne une URL absolue) | admin |
/health | Statut de santé public, binaire (ok/degraded), sans détail interne | Public |
Deux préfixes publics annexes
Le code expose aussi /api/events (liste et détail des événements publiés, sans authentification, filtrage minimal) et /api/slots (regroupe des routes de gestion admin des créneaux et de réservation/annulation par un membre authentifié, sous un préfixe distinct de /api/admin et /api/public). Ces deux préfixes se recoupent fonctionnellement avec /api/public et /api/admin/events/:id/slots — voir le code pour arbitrer lequel utiliser dans une intégration (server/src/routes/public.events.routes.ts, server/src/routes/slots.routes.ts).
Détail — /api/admin, sous-familles
| Sous-préfixe / groupe | Exemples de routes | Description |
|---|---|---|
| Dashboard / analytics | GET /admin/dashboard, GET /admin/stats, GET /admin/analytics/… | KPI, réservations brutes, engagement, activité par événement |
| Utilisateurs | GET/POST /admin/users, GET/PUT/DELETE /admin/users/:id, POST /admin/users/bulk-delete, POST /admin/users/import, GET /admin/users/export | CRUD, import/export CSV, suppression groupée |
| Événements | GET/POST /admin/events, PUT/DELETE /admin/events/:id, POST /admin/events/:id/duplicate, PUT /admin/events/:id/publish | /unpublish, PUT /admin/events/:id/opening-date | CRUD, publication, duplication, date d'ouverture |
| Créneaux | GET/POST /admin/events/:eventId/slots, GET/PUT/DELETE /admin/slots/:id | Gestion des créneaux d'un événement |
| Invitations | POST /admin/events/:id/invitations/send, GET /admin/events/:id/invitations, POST /admin/events/:id/invitations/:userId/resend, POST /admin/events/:id/invitations/resend-unanswered | Envoi, statut, relances |
Paramètres (/admin/settings) | GET/PUT/DELETE /settings/smtp, GET/PATCH /settings/email-brand, GET/PATCH /settings/email-templates/:templateKey | SMTP, identité visuelle, modèles d'email |
| Configuration | GET/PUT /admin/config/polling-interval, GET/PUT /admin/config/magic-link | Intervalle de polling, TTL magic link |
Enveloppes d'email (/admin/shell-parts) | PUT/DELETE /shell-parts/:ownerKind/:ownerId/:partKind | Parties MJML d'en-tête/pied de page (cascade marque → modèle → événement) |
| Codes de secours | GET /admin/recovery-codes/status, POST /admin/recovery-codes/generate, PATCH /admin/recovery-codes/dismiss | Génération et statut des codes de secours admin |
| Notifications d'annulation | GET /admin/cancellation-notifications, POST /admin/cancellation-notifications/resend | Notifications en attente et relance groupée |
Exemple de payload d'erreur de validation
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Format d'email invalide"
}
}La forme exacte du corps d'erreur varie selon l'endpoint et son ancienneté : certaines routes renvoient { "error": { "code", "message" } }, d'autres { "error": "message" }, d'autres encore un code seul (par exemple { "code": "INVALID_CREDENTIALS" } sur la connexion de secours — comportement observé sur l'instance de référence, juillet 2026). Seul le code HTTP fait foi de manière uniforme.
Endpoint de santé
GET /health (public, hors préfixe /api) renvoie un statut binaire sans authentification, utilisable par une sonde de supervision externe :
{
"status": "ok",
"timestamp": "2026-07-13T08:00:00.000Z",
"services": {
"smtp": "ok"
}
}status et services.smtp valent ok ou degraded (chaînes) ; le code HTTP reste 200 dans les deux cas.
Un statut détaillé réservé aux administrateurs (base de données incluse) existe à GET /api/admin/health. Voir Dépannage pour l'usage de ces deux endpoints en diagnostic.
Rate limiting
Plusieurs endpoints sensibles (/api/auth/login, /api/auth/emergency-login, envois de test SMTP/email, upload d'image) sont limités en nombre de requêtes par fenêtre de temps, indépendamment de toute configuration. Le détail des seuils est documenté dans Sécurité — Limitation de débit ; un dépassement renvoie un code HTTP 429 avec { "error": { "code": "RATE_LIMITED", … } }.
Pour aller plus loin
- Détail des tables et colonnes manipulées par ces endpoints : Modèle de données.
- Liste exhaustive et à jour des routes :
server/src/routes/sur GitHub (un fichier par famille, montage des préfixes dansserver/src/app.ts).