Email Spam Tester

API til spamkontrol af e-mail,
indbakke og domæne

Send os én rigtig besked, eller giv os kun et domæne. Alt besvares i JSON.

Ingen nøgle, ingen konto.

Anmodning

# 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}]
}

Anmodning

# 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"}
  ]}
}

Anmodning

# 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"}]
}
På denne side

E-mailtest

Vi læser én rigtig besked fra ende til anden: indhold, signatur, headers og den server, der sendte den. Du får en score, en liste over rettelser og alle kontrollerne bag dem.

Hurtig start

Tre kald. Ingen nøgle, ingen konto, ingen tilmelding. To forespørgsler og én email. Det tredje kald er kun nødvendigt, fordi analysen tager nogle få sekunder.

  1. Reservér en adresse

    Send en POST-anmodning til indbakke-endpointet. Du får en adresse tilbage, som accepterer præcis én meddelelse og udløber efter en time, samt den slug, som alt andet bruger som nøgle.

    Anmodning

    # 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"
    }
  2. Send den rigtige meddelelse til den

    Via SMTP fra den platform, der skal sende kampagnen. Halvdelen af kontrollerne læser headere, som din afsendelsesplatform tilføjer, så en meddelelse, der er skrevet manuelt, måler det forkerte.

    Anmodning

    # 2. send your message to that address, from your own platform
    To: test-<slug>@t.email-spam-tester.com
  3. Poll status, og læs derefter rapporten

    Status-endpointet fylder nogle få hundrede byte og fortæller dig, om det er værd at hente hele rapporten endnu. Selve rapporten fylder flere tusinde linjer.

    Anmodning

    # 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
    }

    Anmodning

    # 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"}}
      ]
    }

Reservér en adresse, send den meddelelse, du var ved at sende til din liste, og læs rapporten. Alt, hvad siden viser, findes i JSON, herunder scoren, alle 42 kontroller med deres dokumentation og det afsnit i standarden, som hver konstatering bygger på.

De første 100.000 rapporter er gratis, uden nøgle og uden konto. Hvis du konfigurerer en agent frem for et script, er MCP-serveren bedre egnet end polling.

Endpoints

Basisadresse https://email-spam-tester.com. Alt svarer med JSON.

POST/api/v1/inbox

Reserverer en engangsadresse. Begge parametre er valgfrie.

langDet sprog, som rettelsesplanen og resultaterne for hvert tjek skrives på, som en ISO-kode. Det afgøres nu, fordi meddelelsen ankommer via SMTP flere minutter senere og ikke indeholder nogen indikation af, hvem der venter på den. En ukendt kode falder tilbage til engelsk.
utm_source, utm_medium, utm_campaignSendes videre til vores analyseværktøj. Nyttigt, hvis du måler din egen integration.

GET/api/v1/tests/{slug}/status

Billigt at polle. Returnerer de to statusfelter og oplysning om, hvor langt tjekkene er nået, og intet andet.

Poll dette i stedet for rapporten. analysis_status når først checks_ready, og AI-planen lander under ai_status cirka et minut senere, så en klient, der kun vil have de deterministiske tjek, ikke behøver at vente på planen.

GET/api/v1/tests/{slug}

Hele rapporten. Svarer med 202, mens adressen er reserveret, og intet endnu er ankommet, og med 200, når det er sket.

GET/api/v1/tests/{slug}/message

Meddelelsen præcis som den blev leveret: alle headere i wire-rækkefølge, begge brødtekster, listen over vedhæftede filer og den rå kilde. Hentes separat, fordi rapporten polles, og dette kan fylde op til en megabyte.

Den rå meddelelse slettes efter sin egen tidsplan, tidligere end rapporten. Derefter svarer dette slutpunkt med årsagen i stedet for kilden.

PUT/api/v1/tests/{slug}/locale

Ændrer sproget for en reservation, der endnu ikke er blevet brugt. Til en agent, der finder ud af, hvilket sprog dens bruger læser, efter at den allerede har bedt om adressen. Afvises, når meddelelsen er ankommet, fordi analysen på det tidspunkt kører.

IndbakkeplaceringBeta

Send én besked til en liste over testindbakker, og se, hvor den landede hos Gmail, Outlook, Yahoo og andre udbydere: Indbakke, Kampagner eller Spam.

