API
API-Dokumentation
Eine Adresse rein, ein Urteil mit Gründen raus. Ohne Schlüssel nutzbar, keine Anmeldung, JSON in beiden Richtungen. Höhere Limits gibt es mit API-Schlüssel.
POST /api/v1/pruefen
Basis-URL: https://mailcheck.moersbergerit.de. Aktuelle Version ist v1; die älteren Pfade ohne /v1 (/api/pruefen, /api/stand) bleiben als Alias erhalten, werden aber nicht mehr dokumentiert. Der Endpunkt erwartet einen JSON-Body mit dem Feld email und liefert das Prüfergebnis.
{"email": "name@beispiel.de"}Es gibt zusätzlich GET /api/v1/pruefen?email=… für schnelle Tests im Browser oder in der Shell. Dabei steht die Adresse in der URL und kann in Protokollen von Proxys oder Browsern landen. Nutzen Sie deshalb POST.
{
"ergebnis": "wegwerf",
"punkte": 98,
"gruende": [
{
"code": "liste",
"text": "Die Domain steht auf Listen bekannter Wegwerf-Anbieter.",
"quellen": ["burner-email-providers", "disposable-email-domains", "fakefilter", "mailchecker"],
"eintrag": "mailinator.com"
}
],
"domain": "mailinator.com",
"empfehlung": "ablehnen",
"vorschlag": null
}Aufbau der Antwort
| Feld | Typ | Bedeutung |
|---|---|---|
ergebnis | String | Eines von ungueltig, wegwerf, verdaechtig, alias, frei, firma. |
punkte | Ganzzahl | Risikowert von 0 (unbedenklich) bis 100 (sicher unbrauchbar). |
gruende | Liste | Objekte mit code (stabil, für Maschinen), text (Klartext, deutsch) und je nach Grund Zusatzfeldern. |
domain | String | Die Domain in technischer Schreibweise, klein geschrieben. Leer, wenn die Adresse syntaktisch ungültig ist. |
empfehlung | String | ablehnen (ungültig, Wegwerf), bestaetigen_lassen (verdächtig) oder annehmen (alle übrigen). |
vorschlag | String oder null | Korrekturvorschlag bei einem wahrscheinlichen Tippfehler in der Domain, etwa gmail.com statt gmial.com. Ohne Vorschlag null (oder das Feld fehlt). Die Weboberfläche zeigt dann „Meinten Sie name@gmail.com?“ mit einem Knopf zum Übernehmen und erneuten Prüfen. |
| Code | Bedeutung |
|---|---|
syntax | Die Adresse ist formal ungültig. |
keine_domain | Hinter dem @ steht keine gültige Domain. |
nxdomain | Die Domain existiert nicht. |
null_mx | Die Domain nimmt ausdrücklich keine E-Mails an. |
mx_lokal | Der Mailserver der Domain zeigt auf eine interne Adresse (z. B. localhost), Mails können nicht zugestellt werden. |
keine_mail | Die Domain hat weder einen Mailserver (MX) noch eine Adresse. |
positivliste | Großer, bekannter E-Mail-Anbieter. |
alias | Weiterleitungs-/Alias-Dienst: ein echtes Postfach dahinter. |
liste | Die Domain steht auf Listen bekannter Wegwerf-Anbieter. Zusatzfelder: quellen, eintrag. |
liste_subdomain | Die Domain gehört zu einem gelisteten Anbieter (Subdomain). Zusatzfelder: quellen, eintrag. |
reserviert | Reservierte Domain wie example.com (RFC 2606, RFC 6761), sie nimmt nie Mails an. |
liste_grosser_hoster | Die Domain steht auf einer Liste, der Mailserver gehört aber zu einem großen Hoster (etwa Google Workspace oder Microsoft 365). Das spricht eher für einen Fehleintrag und führt zu „verdächtig“ mit der Empfehlung bestaetigen_lassen. Zusatzfelder: quellen, eintrag, mx_host. |
liste_schwach | Die Domain steht nur auf schwächeren Listen (mailchecker, groundcat), nicht auf den starken. Führt allein zu „verdächtig“, zusammen mit beiden schwachen Listen oder einem Wegwerf-Mailserver zu „wegwerf“. Zusatzfelder: quellen, eintrag. |
mx | Der Mailserver bedient überwiegend Wegwerf-Domains. Zusatzfeld: mx_host. |
mx_schwach | Kein MX-Eintrag, nur ein Adress-Eintrag. |
dns_fehler | Zeitüberschreitung bei der DNS-Abfrage. |
zufall | Der Teil vor dem @ wirkt zufällig erzeugt. |
domain_neu | Die Domain ist erst wenige Wochen alt. Zusatzfeld: alter_tage. |
tippfehler | Die Domain ähnelt einem großen Anbieter (etwa gmial.com). Zusatzfeld: vorschlag mit der korrigierten Adresse; dieselbe Adresse steht im Feld vorschlag der Antwort. |
rolle | Der Teil vor dem @ ist eine Funktionsadresse wie info@ oder admin@, kein persönliches Postfach. |
eigene_domain | Eigene Domain mit funktionierendem Mailserver. |
Der Grund rolle markiert Funktionsadressen und ist ein schwaches Signal; Sie können ihn etwa nutzen, um bei Registrierungen nach einer persönlichen Adresse zu fragen. Neue Felder und Codes können hinzukommen: Ignorieren Sie unbekannte Werte, statt zu scheitern.
Verlassen Sie sich für Programmlogik auf ergebnis, empfehlung und die code-Werte. Die Klartexte in text können sich ändern. Wie die Punkte zustande kommen, steht auf der Methodik-Seite.
POST /api/v1/pruefen/stapel
Prüft bis zu 10 Adressen in einer Anfrage. Jede Adresse zählt einzeln gegen das Limit. Gleiche Domains werden innerhalb einer Anfrage nur einmal abgefragt.
{"emails": ["name@beispiel.de", "x@mailinator.com"]}{
"anzahl": 2,
"geprueft": 2,
"ergebnisse": [
{ "ergebnis": "frei", "punkte": 10, "gruende": [], "domain": "beispiel.de", "empfehlung": "annehmen", "vorschlag": null },
{ "ergebnis": "wegwerf", "punkte": 98, "gruende": [ { "code": "liste", "…": "…" } ], "domain": "mailinator.com", "empfehlung": "ablehnen", "vorschlag": null }
]
}ergebnisse enthält genau einen Eintrag je Adresse in der Reihenfolge der Anfrage, aufgebaut wie die Einzelantwort. Die Adressen selbst kommen nicht zurück; ordnen Sie über die Position zu.
Wird das Limit mitten im Stapel erreicht, antwortet die API mit Status 207 (Multi-Status). Die bereits geprüften Adressen stehen mit ihrem Ergebnis in der Liste, alle übrigen als {"fehler": "limit", "text": "…"}. Zusätzlich nennt wiederholen_nach die Sekunden, bis wieder Platz im Limit ist. geprueft sagt, wie viele Einträge ein echtes Ergebnis haben. Ist das Limit schon vor der ersten Adresse erschöpft, gibt es 429 mit Retry-After und dem normalen Fehlerformat. Bei mehr als 10 Adressen antwortet die API mit 413 und prüft nichts.
{
"anzahl": 3,
"geprueft": 1,
"wiederholen_nach": 42,
"ergebnisse": [
{ "ergebnis": "frei", "punkte": 0, "…": "…" },
{ "fehler": "limit", "text": "Zu viele Anfragen. Bitte später erneut versuchen." },
{ "fehler": "limit", "text": "Zu viele Anfragen. Bitte später erneut versuchen." }
]
}Fehler
| Status | Wann | Body |
|---|---|---|
200 | Prüfung durchgeführt. Auch ungültige Adressen liefern 200 mit ergebnis: "ungueltig". | Ergebnis wie oben |
207 | Nur Stapel: Limit mitten im Stapel erreicht, Teilergebnis. | geprueft, ergebnisse, wiederholen_nach |
400 | Der Body ist kein gültiges JSON, oder die Stapelliste ist leer. | {"fehler": "kein_json", …}, leere_liste |
413 | Mehr als 10 Adressen im Stapel oder Body über 64 KiB. | zu_viele_adressen, anfrage_zu_gross |
415 | Der Content-Type ist nicht application/json. | falscher_inhaltstyp |
422 | Das Feld email bzw. emails fehlt oder hat den falschen Typ. | email_fehlt, emails_fehlt |
429 | Limit überschritten. Der Header Retry-After nennt die Wartezeit in Sekunden. | {"fehler": "limit", "text": "Zu viele Anfragen. Bitte später erneut versuchen."} |
404, 405, 500 | Unbekannter Pfad, falsche Methode, interner Fehler. | nicht_gefunden, methode_nicht_erlaubt, intern |
Alle Fehler haben dieselbe Form: {"fehler": "<code>", "text": "<Klartext>"}. Verlassen Sie sich auf fehler, nicht auf text. Die Antworten tragen Cache-Control: no-store, die Fehlermeldung spiegelt die Eingabe nie zurück.
Limits und Header
Standardmäßig 10 Anfragen pro Minute und 500 Anfragen pro Tag je Client; im Stapel zählt jede Adresse einzeln. Als Client zählt die IP-Adresse, bei IPv6 das Netz (/64, zusätzlich ein größeres /48-Netz mit vierfachem Limit). Mit einem API-Schlüssel gelten höhere Limits ohne Tageslimit, siehe Pro und Business.
Jede Antwort enthält den Stand des engeren der beiden Fenster:
| Header | Bedeutung |
|---|---|
X-RateLimit-Limit | Anfragen, die das aktuell maßgebliche Fenster (Minute oder Tag) erlaubt. |
X-RateLimit-Remaining | Noch verfügbare Anfragen in diesem Fenster. |
X-RateLimit-Reset | Unix-Zeit in Sekunden, zu der das Fenster wieder Platz bietet. |
Retry-After | Nur bei 429: Wartezeit in Sekunden. |
CORS und Formular-Widget
Alle Pfade unter /api/v1/ sind aus dem Browser fremder Seiten aufrufbar: Access-Control-Allow-Origin: *, erlaubt sind nur GET, POST und OPTIONS sowie die Request-Header Content-Type, X-API-Key und Authorization. Cookies werden nicht verwendet. Die Preflight-Antwort (204) darf 24 Stunden zwischengespeichert werden (Access-Control-Max-Age: 86400). Die Rate-Limit-Header sind für Skripte lesbar. Das Beispiel unten prüft die Adresse beim Absenden eines Formulars: bei ablehnen wird das Absenden blockiert, bei bestaetigen_lassen erscheint nur ein Hinweis. Fällt der Dienst aus, sollte Ihr Formular trotzdem funktionieren.
Beachten Sie, dass das Limit je Besucher-IP gilt und die Adresse im Browser des Besuchers an mailcheck übertragen wird. Erwähnen Sie das in Ihrer Datenschutzerklärung.
POST /api/v1/domains/pruefen
Prüft Domains statt Adressen. Gedacht für Listen: Ihr Browser oder Server sammelt die Domains und schickt nur diese, nie die Adressen. Der Body enthält domains mit 1 bis 100 Einträgen. Doppelte werden zusammengefasst.
curl -s -X POST https://mailcheck.moersbergerit.de/api/v1/domains/pruefen \
-H "Content-Type: application/json" \
-d '{"domains": ["gmail.com", "mailinator.com"]}'{
"anzahl": 2,
"geprueft": 2,
"ergebnisse": [
{"domain": "gmail.com", "ergebnis": "frei", "punkte": 0, "empfehlung": "annehmen", "gruende": []},
{"domain": "mailinator.com", "ergebnis": "wegwerf", "punkte": 95, "empfehlung": "ablehnen", "gruende": []}
]
}anzahl ist die Zahl der Einträge in der Anfrage, geprueft die Zahl der Domains mit echtem Ergebnis. Die Ergebnisse stehen in Anfragereihenfolge. Es gelten dieselben Regeln wie bei der Adressprüfung, ohne Signale aus dem Teil vor dem @. Eine formal ungültige Domain kommt als ungueltig mit leerem domain zurück, ohne die Eingabe zu spiegeln, und zählt nicht gegen das Limit. Ohne Schlüssel gelten 300 Domains pro Minute und 3.000 pro Tag je Client, jede eindeutige Domain zählt eins. Bei erreichtem Limit antwortet die API wie beim Stapel mit 207 oder 429 samt Retry-After.
Domain-Gesundheit (SPF, DMARC)
Bei den Ergebnissen frei, firma, alias und verdaechtig kann die Einzelprüfung Angaben zur E-Mail-Einrichtung der Domain mitliefern. Senden Sie dazu "gesundheit": true im Body oder ?gesundheit=1 bei GET. Standardmäßig ist das Feld aus, damit die Antwort für bestehende Nutzer gleich bleibt.
"gesundheit": {
"mx": {"status": "ok", "anzahl": 2},
"spf": {"status": "ok", "wert": "v=spf1 include:_spf.google.com ~all"},
"dmarc": {"status": "nur_beobachten", "richtlinie": "none"},
"hinweis": "https://www.moersbergerit.de/email-check/"
}spf.status:ok,fehlt(kein SPF-Eintrag),mehrfach(mehr als ein SPF-Eintrag),zu_offen(+alloder?all) oderkein_abschluss(der Eintrag endet ohneall-Mechanismus und ohneredirect). Die optionalen Felderredirect(Ziel einerredirect=-Angabe) undhinweis_subdomain(true) erscheinen nur, wenn sie zutreffen.dmarc.status:ok,fehlt,nur_beobachten(Richtlinienone),teilweise(pctunter 100) odermehrfach(mehr als ein DMARC-Eintrag).richtlinienenntnone,quarantineoderreject.anteilist eine Zahl (derpct-Wert) und steht beiteilweisesowie beipct=0(dann mit Statusnur_beobachten).mx.status:ok,fehlt,nur_a(kein MX, nur ein Adress-Eintrag) oderungueltig(der Mailserver zeigt auf ein unzustellbares Ziel).anzahlnennt die Zahl der Mailserver.- Werte sind auf 255 Zeichen gekürzt. Scheitert die DNS-Abfrage, fehlt das Feld ganz, statt falsche Werte zu melden.
API-Schlüssel
Mit einem Schlüssel gelten höhere Limits: je nach Stufe 60 (Pro) oder 300 (Business) Prüfungen pro Minute, kein Tageslimit, dafür ein Monatskontingent von 10.000 oder 100.000. Domain-Prüfungen zählen wie Adressen. Schlüssel gibt es auf Anfrage, siehe Pro und Business.
- Senden Sie den Schlüssel im Header
X-API-Key: mc_…oder alsAuthorization: Bearer mc_…. - Als URL-Parameter wird er abgelehnt: Status
400, Codeschluessel_in_url. - Ungültig oder gesperrt:
401mitschluessel_ungueltig, ohne Hinweis auf den Grund. - Kontingent aufgebraucht:
429mitkontingent_erschoepft,Retry-Afternennt die Sekunden bis zum Monatsanfang. - Jede Antwort mit Schlüssel trägt
X-Kontingent-Monat(Kontingent) undX-Kontingent-Rest(verbleibend). - Setzen Sie den Schlüssel möglichst nur serverseitig ein. Ein Schlüssel im Browser-Code, etwa per
data-keyim Formular-Widget, ist für jeden Besucher lesbar und damit öffentlich. Verwenden Sie dort nur einen eigens dafür ausgestellten Schlüssel, den wir bei Missbrauch sperren können, nie den Schlüssel Ihres Servers.
GET /api/v1/schluessel
Nur mit Schlüssel. Zeigt Stufe, Limits und den Verbrauch im laufenden Monat.
curl -s https://mailcheck.moersbergerit.de/api/v1/schluessel \
-H "X-API-Key: mc_IHR_SCHLUESSEL"{
"stufe": "pro",
"praefix": "mc_ABCDE",
"limit_minute": 60,
"kontingent_monat": 10000,
"verbraucht_monat": 1234
}GET /api/v1/neu
Domains, die in den letzten Tagen neu auf den Sperrlisten aufgetaucht sind. Der Parameter tage (1 bis 90, Standard 7) wählt den Zeitraum. Höchstens 1.000 Einträge, neueste zuerst. Ohne Schlüssel erlaubt, die Abfrage zählt eins gegen das Limit. Dieselben Daten gibt es als Seite, RSS-Feed und Textdatei.
{
"erfassung_seit": "2026-11-05",
"tage": 7,
"domains": [
{"domain": "beispiel-wegwerf.example", "erstmals": "2026-11-09", "quellen": ["fakefilter"]}
]
}erstmals ist der Tag, an dem mailcheck die Domain zum ersten Mal auf den Listen gesehen hat. erfassung_seit nennt den Beginn dieser Erfassung. Domains, die schon davor auf den Listen standen, erscheinen nicht als neu.
GET /api/v1/stand
Liefert den Stand der Sperrlisten, auch je Quelle.
{
"domains": 90947,
"mx_hosts": 131,
"letztes_update": "2026-11-05T13:19:01",
"quellen": [
{"name": "disposable-email-domains", "anzahl": 10142, "vertrauen": "stark"},
{"name": "burner-email-providers", "anzahl": 27266, "vertrauen": "stark"},
{"name": "fakefilter", "anzahl": 4808, "vertrauen": "stark"},
{"name": "mailchecker", "anzahl": 57679, "vertrauen": "schwach"},
{"name": "groundcat", "anzahl": 18511, "vertrauen": "schwach"}
]
}domains ist die Zahl der gelisteten Domains, mx_hosts die Zahl der als Wegwerf gewerteten Mailserver, letztes_update der Zeitpunkt der letzten Listenaktualisierung (Serverzeit). quellen nennt je Liste die Zahl der Domains und das Vertrauen (stark oder schwach), siehe Starke und schwache Listen.
OpenAPI
Das maschinenlesbare Schema (OpenAPI 3, Version 1.0.0) liegt unter https://mailcheck.moersbergerit.de/api/v1/openapi.json. Sie können es in Postman, Insomnia oder einen Client-Generator laden.
Beispiele
curl -s -X POST https://mailcheck.moersbergerit.de/api/v1/pruefen \
-H "Content-Type: application/json" \
-d '{"email": "name@beispiel.de"}'curl -s -X POST https://mailcheck.moersbergerit.de/api/v1/pruefen/stapel \
-H "Content-Type: application/json" \
-d '{"emails": ["name@beispiel.de", "x@mailinator.com"]}'const antwort = await fetch("https://mailcheck.moersbergerit.de/api/v1/pruefen", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email: "name@beispiel.de" }),
});
if (antwort.status === 429) {
const warten = antwort.headers.get("Retry-After"); // Sekunden
throw new Error("Limit erreicht, erneut in " + warten + " s");
}
const { ergebnis, punkte, empfehlung } = await antwort.json();
if (empfehlung === "ablehnen") { /* Eingabe zurückweisen */ }const r = await fetch("https://mailcheck.moersbergerit.de/api/v1/pruefen/stapel", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ emails: ["a@beispiel.de", "b@beispiel.de"] }),
});
const { ergebnisse } = await r.json(); // Status 200, 207 oder 429
ergebnisse.forEach((e, i) => { // gleiche Reihenfolge wie in der Anfrage
if (e.fehler === "limit") return; // später erneut senden
console.log(i, e.ergebnis, e.empfehlung);
});// Formular auf Ihrer Seite: Prüfung beim Absenden (CORS ist freigegeben).
const form = document.querySelector("#anmeldung");
form.addEventListener("submit", async (ev) => {
ev.preventDefault();
const feld = form.elements.email;
let urteil = null;
try {
const r = await fetch("https://mailcheck.moersbergerit.de/api/v1/pruefen", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email: feld.value.trim() }),
});
if (r.ok) urteil = await r.json();
} catch (e) { /* Dienst nicht erreichbar: nicht blockieren */ }
if (urteil && urteil.empfehlung === "ablehnen") {
feld.setCustomValidity("Bitte eine echte E-Mail-Adresse verwenden.");
feld.reportValidity();
return; // Absenden blockieren
}
feld.setCustomValidity("");
if (urteil && urteil.empfehlung === "bestaetigen_lassen") {
document.querySelector("#hinweis").textContent =
"Bitte prüfen Sie die Adresse. Wir senden Ihnen eine Bestätigungs-Mail."; // nur Hinweis
}
form.submit();
});<?php
$ch = curl_init("https://mailcheck.moersbergerit.de/api/v1/pruefen");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
CURLOPT_POSTFIELDS => json_encode(["email" => "name@beispiel.de"]),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($status === 200) {
$daten = json_decode($body, true);
if ($daten["empfehlung"] === "ablehnen") {
// Eingabe zurückweisen
}
}import requests
r = requests.post("https://mailcheck.moersbergerit.de/api/v1/pruefen",
json={"email": "name@beispiel.de"}, timeout=10)
r.raise_for_status()
daten = r.json()
if daten["empfehlung"] == "ablehnen":
... # Eingabe zurückweisenDatenschutz
Die Adresse wird nicht gespeichert und nicht protokolliert. Gezählt werden Tageszähler je Ergebnisart und bei Wegwerf- und Alias-Treffern die Domain. Wenn Sie Adressen Ihrer Nutzer weitergeben, benötigen Sie dafür Ihre eigene Rechtsgrundlage, siehe Datenschutzerklärung.