API-Referenz zur E-Mail-Prüfung
POST/v1/email/validate
Prüft eine E-Mail-Adresse: Syntax, bekannte Wegwerf-/Temporär-Domains, den Mailserver (MX) der Domain, wahrscheinliche Tippfehler und Funktionsadressen, und liefert ein Urteil accept/review/reject samt Gründen. Senden Sie einen JSON-Body { "email": "user@example.com" }. Gedacht für den Aufruf aus dem JavaScript eines Registrierungsformulars, mit demselben Modell aus veröffentlichbarem, Origin-gebundenem Schlüssel wie GET /v1/geo. Für viele Adressen oder eine serverseitige Registrierungsentscheidung nutzen Sie die weiter unten beschriebenen Endpoints für Batch, Listenjobs und Registrierungsprüfung. Alle Prüfungen erfolgen auf Domain- und Adressebene: Kein Postfach wird kontaktiert, daher belegt kein Ergebnis, dass ein Postfach existiert, wem es gehört oder dass E-Mails dort ankommen.
Authentifizierung
POST /v1/email/validate akzeptiert einen veröffentlichbaren, Origin-gebundenen Schlüssel im Header X-Api-Key – derselbe Schlüsseltyp und dasselbe Modell erlaubter Origins wie bei GET /v1/geo. Alle anderen Endpoints auf dieser Seite (Batch, Listenjobs, Registrierungsprüfung) akzeptieren viele Adressen oder eine beliebige IP, erfordern daher Ihren geheimen Schlüssel über Authorization: Bearer und dürfen nur aus Ihrem Backend aufgerufen werden; ein veröffentlichbarer Schlüssel erhält dort eine 403.
Antwortfelder
- Die gesendete Adresse, exakt so zurückgegeben, wie sie übermittelt wurde.
- domain
- Die Domain in Kleinbuchstaben (internationalisierte Domains in Punycode) oder null, wenn syntaxValid false ist.
- syntaxValid
- Ob die Adresse syntaktisch gültig ist. Keine Prüfung auf Existenz des Postfachs oder Zustellbarkeit.
- isDisposable
- Ob die Domain einem bekannten Wegwerf-/Temporär-E-Mail-Anbieter entspricht – direkt, über eine übergeordnete Domain oder über einen Mailserver, der bekanntermaßen Wegwerf-Domains bedient. Immer false, wenn syntaxValid false ist.
- normalizedEmail
- Bereinigte Adresse in Kleinbuchstaben mit der Domain in Punycode oder null, wenn syntaxValid false ist.
- canonicalEmail
- normalizedEmail ohne +Tag (bei Gmail zusätzlich ohne Punkte und mit googlemail.com auf gmail.com abgebildet) – speichern Sie den Wert, um dieselbe Person bei einer zweiten Registrierung zu erkennen. Null, wenn syntaxValid false ist.
- disposableSource
- Warum isDisposable true ist: list (die Domain selbst steht auf der Liste), parent_domain (eine übergeordnete Domain steht auf der Liste, z. B. a.b.mailinator.com) oder mx_host (der Mailserver der Domain bedient bekannte Wegwerf-Domains). Null, wenn isDisposable false ist.
- isFreeProvider
- Ob die Domain ein Postfachanbieter für Endkunden wie gmail.com oder outlook.com ist. Nur zur Information – ändert nie das Urteil.
- isRoleAccount
- Ob der lokale Teil eine Funktionsadresse wie admin@, info@ oder noreply@ ist.
- didYouMean
- Eine wahrscheinliche Tippfehlerkorrektur der gesamten Adresse (john@gmial.com → john@gmail.com) oder null. Eine Domain mit eigenem funktionierendem Mailserver wird nur „korrigiert“, wenn sie eine Änderung von einem gängigen Anbieter entfernt ist.
- mx.status
- found (MX-Einträge vorhanden), implicit (kein MX, aber ein A/AAAA-Eintrag), none (keines von beiden), null_mx (die Domain erklärt, keine E-Mails anzunehmen), no_domain (die Domain existiert nicht) oder unknown (die Abfrage ist fehlgeschlagen oder hat das Zeitlimit überschritten). Das gesamte mx-Objekt ist null, wenn syntaxValid false ist.
- mx.host
- Der MX-Host mit der niedrigsten Präferenz, wenn status found ist, sonst null. Sagt nichts darüber aus, ob das einzelne Postfach existiert.
- verdict
- accept, review oder reject – die schwerwiegendste der Bedingungen in reasons. Eine Empfehlung für Ihre eigene Richtlinie, keine endgültige Entscheidung.
- reasons
- Jede zutreffende Bedingung, die schwerwiegendste zuerst; leer, wenn verdict accept ist. Siehe „Urteile und Grundcodes“ weiter unten.
Fehler
- 400
- Fehlerhafter Anfrage-Body. Batch: empty_batch oder batch_too_large (mehr als 100 Adressen). Registrierungsprüfung: invalid_ip. Listenjobs: invalid_body, empty_job oder job_too_large (mehr als 100.000 Adressen). Eine ungültige E-Mail-Adresse ist nie eine 400 – sie ist ein Ergebnis mit dem Urteil reject und dem Grund invalid_syntax.
- 401
- Fehlender oder ungültiger API-Schlüssel.
- 403
- POST /v1/email/validate: Origin/Referer der Anfrage steht nicht auf der Liste erlaubter Origins des Schlüssels (es wird kein CORS-Header gesetzt, daher blockiert der Browser die Antwort unabhängig vom JSON-Body). Endpoints mit geheimem Schlüssel: Es wurde ein veröffentlichbarer Schlüssel verwendet.
- 404
- job_not_found – kein Listenjob mit dieser ID in Ihrem Konto.
- 409
- job_not_completed – der Job ist noch in der Warteschlange oder in Bearbeitung oder ist fehlgeschlagen; Ergebnisse können erst nach Abschluss heruntergeladen werden.
- 410
- job_expired – die hochgeladenen Adressen und Ergebnisse des Jobs wurden gelöscht (7 Tage nach der Erstellung).
- 413
- body_too_large – ein CSV-Upload für einen Job, der größer als 10 MB ist.
- 415
- Ein Listenjob-Body, der weder JSON noch text/csv ist.
- 429
- Die Ratenbegrenzung pro Minute oder monthly_limit_exceeded, wenn das monatliche Anfragekontingent des Tarifs überschritten würde – siehe Fehler und Ratenbegrenzungen, um beides zu unterscheiden. Ein Batch oder Listenjob, der das Kontingent überschreiten würde, wird vollständig abgelehnt, bevor irgendetwas verarbeitet wird.
- 503
- job_storage_unavailable – ein Listenjob konnte nicht gespeichert werden. Es wurde nichts berechnet; versuchen Sie es erneut.
Beispiel
Anfrage
curl https://api.watch-ip.com/v1/email/validate \
-H "X-Api-Key: YOUR_PUBLISHABLE_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "John.Doe+news@Gmial.com"}'Antwort
{
"email": "John.Doe+news@Gmial.com",
"domain": "gmial.com",
"syntaxValid": true,
"isDisposable": false,
"normalizedEmail": "john.doe+news@gmial.com",
"canonicalEmail": "john.doe@gmial.com",
"disposableSource": null,
"isFreeProvider": false,
"isRoleAccount": false,
"didYouMean": "john.doe+news@gmail.com",
"mx": {
"status": "none",
"host": null
},
"verdict": "reject",
"reasons": [
"no_mail_server",
"typo_suspected"
]
}Urteile und Grundcodes
Jede Bedingung setzt ein Mindesturteil; die schwerwiegendste gewinnt, und reasons listet alle auf, die schwerwiegendste zuerst. Ob eine Adresse eines Freemail-Anbieters akzeptabel ist, entscheiden Sie – das Urteil ändert sich dadurch nie.
- invalid_syntax
- Reject. Die Adresse ist syntaktisch ungültig (Längengrenzen, erlaubte Zeichen, Position der Punkte, eine echte Domain statt eines IP-Literals). Auch lokale Teile in Anführungszeichen werden abgelehnt – zulässig, aber bei Registrierungen praktisch nie verwendet.
- domain_not_found
- Reject. Die Domain existiert nicht im DNS.
- no_mail_server
- Reject. Die Domain erklärt, keine E-Mails anzunehmen (ein „Null-MX“), oder hat weder MX- noch A/AAAA-Einträge.
- disposable_domain
- Reject. Die Domain, eine übergeordnete Domain oder der Mailserver der Domain entspricht bekannten Wegwerf-/Temporär-E-Mail-Anbietern – siehe disposableSource.
- typo_suspected
- Review. didYouMean enthält eine wahrscheinliche Korrektur, etwa gmial.com → gmail.com.
- role_account
- Review. Der lokale Teil ist eine Funktionsadresse wie admin@, info@, support@ oder noreply@, die meist gemeinsam statt persönlich genutzt wird.
- implicit_mx
- Review. Die Domain hat keinen MX-Eintrag; E-Mails würden auf ihre A/AAAA-Adresse zurückfallen, was bei echten Mail-Domains selten ist.
- dns_unavailable
- Review. Die DNS-Abfrage ist fehlgeschlagen oder hat das Zeitlimit überschritten, daher ist die Mail-Konfiguration der Domain unbekannt (mx.status: unknown). Kein Indiz gegen die Adresse.
Batch-Prüfung
POST/v1/email/batch
Prüft 1–100 Adressen in einer Anfrage mit denselben Prüfungen und derselben Ergebnisform wie POST /v1/email/validate, ein Ergebnis pro Adresse in Eingabereihenfolge. Senden Sie { "emails": [...] }. Adressen derselben Domain teilen sich eine DNS-Abfrage. Zählt eine Anfrage pro Adresse gegen Ihr monatliches Tarifkontingent; ein Batch, der das Kontingent überschreiten würde, wird vollständig mit 429 monthly_limit_exceeded abgelehnt. Für die Ratenbegrenzung pro Minute zählt der gesamte Aufruf als eine Anfrage. Nur mit geheimem Schlüssel.
Anfrage
curl https://api.watch-ip.com/v1/email/batch \
-H "Authorization: Bearer YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{"emails": ["user@gmail.com", "someone@mailinator.com"]}'Antwort
{
"results": [
{ "email": "user@gmail.com", "verdict": "accept", "reasons": [], ... },
{ "email": "someone@mailinator.com", "isDisposable": true, "disposableSource": "list", "verdict": "reject", "reasons": ["disposable_domain"], ... }
]
}E-Mail-Listenjobs
POST/v1/email/jobs
Prüft bis zu 100.000 Adressen im Hintergrund. Senden Sie JSON { "emails": [...], "filename": "..." } oder einen text/csv-Body von höchstens 10 MB: Verwendet wird die Spalte mit der Überschrift email (auch e-mail, email address, email_address oder mail, ohne Beachtung der Groß-/Kleinschreibung) oder die erste Spalte, wenn keine Überschrift eine solche benennt; Komma, Semikolon und Tabulator als Trennzeichen werden erkannt. Der Job wird bei der Erstellung berechnet – eine Anfrage pro eindeutiger Adresse (exakte Übereinstimmung), Duplikate werden also geprüft, aber nur einmal berechnet – und eine Liste, die Ihr Monatskontingent überschreiten würde, wird vollständig abgelehnt. Kann ein Teil eines Jobs auch nach Wiederholungen nicht verarbeitet werden, wird der Job als failed markiert und die Credits für den nicht verarbeiteten Teil werden erstattet. Antwortet mit 202 und dem Job-Objekt. Nur mit geheimem Schlüssel; dieselben Jobs lassen sich auch auf der Dashboard-Seite Email lists hoch- und herunterladen.
Anfrage
curl https://api.watch-ip.com/v1/email/jobs \
-H "Authorization: Bearer YOUR_SECRET_KEY" \
-H "Content-Type: text/csv" \
--data-binary @newsletter.csvAntwort
{
"id": "5b0d6f5e-8a51-4f7e-9d0e-2c1f3f7f8a11",
"status": "queued",
"source": "api",
"filename": null,
"total": 12840,
"credits": 12512,
"processed": 0,
"summary": null,
"createdAt": "2026-09-28T10:00:00.000Z",
"completedAt": null,
"expiresAt": "2026-10-05T10:00:00.000Z"
}Job-Status
GET/v1/email/jobs/{id}
Gibt dasselbe Job-Objekt zurück. Fragen Sie es ab, bis status completed ist; Abfragen werden nicht berechnet.
- status
- queued → processing → completed. failed: Ein Teil der Liste konnte auch nach Wiederholungen nicht verarbeitet werden; es sind keine Ergebnisse verfügbar und die Credits für den nicht verarbeiteten Teil wurden erstattet. expired: Die hochgeladenen Adressen und Ergebnisse wurden 7 Tage nach der Erstellung gelöscht.
- total
- Übermittelte Zeilen, einschließlich Duplikaten.
- credits
- Berechnete Anfragen: eine pro eindeutiger Adresse.
- processed
- Bisher geprüfte Zeilen.
- summary
- Nach Abschluss: Zeilenanzahl pro Urteil (accept/review/reject) und pro aufgetretenem Grundcode. Vorher null.
- expiresAt
- Zeitpunkt, zu dem die hochgeladenen Adressen und Ergebnisse gelöscht werden.
Job-Ergebnisse
GET/v1/email/jobs/{id}/results
Lädt eine CSV-Datei mit einer Zeile pro übermittelter Zeile herunter, in Übermittlungsreihenfolge – einschließlich Duplikaten. Spalten: email, normalized_email, verdict, reasons, syntax_valid, is_disposable, disposable_source, is_free_provider, is_role_account, did_you_mean, mx_status, mx_host. reasons ist durch Semikolons getrennt, leere Zellen bedeuten null, und mx_status ist bei syntaktisch ungültigen Adressen leer (es wurde nichts abgefragt). Einer ungültigen Adresse, die mit =, +, - oder @ beginnt, wird ein Apostroph vorangestellt, damit Tabellenkalkulationen sie nicht als Formel ausführen. 409, bis der Job abgeschlossen ist, 410, sobald er abgelaufen ist. Der Download wird nicht berechnet.
Anfrage
curl https://api.watch-ip.com/v1/email/jobs/5b0d6f5e-8a51-4f7e-9d0e-2c1f3f7f8a11/results \
-H "Authorization: Bearer YOUR_SECRET_KEY" -o results.csvRegistrierungsprüfung
POST/v1/signup/check
Bewertet eine Registrierung anhand von E-Mail-Adresse und IP in einem Aufruf, aus Ihrem Backend beim Absenden des Registrierungsformulars (ein im Browser berechnetes Urteil kann gefälscht werden). Senden Sie { "email": "...", "ip": "...", "userAgent": "..." } – userAgent ist optional. Die Antwort enthält das vollständige Ergebnis der E-Mail-Prüfung (email), Land und ASN der IP sowie – in Tarifen mit Sicherheitsdaten – ihre VPN-/Tor-/Rechenzentrums-/Bedrohungsindikatoren (ip), das Alter der E-Mail-Domain in Tagen laut öffentlichen Registrierungsdaten (RDAP) (emailDomainAgeDays, null wenn unbekannt und bei bekannten Endkunden-Anbietern), einen Score von 0–100 (die Summe der unten aufgeführten Gewichte der Gründe, begrenzt auf 100) und ein Urteil: reject ab 60, review ab 25, sonst accept. In einem Tarif ohne Sicherheitsdaten ist ip.security null, der Score nutzt nur die E-Mail-Signale und reasons enthält ip_security_unavailable. Zählt als eine Anfrage. Nur mit geheimem Schlüssel.
- invalid_syntax
- 70
- domain_not_found · no_mail_server · disposable_domain
- je 60
- ip_tor · ip_threat
- je 40
- ip_vpn
- 25
- new_domain
- 25 – die E-Mail-Domain wurde vor weniger als 30 Tagen registriert
- ip_datacenter
- 20 – nur wenn die IP nicht bereits ein VPN- oder Tor-Exit ist
- automated_user_agent
- 20 – der übergebene userAgent sieht nach einem Bot oder Skript aus
- typo_suspected
- 15
- role_account · implicit_mx
- je 10
- dns_unavailable
- 5
- ip_security_unavailable
- 0 – zur Information: Dieser Tarif enthält keine Sicherheitsdaten
Anfrage
curl https://api.watch-ip.com/v1/signup/check \
-H "Authorization: Bearer YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "jane@new-startup.io", "ip": "203.0.113.1"}'Antwort
{
"email": { "email": "jane@new-startup.io", "verdict": "accept", "reasons": [], ... },
"ip": {
"ip": "203.0.113.1",
"country": "US",
"asn": 64500,
"asOrganization": "Example Hosting",
"security": { "isTor": false, "isVpn": false, "isDatacenter": true, "isThreat": false, "isSanctionedNetwork": false }
},
"emailDomainAgeDays": 12,
"score": 45,
"verdict": "review",
"reasons": ["new_domain", "ip_datacenter"]
}Limits
Jede geprüfte Adresse zählt als eine Anfrage gegen das gemeinsame Monatskontingent Ihres Tarifs – eine Einzelprüfung, jede Adresse in einem Batch, jede eindeutige Adresse in einem Listenjob – und eine Registrierungsprüfung ist eine Anfrage. Batches und Listenjobs werden vollständig angenommen oder abgelehnt, nie teilweise ausgeführt. Die Ratenbegrenzung pro Minute zählt HTTP-Aufrufe, nicht Einträge: Ein Batch mit bis zu 100 IPs oder E-Mail-Adressen zählt als eine Anfrage, während jeder Eintrag weiterhin einzeln auf das monatliche Anfragekontingent angerechnet wird. Uploads und Ergebnisse von Listenjobs werden 7 Tage nach Erstellung des Jobs gelöscht. DNS-Abfragen haben ein kurzes Zeitbudget: Schlägt eine fehl oder überschreitet sie das Zeitlimit, fällt das Ergebnis auf mx.status unknown und den Grund dns_unavailable zurück statt auf einen Fehler. Die Daten zu Wegwerf-Domains werden aus drei von der Community gepflegten Open-Source-Listen zusammengeführt, alle paar Stunden aktualisiert und um Mailserver ergänzt, die nachweislich gelistete Domains bedienen – siehe Datenquellen. Ein sehr neuer Wegwerf-Anbieter wird möglicherweise noch nicht erkannt. Alle Prüfungen erfolgen auf Domain- und Adressebene: Kein Postfach wird kontaktiert, daher belegt kein Ergebnis, dass ein Postfach existiert, wem es gehört oder dass E-Mails dort ankommen.
Verwandte Seiten
- AuthentifizierungVeröffentlichbare vs. geheime Schlüssel, Origin-Bindung und Ratenbegrenzungen.
- GET /v1/geo-ReferenzVollständige Feldreferenz für den Endpoint zur Besucher-Geolokalisierung.
- Erkennung von Wegwerf-E-MailsWegwerf-, vertippte und E-Mail-Adressen ohne Mailserver bei der Registrierung erkennen – einzeln oder in großen Mengen.
- Schutz vor Signup-MissbrauchE-Mail- und IP-Signale zu einer Registrierungsentscheidung kombinieren: annehmen, prüfen oder ablehnen.
- DatenquellenWelche Quelle hinter jedem Antwortfeld steht, und ihre bekannten Lücken.