Hurtig start

  1. Opret en test

    Send en POST-anmodning til placement-endpointet. Du får en markør og testindbakkerne tilbage.

    Anmodning

    # 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"}
        ]
      }
    }
  2. Send én besked til hver indbakke

    Sæt markøren i emnelinjen, og send fra din normale platform til alle adresserne på én gang.

    Anmodning

    # 2. one message to every address, with the marker in the subject
    Subject: October invoice est-3f9a1c7e2b4d6a80c5e1f2d3
    To: <seed>, <mailbox>, ...
  3. Poll efter mapperne

    Hver adresse udfyldes med sin udbyder og mappe. Poll, indtil statussen ikke længere er waiting.

    Anmodning

    # 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"}
        ]
      }
    }

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.

Infrastrukturkontrol

Én GET kontrollerer mailopsætningen for et domæne uden at sende noget, gemmer resultatet og fortæller dig, hvad der er ændret siden din seneste kørsel. Ingen nøgle kræves. I cron afsluttes linjen nedenfor med en værdi forskellig fra nul, når domænet er defekt, eller dets opsætning er ændret på en måde, der har betydning.

Hurtig start

  1. Foretag én GET

    Angiv domænet. ip tilføjer dine afsenderadresser, og selector angiver de DKIM-selectors, der skal læses.

    Anmodning

    curl -s 'https://email-spam-tester.com/api/v1/infra/check?domain=example.com&selector=mail&diff=true'
  2. Læs resultatet

    ok er svaret til et script, og sections viser, hvilken del der fejlede.

    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"}
        ]
      }
    }
  3. Læg det i cron

    Med diff=true sammenlignes hver kørsel med din seneste, og jq omdanner svaret til en exitkode.

    Anmodning

    # 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)'
domainPåkrævet. Tager det samme som værktøjerne: et domæne, en URL, en e-mailadresse.
ipDin afsendelsesadresse. Gentag den for flere, op til 6.
selectorEn DKIM-selektor. Gentag den for flere, op til 10. Hver selektor, du angiver, skal eksistere, ellers mislykkes dkim-sektionen.
heloDet navn, din server angiver i HELO, sammenlignet med dens PTR.
accountHvem anmodningen er for. Påkrævet med en nøgle, der betjener mange personer.
checksSektioner, der skal køres, kommasepareret. Alle som standard.
difftrue sammenligner denne kørsel med din seneste kørsel af domænet.
since7d, 12h eller en ISO 8601-dato. Sammenligner med din kørsel tættest på dette tidspunkt inden for 12 timer, ellers den seneste før det. Aktiverer diff.
baselineId'et for en af dine kørsler, der skal sammenlignes med. Aktiverer diff.
freshtrue springer cachen på 60 sekunder over.

Læsning af svaret

Et afsluttet tjek svarer med 200, og resultatet findes i svarets body. status er den værste af de obligatoriske sektioner: spf, dkim, dmarc, ptr, blocklist_ip, blocklist_domain, mx og smtp. unknown i en obligatorisk sektion tæller som warn. ok er true, når status er pass eller warn. score går fra 0 til 100 for de obligatoriske sektioner, der svarede, og er null, når fejl og unknown efterlader mindre end halvdelen af den relevante vægt. mta_sts, tls_rpt, bimi, dnssec, dane, ns og registration rapporteres og sammenlignes, men de påvirker ikke ok eller score.

En sektion kan være pass, warn, fail, error (vi kunne ikke kontrollere), unknown (for lidt at gå ud fra) eller skipped (gælder ikke). skipped påvirker ikke resultatet, og årsagen findes i not_checked. dkim_signature og alignment er der altid, fordi de kræver en rigtig meddelelse.

Hvad ip og selector ændrer

PTR og blokeringslister handler om adresser, så en kørsel skal bruge nogle. Den bruger de ip-værdier, du angiver. Uden nogen tager den op til fire fra dine MX-værter og fra ip4:- og ip6:-termer med én adresse i SPF-posten på roden. Adresser fra en kendt mailudbyder angives som managed og kontrolleres ikke, og hvis der derefter ikke er nogen tilbage, svarer ptr og blocklist_ip med skipped. En selector kan ikke læses fra DNS, så en kørsel prøver dine, dem som dine tidligere kørsler fandt, og en liste over almindelige navne. At der ikke findes noget, beviser intet, og dkim svarer med unknown. Hvis du sender fra din egen server, skal du angive begge.

