MailLandDocs
Konto

Abrechnung

Verwalten Sie Ihr Abonnement, sehen Sie Rechnungen ein und überwachen Sie die Nutzung

MailLand verwendet Stripe für die Abonnementverwaltung und Abrechnung. Jeder Arbeitsbereich hat sein eigenes Abonnement mit nutzungsbasierter oder planbasierter Preisgestaltung. Jedes Mitglied kann den Abrechnungsstatus lesen; nur der Workspace-Eigentümer kann ihn ändern (mutierende Aufrufe liefern 403 INSUFFICIENT_PERMISSIONS, und API-Schlüssel werden bei diesen Endpunkten immer abgelehnt).

Zahlungsstatus

paymentStatus wird als Snake-Case-String zurückgegeben, nicht als numerisches Enum:

StatusBeschreibung
currentAbonnement aktiv, Zahlung aktuell
grace_periodZahlung fehlgeschlagen, Kulanzzeit aktiv
overdueZahlung überfällig, Funktionen eingeschränkt
blockedKonto wegen Nichtzahlung gesperrt

Abonnementdetails abrufen

GET https://api.mail.land/v1/account/subscription
Get subscription details
curl https://api.mail.land/v1/account/subscription \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
Subscription response
{
  "planName": "Pro",
  "monthlyEmailLimit": 100000,
  "rateLimitPerSecond": 10,
  "pricePerMonth": 49.00,
  "startDate": "2026-01-15T08:00:00Z",
  "endDate": "2026-03-01T00:00:00Z",
  "status": "Active",
  "paymentStatus": "current",
  "marketingPausedDueToPayment": false,
  "sendingBlockedDueToPayment": false,
  "transactionalDailyLimit": 5000,
  "daysUntilBlocked": null,
  "cancelAtPeriodEnd": false,
  "planFamilyId": "fam_pro",
  "planTierPublicId": "tier_pro_monthly",
  "usage": {
    "emailsSentThisMonth": 45000,
    "monthlyLimit": 100000,
    "percentageUsed": 45.0,
    "transactionalCount": 30000,
    "marketingCount": 12000,
    "apiCount": 40000,
    "smtpCount": 5000,
    "campaignCount": 3000,
    "automationCount": 2000,
    "inboundForwardCount": 500
  }
}

Es gibt kein id, planId, interval, currentPeriodStart/currentPeriodEnd, oder verschachtelte numerische paymentStatus-/Validierungs-/Domain-/Team-/Automatisierungs-Nutzungsfelder in dieser Antwort, verwenden Sie die obigen Feldnamen. paymentStatus ist ein Snake-Case-String: "current", "grace_period", "overdue" oder "blocked". status ist PascalCase ("Active", "Suspended", "Cancelled"): die einzige Ausnahme ist der Fallback ohne Abonnement, der klein geschriebenes "active" liefert.

Nutzungsfelder

FeldBeschreibung
emailsSentThisMonthIm aktuellen Abrechnungszeitraum gesendete E-Mails
monthlyLimitMaximale E-Mails pro Zeitraum
percentageUsedemailsSentThisMonth als Prozentsatz von monthlyLimit
transactionalCountGesendete transaktionale E-Mails
marketingCountGesendete Marketing-E-Mails
apiCountÜber die API gesendete E-Mails
smtpCountÜber SMTP-Relay gesendete E-Mails
campaignCountVon Kampagnen gesendete E-Mails
automationCountVon Automatisierungen gesendete E-Mails
inboundForwardCountVon Weiterleitungsregeln für eingehende E-Mails gesendete E-Mails

Es gibt keine Validierungs-, Domain-, Teammitglieder- oder Automatisierungs-Nutzungszähler in dieser Antwort, nur E-Mail-Versandzähler.

Wann wird die E-Mail-Nutzung gezählt

Empfänger zählen gegen Ihre Nutzung und Ihr Kontingent (emailsSentThisMonth / monthlyLimit) in dem Moment, in dem die Annahme dauerhaft erfasst wird. Empfänger, die vor der Annahme abgelehnt oder unterdrückt werden, zählen niemals. Ein Bounce, eine nachgelagerte Unterdrückung, ein Zustellfehler oder eine andere Nichtzustellung nach der Annahme stellt Nutzung oder Kontingent nicht automatisch wieder her: die Zählung wird nicht rückwirkend angepasst. Dieser Abschnitt beschreibt nur die Nutzungsabrechnung; er besagt oder impliziert keine Stripe-Preisgestaltung pro E-Mail oder ein Erstattungsrecht, die separat durch Ihre Abonnementbedingungen geregelt sind.

Das Kontingent wird bei jedem Stripe-Abrechnungszeitraum für über Stripe abgerechnete Pläne zurückgesetzt, oder am 1. jedes UTC-Kalendermonats für Pläne, die nicht über Stripe abgerechnet werden (Free und vom Administrator gewährte Pläne): nicht immer "pro Zeitraum" im Stripe-Sinne.

