Spamkontroll-API för e-post,
inkorg och domän
Skicka ett riktigt meddelande till oss eller ange bara en domän. Alla svar är i JSON.
Ingen nyckel, inget konto.
Begäran
# 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'
Svar
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}]
}Begäran
# 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'
Svar
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"}
]}
}Begäran
# 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'
Svar
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"}]
}Välj den du behöver
På den här sidan
E-posttest
Vi läser ett riktigt meddelande från början till slut: innehåll, signatur, huvuden och servern som skickade det. Du får ett betyg, en lista över korrigeringar och varje kontroll bakom dem.
Snabbstart
Tre anrop. Ingen nyckel, inget konto, ingen registrering. Två begäranden och ett e-postmeddelande. Det tredje anropet behövs bara eftersom analysen tar några sekunder.
Reservera en adress
Skicka POST till inkorgens slutpunkt. Du får tillbaka en adress som tar emot exakt ett meddelande och upphör att gälla efter en timme, samt den slug som allt annat är kopplat till.
Begäran
# 1. reserve a single-use address curl -sX POST 'https://email-spam-tester.com/api/v1/inbox?lang=en'Svar
{ "address": "test-<slug>@t.email-spam-tester.com", "slug": "<slug>", "expires_at": "2026-01-01T12:00:00Z" }Skicka det riktiga meddelandet till den
Via SMTP, från plattformen som ska skicka kampanjen. Hälften av kontrollerna läser huvuden som din sändningsplattform lägger till, så ett manuellt skapat meddelande mäter fel sak.
Begäran
# 2. send your message to that address, from your own platform To: test-<slug>@t.email-spam-tester.comAvfråga statusen och läs sedan rapporten
Statusslutpunkten omfattar några hundra byte och talar om huruvida det är värt att hämta hela rapporten ännu. Själva rapporten omfattar flera tusen rader.
Begäran
# 3. poll curl -s 'https://email-spam-tester.com/api/v1/tests/<slug>/status'Svar
{ "slug": "<slug>", "analysis_status": "checks_ready", "ai_status": "running", "checks_done": 42, "checks_total": 42 }Begäran
# 4. read the report once analysis_status is checks_ready curl -s 'https://email-spam-tester.com/api/v1/tests/<slug>'Svar
{ "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"}} ] }
Reservera en adress, skicka meddelandet som du var på väg att skicka till din lista och läs rapporten. Allt som sidan visar finns i JSON, inklusive poängen, samtliga 42 kontroller med tillhörande belägg och avsnittet i standarden som varje resultat bygger på.
De första 100 000 rapporterna är kostnadsfria, utan nyckel och utan konto. Om du kopplar in en agent i stället för ett skript passar MCP-servern bättre än avfrågning.
Ändpunkter
Basadress https://email-spam-tester.com. Allt svarar med JSON.
POST/api/v1/inbox
Reserverar en engångsadress. Båda parametrarna är valfria.
| lang | Språket som åtgärdsplanen och resultaten per kontroll skrivs på, som en ISO-kod. Det bestäms nu eftersom meddelandet anländer via SMTP flera minuter senare och inte innehåller någon ledtråd om vem som väntar på det. En okänd kod använder engelska som reservspråk. |
| utm_source, utm_medium, utm_campaign | Skickas vidare till vår analys. Användbart om du mäter din egen integration. |
GET/api/v1/tests/{slug}/status
Billig att polla. Returnerar de två statusfälten och hur långt kontrollerna har kommit, och inget annat.
GET/api/v1/tests/{slug}
Hela rapporten. Svarar med 202 medan adressen är reserverad och inget ännu har anlänt, och med 200 när det har gjort det.
GET/api/v1/tests/{slug}/message
Meddelandet exakt som det levererades: varje huvud i överföringsordning, båda meddelandekropparna, listan över bilagor och den råa källan. Hämtas separat eftersom rapporten pollas och detta kan bli upp till en megabyte.
PUT/api/v1/tests/{slug}/locale
Ändrar språket för en reservation som ännu inte har använts. För en agent som får veta vilket språk användaren läser efter att den redan har frågat efter adressen. Avvisas när meddelandet väl har anlänt, eftersom analysen då körs.
InkorgsplaceringBeta
Skicka ett meddelande till en lista med testinkorgar och se var det hamnade hos Gmail, Outlook, Yahoo och andra leverantörer: Inkorgen, Kampanjer eller Spam.
Snabbstart
Skapa ett test
Gör en POST till slutpunkten för placering. Du får tillbaka en markör och testinkorgarna.
Begäran
# 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}'Svar
{ "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"} ] } }Skicka ett meddelande till varje inkorg
Lägg markören i ämnesraden och skicka från din vanliga plattform till alla adresser på en gång.
Begäran
# 2. one message to every address, with the marker in the subject Subject: October invoice est-3f9a1c7e2b4d6a80c5e1f2d3 To: <seed>, <mailbox>, ...Hämta mapparna regelbundet
Varje adress fylls i med sin leverantör och mapp. Hämta regelbundet tills statusen inte längre är waiting.
Begäran
# 3. poll for the folders curl -s 'https://email-spam-tester.com/api/v1/placement/<slug>'Svar
{ "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"} ] } }
Ändpunkter
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.
Infrastrukturkontroll
En GET-förfrågan kontrollerar e-postkonfigurationen för en domän utan att skicka något, sparar resultatet och visar vad som har ändrats sedan din senaste körning. Ingen nyckel behövs. I cron avslutas raden nedan med en kod som inte är noll när domänen är felaktig eller dess konfiguration har ändrats på ett sätt som har betydelse.
Snabbstart
Gör ett GET-anrop
Skicka med domänen. ip lägger till dina avsändaradresser, och selector anger namnen på de DKIM-selektorer som ska läsas.
Begäran
curl -s 'https://email-spam-tester.com/api/v1/infra/check?domain=example.com&selector=mail&diff=true'Läs resultatet
ok är svaret för ett skript, och sections visar vilken del som misslyckades.
Svar
{ "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"} ] } }Lägg in det i cron
Med diff=true jämförs varje körning med din senaste, och jq omvandlar svaret till en returkod.
Begäran
# 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 | Obligatorisk. Tar det som verktygen tar: en domän, en URL, en e-postadress. |
| ip | Din avsändaradress. Upprepa den för fler, upp till 6. |
| selector | En DKIM-selektor. Upprepa den för fler, upp till 10. Varje selektor du anger måste finnas, annars misslyckas DKIM-avsnittet. |
| helo | Namnet som din server anger i HELO, jämfört med dess PTR. |
| account | Vem begäran gäller. Obligatorisk med en nyckel som betjänar många personer. |
| checks | Avsnitt som ska köras, kommaseparerade. Alla som standard. |
| diff | true jämför den här körningen med din senaste körning av domänen. |
| since | 7d, 12h eller ett ISO 8601-datum. Jämför med den av dina körningar som ligger närmast den tidpunkten inom 12 timmar, annars den sista före den. Aktiverar diff. |
| baseline | Id:t för en av dina körningar att jämföra med. Aktiverar diff. |
| fresh | true hoppar över 60-sekunderscachen. |
Läsa svaret
En kontroll som har slutförts svarar med 200, och utfallet finns i svarskroppen. status är den sämsta statusen bland de obligatoriska sektionerna: spf, dkim, dmarc, ptr, blocklist_ip, blocklist_domain, mx och smtp. unknown i en obligatorisk sektion räknas som warn. ok är true när status är pass eller warn. score går från 0 till 100 för de obligatoriska sektioner som svarade, och är null när error och unknown gör att mindre än hälften av den tillämpliga vikten återstår. mta_sts, tls_rpt, bimi, dnssec, dane, ns och registration rapporteras och jämförs, men de påverkar inte ok eller score.
En sektion kan vara pass, warn, fail, error (vi kunde inte kontrollera), unknown (för lite underlag) eller skipped (inte tillämpligt). skipped påverkar inte resultatet, och orsaken finns i not_checked. dkim_signature och alignment finns alltid med, eftersom de kräver ett riktigt meddelande.
Vad ip och selector ändrar
PTR och blockeringslistor gäller adresser, så en körning behöver några. Den använder de ip-värden du skickar med. Om inga anges hämtar den upp till fyra från dina MX-värdar och från ip4:- och ip6:-termer med en enda adress i SPF-posten på rotnivå. Adresser som tillhör en känd e-postleverantör markeras som managed och kontrolleras inte, och om inga adresser återstår svarar ptr och blocklist_ip med skipped. En selector kan inte läsas ut från DNS, så en körning provar din, de som hittades av dina tidigare körningar och en lista med vanliga namn. Att inte hitta något bevisar ingenting, och dkim svarar med unknown. Om du skickar från din egen server ska du skicka med båda.
Vad som ändrades
Varje post i diff.changes har en path, en kind (added, removed, changed), en severity (critical, warning, info) och en effect (worsened, improved, neutral). Endast critical och warning aktiverar diff.changed, så en roterad DKIM-nyckel med samma längd, en ny MX-adress eller ett förnyat certifikat gör inte att cron-raden misslyckas. diff.worsened följer effekten av alla ändringar. Vid en första körning finns det inget att jämföra med, och diff.first_run anger detta.
En baslinje är alltid en av dina egna körningar, så om någon annan kontrollerar domänen mellan två av dina körningar döljs ingenting. Allt som vi inte kunde läsa den här gången hamnar i diff.not_compared med sitt senast kända värde bevarat, vilket innebär att en ändring som görs under ett avbrott visas när uppslagningen fungerar igen. En körning med ett annat ip eller en annan selector stannar i samma serie, och det som den inte frågade efter jämförs inte heller.
Varför en schemalagd kontroll bör använda en nyckel
Utan en nyckel hör din historik till en nycklad hash av din IP-adress, så den upphör när adressen ändras, och personer bakom samma adress delar den: en kollegas körning flyttar din baslinje. Med en personlig API-nyckel i Authorization: Bearer följer historiken nyckeln. Körningar med en nyckel sparas i 365 dagar och kan endast öppnas med den nyckeln. Körningar utan nyckel sparas i 30 dagar och kan öppnas av alla som har deras id.
6 förfrågningar per minut och 50 per dag per IP, eller 30 och 500 per nyckel. Över den gränsen är svaret 429 med Retry-After. En identisk förfrågan inom 60 sekunder hämtas från en cache, markeras med cached: true, skapar ingen körning och räknas inte. Läsning av sparade körningar tillåter 120 förfrågningar per minut och klient. 503 med Retry-After innebär att för många kontroller körs eller, vid läsning av sparade körningar, att lagringen inte är tillgänglig. 401 innebär en felaktig nyckel. 422 innehåller detail.code: invalid_domain, invalid_ip, invalid_selector, invalid_check, invalid_since, unknown_baseline eller account_required.
Ändpunkter
GET/api/v1/infra/check
Kör kontrollen. Parametrarna finns i tabellen ovan.
GET/api/v1/infra/runs/{public_id}
En lagrad körning, i sin helhet. 404 om den inte finns eller tillhör en annan nyckel.
GET/api/v1/infra/domains/{domain}/runs
Dina körningar för en domän, nyaste först: id, tid, status, poäng och antal ändringar. Tar limit (1 till 100, 30 som standard) och before, ett körnings-id.
GET/api/v1/infra/diff
Samma jämförelse mellan två lagrade körningar, ?from=<id>&to=<id>. Du behöver åtkomst till båda.
GET/api/v1/infra/checks
Varje avsnitt med dess vikt, poängversionen och gränserna.
Enskilda kontroller
Varje anrop besvarar en fråga och sparar ingen historik. Ett verktyg kör en del av infrastrukturkontrollen på egen hand, förutom headerverktyget, som läser ett meddelande du redan har tagit emot.
Snabbstart
Välj en kontroll
Välj verktyget från listan nedan och ange domänen, adressen eller IP-numret som efterfrågas.
Begäran
curl -s 'https://email-spam-tester.com/api/v1/tools/spf?domain=example.com'Läs status och resultat
Varje verktyg svarar med en status och sina resultat. Fälten efter dem beror på verktyget.
Svar
{ "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} }
Ändpunkter
GET/api/v1/tools/spf
SPF-posten för en domän: dess syntax, varje include och redirect som följs samt antalet DNS-uppslag som hela trädet förbrukar mot gränsen på tio. Ange ?domain=example.com.
GET/api/v1/tools/dmarc
DMARC-posten för en domän, eller för dess organisationsdomän när den saknar en egen: taggarna, policyn och huruvida varje extern rapportadress har godkänt att ta emot rapporter. Ange ?domain=example.com.
GET/api/v1/tools/dkim
DKIM-nyckeln som publicerats för en selektor: huruvida den finns och kan avkodas, dess typ och storlek samt flaggorna för återkallning och testning. Ange ?domain=example.com&selector=s1.
GET/api/v1/tools/blocklist
En IPv4-adress, en IPv6-adress eller en domän som kontrolleras mot de DNS-blocklistor som rapporten använder, med svaret från varje lista. Ange ?target=203.0.113.5.
GET/api/v1/tools/mx
MX-posterna för en domän i den ordning som avsändare provar dem, med IPv4- och IPv6-adresserna för varje värd. Null MX, en domän utan MX, värdar som är IP-adresser eller CNAME-poster och värdar som inte kan matchas rapporteras, liksom MTA-STS- och TLS-RPT-posterna. Skicka med ?domain=example.com.
GET/api/v1/tools/bimi
BIMI-konfigurationen för en domän i fyra steg: DMARC-policyn som BIMI kräver, posten på default._bimi, SVG-logotypen kontrollerad mot Tiny PS-profilen och märkescertifikatet med dess typ, domäner och utgångsdatum. Skicka med ?domain=example.com och &selector= för en annan selektor än default.
GET/api/v1/tools/ptr
PTR-posterna för en adress och om något av dessa namn matchar tillbaka till den. En uppslagning som misslyckades ger statusen error; en post som saknas ger statusen fail. Ange ?ip=8.8.8.8.
GET/api/v1/tools/mta-sts
MTA-STS-posten för en domän och policyfilen som den pekar på: läget, värdarna som anges och eventuella MX-värdar som policyn utelämnar. Ange ?domain=example.com.
GET/api/v1/tools/tls-rpt
TLS-RPT-posten för en domän och adresserna som tar emot dess rapporter. Ange ?domain=example.com.
GET/api/v1/tools/dnssec
Huruvida zonen för en domän är signerad, osignerad eller felaktig, utifrån dess DNSKEY- och DS-poster. En felaktig signatur skiljs från ett avbrott hos resolvern. Ange ?domain=example.com.
GET/api/v1/tools/dane
TLSA-posterna för MX-värdarna, jämförda med certifikatet som en värd presenterar när certifikatet kunde läsas. Ange ?domain=example.com.
GET/api/v1/tools/smtp
STARTTLS och certifikatet på de två första MX-värdarna: TLS-version, utfärdare, utgångsdatum och huruvida kedjan och namnet är giltiga. Vi ansluter endast till värdar under domänen du frågade om och hoppar över e-postleverantörer, och ett resultat per adress delas i 6 timmar. Ingen e-post skickas. Ange ?domain=example.com.
GET/api/v1/tools/ns
Namnservrarna för en domän och huruvida dess zon har en SOA-post. En namnserver ger en varning. Ange ?domain=example.com.
GET/api/v1/tools/registration
När registreringen av en domän löper ut, från RDAP. Mindre än 30 dagar kvar ger en varning. En zon utan RDAP-tjänst svarar skipped. Ange ?domain=example.com.
POST/api/v1/tools/header
Rubrikerna i ett mottaget meddelande, skickade som JSON {"headers": "..."} eller som text/plain: vägen nod för nod med fördröjningar, TLS och klockavvikelse, mottagarens egna Authentication-Results, justeringen mellan domänerna i From, DKIM d= och Return-Path samt rubrikerna för DKIM, ARC, avregistrering och skräppostfilter. Allt efter den första tomma raden tas bort utan att läsas. Rubrikerna behandlas i minnet och lagras, cachelagras eller loggas inte.
Kontrollera domänen varje natt.
Testa e-postmeddelandet innan det går iväg.
Gemensamt för varje produkt
Åtkomst, nycklar, rapportformatet, statusar, fel samt OpenAPI och llms.txt för maskiner.
Autentisering
Det finns ingen. Ingen nyckel att begära, inget huvud att ange, inget konto att skapa. Sluggen du får tillbaka är behörigheten: den som har den kan läsa rapporten, och ingen annan kan gissa den.
Personliga API-nycklar
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.
Läsa rapporten
Fälten som innehåller svaret, i den ordning du troligen vill ha dem.
| score_ours | 0 till 100. Vår modell. Autentisering och infrastruktur väger tyngst, eftersom de avgör leveransen innan ett filter läser ett enda ord av innehållet. |
| score_compat | 0 till 10. Återskapar det SpamAssassin-liknande tal som redan används för jämförelser, så att rapporten är jämförbar med vad någon har sett någon annanstans. |
| subscores | Samma skala från 0 till 100 per avsnitt: auth, infra_spam, content, compliance. |
| checks[] | Alla 42, var och en med en status, ett resultat på en rad, underlaget som beslutet baserades på och vad det kostade de två poängen. |
| checks[].citations | Var upptäckten kommer ifrån: avsnittet i RFC, ordagrant citerat, och sidan där Google anger sitt eget krav. Sammanställda för hand i stället för genererade, så de går att lita på. |
| fixes[] | Vad som ska ändras, i ordning, med det antal poäng varje ändring är värd. Poängökningarna beräknas genom att rapporten poängsätts på nytt, de uppskattas inte. |
| complete | False när en kontroll inte kunde köras. En okontrollerad punkt är aldrig godkänd, så betrakta poängen som optimistisk tills den är true. |
| report_url | Den läsbara sidan. Ge den till en person i stället för en vägg av JSON. |
Statusar
En kontroll kan vara en av fem saker, och skillnaden mellan två av dem är viktigare än den ser ut.
| pass | Kontrollen kördes och hittade inget fel. |
| warn | Värt att åtgärda. Kostar poäng. |
| fail | Kommer att kosta dig leveranser. Kostar fler poäng. |
| hoppa över | Var inte tillämpligt. Inga bilagor att skanna, ingen HTML-del att väga in. Inte godkänt. |
| fel | Vi kunde inte fastställa det. Undantas från poängberäkningen och flaggas, i stället för att räknas som godkänt. |
analysis_status går igenom received, analyzing, checks_ready, failed. ai_status går igenom pending, running, ready, fallback, error. Den deterministiska rapporten är slutgiltig vid checks_ready; ai_status lägger endast till planen.
Vad som kan returneras
| 202 | Adressen är reserverad och inget meddelande har anlänt. Svaret innehåller adressen, utgångstiden och språket, så att en anropare som inte skapade reservationen ändå kan visa den. |
| 404 | Ingen sådan slug. Den har aldrig funnits eller så har reservationen glömts bort. |
| 410 | Adressen löpte ut innan ett meddelande anlände. |
| 409 | Du försökte ändra språket efter att meddelandet redan hade anlänt. |
| 429 | Gränsen för kostnadsfria tester för din adress. Det finns för närvarande ingen gräns per person för den här tjänsten; om en sådan gräns någon gång införs anger svaret när den återställs. |
Fyra saker som är bra att känna till
Ett meddelande per adress
Det andra nekas. Din tidigare rapport förblir intakt, vilket är poängen.
En timme att använda den
Adressen upphör att gälla; det gör inte rapporten. Rapportlänkar är permanenta, så en som klistras in i ett ärende fortsätter att fungera.
Skicka från plattformen
Att testa en kampanj från ett personligt konto mäter det kontot. Nästan allt i autentiseringsavsnittet handlar om infrastrukturen för utskick, inte texten.
Testa igen efter korrigering
De förväntade förbättringarna beräknas en korrigering i taget och de kan inte kombineras. Den andra rapporten ger den faktiska siffran.
För maskiner
- /api/openapi.json OpenAPI-beskrivningen, genererad från samma kod som tillhandahåller API:et.
- /llms.txt, /llms-full.txt En kort karta över den här webbplatsen för språkmodeller, enligt llms.txt-konventionen, och en längre version med hela flödet och rapportfälten i en fil.
- /mcp En MCP-server med samma funktion och en blockerande väntan, vilket är bättre än att göra polling inifrån en modell.
- For agents Agentsidan: när detta ska användas, hur en överhoppad kontroll ska jämföras med en godkänd och vilka resultat som är DNS-poster som en person måste ändra snarare än text som en agent kan redigera.
GET/api/health
Tillgänglighetskontroll. Ingen autentisering, inga sidoeffekter.
Prova en manuellt först
Det tar ungefär en minut och visar exakt vad JSON beskriver.
Hämta en testadressSandlåda.
Varje endpoint, med en knapp som kör den mot den aktiva tjänsten. Inget här kräver en nyckel, så en begäran som du skickar från den här sidan är verklig: den reserverar en riktig adress och räknas.
Prova i sandlådan