Hvad der er ændret

Hver post i diff.changes har en path, en kind (added, removed, changed), en severity (critical, warning, info) og en effect (worsened, improved, neutral). Kun critical og warning sætter diff.changed, så en roteret DKIM-nøgle med samme længde, en ny MX-adresse eller et fornyet certifikat får ikke cron-linjen til at fejle. diff.worsened følger effekten af enhver ændring. Ved en første kørsel er der intet at sammenligne med, og diff.first_run angiver dette.

En baseline er altid en af dine egne kørsler, så det skjuler intet, hvis en anden kontrollerer domænet mellem to af dine kørsler. Alt, som vi ikke kunne læse denne gang, overføres til diff.not_compared med den senest kendte værdi bevaret, hvilket betyder, at en ændring foretaget under en driftsafbrydelse vises, når opslaget virker igen. En kørsel med en anden ip eller selector forbliver i samme serie, og det, den ikke spurgte om, sammenlignes heller ikke.

Hvorfor et planlagt tjek bør bruge en nøgle

Uden en nøgle tilhører din historik en nøglebaseret hash af din IP-adresse, så den slutter, når adressen ændres, og personer bag én adresse deler den: En kollegas kørsel flytter din baseline. Med en personlig API-nøgle i Authorization: Bearer følger historikken nøglen. Kørsler med en nøgle opbevares i 365 dage og kan kun åbnes med den nøgle. Kørsler uden en opbevares i 30 dage og kan åbnes af alle, der har deres id.

6 anmodninger i minuttet og 50 om dagen pr. IP, eller 30 og 500 pr. nøgle. Over dette er svaret 429 med Retry-After. En identisk anmodning inden for 60 sekunder kommer fra en cache, markeres med cached: true, skriver ingen kørsel og tæller ikke med. Læsning af gemte kørsler tillader 120 anmodninger i minuttet pr. klient. 503 med Retry-After betyder, at der kører for mange tjek, eller, ved læsning af gemte kørsler, at lageret ikke er tilgængeligt. 401 er en forkert nøgle. 422 indeholder detail.code: invalid_domain, invalid_ip, invalid_selector, invalid_check, invalid_since, unknown_baseline eller account_required.

Endpoints

GET/api/v1/infra/check

Kører kontrollen. Parametrene er i tabellen ovenfor.

GET/api/v1/infra/runs/{public_id}

Én gemt kørsel, komplet. 404, hvis den ikke findes eller tilhører en anden nøgle.

GET/api/v1/infra/domains/{domain}/runs

Dine kørsler af et domæne, nyeste først: id, tidspunkt, status, score og antal ændringer. Tager limit (1 til 100, 30 som standard) og before, et kørsels-id.

GET/api/v1/infra/diff

Den samme sammenligning mellem to gemte kørsler, ?from=<id>&to=<id>. Du skal have adgang til begge.

GET/api/v1/infra/checks

Hver sektion med dens vægt, scoreversionen og grænserne.

Enkeltkontroller

Hvert kald besvarer ét spørgsmål og gemmer ingen historik. Et værktøj kører én del af infrastrukturkontrollen selvstændigt, bortset fra header-værktøjet, som læser en meddelelse, du allerede har modtaget.

Hurtig start

  1. Vælg en kontrol

    Vælg værktøjet fra listen nedenfor, og angiv det domæne, den adresse eller den IP, det beder om.

    Anmodning

    curl -s 'https://email-spam-tester.com/api/v1/tools/spf?domain=example.com'
  2. Læs status og resultater

    Hvert værktøj svarer med en status og sine resultater. Felterne efter dem afhænger af værktøjet.

    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}
    }

Endpoints

De svarer alle med 200 med en status og en liste over fund, hver med en kode og dens parametre. Status er pass, warn, fail eller error, og et værktøj, der deles med infrastrukturkontrollen, kan også svare unknown eller skipped. Et opslag, der fik timeout, eller en liste, der afviste forespørgslen, tæller aldrig som en pass. 30 anmodninger i minuttet og 300 om dagen pr. IP på tværs af værktøjerne; derover er svaret 429 med Retry-After.

GET/api/v1/tools/spf

Et domænes SPF-post: dens syntaks, alle fulgte include- og redirect-referencer samt det antal DNS-opslag, hele træet bruger af grænsen på ti. Angiv ?domain=example.com.

