Authentification
Authentifiez-vous auprès de l'API Mail.Land en utilisant des tokens Bearer ou des clés API
MailLand prend en charge deux méthodes d'authentification : les tokens Bearer (JWT) pour les sessions utilisateur et les clés API pour l'intégration serveur à serveur. Toutes les requêtes API nécessitent une authentification via l'en-tête Authorization.
Méthodes d'authentification
| Méthode | En-tête | Cas d'utilisation |
|---|---|---|
| Token Bearer | Authorization: Bearer <token> | Sessions utilisateur, tableau de bord |
| Clé API | X-API-Key: <key> | Serveur à serveur, automatisation |
Inscription
POST https://api.mail.land/v1/auth/register{
"email": "[email protected]",
"password": "SecureP@ssw0rd!",
"fullName": "John Doe",
"companyName": "My Company"
}curl -X POST https://api.mail.land/v1/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "SecureP@ssw0rd!",
"fullName": "John Doe",
"companyName": "My Company"
}'| Champ | Type | Requis | Description |
|---|---|---|---|
email | string | Oui | Adresse e-mail |
password | string | Oui | Mot de passe (8 à 128 caractères ; nécessite une majuscule, une minuscule, un chiffre et un caractère spécial) |
fullName | string | Non | Nom complet |
companyName | string | Non | Nom de l'entreprise / de l'espace de travail |
Les champs inconnus (comme un tenantName envoyé par erreur) sont ignorés silencieusement.
{
"requiresEmailVerification": true,
"verificationTicket": "vt_abc123...",
"maskedEmail": "u***@example.com"
}Le statut de la réponse est 201.
Après l'inscription, vérifiez l'adresse e-mail avant de vous connecter.
Vérification de l'e-mail
L'inscription envoie un code à 6 chiffres par e-mail. Appelez POST /v1/auth/verify-email-ticket avec { "ticket": "<verificationTicket>", "code": "123456" } ; en cas de succès, la réponse contient les tokens de connexion.
POST https://api.mail.land/v1/auth/verify-email-ticket{
"ticket": "vt_abc123...",
"code": "123456"
}curl -X POST https://api.mail.land/v1/auth/verify-email-ticket \
-H "Content-Type: application/json" \
-d '{"ticket": "vt_abc123...", "code": "123456"}'Renvoyer l'e-mail de vérification : appelez POST /v1/auth/resend-verification-ticket avec { "ticket": "..." }. La requête est limitée en fréquence et renvoie un nouveau ticket.
POST https://api.mail.land/v1/auth/resend-verification-ticket{
"ticket": "vt_abc123..."
}curl -X POST https://api.mail.land/v1/auth/resend-verification-ticket \
-H "Content-Type: application/json" \
-d '{"ticket": "vt_abc123..."}'Connexion
POST https://api.mail.land/v1/auth/login{
"email": "[email protected]",
"password": "SecureP@ssw0rd!"
}curl -X POST https://api.mail.land/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "SecureP@ssw0rd!"
}'Réponse
La réponse de connexion varie en fonction de l'état du compte :
Connexion réussie :
{
"userId": "v4j2x7n1m9k5p3",
"email": "[email protected]",
"fullName": "John Doe",
"avatarUrl": null,
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"refreshToken": "rt_a1b2c3d4e5...",
"expiresAt": "2026-09-25T13:00:00Z",
"requiresTwoFactor": false,
"twoFactorChallengeId": null,
"tenantCount": 1,
"activeTenantId": "k3m9x2p7qw4rtz",
"activeTenantName": "My Company",
"requiresEmailVerification": false,
"verificationTicket": null,
"maskedEmail": null
}Il n'y a pas d'objet user ni de champ role dans la réponse. Un compte non vérifié reçoit un 200 avec requiresEmailVerification: true et un verificationTicket, pas une erreur.
Authentification à deux facteurs requise :
{
"accessToken": null,
"refreshToken": null,
"requiresTwoFactor": true,
"twoFactorChallengeId": "2fa_challenge_abc123"
}Lorsque requiresTwoFactor est true, complétez la vérification 2FA avant de recevoir les tokens.
Actualisation du token
Les tokens d'accès expirent après 60 minutes. Utilisez le token d'actualisation pour obtenir un nouveau token d'accès :
POST https://api.mail.land/v1/auth/refresh-token{
"refreshToken": "rt_a1b2c3d4e5..."
}curl -X POST https://api.mail.land/v1/auth/refresh-token \
-H "Content-Type: application/json" \
-d '{"refreshToken": "rt_a1b2c3d4e5..."}'La réponse a la même forme que la réponse de connexion ci-dessus (l'AuthResponse complet), pas seulement ces trois champs :
{
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"refreshToken": "rt_new_token...",
"expiresAt": "2026-09-25T14:00:00Z"
}Chaque token d'actualisation ne peut être utilisé qu'une seule fois. La réponse inclut un nouveau token d'actualisation pour la prochaine rotation.
Déconnexion
Invalider la session en cours :
POST https://api.mail.land/v1/auth/logoutEnvoyez { "refreshToken": "..." } dans le corps de la requête (ou le cookie de refresh token). Le refresh token est révoqué ; l'access token reste valide jusqu'à son expiration : un en-tête Bearer seul ne révoque rien.
curl -X POST https://api.mail.land/v1/auth/logout \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."Révoquer toutes les sessions actives :
POST https://api.mail.land/v1/auth/revoke-all-tokenscurl -X POST https://api.mail.land/v1/auth/revoke-all-tokens \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."Gestion des mots de passe
Mot de passe oublié
POST https://api.mail.land/v1/auth/forgot-password{
"email": "[email protected]"
}curl -X POST https://api.mail.land/v1/auth/forgot-password \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]"}'Envoie un e-mail de réinitialisation du mot de passe avec un token à durée limitée.
Réinitialisation du mot de passe
POST https://api.mail.land/v1/auth/reset-passwordconfirmPassword est requis et doit correspondre à newPassword ; les mêmes règles de complexité qu'à l'inscription s'appliquent.
{
"token": "reset-token-from-email",
"newPassword": "NewSecureP@ssw0rd!",
"confirmPassword": "NewSecureP@ssw0rd!"
}curl -X POST https://api.mail.land/v1/auth/reset-password \
-H "Content-Type: application/json" \
-d '{
"token": "reset-token-from-email",
"newPassword": "NewSecureP@ssw0rd!",
"confirmPassword": "NewSecureP@ssw0rd!"
}'Validation du token de réinitialisation
Vérifiez si un token de réinitialisation est encore valide avant d'afficher le formulaire de réinitialisation :
GET https://api.mail.land/v1/auth/validate-reset-token?token=reset-token-from-emailcurl "https://api.mail.land/v1/auth/validate-reset-token?token=reset-token-from-email"{
"valid": true,
"message": "Token is valid"
}Changement de mot de passe
Changer le mot de passe de l'utilisateur actuellement authentifié :
POST https://api.mail.land/v1/auth/change-password{
"currentPassword": "OldP@ssw0rd!",
"newPassword": "NewSecureP@ssw0rd!"
}curl -X POST https://api.mail.land/v1/auth/change-password \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{
"currentPassword": "OldP@ssw0rd!",
"newPassword": "NewSecureP@ssw0rd!"
}'Gestion du profil
Obtenir l'utilisateur actuel
GET https://api.mail.land/v1/auth/mecurl https://api.mail.land/v1/auth/me \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."{
"id": "v4j2x7n1m9k5p3",
"email": "[email protected]",
"fullName": "John Doe",
"companyName": "Acme",
"avatarUrl": "https://cdn.mail.land/avatars/usr_a1b2c3d4e5.jpg",
"status": "Active",
"createdAt": "2026-01-15T08:00:00Z",
"subscription": {
"planName": "Pro",
"monthlyEmailLimit": 50000,
"rateLimitPerSecond": 10,
"startDate": "2026-01-15T08:00:00Z",
"endDate": "2026-10-15T08:00:00Z",
"status": "Active"
},
"stats": {
"credentialCount": 3,
"domainCount": 2
}
}Il n'y a pas de champ firstName, lastName, phone, tenantId, role ni twoFactorEnabled dans cette réponse.
Mettre à jour le profil
PUT https://api.mail.land/v1/auth/profilefullName est obligatoire ; omettre companyName l'efface. Cette mise à jour ne fait correspondre que l'identifiant de l'utilisateur, elle fonctionne donc depuis n'importe quel espace de travail où l'utilisateur est actif, pas seulement celui où le compte a été créé.
{
"fullName": "Jane Smith",
"companyName": "Acme"
}curl -X PUT https://api.mail.land/v1/auth/profile \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{
"fullName": "Jane Smith",
"companyName": "Acme"
}'Télécharger un avatar
POST https://api.mail.land/v1/account/avatarEnvoyez une requête multipart/form-data avec le fichier image de l'avatar. Formats pris en charge : JPEG, PNG, GIF ou WebP (le contenu est vérifié, pas seulement l'extension). Taille maximale : 1 Mo.
curl -X POST https://api.mail.land/v1/account/avatar \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-F "file=@/path/to/avatar.jpg"Authentification sociale
MailLand prend en charge la connexion sociale via Google, GitHub et Microsoft :
Rediriger vers le fournisseur
GET https://api.mail.land/auth/social/{provider}Où {provider} est google, github ou microsoft. Cette URL redirige l'utilisateur vers l'écran de consentement OAuth du fournisseur.
curl https://api.mail.land/auth/social/googleGérer le callback
Après autorisation par l'utilisateur, le fournisseur redirige vers MailLand avec un code d'autorisation :
GET https://api.mail.land/auth/social/{provider}/callback?code=...curl "https://api.mail.land/auth/social/google/callback?code=authorization-code-from-provider"Le callback est géré par MailLand, qui redirige le navigateur vers {frontend}/{locale}/auth/callback?code=<code à usage unique>&provider=.... Ce code est le code à usage unique propre à MailLand, et non le code d'autorisation du fournisseur : transmettez-le tel quel à l'étape d'échange ci-dessous.
Échanger contre des tokens
POST https://api.mail.land/v1/auth/social/exchange{
"code": "one-time-code-from-callback-redirect"
}curl -X POST https://api.mail.land/v1/auth/social/exchange \
-H "Content-Type: application/json" \
-d '{"code": "one-time-code-from-callback-redirect"}'Retourne le même AuthResponse que la connexion classique.
Suppression du compte
La suppression se fait par espace de travail, pas par compte utilisateur, et seul un Owner de l'espace de travail peut la déclencher. Elle planifie la suppression après un délai de grâce plutôt que de supprimer immédiatement :
POST https://api.mail.land/v1/account/lifecycle/schedule-deletion{
"gracePeriodDays": 30
}curl -X POST https://api.mail.land/v1/account/lifecycle/schedule-deletion \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{"gracePeriodDays": 30}'gracePeriodDays accepte de 7 à 90 (par défaut 30) ; les valeurs hors de cette plage sont plafonnées, pas refusées. La suppression planifiée peut être annulée à tout moment avant la fin du délai de grâce :
POST https://api.mail.land/v1/account/lifecycle/cancel-deletionLes Owners de l'espace de travail planifient la suppression avec POST /v1/account/lifecycle/schedule-deletion (gracePeriodDays de 7 à 90, par défaut 30, les valeurs hors plage sont plafonnées) et peuvent l'annuler avec POST /v1/account/lifecycle/cancel-deletion jusque-là. Il n'existe pas d'endpoint DELETE /v1/auth/delete-account, et cette action n'est pas par utilisateur : elle supprime tout l'espace de travail une fois le délai de grâce écoulé.
Réponses d'erreur
| Statut | Code | Description |
|---|---|---|
400 | VALIDATION_FAILED | La requête d'inscription a échoué à la validation, avec un tableau errors[] |
401 | UNAUTHORIZED | E-mail ou mot de passe incorrect |
403 | FORBIDDEN | Le compte est inactif |
409 | CONFLICT | L'e-mail est déjà enregistré |
429 | TOO_MANY_LOGIN_ATTEMPTS | Trop de tentatives de connexion échouées ; la réponse inclut Retry-After |
Un e-mail non vérifié ne renvoie pas d'erreur : la connexion répond 200 avec requiresEmailVerification: true et un nouveau verificationTicket.
Prochaines étapes
- Authentification à deux facteurs : ajouter la 2FA à votre compte
- Gestion d'équipe : inviter des membres de l'équipe
- Espaces de travail : gérer plusieurs espaces de travail
- Clés API : créer des clés API pour l'accès serveur à serveur