Verbinden Sie Ihre Website-Anmeldeformulare mit Mailoo. Jede gültige Übermittlung erstellt eine eingehende Nachricht und aktualisiert einen Abonnenten. Verwenden Sie eine FORM-Integration und rufen Sie die API ausschließlich von Ihrem Server oder BFF auf.
Schnellstart
- Erstellen Sie ein Projekt und eine Form-Integration im Mailoo-Dashboard (oder per MCP
create_integrationmittype=FORM). - Generieren Sie einen API-Schlüssel. Für RESTRICTED-Schlüssel ergänzen Sie
webhook.form-submission. Agenten können Connection & settings, Vorlagen, Abonnenten, Kampagnen und Nachrichten auch über MCP-Toolsmanage_form_*konfigurieren (Scopeform.manage/ MCP-Token) --- siehe/development/mailoo-mcp{.interpreted-text role="doc"}. - Speichern Sie den Schlüssel und die IDs in serverseitigen Umgebungsvariablen.
- Senden Sie Formulardaten an Ihre eigene Route; diese Route leitet an Mailoo weiter.
- Bestätigen Sie Nachricht und Abonnent im Dashboard.
:::: important ::: title Important :::
Nur serverseitig. Der Browser darf X-API-Key nicht enthalten. Platzieren Sie Mailoo-Zugangsdaten nicht in clientseitigem JavaScript.
::::
:::: note ::: title Note :::
Legacy (nicht empfohlen): Direkte Aufrufe der Mailoo-Webhooks aus dem Browser können funktionieren, wenn CORS und erlaubte Origins konfiguriert sind, doch dabei wird der API-Schlüssel offengelegt. Verwenden Sie dies nicht für neue Integrationen. ::::
Next.js mit @mailoo/forms
Für Next.js-App-Router-Hosts bevorzugen Sie das Paket @mailoo/forms: Same-Origin-BFF-Routenfabriken, typisierte Submit-Bodies und Client-Hooks. Siehe website-forms-nextjs-example{.interpreted-text role="doc"}.
Für Registrierung oder Aktivierung eines identifizierten Benutzers (nicht anonyme Newsletter-Anmeldung) senden Sie Lifecycle-Ereignisse von Ihrem Server --- siehe lifecycle-events{.interpreted-text role="doc"}.
Integration erstellen
- Gehen Sie zu Dashboard → Projects → [Ihr Projekt] → Integrations.
- Erstellen Sie eine neue Integration und wählen Sie Form Integration.
- Legen Sie Name, Status (Active) und optionale Allowed origins fest (Schema + Host, z. B.
https://example.com). Wenn die Liste leer ist, wird der Origin nicht geprüft. Die Authentifizierung bleibt beim API-Schlüssel. Ein BFF, das den Browser-Originweiterleitet, erzwingt trotzdem eine gefüllte Liste.
Anfragekörper
Ihr Server sendet JSON an Mailoo:
email--- erforderlichname--- optionalsubject--- optional (Standardwerte wie"New subscription")content--- optional (Standardwerte wie"New subscription from {email}")source,metadata--- optional, werden mit der Nachricht gespeichert
Eine Kampagne oder Nachrichtenvorlage ist nicht erforderlich, damit das Formular Übermittlungen akzeptiert. Die eingehende Nachricht wird aus dem Anfragekörper (oder Standardwerten) erstellt.
Die Weiterleitung des Benutzers nach einer erfolgreichen Übermittlung liegt vollständig in der Verantwortung Ihrer Website. Mailoo stellt keine Weiterleitungs-URL bereit.
API-Endpunkt
POST /api/v1/webhooks/forms/{projectUid}/{integrationId}
Header: Content-Type: application/json, X-API-Key (erforderlich). Optionaler Origin, wenn Sie eine Allowlist für erlaubte Origins verwenden.
Beispielkörper:
{
"email": "john@example.com",
"name": "John Doe",
"source": "https://yoursite.com/newsletter",
"metadata": {
"type": "newsletter_subscription"
}
}
Neuer Abonnent --- Nachricht erstellt:
{
"success": true,
"messageId": "msg_abc123def456",
"message": "Form submission processed successfully"
}
Bereits abonniert (gleiche E-Mail) --- keine neue Nachricht; unsubscribedAt wird bei Bedarf gelöscht; die Antwort enthält keine messageId:
{
"success": true,
"message": "Already subscribed"
}
Validierungsfehler liefern error und message (zum Beispiel "Email is required", "Invalid email format").
Serverseitiges Beispiel (Express)
Das Formular sendet an Ihre Route. Ihre Route ruft Mailoo auf:
app.post('/api/subscribe', async (req, res) => {
const { email, name } = req.body
if (!email || !email.includes('@')) {
return res.status(400).json({ error: 'Valid email is required' })
}
const response = await fetch(
`${process.env.MAILOO_API_URL}/api/v1/webhooks/forms/${process.env.PROJECT_UID}/${process.env.INTEGRATION_ID}`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': process.env.MAILOO_API_KEY,
Origin: process.env.WEBSITE_ORIGIN || '',
},
body: JSON.stringify({
email: email.trim(),
name: name?.trim() || undefined,
source: req.headers.referer || 'server-side-form',
}),
}
)
const result = await response.json()
return res.status(response.status).json(result)
})
Umgebungsvariablen (Beispiel):
MAILOO_API_URL=https://api.mailoo.app
PROJECT_UID=your-project-uid
INTEGRATION_ID=your-form-integration-id
MAILOO_API_KEY=your-api-key
WEBSITE_ORIGIN=https://yourdomain.com
Für Next.js empfiehlt sich @mailoo/forms -- siehe website-forms-nextjs-example{.interpreted-text role="doc"}.
Browser-Formular (sendet nur an Ihr Backend)
Minimale HTML-Felder: email (erforderlich), name (optional). JavaScript sollte JSON per POST an Ihre Same-Origin-Route senden (z. B. /api/subscribe), niemals direkt an Mailoo mit einem aktiven Schlüssel.
Ausgehendes SMTP und Willkommensmail
Optionale Willkommens- oder Antwortmail nutzt ausgehendes SMTP auf der Integration. Es gibt keinen Plattform-SMTP-Fallback. Siehe outbound-smtp{.interpreted-text role="doc"} und transactional-email{.interpreted-text role="doc"}.
Abonnenten und Vorlagen (nur Dashboard)
Abonnenten
: Aufgelistet im Dashboard (E-Mail, Name, Daten). Pro Zeile: Unsubscribe, Delete oder Restore für abgemeldete Adressen. Externe Websites können die Abonnentenliste nicht über die API lesen; sie übermitteln nur über den Formular-Webhook.
Nachrichtenvorlagen
: Integration-Tab E-Mail-Vorlagen (HTML-Blöcke + Liquid). Neue Kampagnen wählen eine Vorlage; Formularfelder kommen aus campaign-Slots. On-Event-Kampagnen dienen Willkommen und Dashboard-Antwort. Das Formular braucht keine Vorlage zum Annehmen von Übermittlungen. Rendering mit LiquidJS.
Lokalisierung (BLOG-Stil)
: Blöcke, Vorlagen und Kampagnen-Slotwerte: kanonische Felder (EN) plus optionales locales-JSON. Liquid-Schlüssel bleiben sprachneutral. Optional locale bei Form-/Transactional-/Lifecycle-Requests; fehlt der Wert oder das Overlay, gilt kanonisch und wird geloggt. Massenversand nutzt Subscriber.locale. Auf der E-Mail-Vorlagen-Registerkarte zeigt jede Locale-Karte eine Live-Vorschau des Overlays (oder des kanonischen Fallbacks, wenn das Overlay-Feld leer ist).
Abmeldung
-
Transaktions-``{{unsubLink}}`` --- bevorzugt beim Versand über
transactional-email{.interpreted-text role="doc"}. -
Ein-Klick-Seite ---
https://mailoo.app/{locale}/unsubscribe/confirmmit signierten Abfrageparametern. -
API (Server, mit API-Schlüssel):
POST /api/v1/webhooks/unsubscribe Content-Type: application/json X-API-Key: your-api-key {"email": "user@example.com", "integrationId": "your-integration-id"}
Kampagnen (Dashboard)
Kampagnen befinden sich unter der Formular-Integration (Reiter Campaigns). Sie können ONE_TIME-, ON_EVENT- oder RECURRING-Kampagnen aus einer Nachrichtenvorlage erstellen und mit Prüfen Einstellungen, die aktuelle aktive Abonnentenliste, eine Vorschau pro Abonnent und optionalen Testversand (eine Adresse über denselben Kampagnen-Sender) prüfen. Prüfen speichert die Zielgruppe nicht.
Vorlagen-Hülle. Jede Vorlage speichert optional shellWidthPx (Spaltenbreite, Standard 600, Bereich 320--800) und shellBackground (Seitenhintergrund als Hex, Standard #f4f4f5). Blöcke sind HTML-Fragmente; Mailoo wickelt sie beim Kompilieren für Versand und Dashboard-Vorschau in diese Hülle.
On-Event-Willkommen nach einer neuen Formular-Anmeldung kann über das ausgehende SMTP der Integration gesendet werden, wenn der Kampagnenstatus ``SCHEDULED`` ist (neue Kampagnen starten als DRAFT). Registrierung und Aktivierung identifizierter Benutzer nutzen Lifecycle-Ereignisse (user.registered / user.activated) --- siehe lifecycle-events{.interpreted-text role="doc"} (gleiche SCHEDULED-Regel für USER_REGISTERED / USER_ACTIVATED).
ONE_TIME-Massenversand. Unter Setup Kampagnen-Versandgeschwindigkeit setzen (config.campaignSend.delayBetweenEmailsMs, Ganzzahl 0...600000; pflicht --- kein Default). Optional Empfängerfilter an der Kampagne setzen (z. B. registriert vor einem Datum) --- gespeichert als recipientFilter und angewendet beim Prüfen der Zielgruppe und beim Kopieren der Abonnenten für den Versand. Send Now ruft POST …/campaigns/{id}/send auf. Fehlen noch CampaignRecipient-Zeilen, kopiert die API die aktuellen aktiven Abonnenten, die dem Kampagnenfilter entsprechen (unsubscribedAt null plus recipientFilter-Regeln) in die Kampagne und setzt sendRequestedAt. Der Worker nimmt ein PostgreSQL-Advisory-Lock, setzt SENDING, wartet kurz nach dem Claim und sendet pending-Empfänger mit der konfigurierten Pause. Mehrere API-Pods können dieselbe Kampagne nicht doppelt senden. Bei Fehler FAILED mit vollständigem lastError; Retry send (POST …/retry) setzt nur failed erneut auf pending (erfolgreiche werden nicht erneut gesendet). PATCH status=SENDING ist verboten (400). Testversand (POST …/test-send) nutzt denselben Sender für einen aktiven Abonnenten und stellt die Kampagne nicht in die Warteschlange. RECURRING ist noch nicht verdrahtet.
Nach dem Versand zeigt der Kampagnen-Tab Empfänger-Summen (ausstehend, gesendet, fehlgeschlagen, zugestellt, geöffnet, geklickt). Öffnen Sie diese Übersicht (oder Empfänger), um die Tabelle je Adresse mit Status, Zeitstempeln und Fehlern zu sehen.
Fehlerbehebung
401 --- Ungültiger API-Schlüssel
: Überprüfen Sie den Schlüssel, die Projekt-UID und ob der Schlüssel aktiv ist. RESTRICTED-Schlüssel benötigen webhook.form-submission.
403 --- Origin nicht erlaubt
: Fügen Sie den übermittelnden Origin zu Allowed origins hinzu, oder leeren Sie die Liste, wenn Sie keine Origin-Prüfung benötigen.
429 --- Ratenbegrenzung
: Warten Sie und versuchen Sie es erneut; reihen Sie Anfragen auf Ihrem Server bei hohem Traffic in eine Warteschlange ein.
Validierungsfehler
: Nur email ist erforderlich. Optionale Felder: name, subject, content. Senden Sie kein message-Feld in der Erwartung, dass es zum Posteingangstext wird -- verwenden Sie content.
Sicherheit
- Bewahren Sie API-Schlüssel auf dem Server auf; rotieren Sie regelmäßig.
- Validieren Sie E-Mails auf Client und Server; verwenden Sie HTTPS.
- Bieten Sie klare Opt-in- und Abmelde-Pfade an.
Nächste Schritte
website-forms-nextjs-example{.interpreted-text role="doc"} ---@mailoo/forms-BFFlifecycle-events{.interpreted-text role="doc"} --- App-Registrierungs-/Aktivierungsereignisseoutbound-smtp{.interpreted-text role="doc"} /transactional-email{.interpreted-text role="doc"}contact-feedback-form{.interpreted-text role="doc"} --- CONTACT_FORM für Support-Nachrichten- OpenAPI:
https://api.mailoo.app/docs/v1