API-Referenz
Vier Routen bilden die Embed API — Webinar erstellen/auflisten, Webinar-Registrierung, Kurs-Einschreibung und Kurs-Embed-Token-Ausstellung. Alle sind unter /api/v1 versioniert, ebenso wie die Send API, und teilen sich deren Bearer-Schlüssel-Authentifizierung.
Authentifizierung
Authorization: Bearer mia_live_...
Ein fehlender oder ungültiger Schlüssel liefert bei jeder Route unten 401 \{ "error": "Missing or invalid Authorization: Bearer <apiKey>" \}. Schlüssel werden unter Entwickler im Dashboard verwaltet — siehe den Schnellstart.
POST /api/v1/webinars
Erstellt ein Webinar. accessMode wird immer auf "registration" erzwungen — die Embed API befasst sich ausschließlich mit Sessions mit öffentlicher Registrierung, nie mit reinen Abonnenten-Live-Sessions.
| Feld | Typ | Erforderlich | Hinweise |
| --- | --- | --- | --- |
| title | string | ja | Getrimmt; leer nach dem Trimmen liefert 400. |
| scheduledAt | number | nein | Unix-ms-Zeitstempel. |
| courseId | string | nein | Verknüpft das Webinar mit einem bestehenden Kurs. |
| capacity | number | nein | Muss, falls vorhanden, >= 0 sein. Registrierungen über die Kapazität hinaus werden wartelistet, nicht abgelehnt. |
Gibt 201 \{ "webinar": LiveSession \} zurück.
GET /api/v1/webinars
Kein Body. Gibt 200 \{ "webinars": LiveSession[] \} zurück — jede Session im Konto mit accessMode: "registration"; reine Abonnenten-Sessions werden herausgefiltert.
POST /api/v1/webinars/[id]/register
Registriert einen Endnutzer für ein Webinar und sendet die Bestätigungs-/Wartelisten-E-Mail.
| Feld | Typ | Erforderlich | Hinweise |
| --- | --- | --- | --- |
| email | string | ja | Muss einem einfachen E-Mail-Muster entsprechen, sonst 400 \{ "error": "A valid \email` is required" }. | | name| string | ja | Getrimmt, maximal 200 Zeichen, sonst400 { "error": "A `name` is required" }`. |
Fehler: 404, falls das Webinar nicht existiert oder nicht Ihnen gehört; 400, falls es nicht accessMode: "registration" ist; 409, falls es bereits beendet wurde.
Antwort:
{ "status": "confirmed", "joinUrl": "https://mailinapp.com/webinar/<id>/join?token=..." }
oder, sobald die Kapazität erreicht ist:
{ "status": "waitlisted", "joinUrl": null }
Eine bestätigte Registrierung löst die registered-Lifecycle-E-Mail des Webinars aus; eine wartelistete erhält unabhängig von einer etwaigen Bindung den schlichten Wartelisten-Hinweis.
POST /api/v1/courses/[id]/enroll
Gewährt oder entzieht Kurszugriff für eine E-Mail-Adresse, gebunden an Ihre eigene Berechtigungsentscheidung statt an einen MailInApp-Checkout.
| Feld | Typ | Erforderlich | Hinweise |
| --- | --- | --- | --- |
| email | string | ja | Dieselbe Validierung wie bei der Registrierung; vor Gebrauch klein geschrieben und getrimmt. |
| active | boolean | nein | Standardmäßig true. false entzieht den Zugriff. |
404, falls der Kurs nicht existiert oder nicht Ihnen gehört. Antwort: 200 \{ "subscriberId": "...", "active": true \}.
Eine neue Gewährung (active: true bei einem Abonnenten, der noch nicht berechtigt war) löst die enrolled-Lifecycle-E-Mail des Kurses aus. Der Entzug des Zugriffs mailt den Endnutzer nie in Ihrem Namen an.
POST /api/v1/courses/[id]/embed-token
Stellt ein kurzlebiges (5-minütiges) signiertes Token zur Einbettung des Kursportals aus, nachdem erneut geprüft wurde, dass der Abonnent tatsächlich berechtigt ist.
| Feld | Typ | Erforderlich | Hinweise |
| --- | --- | --- | --- |
| email | string | ja | Dieselbe Validierung wie oben. |
Fehler: 404, falls der Kurs nicht existiert, nicht Ihnen gehört oder nicht published ist; 409, falls das Konto noch keine /learn/<slug>-Mitgliedschafts-URL beansprucht hat; 403, falls diese E-Mail-Adresse aktuell nicht berechtigt ist (rufen Sie zuerst enroll auf).
Antwort: 200 \{ "portalUrl": "https://mailinapp.com/learn/<slug>/courses/<courseId>/embed?token=..." \}. Leiten Sie das iframe oder ein neues Fenster Ihrer App an portalUrl — es meldet den Besucher an und lässt ihn im gewöhnlichen Kursportal landen.
Lifecycle-E-Mail-Bindungen
Ein Kurs oder Webinar kann jedes seiner Lifecycle-Ereignisse an ein Studio-Projekt statt an den schlichten Bestätigungstext der Plattform binden:
| Ressource | Ereignisse |
| --- | --- |
| Kurs | enrolled, completed (reminder wird der Vollständigkeit halber akzeptiert, ohne automatischen Auslöser — Kurse haben kein natürliches Fälligkeitsdatum, gegen das eines ausgelöst werden könnte) |
| Webinar (LiveSession) | registered, reminder |
Bindungen werden im eigenen Panel Lifecycle-E-Mails des Kurses/Webinars im Dashboard festgelegt, nicht über diese API. Sie wirken beim nächsten Ereignis, unabhängig davon, ob es durch die Embed API oder die entsprechende Dashboard-/öffentliche-Formular-Aktion ausgelöst wurde. Ein Ereignis ohne Bindung (oder eines, das auf ein gelöschtes/fremdes Projekt zeigt) fällt direkt auf die heutige schlichte E-Mail zurück — das lässt einen Versand nie fehlschlagen.
Ein gebundenes Ereignis rendert über renderSingleRecipientEmail, genau wie der Template-Modus der Send API: vollständige Fallback-Engine, interaktive Blöcke und ein persönlicher signierter Live-Ansicht-Link. Auch das eigene Webhook-/Antworten-Tracking des Projekts erfasst es, zugeordnet zu diesem spezifischen Lifecycle-Ereignis statt zu einer gespeicherten Kontaktzeile.
Ratenlimits
Zwei unabhängige Obergrenzen gelten pro Route:
- Pro API-Schlüssel: 60 Anfragen/Minute. Überschreitung liefert
429 \{ "error": "Rate limit exceeded" \}speziell für diesen Schlüssel. - Pro Konto, Embed-API-Kontingent: Ihr Tarif enthält eine Anzahl an Embed-API-Aufrufen pro Kalendermonat, geteilt über alle vier obigen Routen.
0bei Free/Starter liefert403 \{ "error": "The Embed API isn't included in your plan" \}; die Überschreitung des Kontingents einer kostenpflichtigen Stufe liefert429 \{ "error": "Monthly Embed API quota for your plan exceeded" \}, bis es am 1. zurückgesetzt wird.
Die Webinar-Erstellung prüft zusätzlich erneut Ihr Live-Streaming-Kontingent (checkLiveSessionQuota) — dieselbe Broadcast-Minuten-/Kurs-Sperre, die auch der eigene Erstellungsablauf des Dashboards durchsetzt — und liefert 403 mit der eigenen Meldung dieser Prüfung, falls sie fehlschlägt.
Fehlercodes
| Status | Bedeutung |
| --- | --- |
| 400 | Fehlerhaftes JSON oder ein fehlendes/ungültiges Pflichtfeld — siehe die eigene Tabelle jeder Route oben. |
| 401 | Fehlender oder ungültiger Authorization-Header, oder der Schlüssel wurde widerrufen. |
| 403 | Embed API nicht in Ihrem Tarif enthalten, Kontingentprüfung fehlgeschlagen, Live-Session-Kontingent überschritten, oder (embed-token) die E-Mail-Adresse ist aktuell nicht berechtigt. |
| 404 | Das Webinar/der Kurs existiert nicht oder gehört nicht Ihrem Konto — bewusst dieselbe Antwort wie „existiert nicht“, dieselbe Begründung wie beim 404 des Template-Modus der Send API. |
| 409 | (Webinar) Die Session ist bereits beendet. (Embed-token) Das Konto hat noch keine Mitgliedschafts-URL beansprucht. |
| 429 | Pro-Schlüssel-Ratenlimit oder monatliches Kontingent überschritten. |
Siehe auch
- Send-API-Referenz — der Freiform-/Template-Transaktionsendpunkt, dessen Auth-Modell sich diese API teilt.
- Learning-Membership-Überblick — Kurse, Abonnenten und Berechtigung, die Konzepte, die die enroll-/embed-token-Routen umhüllen.
- Live-Sessions & Webinare — Webinar-Registrierung, Kapazität/Warteliste und Beitritts-Links, die Konzepte, die die Webinar-Routen umhüllen.