WakaStart
Modules

API Invitations — Création

Créer une invitation : prérequis, endpoint POST /api/invitations, body, réponse et gestion d'erreurs.

Version v1.05 min de lecture

API Invitations — Création

L'API Invitations permet à votre Wakapp d'inviter des utilisateurs à rejoindre un Customer. WakaStart gère l'envoi email, la création du compte Keycloak et le provisioning des droits.

Pré-requis

  1. Feature invitation activée en cascade (App ∧ Network ∧ Customer)
  2. Droit invitations.create sur le token ou la clé API — ce droit est un AppRight accordé via le(s) profil(s) assigné(s) à l'inviteur, vérifié par RequireRight("invitations.create")
  3. adminLevel >= CUSTOMER_ADMIN pour l'appelant — humain (BFF) ou technique (clé API). Pour une clé API, c'est ApiKey.adminLevel (résolu en effectiveAdminLevel) qui est évalué ; une clé sans adminLevel explicite (défaut NONE) est refusée comme n'importe quel appelant insuffisamment privilégié
  4. Optionnel : App.acceptInvitationUrl configurée pour personnaliser l'URL dans l'email

Le concept userLevel (et la règle userLevel >= INVITE) a été retiré du contrôle d'accès aux invitations. La création est désormais conditionnée par le droit applicatif invitations.create et par le niveau adminLevel >= CUSTOMER_ADMIN de l'appelant. Le body de la requête n'accepte plus de champ userLevel : en l'envoyer renvoie désormais un 400 (DTO strict, whitelist/forbidNonWhitelisted).


Cycle de vie d'une invitation

Chargement du diagramme…
StatutDescription
PENDINGCréée, en attente d'acceptation
ACCEPTEDL'invité a finalisé son compte
EXPIREDDélai dépassé (10 jours par défaut)
CANCELLEDRévoquée par l'inviteur

Flux d'invitation complet

Chargement du diagramme…

Endpoint — Créer une invitation

http
POST /api/invitations Authorization: Bearer <wakaToken> Content-Type: application/json { "customerId": "550e8400-e29b-41d4-a716-446655440000", "invitedEmail": "alice@acme.com", "invitedFirstName": "Alice", "invitedLastName": "Martin", "profileId": "22222222-2222-2222-2222-222222222222", "teamAssignments": [ { "teamId": "33333333-3333-3333-3333-333333333333", "teamLevel": "MEMBER" } ], "message": "Bienvenue sur notre application !", "language": "fr" }

Champs du body :

ChampTypeRequisDescription
customerIdUUIDOuiCustomer cible
invitedEmailstringOuiEmail (lowercase appliqué automatiquement)
invitedFirstNamestring (max 100)NonPré-remplit le compte
invitedLastNamestring (max 100)NonPré-remplit le compte
profileIdUUIDOuiProfil à attribuer (détermine les droits)
teamAssignmentsarrayNonÉquipes à rejoindre
messagestringNonMessage personnalisé dans l'email
languagestringNonfr, en, es, de, nl, it, pt (défaut: fr)

teamLevel ∈ NONE | VIEWER | CONTRIBUTOR | MEMBER | MANAGER | ADMIN

Alternative WID : customerId, profileId et teamId (dans teamAssignments) peuvent aussi être fournis via leur WID (customerWid, profileWid, teamWid) en alternative à l'UUID — les deux formes sont acceptées en XOR, jamais les deux à la fois pour un même champ.

Réponse 201 :

json
{ "id": "uuid", "customerId": "uuid", "invitedEmail": "alice@acme.com", "status": "PENDING", "token": "a3f8c2d1e4b7...", "expiresAt": "2026-05-29T10:30:00.000Z", "createdAt": "2026-05-19T10:30:00.000Z", "inviter": { "firstName": "Bob", "lastName": "Smith", "email": "bob@..." }, "profile": { "name": "Participant", "app": { "name": "MonApp" } } }

Erreurs :

CodeCause
400Email invalide ou jetable (yopmail, etc.)
400Team assignment référence une team d'un autre Customer
400Le realm du Network n'est pas provisionné sur l'envType cible
400Champ non reconnu dans le body (ex: userLevel, retiré du contrat)
403Droit invitations.create absent, adminLevel < CUSTOMER_ADMIN, ou feature désactivée
403Limite App.invitationPerUserLimit atteinte
404Customer ou Profile introuvable
409Utilisateur avec cet email existe déjà dans ce Customer
409Invitation PENDING existe déjà pour cet email + Customer

Endpoints de gestion

Lister les invitations

http
GET /api/invitations/sent # Par l'utilisateur courant GET /api/invitations/sent/app/:appId # Filtrées par App GET /api/invitations/by-customer/:customerId # Toutes pour un Customer

Query params : status, page (défaut 1), limit (défaut 20)

Renvoyer une invitation

http
POST /api/invitations/:id/resend

Génère un nouveau token, réinitialise expiresAt à +10 jours, renvoie l'email. L'ancien token est immédiatement invalide.

Utilisable sur les invitations PENDING ou EXPIRED.

Révoquer une invitation

http
DELETE /api/invitations/:id

Passe l'invitation en CANCELLED. Réponse 200 OK. Droit requis : invitations.revoke.


Exemple curl

bash
# Créer l'invitation depuis votre backend curl -X POST https://api.wakastart.app/api/invitations \ -H "x-api-key: sk_live_yourkey" \ -H "Content-Type: application/json" \ -d '{ "customerId": "11111111-1111-1111-1111-111111111111", "invitedEmail": "alice@acme.com", "invitedFirstName": "Alice", "profileId": "22222222-2222-2222-2222-222222222222", "language": "fr" }' # → 201 : invitation créée, email envoyé automatiquement

Bonnes pratiques

  • Idempotence côté création : si un appel échoue après création (réseau), retenter lèvera un 409 Conflict — c'est sûr, l'invitation existante est toujours valide.
  • Ne jamais logger le token d'invitation — c'est un secret permettant de créer un compte.
  • Pré-remplir invitedFirstName/LastName quand possible — meilleure UX.
  • Gérer les 4 états d'erreur avec des messages explicites adaptés.

Aller plus loin