Référence de l'API
Quatre routes composent l'API d'intégration — création/liste de webinaires, inscription à un webinaire, inscription à un cours, et création de jeton d'intégration de cours. Toutes sont versionnées sous /api/v1, comme l'API d'envoi, et partagent son authentification par clé porteuse.
Authentification
Authorization: Bearer mia_live_...
Une clé manquante ou invalide renvoie 401 \{ "error": "Missing or invalid Authorization: Bearer <apiKey>" \} sur chaque route ci-dessous. Les clés sont gérées sous Développeurs dans le tableau de bord — voir le démarrage rapide.
POST /api/v1/webinars
Crée un webinaire. accessMode est toujours forcé à "registration" — l'API d'intégration ne traite jamais que des sessions à inscription publique, jamais des sessions en direct réservées aux abonnés.
| Champ | Type | Requis | Notes |
| --- | --- | --- | --- |
| title | string | oui | Nettoyé des espaces ; vide après nettoyage renvoie 400. |
| scheduledAt | number | non | Horodatage Unix en ms. |
| courseId | string | non | Lie le webinaire à un cours existant. |
| capacity | number | non | Doit être >= 0 si présent. Les inscriptions au-delà de la capacité sont mises en liste d'attente, pas rejetées. |
Renvoie 201 \{ "webinar": LiveSession \}.
GET /api/v1/webinars
Aucun corps. Renvoie 200 \{ "webinars": LiveSession[] \} — chaque session du compte avec accessMode: "registration", les sessions réservées aux abonnés sont filtrées.
POST /api/v1/webinars/[id]/register
Inscrit un utilisateur final à un webinaire et envoie l'email de confirmation/liste d'attente.
| Champ | Type | Requis | Notes |
| --- | --- | --- | --- |
| email | string | oui | Doit correspondre à un schéma d'email basique, sinon 400 \{ "error": "A valid \email` is required" }. | | name| string | oui | Nettoyé des espaces, 200 caractères maximum, sinon400 { "error": "A `name` is required" }`. |
Erreurs : 404 si le webinaire n'existe pas ou ne vous appartient pas ; 400 s'il n'est pas en accessMode: "registration" ; 409 s'il est déjà terminé.
Réponse :
{ "status": "confirmed", "joinUrl": "https://mailinapp.com/webinar/<id>/join?token=..." }
ou, une fois la capacité atteinte :
{ "status": "waitlisted", "joinUrl": null }
Une inscription confirmée déclenche l'email de cycle de vie registered du webinaire ; une inscription en liste d'attente reçoit le simple avis de liste d'attente, quelle que soit la liaison configurée.
POST /api/v1/courses/[id]/enroll
Accorde ou révoque l'accès à un cours pour une adresse email, selon votre propre décision d'attribution de droits plutôt qu'un paiement MailInApp.
| Champ | Type | Requis | Notes |
| --- | --- | --- | --- |
| email | string | oui | Même validation que pour l'inscription ; mis en minuscules et nettoyé des espaces avant utilisation. |
| active | boolean | non | Par défaut true. false révoque l'accès. |
404 si le cours n'existe pas ou ne vous appartient pas. Réponse : 200 \{ "subscriberId": "...", "active": true \}.
Un nouvel octroi (active: true sur un abonné qui n'y avait pas déjà droit) déclenche l'email de cycle de vie enrolled du cours. Révoquer l'accès n'envoie jamais d'email à l'utilisateur final en votre nom.
POST /api/v1/courses/[id]/embed-token
Crée un jeton signé à courte durée de vie (5 minutes) pour intégrer le portail de cours, après avoir revérifié que l'abonné y a réellement droit.
| Champ | Type | Requis | Notes |
| --- | --- | --- | --- |
| email | string | oui | Même validation que ci-dessus. |
Erreurs : 404 si le cours n'existe pas, ne vous appartient pas, ou n'est pas published ; 409 si le compte n'a pas encore réclamé d'URL d'adhésion /learn/<slug> ; 403 si cet email n'a pas actuellement droit d'accès (appelez d'abord enroll).
Réponse : 200 \{ "portalUrl": "https://mailinapp.com/learn/<slug>/courses/<courseId>/embed?token=..." \}. Redirigez l'iframe ou une nouvelle fenêtre de votre application vers portalUrl — cela connecte le visiteur et l'amène dans le portail de cours ordinaire.
Liaisons d'email de cycle de vie
Un cours ou un webinaire peut lier n'importe lequel de ses événements de cycle de vie à un projet studio au lieu du texte de confirmation simple de la plateforme :
| Ressource | Événements |
| --- | --- |
| Cours | enrolled, completed (reminder accepté pour la parité, sans déclenchement automatique — les cours n'ont pas d'échéance naturelle sur laquelle en déclencher un) |
| Webinaire (LiveSession) | registered, reminder |
Les liaisons sont définies depuis le propre panneau Emails de cycle de vie du cours/webinaire dans le tableau de bord, pas via cette API. Elles prennent effet dès le prochain événement, qu'il ait été déclenché par l'API d'intégration ou par l'action équivalente du tableau de bord/formulaire public. Un événement sans liaison (ou pointant vers un projet supprimé ou étranger) revient directement à l'email simple d'aujourd'hui — cela ne casse jamais un envoi.
Un événement lié se rend via renderSingleRecipientEmail exactement comme le mode template de l'API d'envoi : moteur de repli complet, blocs interactifs, et un lien de vue en direct personnel signé. Le propre suivi webhook/Réponses du projet le capture aussi, attribué à cet événement de cycle de vie spécifique plutôt qu'à une ligne de contact stockée.
Limites de fréquence
Deux plafonds indépendants s'appliquent, par route :
- Par clé API : 60 requêtes/minute. Le dépasser renvoie
429 \{ "error": "Rate limit exceeded" \}pour cette clé spécifiquement. - Par compte, quota API d'intégration : votre forfait inclut un nombre d'appels à l'API d'intégration par mois civil, partagé entre les quatre routes ci-dessus.
0sur Free/Starter renvoie403 \{ "error": "The Embed API isn't included in your plan" \}; dépasser le quota d'un palier payant renvoie429 \{ "error": "Monthly Embed API quota for your plan exceeded" \}jusqu'à sa réinitialisation le 1er du mois.
La création de webinaire revérifie en plus votre quota de streaming en direct (checkLiveSessionQuota) — la même limite de minutes de diffusion/cours qu'applique le propre flux de création du tableau de bord — et renvoie 403 avec le propre message de cette vérification en cas d'échec.
Codes d'erreur
| Statut | Signification |
| --- | --- |
| 400 | JSON malformé ou champ requis manquant/invalide — voir le propre tableau de chaque route ci-dessus. |
| 401 | En-tête Authorization manquant ou invalide, ou la clé a été révoquée. |
| 403 | API d'intégration non incluse dans votre forfait, échec de la vérification de quota, quota de session en direct dépassé, ou (embed-token) l'email n'a pas actuellement droit d'accès. |
| 404 | Le webinaire/cours n'existe pas ou n'appartient pas à votre compte — délibérément la même réponse que « n'existe pas », le même raisonnement que le 404 du mode template de l'API d'envoi. |
| 409 | (Webinaire) la session est déjà terminée. (Embed-token) le compte n'a pas encore réclamé d'URL d'adhésion. |
| 429 | Limite de fréquence par clé ou quota mensuel dépassé. |
Voir aussi
- Référence de l'API d'envoi — l'endpoint transactionnel libre/template avec lequel cette API partage son modèle d'authentification.
- Aperçu de l'adhésion à l'apprentissage — cours, abonnés et droits d'accès, les concepts qu'enveloppent les routes enroll/embed-token.
- Sessions en direct et webinaires — inscription aux webinaires, capacité/liste d'attente et liens de participation, les concepts qu'enveloppent les routes de webinaire.