Abonnenten
Verwalten Sie Ihre Abonnentenkontakte, importieren Sie Listen und verfolgen Sie das Engagement
Verwalten Sie Ihre E-Mail-Abonnentenkontakte. Jeder Abonnent verfügt über ein Profil mit Engagement-Tracking, benutzerdefinierten Feldern und Statusverwaltung.
Abonnentenstatus
| Status | Wert | Beschreibung |
|---|---|---|
Active | 0 | Abonniert und empfängt E-Mails |
Unsubscribed | 1 | Von E-Mails abgemeldet |
Bounced | 2 | Hard Bounce verzeichnet |
Complained | 3 | Spam-Beschwerde eingereicht |
Pending | 4 | Reserviert: MailLand hat keinen Double-Opt-in-Ablauf, sodass nie etwas diesen Status setzt |
optInMethod und die consent*-Felder eines Abonnenten werden nur als Nachweis erfasst, sie steuern keinen Bestätigungs-Workflow.
Abonnenten erstellen
POST https://api.mail.land/v1/marketing/subscribers{
"email": "[email protected]",
"firstName": "John",
"lastName": "Doe",
"phone": "+1234567890",
"company": "Acme Corp",
"mailingListId": "ddv6ou6kz4wbto",
"source": "api",
"birthday": "1990-05-14",
"customFields": {
"plan": "enterprise",
"region": "us-west"
}
}| Feld | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
email | string | Ja | E-Mail-Adresse |
firstName | string | Nein | Vorname |
lastName | string | Nein | Nachname |
phone | string | Nein | Telefonnummer |
company | string | Nein | Unternehmensname |
mailingListId | string | Nein | Mailingliste zum Hinzufügen |
source | string | Nein | Abonnementquelle (z. B. api, form, import) |
birthday | string | Nein | YYYY-MM-DD. Wird vom DateBased-Automatisierungstrigger gelesen |
customFields | object | Nein | Benutzerdefinierte Schlüssel-Wert-Felder |
curl -X POST https://api.mail.land/v1/marketing/subscribers \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"firstName": "John",
"lastName": "Doe",
"mailingListId": "ddv6ou6kz4wbto",
"source": "api"
}'Antwort
{
"id": "exz31qoqlf01sj",
"email": "[email protected]",
"firstName": "John",
"lastName": "Doe",
"phone": "+1234567890",
"company": "Acme Corp",
"status": "active",
"statusName": "Active",
"source": "api",
"mailingListId": "ddv6ou6kz4wbto",
"mailingListName": "Product Updates",
"customFields": {
"plan": "enterprise",
"region": "us-west"
},
"subscribedAt": "2026-02-17T12:00:00Z",
"unsubscribedAt": null,
"createdAt": "2026-02-17T12:00:00Z",
"updatedAt": "2026-02-17T12:00:00Z"
}Abonnenten auflisten
GET https://api.mail.land/v1/marketing/subscribers| Parameter | Typ | Standard | Beschreibung |
|---|---|---|---|
cursor | string | - | Opaker Cursor aus dem nextCursor der vorherigen Seite. Für die erste Seite weglassen. |
limit | int | 20 | Einträge pro Seite |
search | string | - | Suche nach E-Mail oder Name (nicht Unternehmen) |
mailingListId | string | - | Nach Mailingliste filtern |
status | int | - | Nach Abonnentenstatus filtern |
sortBy | string | - | Sortierfeld |
sortDesc | bool | false | Absteigende Sortierung |
curl "https://api.mail.land/v1/marketing/subscribers?limit=20&mailingListId=ddv6ou6kz4wbto" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."Abonnentendetails abrufen
GET https://api.mail.land/v1/marketing/subscribers/{id}Gibt ein erweitertes Profil mit Engagement-Metriken zurück:
curl https://api.mail.land/v1/marketing/subscribers/exz31qoqlf01sj \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."{
"id": "exz31qoqlf01sj",
"email": "[email protected]",
"firstName": "John",
"lastName": "Doe",
"phone": "+1234567890",
"company": "Acme Corp",
"status": "active",
"source": "api",
"mailingListId": "ddv6ou6kz4wbto",
"mailingListName": "Product Updates",
"customFields": { "plan": "enterprise" },
"birthday": "1990-05-14",
"emailsSent": 50,
"emailsOpened": 25,
"emailsClicked": 10,
"lastEmailSentAt": "2026-02-17T09:30:00Z",
"lastEmailOpenedAt": "2026-02-16T15:20:00Z",
"lastEmailClickedAt": "2026-02-15T11:10:00Z",
"openRate": 50.0,
"clickRate": 40.0,
"subscribedAt": "2026-01-15T08:00:00Z",
"createdAt": "2026-01-15T08:00:00Z",
"updatedAt": "2026-02-17T12:00:00Z"
}Abonnenten aktualisieren
PUT https://api.mail.land/v1/marketing/subscribers/{id}{
"firstName": "Jane",
"lastName": "Smith",
"phone": "+1234567890",
"company": "TechCorp",
"mailingListId": "ddv6ou6kz4wbto",
"customFields": { "plan": "pro" },
"birthday": "1990-05-14",
"status": "Active"
}PUT ersetzt das gesamte Profil, es führt keinen Merge durch. firstName, lastName, phone, company und mailingListId werden bei Weglassen alle mit null (bzw. Listenentfernung) überschrieben, nicht unverändert gelassen. Das Weglassen von mailingListId entfernt die Listenmitgliedschaft des Abonnenten. Senden Sie jedes Feld, das Sie behalten möchten, einschließlich mailingListId. customFields und status bleiben bei Weglassen unverändert. birthday folgt einer eigenen Regel: Feld weglassen lässt es unverändert, "birthday": null senden löscht es, ein YYYY-MM-DD-Wert setzt es, ein leerer String ("") wird mit 400 abgelehnt. Hat der Empfänger bereits einen Kontakt ohne Liste, wird die entfernte Mitgliedschaft nur noch als Verlauf aufbewahrt: Sie erscheint nicht mehr in den Kontakten; Abmeldungen, Einwilligungsnachweise und Kampagnenverlauf bleiben erhalten.
curl -X PUT https://api.mail.land/v1/marketing/subscribers/exz31qoqlf01sj \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{
"firstName": "Jane",
"lastName": "Smith",
"company": "TechCorp",
"mailingListId": "ddv6ou6kz4wbto",
"customFields": { "plan": "pro" },
"status": "Active"
}'Abonnenten abmelden
POST https://api.mail.land/v1/marketing/subscribers/{id}/unsubscribeErfasst ein Opt-out, das auf die Liste des Abonnenten beschränkt ist (oder auf alle Marketing-Sendungen, falls der Abonnent keiner Liste angehört) und setzt den Abonnentenstatus auf Unsubscribed mit einem unsubscribedAt-Zeitstempel. Transaktionale E-Mails sind von diesem Aufruf nicht betroffen.
curl -X POST https://api.mail.land/v1/marketing/subscribers/exz31qoqlf01sj/unsubscribe \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."Abonnenten löschen
DELETE https://api.mail.land/v1/marketing/subscribers/{id}Entfernt den Abonnenten und seine Engagement-Daten dauerhaft. Opt-outs und Unterdrückungen bleiben erhalten, sodass ein erneutes Hinzufügen derselben Adresse sie nicht wieder abonniert.
curl -X DELETE https://api.mail.land/v1/marketing/subscribers/exz31qoqlf01sj \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."Abonnenten importieren
POST https://api.mail.land/v1/marketing/subscribers/importImportieren Sie Abonnenten aus CSV-Inhalten:
{
"mailingListId": "ddv6ou6kz4wbto",
"csvContent": "email,firstName,lastName\n[email protected],John,Doe\n[email protected],Jane,Smith",
"source": "csv_import",
"updateExisting": true
}| Feld | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
mailingListId | string | Nein | Ziel-Mailingliste |
csvContent | string | Ja | CSV-Daten: siehe den Format-Hinweis unten, die Kopfzeile wird nicht als Kopfzeile verwendet |
Die erste Zeile wird als Kopfzeile behandelt und übersprungen, unabhängig von ihrem Inhalt: sie wird nie gelesen, um die Spalten 1–3 Feldern zuzuordnen. Spalten sind positionsbasiert: Spalte 1 ist immer email, Spalte 2 immer firstName, Spalte 3 immer lastName; jede andere Spalte wird ignoriert, außer einer mit der Überschrift birthday (Groß-/Kleinschreibung egal, an beliebiger Position nach Spalte 1), die anhand ihres Spaltennamens statt ihrer Position gelesen wird. Ihr Wert muss YYYY-MM-DD sein; ein ungültiger Wert wird pro Zeile in errors gemeldet, und der Kontakt wird trotzdem importiert, nur ohne Geburtstag. Eine Datei ohne birthday-Kopfzeile verhält sich genau wie zuvor. Werte werden an einfachen Kommas aufgeteilt, sodass ein Wert mit einem Komma in Anführungszeichen nicht unterstützt wird und falsch aufgeteilt wird. Die Antwort enthält außerdem die Zähler importedNewMembershipForExistingRecipient, updatedMembership, alreadyMember, suppressed und skippedDuplicateInFile zusätzlich zu dem unten Gezeigten.
| source | string | Nein | Bezeichnung der Importquelle |
| updateExisting | bool | Nein | Vorhandene Abonnenten aktualisieren (Standard: false) |
curl -X POST https://api.mail.land/v1/marketing/subscribers/import \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{
"mailingListId": "ddv6ou6kz4wbto",
"csvContent": "email,firstName,lastName\[email protected],John,Doe\[email protected],Jane,Smith",
"source": "csv_import",
"updateExisting": true
}'{
"imported": 50,
"updated": 10,
"skipped": 5,
"errors": [
"Invalid email: not-an-email",
"Could not resolve a recipient identity for: [email protected]"
]
}Importierte Abonnenten lösen die SubscriberJoins-Automatisierung aus: für jede Mitgliedschaft, die der Import tatsächlich anlegt, genauso wie bei einer einzelnen Erstellung über POST /v1/marketing/subscribers. Ein Kontakt, der bereits auf der Zielliste ist, ein Duplikat innerhalb der Datei oder eine Zeile, die an einem (TenantId, Email)-Konflikt scheitert, wird nicht eingeschrieben. Hat die Zielliste eine aktive SubscriberJoins-Automatisierung (oder besitzt der Tenant eine nicht listengebundene), sendet ein Import neuer Kontakte diese Automatisierung jetzt an jeden von ihnen, den Import entsprechend dimensionieren. Sperrungen werden weiterhin durchgesetzt: Die Einschreibung umgeht niemals einen gesperrten Empfänger.
Abonnenten exportieren
GET https://api.mail.land/v1/marketing/subscribers/export| Parameter | Typ | Beschreibung |
|---|---|---|
mailingListId | string | Nach Mailingliste filtern |
status | int | Nach Status filtern |
Gibt einen CSV-Datei-Download mit dem Dateinamen subscribers_yyyyMMdd_HHmmss.csv zurück.
curl "https://api.mail.land/v1/marketing/subscribers/export?mailingListId=ddv6ou6kz4wbto" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-o subscribers_export.csvAbonnentenstatistiken
GET https://api.mail.land/v1/marketing/subscribers/stats| Parameter | Typ | Beschreibung |
|---|---|---|
mailingListId | string | Nach Mailingliste filtern |
curl "https://api.mail.land/v1/marketing/subscribers/stats?mailingListId=ddv6ou6kz4wbto" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."{
"total": 1500,
"active": 1200,
"unsubscribed": 200,
"bounced": 80,
"complained": 10,
"pending": 10
}Abonnentenanzahl
GET https://api.mail.land/v1/marketing/subscribers/count| Parameter | Typ | Beschreibung |
|---|---|---|
mailingListId | string | Nach Mailingliste filtern |
curl "https://api.mail.land/v1/marketing/subscribers/count?mailingListId=ddv6ou6kz4wbto" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."{
"count": 1500,
"mailingListId": "ddv6ou6kz4wbto"
}Abonnentenwachstum
GET https://api.mail.land/v1/marketing/subscribers/growth| Parameter | Typ | Standard | Beschreibung |
|---|---|---|---|
days | int | 30 | Betrachtungszeitraum (max. 90) |
mailingListId | string | - | Nach Mailingliste filtern |
curl "https://api.mail.land/v1/marketing/subscribers/growth?days=30&mailingListId=ddv6ou6kz4wbto" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."{
"dataPoints": [
{
"date": "2026-02-17",
"newSubscribers": 50,
"unsubscribes": 5,
"cumulativeTotal": 1500
}
],
"totalNew": 500,
"totalUnsubscribes": 50,
"netGrowth": 450,
"currentTotal": 1500
}Fehlerantworten
| Status | Code | Beschreibung |
|---|---|---|
400 | INVALID_EMAIL_FORMAT | Ungültiges E-Mail-Format |
400 | INVALID_REQUEST | E-Mail-Adresse des Abonnenten existiert bereits |
403 | FORBIDDEN | Unzureichende Berechtigungen |
404 | RESOURCE_NOT_FOUND | Abonnent nicht gefunden |