GET/api/v1/tools/dmarc

Et domænes DMARC-post eller posten for dets organisatoriske domæne, når det ikke selv har en: tags, politikken, og om hver ekstern rapportadresse har accepteret at modtage rapporter. Angiv ?domain=example.com.

GET/api/v1/tools/dkim

Den DKIM-nøgle, der er publiceret for en selector: om den findes og kan afkodes, dens type og størrelse samt flagene for tilbagekaldelse og test. Angiv ?domain=example.com&selector=s1.

GET/api/v1/tools/blocklist

En IPv4-adresse, en IPv6-adresse eller et domæne, der kontrolleres mod de DNS-blokeringslister, rapporten bruger, med svaret fra hver liste. Angiv ?target=203.0.113.5.

GET/api/v1/tools/mx

Et domænes MX-poster i den rækkefølge, afsendere prøver dem, med IPv4- og IPv6-adresserne for hver vært. Null MX, et domæne uden MX, værter, der er IP-adresser eller CNAME'er, og værter, der ikke kan slås op, rapporteres, og det samme gør MTA-STS- og TLS-RPT-posterne. Angiv ?domain=example.com.

GET/api/v1/tools/bimi

Et domænes BIMI-opsætning i fire trin: den DMARC-politik, som BIMI kræver, posten på default._bimi, SVG-logoet kontrolleret mod Tiny PS-profilen og mærkecertifikatet med dets type, domæner og udløbsdato. Angiv ?domain=example.com og &selector= for en anden selektor end default.

GET/api/v1/tools/ptr

PTR-posterne for en adresse, og om nogen af disse navne slår tilbage til den. Et opslag, der mislykkedes, giver statussen error; en manglende post giver statussen fail. Angiv ?ip=8.8.8.8.

GET/api/v1/tools/mta-sts

MTA-STS-posten for et domæne og den politikfil, den peger på: tilstanden, de angivne værter og enhver MX-vært, som politikken udelader. Angiv ?domain=example.com.

GET/api/v1/tools/tls-rpt

TLS-RPT-posten for et domæne og de adresser, der modtager dets rapporter. Angiv ?domain=example.com.

GET/api/v1/tools/dnssec

Om zonen for et domæne er signeret, usigneret eller defekt, baseret på dens DNSKEY- og DS-poster. En ugyldig signatur skelnes fra et nedbrud hos resolveren. Angiv ?domain=example.com.

GET/api/v1/tools/dane

TLSA-posterne for MX-værterne sammenlignet med det certifikat, en vært præsenterer, når certifikatet kunne læses. Angiv ?domain=example.com.

GET/api/v1/tools/smtp

STARTTLS og certifikatet på de første to MX-værter: TLS-version, udsteder, udløbsdato, og om kæden og navnet er gyldige. Vi opretter kun forbindelse til værter under det domæne, du forespurgte om, og springer mailudbydere over, og ét resultat pr. adresse deles i 6 timer. Der sendes ingen mail. Angiv ?domain=example.com.

GET/api/v1/tools/ns

Navneserverne for et domæne, og om dets zone har en SOA-post. Én navneserver er en warn. Angiv ?domain=example.com.

GET/api/v1/tools/registration

Hvornår registreringen af et domæne udløber, baseret på RDAP. Under 30 resterende dage er en warn. En zone uden en RDAP-tjeneste svarer skipped. Angiv ?domain=example.com.

POST/api/v1/tools/header

Headerne i en modtaget meddelelse, sendt som JSON {"headers": "..."} eller som text/plain: ruten hop for hop med forsinkelser, TLS og forskydning af uret, modtagerens egne Authentication-Results, justeringen af domænerne i From, DKIM d= og Return-Path samt DKIM-, ARC-, afmeldings- og spamfilterheadere. Alt efter den første tomme linje kasseres ulæst. Headerne behandles i hukommelsen og bliver ikke gemt, cachelagret eller logget.

Tjek domænet hver nat.
Test e-mailen, før den sendes.

Fælles for alle produkter

Adgang, nøgler, rapportformatet, statusser, fejl samt OpenAPI og llms.txt til maskiner.

Godkendelse