Pläne & Aufbewahrung

Die Pläne sind Free, Pro und Max. Nachrichtenprotokolle werden 30 Tage bei Free, 90 Tage bei Pro und 180 Tage bei Max aufbewahrt.

Richtlinienzusammenfassung

Rufen Sie den Verifizierungsstatus des Arbeitsbereichs und die Senderichtlinie ab:

GET https://api.mail.land/v1/account/subscription/policy-summary
Get policy summary
curl https://api.mail.land/v1/account/subscription/policy-summary \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Die Antwort ist ein verschachteltes Objekt, nicht flach (SubscriptionController.cs:137-200):

Policy summary response
{
  "subscription": {
    "planFamilyId": "fam_pro",
    "planFamilyName": "Pro",
    "planTierId": "tier_pro_monthly",
    "monthlyQuota": 100000,
    "pricePerMonth": 49.00
  },
  "usage": {
    "usedThisMonth": 45000,
    "remainingThisMonth": 55000,
    "percentUsed": 45.0
  },
  "effectiveRates": {
    "transactionalRatePerMin": 600,
    "marketingRatePerMin": 300,
    "isOverridden": false
  },
  "domainWarmup": [
    {
      "domainId": "h4k7m1n9w2p5x8",
      "domainName": "example.com",
      "currentStage": 2,
      "totalStages": 5,
      "todaySentCount": 350,
      "dailyLimit": 500,
      "progressPercent": 70.0,
      "completed": false,
      "bypassed": false
    }
  ],
  "alerts": [
    {
      "type": "warning",
      "code": "QUOTA_WARNING",
      "message": "You have used 80% of your monthly quota. Consider upgrading your plan.",
      "actionUrl": "/billing"
    }
  ],
  "dailySendingLimit": {
    "limit": 5000,
    "usedToday": 1200,
    "remainingToday": 3800,
    "resetsAt": "2026-02-18T00:00:00Z"
  },
  "verification": {
    "level": 2,
    "levelName": "SenderVerified",
    "limits": {},
    "progress": {},
    "nextSteps": []
  }
}
FeldBeschreibung
subscriptionPlanfamilie, Tarifstufe sowie monatliches Kontingent/Preis
usageVerbrauchte, verbleibende E-Mails und der prozentuale Verbrauch in diesem Monat
effectiveRatesEffektive Sende-Raten pro Minute und ob sie überschrieben sind
domainWarmupWarmup-Fortschritt pro Domain, ein Eintrag je Domain im Warmup
alertsAktive Warnungen für diesen Workspace (Kontingent, Tageslimit u. Ä.)
dailySendingLimitTägliches Sendelimit und verbleibendes Kontingent, sofern zutreffend
verificationAktuelle Verifizierungsstufe, ihre Limits, Fortschritt und nächste Schritte

Checkout-Sitzung erstellen

Starten Sie eine Stripe-Checkout-Sitzung, um ein Abonnement abzuschließen oder zu upgraden:

POST https://api.mail.land/v1/account/billing/checkout
Checkout request
{
  "planTierId": "tier_pro_monthly",
  "locale": "en",
  "businessAttested": true,
  "businessAttestationKey": "business-use-v3-button"
}
FeldTypErforderlichBeschreibung
planTierIdstringJaÖffentliche ID der Plan-Stufe
localestringNeinSprache für die gehostete Checkout-Seite
businessAttestedbooleanJatrue bestätigt, dass Sie MailLand für geschäftliche oder berufliche Zwecke erwerben (auch als Freiberufler, Einzelunternehmer oder für Ihre eigene Website). Das Dashboard sendet es über die Zahlungsschaltfläche: Ihre Beschriftung lautet „Pay for business use“, und ein einzeiliger Hinweis darunter nennt, was der Klick bestätigt
businessAttestationKeystringJaDie Version des Wortlauts, auf die sich die Bestätigung bezieht; derzeit business-use-v3-button (business-use-v1, der frühere Wortlaut, wird weiterhin akzeptiert)

Eine Anfrage ohne businessAttested: true und einen akzeptierten businessAttestationKey wird mit 400 BUSINESS_ATTESTATION_REQUIRED abgelehnt, bevor etwas belastet wird. MailLand speichert, wer wann bestätigt hat, mit welchem Wortlaut (dem von Ihnen gesendeten Schlüssel) und in welcher Sprache. In Stripe Checkout können Sie eine Steuer-ID eingeben; sie ist optional. Die Preise verstehen sich ohne USt., und MailLand erhebt keine USt.; eine geprüfte EU-USt-IdNr. außerhalb des Vereinigten Königreichs fügt Ihren Rechnungen den Reverse-Charge-Hinweis hinzu.

Es gibt kein successUrl- oder cancelUrl-Feld: Erfolgs-/Abbruch-URLs werden nicht vom Aufrufer angegeben.

