Email Spam Tester

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

  1. 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"
    }
  2. 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.com
  3. Avfrå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.

langSprå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_campaignSkickas 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.

Polla detta i stället för rapporten. analysis_status når checks_ready först, och AI-planen hamnar under ai_status ungefär en minut senare, så en anropare som bara vill ha de deterministiska kontrollerna behöver inte vänta på planen.

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.

Råmeddelandet raderas enligt en egen tidsgräns, tidigare än rapporten. Därefter svarar denna slutpunkt med orsaken i stället för källan.

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

  1. 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"}
        ]
      }
    }
  2. 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>, ...
  3. 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

  1. 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'
  2. 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"}
        ]
      }
    }
  3. 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)'
domainObligatorisk. Tar det som verktygen tar: en domän, en URL, en e-postadress.
ipDin avsändaradress. Upprepa den för fler, upp till 6.
selectorEn DKIM-selektor. Upprepa den för fler, upp till 10. Varje selektor du anger måste finnas, annars misslyckas DKIM-avsnittet.
heloNamnet som din server anger i HELO, jämfört med dess PTR.
accountVem begäran gäller. Obligatorisk med en nyckel som betjänar många personer.
checksAvsnitt som ska köras, kommaseparerade. Alla som standard.
difftrue jämför den här körningen med din senaste körning av domänen.
since7d, 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.
baselineId:t för en av dina körningar att jämföra med. Aktiverar diff.
freshtrue 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

  1. 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'
  2. 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

Alla svarar med 200 och en status samt en lista över resultat, vart och ett med en kod och dess parametrar. Statusen är pass, warn, fail eller error, och ett verktyg som delas med infrastrukturkontrollen kan även svara unknown eller skipped. En uppslagning som nådde tidsgränsen eller en lista som avvisade frågan räknas aldrig som pass. 30 förfrågningar per minut och 300 per dag per IP för samtliga verktyg; över detta är svaret 429 med Retry-After.

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.

Det innebär också att en slug bör behandlas som ett lösenord. En rapport visar ämnesraden, avsändaren, returadressen och meddelandets fullständiga källkod för alla som har länken.

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_ours0 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_compat0 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.
subscoresSamma 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[].citationsVar 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.
completeFalse 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_urlDen 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.

passKontrollen kördes och hittade inget fel.
warnVärt att åtgärda. Kostar poäng.
failKommer att kosta dig leveranser. Kostar fler poäng.
hoppa överVar inte tillämpligt. Inga bilagor att skanna, ingen HTML-del att väga in. Inte godkänt.
felVi 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

202Adressen ä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.
404Ingen sådan slug. Den har aldrig funnits eller så har reservationen glömts bort.
410Adressen löpte ut innan ett meddelande anlände.
409Du försökte ändra språket efter att meddelandet redan hade anlänt.
429Grä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

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 testadress

Sandlå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