Der er ingen. Ingen nøgle at anmode om, ingen header at angive, ingen konto at oprette. Den slug, du får tilbage, er adgangsmuligheden: Den, der har den, kan læse rapporten, og ingen andre kan gætte den.

Det betyder også, at en slug bør behandles som en adgangskode. En rapport viser emnelinjen, afsenderen, returadressen og meddelelsens fulde kilde til enhver, der har linket.

Personlige API-nøgler

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æsning af rapporten

Felterne, der indeholder svaret, i den rækkefølge, du sandsynligvis ønsker dem.

score_ours0 til 100. Vores model. Godkendelse og infrastruktur vægter mest, fordi de afgør leveringen, før et filter læser et eneste ord af teksten.
score_compat0 til 10. Gengiver det SpamAssassin-lignende tal, som folk allerede sammenligner med, så rapporten kan sammenlignes med det, nogen har set et andet sted.
subscoresDen samme skala fra 0 til 100 pr. sektion: auth, infra_spam, content, compliance.
checks[]Alle 42, hver med en status, en konklusion på én linje, det evidensgrundlag, den blev afgjort ud fra, og hvad den kostede på de to scorer.
checks[].citationsHvor resultatet kommer fra: afsnittet i RFC'en, citeret ordret, og siden, hvor Google angiver sit eget krav. Udvalgt manuelt frem for genereret, så der kan stoles på dem.
fixes[]Hvad der skal ændres, i rækkefølge, med det antal point, som hver ændring er værd. Gevinsterne beregnes ved at score rapporten igen, ikke ved et skøn.
completeFalse, når en kontrol ikke kunne køres. Et ukontrolleret punkt er aldrig godkendt, så betragt scoren som optimistisk, indtil værdien er true.
report_urlDen menneskeligt læsbare side. Giv den til en person i stedet for en mur af JSON.

Statusser

En kontrol har én af fem statusser, og forskellen mellem to af dem betyder mere, end det ser ud til.

passKontrollen blev kørt og fandt ingen fejl.
warnVærd at rette. Koster point.
failVil koste dig levering. Koster flere point.
spring overFandt ikke anvendelse. Ingen vedhæftede filer at scanne, ingen HTML-del at vægte. Ikke godkendt.
fejlVi kunne ikke afgøre det. Udeladt fra scoren og markeret i stedet for at blive talt som godkendt.

analysis_status gennemgår received, analyzing, checks_ready, failed. ai_status gennemgår pending, running, ready, fallback, error. Den deterministiske rapport er endelig ved checks_ready; ai_status tilføjer altid kun planen.

Hvad der kan returneres

202Adressen er reserveret, og ingen meddelelse er ankommet. Svarteksten indeholder adressen, udløbstidspunktet og sproget, så en klient, der ikke oprettede reservationen, stadig kan vise den.
404Denne slug findes ikke. Den har aldrig eksisteret, eller reservationen blev glemt.
410Adressen udløb, før en meddelelse ankom.
409Du forsøgte at ændre sproget, efter at meddelelsen allerede var ankommet.
429Grænsen for gratis test for din adresse. Der er lige nu ingen grænse pr. person for denne tjeneste; hvis en sådan grænse nogensinde fastsættes, angiver svarteksten, hvornår den nulstilles.

Fire ting, der er værd at vide

Én meddelelse pr. adresse

Den anden afvises. Din tidligere rapport forbliver intakt, hvilket er formålet.

En time til at bruge den

Adressen udløber; det gør rapporten ikke. Rapportlinks er permanente, så et link, der indsættes i en sag, bliver ved med at virke.

Send fra platformen

Hvis du tester en kampagne fra en personlig konto, måler du denne konto. Næsten alt i afsnittet om autentificering handler om afsendelsesinfrastrukturen, ikke teksten.

Test igen efter rettelse

De forventede forbedringer beregnes én rettelse ad gangen, og de kan ikke kombineres. Den anden rapport er det ærlige tal.

Til maskiner

GET/api/health

Livstegn. Ingen godkendelse, ingen bivirkninger.

Prøv først én manuelt

Det tager cirka et minut og viser dig præcis, hvad JSON beskriver.

Få en testadresse

Sandkasse.

Hvert endpoint har en knap, der kører det mod live-tjenesten. Intet her kræver en nøgle, så en anmodning, du sender fra denne side, er reel: Den reserverer en rigtig adresse, og den tæller med.

Prøv det i sandkassen