Create checkout session
curl -X POST https://api.mail.land/v1/account/billing/checkout \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{ "planTierId": "tier_pro_monthly", "locale": "en", "businessAttested": true, "businessAttestationKey": "business-use-v3-button" }'
Checkout response
{
  "upgraded": false,
  "sessionId": "cs_live_abc123...",
  "url": "https://checkout.stripe.com/c/pay/cs_live_abc123..."
}

Leiten Sie den Benutzer zur url weiter, um die Zahlung auf der gehosteten Stripe-Checkout-Seite abzuschließen. Wenn der Workspace bereits ein aktives Abonnement hat, wird der Plan direkt geändert, statt ein neues Checkout zu öffnen: Die Antwort ist { "upgraded": true } ohne sessionId/url, und es gibt keine Weiterleitung. Leiten Sie nur weiter, wenn url vorhanden ist.

Abrechnungsportal

Öffnen Sie das Stripe-Kundenportal zur Selbstverwaltung (Zahlungsmethode aktualisieren, kündigen, Rechnungen einsehen):

POST https://api.mail.land/v1/account/billing/portal
Portal request
{
  "locale": "en"
}

locale ist optional.

Open billing portal
curl -X POST https://api.mail.land/v1/account/billing/portal \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{ "locale": "en" }'
Portal response
{
  "url": "https://billing.stripe.com/p/session/abc123..."
}

Leiten Sie den Benutzer zur url weiter, um auf das Stripe-Portal zuzugreifen.

Rechnungen auflisten

GET https://api.mail.land/v1/account/billing/invoices
ParameterTypStandardBeschreibung
limitint20Anzahl der zurückzugebenden Rechnungen
cursorstring-Undurchsichtiger Cursor aus dem nextCursor einer vorherigen Antwort
List invoices
curl https://api.mail.land/v1/account/billing/invoices \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
Invoices response
{
  "items": [
    {
      "publicId": "inv_abc123",
      "invoiceNumber": "INV-2026-0015",
      "stripeInvoiceId": "in_1AbCdEfGhIjKlMn",
      "status": "Paid",
      "amountDue": 4900,
      "amountPaid": 4900,
      "currency": "eur",
      "periodStart": "2026-01-01T00:00:00Z",
      "periodEnd": "2026-02-01T00:00:00Z",
      "paidAt": "2026-01-01T00:05:00Z",
      "hostedInvoiceUrl": "https://pay.stripe.com/invoice/inv_abc123",
      "invoicePdfUrl": "https://pay.stripe.com/invoice/inv_abc123/pdf",
      "createdAt": "2026-01-01T00:00:00Z"
    },
    {
      "publicId": "inv_def456",
      "invoiceNumber": "INV-2026-0014",
      "stripeInvoiceId": "in_2BcDeFgHiJkLmNo",
      "status": "Paid",
      "amountDue": 4900,
      "amountPaid": 4900,
      "currency": "eur",
      "periodStart": "2025-12-01T00:00:00Z",
      "periodEnd": "2026-01-01T00:00:00Z",
      "paidAt": "2025-12-01T00:05:00Z",
      "hostedInvoiceUrl": "https://pay.stripe.com/invoice/inv_def456",
      "invoicePdfUrl": "https://pay.stripe.com/invoice/inv_def456/pdf",
      "createdAt": "2025-12-01T00:00:00Z"
    }
  ],
  "nextCursor": null,
  "hasMore": false
}

Dies ist eine cursor-paginierte Antwort, nicht { "invoices": [...] }: geben Sie nextCursor als cursor-Parameter zurück, um die nächste Seite zu erhalten, und stoppen Sie, wenn hasMore false ist. Die Standard-Seitengröße ist 20, nicht 10; die Feldnamen sind invoiceNumber, amountDue, amountPaid, hostedInvoiceUrl und invoicePdfUrl (nicht number, amount, invoiceUrl, invoicePdf).

Rechnungsbeträge sind in der kleinsten Einheit der currency der Rechnung angegeben (Cent für EUR). Teilen Sie durch 100, um den Betrag anzuzeigen. Die Tarifpreise sind in Euro (EUR) angegeben und verstehen sich zuzüglich MwSt.

Fehlerantworten

StatusCodeBeschreibung
400VALIDATION_FAILEDUngültiger Anfragetext
400INVALID_REQUESTTarifstufe existiert, ist aber nicht mit Stripe synchronisiert
403INSUFFICIENT_PERMISSIONSNur der Workspace-Eigentümer kann diese Mutation durchführen (Abrechnungs-Lesezugriff steht jedem Mitglied offen)
404RESOURCE_NOT_FOUNDUnbekannte oder inaktive Tarifstufe
502STRIPE_ERRORStripe-Anfrage fehlgeschlagen

Weitere Abrechnungsendpunkte

Ebenfalls verfügbar, oben nicht im Detail beschrieben: POST /v1/account/billing/cancel, POST /v1/account/billing/reactivate und der öffentliche Endpunkt GET /public/plans/catalog.

Nächste Schritte

Auf dieser Seite