Spamcheck-API voor e-mail,
inbox en domein
Stuur ons één echt bericht, of geef ons alleen een domein. Alles wordt beantwoord in JSON.
Geen sleutel, geen account.
Verzoek
# reserve a single-use address
$ curl -sX POST '.../api/v1/inbox?lang=en'
# send your message to that address, then
$ curl -s '.../api/v1/tests/k7m2x9qplw4tz8vn3b6c/status'
# read the report
$ curl -s '.../api/v1/tests/k7m2x9qplw4tz8vn3b6c'
Antwoord
200 OK
{
"address": "test-k7m2x9qplw4tz8vn3b6c@t.email-spam-tester.com",
"slug": "k7m2x9qplw4tz8vn3b6c",
"expires_at": "2026-10-31T13:00:00Z"
}200 OK
{
"analysis_status": "checks_ready",
"ai_status": "running",
"checks_done": 42,
"checks_total": 42
}200 OK
{
"score_ours": 86.4,
"score_compat": 9.2,
"subscores": {"auth": 100.0, "infra_spam": 78.1, "content": 92.0},
"complete": true,
"checks": [{"id": "auth.dmarc", "status": "warn"}],
"fixes": [{"id": "dmarc-enforce", "gain_ours": 4.0}]
}Verzoek
# create a test
$ curl -sX POST '.../api/v1/placement' \
-d '{"public_results_accepted":true}'
# put the marker in the subject, send once to all, then
$ curl -s '.../api/v1/placement/wR3kP9xLq2vT8mZc'
Antwoord
201 Created
{
"marker": "est-3f9a1c7e2b4d6a80c5e1f2d3",
"status": "waiting",
"results": [{"provider": "gmail", "placement": "pending"}],
"fleet": {"status": "observing", "results": [
{"provider": "yahoo", "placement": "pending"},
{"provider": "outlook", "placement": "pending"}
]}
}200 OK
{
"status": "complete",
"results": [{"provider": "gmail", "placement": "primary"}],
"fleet": {"status": "finished", "results": [
{"provider": "yahoo", "placement": "inbox"},
{"provider": "outlook", "placement": "spam"}
]}
}Verzoek
# no email needed, one GET
$ curl -s '.../api/v1/infra/check?domain=example.com'
# compare with your last run
$ curl -s '.../api/v1/infra/check?domain=example.com&diff=true' \
| jq '.diff'
Antwoord
200 OK
{
"domain": "example.com",
"ok": false,
"status": "fail",
"score": 78,
"coverage": {"answered": 7, "total": 8},
"sections": {"ptr": {"status": "fail", "core": true}}
}200 OK
{
"changed": true,
"worsened": true,
"status_from": "pass",
"score_from": 100,
"changes": [{"path": "dkim.key.mail.sha256", "kind": "removed",
"severity": "critical", "effect": "worsened"}]
}Kies wat je nodig hebt
Op deze pagina
E-mailtest
We lezen één echt bericht volledig uit: inhoud, handtekening, headers en de server die het heeft verstuurd. Je krijgt een score, een lijst met oplossingen en elke onderliggende controle.
Snel aan de slag
Drie aanroepen. Geen sleutel, geen account, geen registratie. Twee verzoeken en één e-mail. De derde aanroep is alleen nodig omdat de analyse enkele seconden duurt.
Reserveer een adres
Stuur een POST-verzoek naar het inbox-endpoint. Je krijgt een adres terug dat precies één bericht accepteert en na een uur verloopt, plus de slug waaraan al het andere is gekoppeld.
Verzoek
# 1. reserve a single-use address curl -sX POST 'https://email-spam-tester.com/api/v1/inbox?lang=en'Antwoord
{ "address": "test-<slug>@t.email-spam-tester.com", "slug": "<slug>", "expires_at": "2026-01-01T12:00:00Z" }Stuur het echte bericht ernaartoe
Via SMTP, vanaf het platform dat de campagne zal verzenden. De helft van de controles leest headers die je verzendplatform toevoegt, dus een handmatig opgesteld bericht meet het verkeerde.
Verzoek
# 2. send your message to that address, from your own platform To: test-<slug>@t.email-spam-tester.comPoll de status en lees daarna het rapport
Het status-endpoint is enkele honderden bytes groot en vertelt je of het volledige rapport al kan worden opgehaald. Het rapport zelf beslaat enkele duizenden regels.
Verzoek
# 3. poll curl -s 'https://email-spam-tester.com/api/v1/tests/<slug>/status'Antwoord
{ "slug": "<slug>", "analysis_status": "checks_ready", "ai_status": "running", "checks_done": 42, "checks_total": 42 }Verzoek
# 4. read the report once analysis_status is checks_ready curl -s 'https://email-spam-tester.com/api/v1/tests/<slug>'Antwoord
{ "report_url": "https://email-spam-tester.com/t/<slug>", "score_ours": 86.4, "score_compat": 9.2, "subscores": {"auth": 100.0, "infra_spam": 78.1, "content": 92.0, "compliance": 75.0}, "complete": true, "checks": [ { "id": "auth.dmarc", "status": "warn", "title": "DMARC result", "summary": "DMARC passes, but the policy is p=none.", "weight_ours": -4.0, "evidence": {"policy": "none", "aligned": "dkim"}, "citations": {"standards": [{"title": "RFC 9989 §4.7", "quote": "..."}]} } ], "fixes": [ {"id": "dmarc-enforce", "gain_ours": 4.0, "gain_compat": 0.0, "fix": {"title": "Move DMARC to quarantine", "severity": "medium"}} ] }
Reserveer een adres, stuur het bericht dat je naar je lijst wilde verzenden en lees het rapport. Alles wat de pagina toont, staat in de JSON, inclusief de score, alle 42 controles met het bijbehorende bewijs en de sectie van de standaard waarop elke bevinding berust.
De eerste 100.000 rapporten zijn gratis, zonder sleutel en zonder account. Als je een agent in plaats van een script integreert, is de MCP-server geschikter dan polling.
Endpoints
Basisadres https://email-spam-tester.com. Alles retourneert JSON.
POST/api/v1/inbox
Reserveert een adres voor eenmalig gebruik. Beide parameters zijn optioneel.
| lang | Taal waarin het verbeterplan en de bevindingen per controle worden geschreven, als ISO-code. Wordt nu bepaald omdat het bericht minuten later via SMTP binnenkomt en geen aanwijzing bevat over wie erop wacht. Bij een onbekende code wordt teruggevallen op Engels. |
| utm_source, utm_medium, utm_campaign | Worden doorgegeven aan onze analytics. Nuttig als je je eigen integratie meet. |
GET/api/v1/tests/{slug}/status
Goedkoop om te pollen. Retourneert de twee statusvelden en hoe ver de controles zijn gevorderd, en verder niets.
GET/api/v1/tests/{slug}
Het volledige rapport. Retourneert 202 zolang het adres is gereserveerd en er nog niets is binnengekomen, en 200 zodra dat wel het geval is.
GET/api/v1/tests/{slug}/message
Het bericht precies zoals het is afgeleverd: elke header in transmissievolgorde, beide berichtteksten, de lijst met bijlagen en de onbewerkte bron. Wordt afzonderlijk opgehaald omdat het rapport wordt gepolld en dit tot een megabyte groot kan zijn.
PUT/api/v1/tests/{slug}/locale
Wijzigt de taal van een reservering die nog niet is gebruikt. Voor een agent die pas ontdekt welke taal zijn gebruiker leest nadat deze al om het adres heeft gevraagd. Wordt geweigerd zodra het bericht is aangekomen, omdat de analyse dan al wordt uitgevoerd.
InboxplaatsingBèta
Stuur één bericht naar een lijst met testinboxen en bekijk waar het bij Gmail, Outlook, Yahoo en andere providers terechtkwam: Inbox, Reclame of Spam.
Snel aan de slag
Maak een test
Stuur een POST naar het plaatsingseindpunt. Je krijgt een markering en de testinboxen terug.
Verzoek
# 1. create a test curl -sX POST 'https://email-spam-tester.com/api/v1/placement' \ -H 'Content-Type: application/json' \ -d '{"public_results_accepted":true}'Antwoord
{ "slug": "<slug>", "marker": "est-3f9a1c7e2b4d6a80c5e1f2d3", "status": "waiting", "deadline": "2026-10-31T12:30:00Z", "poll_after_seconds": 60, "results": [ {"address": "<seed>", "provider": "gmail", "kind": "Gmail", "placement": "pending", "observed_at": null} ], "fleet": { "status": "observing", "results": [ {"address": "<mailbox>", "provider": "yahoo", "available": true, "placement": "pending", "coverage": "pending"} ] } }Stuur één bericht naar elke inbox
Zet de markering in het onderwerp en stuur het vanaf je normale platform in één keer naar alle adressen.
Verzoek
# 2. one message to every address, with the marker in the subject Subject: October invoice est-3f9a1c7e2b4d6a80c5e1f2d3 To: <seed>, <mailbox>, ...Vraag de mappen op
Bij elk adres worden de provider en map ingevuld. Blijf opvragen totdat de status niet meer waiting is.
Verzoek
# 3. poll for the folders curl -s 'https://email-spam-tester.com/api/v1/placement/<slug>'Antwoord
{ "status": "complete", "received": 2, "total": 2, "results": [ {"address": "<seed>", "provider": "gmail", "kind": "Gmail", "placement": "primary", "observed_at": "2026-10-31T12:04:11Z"}, {"address": "<seed>", "provider": "gmail", "kind": "Google Workspace", "placement": "promotions", "observed_at": "2026-10-31T12:04:11Z"} ], "fleet": { "status": "finished", "results": [ {"address": "<mailbox>", "provider": "yahoo", "available": true, "placement": "inbox", "coverage": "ok"}, {"address": "<mailbox>", "provider": "outlook", "available": true, "placement": "spam", "coverage": "ok"} ] } }
Endpoints
An optional test using public GMass seed inboxes and available project test mailboxes, alone or alongside the email score. Explain to the sender that GMass receives their email and publishes its subject, sender name and placement before creating a test. Use all test mailboxes for non-confidential test messages only.
GET /api/v1/placement/availability
Returns providers: the provider identifiers of currently healthy,
admitted project mailboxes. No addresses or credentials are exposed. This read does
not create a test or contact GMass. Actual recipients are allocated at creation and
may differ as availability or capacity changes.
POST /api/v1/placement
Send JSON {"public_results_accepted":true}. Returns HTTP 201 with
slug, marker, results (the seed addresses),
deadline and expires_at. Limit: 20 tests per IP per UTC day.
For one-send combined testing, first reserve an email score address and include
its score_slug in the placement creation JSON. Repeated creation for
that score returns the same placement test. Send the marked email to the score
address, every returned seed and every available fleet.results address;
keep the main /t/<score_slug>
report link. Creating a link after the score address was used or expired returns HTTP 409.
GET /api/v1/placement/by-score/{score_slug}
Read and refresh the placement run attached to the main email test. The response has the same format and polling limits as the standalone endpoint below. HTTP 404 means placement was not included or its stored results have been removed.
GET /api/v1/placement/{slug}
Use poll_after_seconds (normally 60 seconds) while the page is open.
Upstream errors trigger a shared cooldown. Add the marker to the subject and
send through the sender's normal platform to every seed. Observations are saved for
30 days. Collection ends after 30 minutes or when all seeds have results.
status: waiting, complete or timed_out. Each result has an address,
provider, kind, placement and observed_at. Placement is primary, promotions, inbox,
updates, social, forums, spam, unknown, pending or not_observed. Missing results do
not mean Spam; Promotions is an inbox category. provider_error indicates
an upstream outage without discarding saved observations. HTTP 404 means unknown,
410 expired, 429 quota exhausted, and 503 no test inboxes available at creation.
The optional fleet object contains independently collected project
mailbox results, with status observing, settling or finished. Refresh
every 30 seconds until it finishes, even when Gmail has completed. Each fleet result
includes address, provider, available,
placement, category and coverage. Exclude
unavailable addresses from new sends; retain their saved observations. Category
data may be unavailable even when the physical folder is known.
If GMass is unavailable at creation but project mailboxes can be allocated,
provider is fleet and the top-level seed results are empty.
Use fleet.results; do not interpret an empty Gmail list as successful
delivery. Existing runs never gain new recipient addresses silently.
Infrastructuurcontrole
Eén GET-verzoek controleert de e-mailconfiguratie van een domein zonder iets te verzenden, bewaart het resultaat en vertelt je wat er sinds je vorige uitvoering is veranderd. Geen sleutel nodig. In cron eindigt de onderstaande regel met een niet-nulstatus wanneer het domein defect is of de configuratie ervan op een relevante manier is gewijzigd.
Snel aan de slag
Doe één GET
Geef het domein door. ip voegt je verzendadressen toe, en selector noemt de DKIM-selectors die moeten worden gelezen.
Verzoek
curl -s 'https://email-spam-tester.com/api/v1/infra/check?domain=example.com&selector=mail&diff=true'Lees het oordeel
ok is het antwoord voor een script, en sections laat zien welk onderdeel is mislukt.
Antwoord
{ "id": "ir_01JB8Y4T2M6K9QZ7H3V5N1XWDA", "domain": "example.com", "checked_at": "2026-10-31T12:00:00Z", "ok": false, "status": "fail", "score": 78, "coverage": {"answered": 7, "total": 8}, "ips": [{"ip": "203.0.113.5", "sources": ["mx", "spf"], "managed": false}], "sections": { "dkim": {"status": "pass", "core": true, "findings": [], "data": {}}, "ptr": {"status": "fail", "core": true, "findings": [], "data": {}} }, "not_checked": [ {"check": "dkim_signature", "reason": "needs_a_message"}, {"check": "alignment", "reason": "needs_a_message"} ], "diff": { "baseline": {"id": "ir_01JB2...", "checked_at": "2026-10-24T12:00:00Z"}, "first_run": false, "changed": true, "worsened": true, "status_from": "pass", "score_from": 100, "changes": [ {"path": "dkim.key.mail.sha256", "section": "dkim", "kind": "removed", "severity": "critical", "effect": "worsened", "from": "9f2c...", "to": null} ], "not_compared": [ {"path": "blocklist_ip.203.0.113.5.bl.spamcop.net.listed", "reason": "lookup_failed"} ] } }Zet het in cron
Met diff=true wordt elke uitvoering vergeleken met je vorige, en jq zet het antwoord om in een afsluitcode.
Verzoek
# exits non-zero if the domain is broken or its setup changed curl -s 'https://email-spam-tester.com/api/v1/infra/check?domain=example.com&selector=mail&diff=true' \ | jq -e '.ok and (.diff.changed | not)'
| domain | Vereist. Accepteert wat de tools accepteren: een domein, een URL, een e-mailadres. |
| ip | Je verzendadres. Herhaal dit voor meer adressen, tot maximaal 6. |
| selector | Een DKIM-selector. Herhaal dit voor meer selectors, tot maximaal 10. Elke selector die je doorgeeft moet bestaan, anders mislukt de DKIM-sectie. |
| helo | De naam die je server opgeeft in HELO, vergeleken met zijn PTR. |
| account | Voor wie het verzoek is. Vereist bij een sleutel die voor veel mensen wordt gebruikt. |
| checks | Uit te voeren secties, door komma's gescheiden. Standaard allemaal. |
| diff | true vergelijkt deze uitvoering met je laatste uitvoering van het domein. |
| since | 7d, 12h of een ISO 8601-datum. Vergelijkt met je uitvoering die binnen 12 uur het dichtst bij dat moment ligt, anders met de laatste uitvoering ervoor. Schakelt diff in. |
| baseline | De id van een van je uitvoeringen om mee te vergelijken. Schakelt diff in. |
| fresh | true slaat de cache van 60 seconden over. |
Het antwoord lezen
Een voltooide controle antwoordt met 200 en het oordeel staat in de body. status is de slechtste van de vereiste secties: spf, dkim, dmarc, ptr, blocklist_ip, blocklist_domain, mx en smtp. unknown in een vereiste sectie telt als warn. ok is true wanneer de status pass of warn is. score loopt van 0 tot 100 over de vereiste secties die een antwoord gaven en is null wanneer er door errors en unknowns minder dan de helft van het toepasselijke gewicht overblijft. mta_sts, tls_rpt, bimi, dnssec, dane, ns en registration worden gerapporteerd en vergeleken, maar hebben geen invloed op ok of score.
Een sectie kan pass, warn, fail, error (we konden de controle niet uitvoeren), unknown (te weinig informatie) of skipped (niet van toepassing) zijn. skipped heeft geen invloed op het resultaat en de reden staat in not_checked. dkim_signature en alignment zijn er altijd, omdat ze een echt bericht nodig hebben.
Wat ip en selector veranderen
PTR en blocklists gaan over adressen, dus een run heeft er enkele nodig. De run gebruikt de ip-waarden die je doorgeeft. Zonder waarden neemt de run er maximaal vier van je MX-hosts en uit ip4:- en ip6:-termen met één adres in het SPF-record op het hoofddomein. Adressen van een bekende mailprovider worden als managed vermeld en niet gecontroleerd, en als er niets overblijft, antwoorden ptr en blocklist_ip met skipped. Een selector kan niet uit DNS worden afgeleid, dus een run probeert die van jou, de selectors die tijdens je eerdere runs zijn gevonden en een lijst met gangbare namen. Niets vinden bewijst niets en dkim antwoordt met unknown. Als je vanaf je eigen server verstuurt, geef je beide door.
Wat is veranderd
Elke vermelding in diff.changes heeft een path, een kind (added, removed, changed), een severity (critical, warning, info) en een effect (worsened, improved, neutral). Alleen critical en warning stellen diff.changed in, zodat een geroteerde DKIM-sleutel met dezelfde lengte, een nieuw MX-adres of een vernieuwd certificaat de cronregel niet laat mislukken. diff.worsened volgt het effect van elke wijziging. Bij een eerste uitvoering is er niets om mee te vergelijken, en diff.first_run geeft dat aan.
Een baseline is altijd een run van jezelf, dus als iemand anders het domein tussen twee van je runs controleert, blijft er niets verborgen. Alles wat we deze keer niet konden uitlezen, gaat naar diff.not_compared, waarbij de laatst bekende waarde behouden blijft. Dit betekent dat een wijziging die tijdens een storing is aangebracht zichtbaar wordt zodra de lookup weer werkt. Een run met een andere ip of selector blijft in dezelfde reeks en wat die run niet opvroeg, wordt ook niet vergeleken.
Waarom een geplande controle een sleutel moet gebruiken
Zonder sleutel hoort je geschiedenis bij een hash met sleutel van je IP-adres, dus eindigt die wanneer het adres verandert en delen mensen achter hetzelfde adres die geschiedenis: de run van een collega verplaatst je baseline. Met een persoonlijke API-sleutel in Authorization: Bearer volgt de geschiedenis de sleutel. Runs met een sleutel worden 365 dagen bewaard en zijn alleen met die sleutel toegankelijk. Runs zonder sleutel worden 30 dagen bewaard en zijn toegankelijk voor iedereen die de id ervan heeft.
6 requests per minuut en 50 per dag per IP, of 30 en 500 per sleutel. Daarboven is het antwoord 429 met Retry-After. Een identiek request binnen 60 seconden komt uit een cache, wordt gemarkeerd met cached: true, maakt geen run aan en telt niet mee. Het lezen van opgeslagen runs staat 120 requests per minuut per client toe. 503 met Retry-After betekent dat er te veel controles worden uitgevoerd of, bij het lezen van opgeslagen runs, dat de opslag niet beschikbaar is. 401 betekent een onjuiste sleutel. 422 bevat detail.code: invalid_domain, invalid_ip, invalid_selector, invalid_check, invalid_since, unknown_baseline of account_required.
Endpoints
GET/api/v1/infra/check
Voert de controle uit. De parameters staan in de tabel hierboven.
GET/api/v1/infra/runs/{public_id}
Eén opgeslagen uitvoering, volledig. 404 als deze niet bestaat of bij een andere sleutel hoort.
GET/api/v1/infra/domains/{domain}/runs
Jouw uitvoeringen voor een domein, nieuwste eerst: id, tijd, status, score en aantal wijzigingen. Accepteert limit (1 tot 100, standaard 30) en before, een uitvoerings-id.
GET/api/v1/infra/diff
Dezelfde vergelijking tussen twee opgeslagen uitvoeringen, ?from=<id>&to=<id>. Je hebt toegang tot beide nodig.
GET/api/v1/infra/checks
Elke sectie met het gewicht, de scoreversie en de limieten.
Afzonderlijke controles
Elke aanroep beantwoordt één vraag en bewaart geen geschiedenis. Een tool voert zelfstandig één deel van de infrastructuurcontrole uit, behalve de headertool, die een bericht leest dat je al hebt ontvangen.
Snel aan de slag
Kies een controle
Kies de tool uit de onderstaande lijst en geef het domein, het adres of het IP door waarnaar wordt gevraagd.
Verzoek
curl -s 'https://email-spam-tester.com/api/v1/tools/spf?domain=example.com'Lees de status en bevindingen
Elke tool antwoordt met een status en de bijbehorende bevindingen. De velden daarna zijn afhankelijk van de tool.
Antwoord
{ "tool": "spf", "query": {"domain": "example.com"}, "checked_at": "2026-10-31T12:00:00Z", "duration_ms": 412, "status": "fail", "findings": [ {"code": "spf.too_many_lookups", "level": "fail", "params": {"limit": 10, "count": 12}, "message": "RFC 7208 §4.6.4 allows at most 10 DNS lookups, and this record needs 12, so receivers return permerror."} ], "record": "v=spf1 include:_spf.example.net ~all", "lookups": {"count": 12, "limit": 10, "void": 0} }
Endpoints
GET/api/v1/tools/spf
Het SPF-record van een domein: de syntaxis, elke gevolgde include en redirect, en hoeveel DNS-lookups de volledige boom gebruikt van de limiet van tien. Geef ?domain=example.com door.
GET/api/v1/tools/dmarc
Het DMARC-record van een domein, of van het organisatiedomein als het zelf geen record heeft: de tags, het beleid en of elk extern rapportadres ermee heeft ingestemd rapporten te ontvangen. Geef ?domain=example.com door.
GET/api/v1/tools/dkim
De DKIM-sleutel die voor een selector is gepubliceerd: of deze bestaat en kan worden gedecodeerd, het type en de grootte, en de vlaggen voor intrekking en testen. Geef ?domain=example.com&selector=s1 door.
GET/api/v1/tools/blocklist
Een IPv4-adres, een IPv6-adres of een domein dat wordt gecontroleerd aan de hand van de DNS-blocklists die het rapport gebruikt, met het antwoord van elke lijst. Geef ?target=203.0.113.5 door.
GET/api/v1/tools/mx
De MX-records van een domein in de volgorde waarin afzenders ze proberen, met de IPv4- en IPv6-adressen van elke host. Null MX, een domein zonder MX, hosts die IP-adressen of CNAMEs zijn en hosts die niet kunnen worden omgezet, worden gerapporteerd, net als de MTA-STS- en TLS-RPT-records. Geef ?domain=example.com door.
GET/api/v1/tools/bimi
De BIMI-configuratie van een domein in vier stappen: het DMARC-beleid dat BIMI vereist, het record op default._bimi, het SVG-logo dat wordt gecontroleerd aan de hand van het Tiny PS-profiel, en het merkcertificaat met het type, de domeinen en de vervaldatum. Geef ?domain=example.com door, en &selector= voor een andere selector dan default.
GET/api/v1/tools/ptr
De PTR-records van een adres en of een van die namen weer naar dat adres verwijst. Een mislukte lookup geeft de status error; een ontbrekend record geeft de status fail. Geef ?ip=8.8.8.8 door.
GET/api/v1/tools/mta-sts
Het MTA-STS-record van een domein en het beleidsbestand waarnaar het verwijst: de modus, de vermelde hosts en elke MX-host die niet onder het beleid valt. Geef ?domain=example.com mee.
GET/api/v1/tools/tls-rpt
Het TLS-RPT-record van een domein en de adressen die de rapporten ontvangen. Geef ?domain=example.com mee.
GET/api/v1/tools/dnssec
Of de zone van een domein ondertekend, niet ondertekend of defect is, op basis van de DNSKEY- en DS-records. Een ongeldige handtekening wordt onderscheiden van een storing van de resolver. Geef ?domain=example.com mee.
GET/api/v1/tools/dane
De TLSA-records van de MX-hosts, vergeleken met het certificaat dat een host presenteert wanneer dat certificaat kon worden gelezen. Geef ?domain=example.com mee.
GET/api/v1/tools/smtp
STARTTLS en het certificaat op de eerste twee MX-hosts: TLS-versie, uitgever, vervaldatum en of de keten en de naam geldig zijn. We maken alleen verbinding met hosts onder het domein waarnaar je hebt gevraagd en slaan e-mailproviders over, en per adres wordt één resultaat 6 uur lang gedeeld. Er wordt geen e-mail verzonden. Geef ?domain=example.com mee.
GET/api/v1/tools/ns
De naamservers van een domein en of de zone een SOA-record heeft. Eén naamserver is een waarschuwing. Geef ?domain=example.com mee.
GET/api/v1/tools/registration
Wanneer de registratie van een domein verloopt, volgens RDAP. Minder dan 30 resterende dagen is een waarschuwing. Een zone zonder RDAP-service antwoordt met skipped. Geef ?domain=example.com mee.
POST/api/v1/tools/header
De headers van een ontvangen bericht, verzonden als JSON {"headers": "..."} of als text/plain: de route van hop tot hop met vertragingen, TLS en klokafwijking, de eigen Authentication-Results van de ontvanger, de overeenstemming tussen de domeinen van From, DKIM d= en Return-Path, en de headers voor DKIM, ARC, afmelden en spamfilters. Alles na de eerste lege regel wordt ongelezen verwijderd. De headers worden in het geheugen verwerkt en niet opgeslagen, gecachet of gelogd.
Controleer het domein elke nacht.
Test de e-mail voordat die wordt verzonden.
Gedeeld door elk product
Toegang, sleutels, de rapportindeling, statussen, fouten, plus OpenAPI en llms.txt voor machines.
Authenticatie
Die is er niet. Geen sleutel om aan te vragen, geen header om in te stellen, geen account om aan te maken. De slug die je terugkrijgt is de toegang: wie deze bezit, kan dat rapport lezen, en niemand anders kan deze raden.
Persoonlijke API-sleutels
Everything above works without a key. A key is for automation platforms such as
Zapier, where every user's calls come from the platform's servers and per-IP limits
would be shared by all of them. With a key, limits count per key (50 tests a day,
3 with placement, 5 permanent mailboxes), the key's tests form a history, and the
key can keep permanent mailboxes whose reports only it can read. Send the key as
Authorization: Bearer est_live_… on any call on this page. The routes
below also take account, a short name of your choosing
([A-Za-z0-9_-], up to 64 characters) that keeps separate lists under one
key. GET /api/v1/installations/tests requires it; pass the same one on
POST /api/v1/inbox so the test shows up there. The Zapier integration
uses zapier.
POST /api/v1/keys
Send JSON {"email":"you@example.com"}. Returns HTTP 201 with
key and email. The key is shown once; only its hash is
kept. Asking again gives a new key and leaves the earlier ones working. Limit: 5 keys
per IP per UTC day. The form on /zapier/ calls this.
GET /api/v1/keys/me
Returns email, key_prefix and created_at of
the key in the header, or HTTP 401. Use it to check a key.
GET /api/v1/installations/tests
The key's tests, newest first: ?account=…&limit=50 (up to 100),
and before=<slug> for the next page. Each item has
slug, created_at, analysis_status
(waiting or expired before an email arrived),
score_ours, score_compat, placement and
changes, the checks that moved since the previous test of the same
sending domain. Read the full report at /api/v1/tests/{slug}.
POST /api/v1/installations/mailboxes
Send JSON {"domain":"example.com","account":"…"}. Returns the
permanent mailbox of that sending domain: id, address,
domain, state, daily_cap and
created. HTTP 201 when it is new, 200 when it already existed, 409 when
the key keeps as many mailboxes as it may. Subscribe the address to a newsletter or
a sequence and every email that arrives is checked. GET on the same
path with ?account=… lists them, and DELETE
/api/v1/installations/mailboxes/{mailbox_id} stops one.
GET /api/v1/installations/mailboxes/{mailbox_id}/letters
The emails that arrived, oldest first, paged with after_id and
next_after_id. settled=true ends the page before the first
email still being checked, so paging never skips one. newest=true turns
the order round, for a quick look at the latest; settled does nothing
with it. Each has
test_id, slug, received_at,
analysis_status, score_ours, score_compat,
subject, from_addr and kind.
GET /api/v1/installations/letters/{slug}
The report of one email in a permanent mailbox, the same JSON as
/api/v1/tests/{slug} with report_url null: there is no
public page for it. HTTP 410 once the report has expired.
Het rapport lezen
De velden die het antwoord bevatten, in de volgorde waarin je ze waarschijnlijk wilt lezen.
| score_ours | 0 tot 100. Ons model. Authenticatie en infrastructuur wegen het zwaarst, omdat zij de bezorging bepalen voordat een filter ook maar één woord van de tekst leest. |
| score_compat | 0 tot 10. Reproduceert het SpamAssassin-achtige getal dat mensen al gebruiken om te vergelijken, zodat het rapport vergelijkbaar is met wat iemand elders heeft gezien. |
| subscores | Dezelfde schaal van 0 tot 100 per sectie: auth, infra_spam, content, compliance. |
| checks[] | Alle 42, elk met een status, een bevinding van één regel, het bewijs waarop de beslissing is gebaseerd en hoeveel punten dit in beide scores kostte. |
| checks[].citations | Waar de bevinding vandaan komt: de sectie van de RFC, letterlijk geciteerd, en de pagina waarop Google zijn eigen vereiste vermeldt. Handmatig samengesteld in plaats van gegenereerd, zodat erop kan worden vertrouwd. |
| oplossingen[] | Wat moet worden gewijzigd, in de juiste volgorde, met het aantal punten dat elke wijziging waard is. De winst wordt berekend door het rapport opnieuw te scoren, niet geschat. |
| volledig | Onwaar wanneer een controle niet kon worden uitgevoerd. Een niet-gecontroleerd item geldt nooit als geslaagd, dus beschouw de score als optimistisch totdat dit waar is. |
| rapport_url | De voor mensen leesbare pagina. Geef die aan een persoon in plaats van een muur van JSON. |
Statussen
Een controle is een van vijf dingen, en het verschil tussen twee ervan is belangrijker dan het lijkt.
| geslaagd | De controle is uitgevoerd en heeft niets verkeerds gevonden. |
| waarschuwing | De moeite waard om op te lossen. Kost punten. |
| mislukt | Kost je bezorging. Kost meer punten. |
| overslaan | Niet van toepassing. Geen bijlagen om te scannen, geen HTML-gedeelte om te wegen. Niet geslaagd. |
| fout | We konden dit niet vaststellen. Uitgesloten van de score en gemarkeerd, in plaats van als geslaagd meegeteld. |
analysis_status doorloopt received, analyzing, checks_ready, failed. ai_status doorloopt pending, running, ready, fallback, error. Het deterministische rapport is definitief bij checks_ready; ai_status voegt alleen het plan toe.
Wat kan worden teruggegeven
| 202 | Het adres is gereserveerd en er is geen bericht aangekomen. De hoofdtekst bevat het adres, de vervaldatum en de taal, zodat een aanroeper die de reservering niet heeft aangemaakt deze toch kan weergeven. |
| 404 | Deze slug bestaat niet. Deze heeft nooit bestaan of de reservering is vergeten. |
| 410 | Het adres is verlopen voordat er een bericht aankwam. |
| 409 | Je hebt geprobeerd de taal te wijzigen nadat het bericht al was aangekomen. |
| 429 | De limiet voor gratis tests voor je adres. Er geldt momenteel geen limiet per persoon voor deze service; als die ooit wordt ingesteld, vermeldt de hoofdtekst wanneer deze opnieuw wordt ingesteld. |
Vier dingen om te weten
Eén bericht per adres
Het tweede wordt geweigerd. Je eerdere rapport blijft intact, wat precies de bedoeling is.
Een uur om het te gebruiken
Het adres verloopt; het rapport niet. Rapportlinks zijn permanent, dus een link die in een ticket is geplakt, blijft werken.
Verzenden vanaf het platform
Als je een campagne vanuit een persoonlijk account test, meet je dat account. Bijna alles in het gedeelte over authenticatie gaat over de verzendinfrastructuur, niet over de tekst.
Opnieuw testen na herstel
De verwachte verbeteringen worden per oplossing berekend en kunnen niet worden gecombineerd. Het tweede rapport geeft het eerlijke getal.
Voor machines
- /api/openapi.json De OpenAPI-beschrijving, gegenereerd op basis van dezelfde code die de API uitvoert.
- /llms.txt, /llms-full.txt Een korte kaart van deze site voor taalmodellen, volgens de llms.txt-conventie, en een langere versie met de volledige cyclus en de rapportvelden in één bestand.
- /mcp Een MCP-server met dezelfde functionaliteit en een blokkerende wachtfunctie, wat beter werkt dan pollen vanuit een model.
- For agents De agentpagina: wanneer je dit gebruikt, hoe je een overgeslagen controle ten opzichte van een geslaagde controle interpreteert, en welke bevindingen DNS-records zijn die een persoon moet wijzigen in plaats van tekst die een agent kan bewerken.
GET/api/health
Liveness. Geen authenticatie, geen bijwerkingen.
Probeer er eerst één handmatig
Het duurt ongeveer een minuut en laat je precies zien wat de JSON beschrijft.
Vraag een testadres aanSandbox.
Elk endpoint, met een knop die het uitvoert op de live service. Hiervoor is geen sleutel nodig, dus een verzoek dat je vanaf deze pagina verstuurt is echt: het reserveert een echt adres en telt mee.
Probeer het in de sandbox