Email Spam Tester

API:et

Tre anrop. Ingen nyckel, inget konto, ingen registrering.

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 41 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.

Prova i sandlådan → 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.

Flödet

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.

  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.

  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.

# 1. reserve a single-use address
curl -sX POST 'https://email-spam-tester.com/api/v1/inbox?lang=en'

{
  "address": "test-<slug>@t.email-spam-tester.com",
  "slug": "<slug>",
  "expires_at": "2026-01-01T12:00:00Z"
}
# 2. send your message to that address, then poll
curl -s 'https://email-spam-tester.com/api/v1/tests/<slug>/status'

{
  "slug": "<slug>",
  "analysis_status": "checks_ready",
  "ai_status": "running",
  "checks_done": 39,
  "checks_total": 39
}
# 3. read the report once analysis_status is checks_ready
curl -s 'https://email-spam-tester.com/api/v1/tests/<slug>'

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

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.

Ä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.

GET/api/health

Tillgänglighetskontroll. Ingen autentisering, inga sidoeffekter.

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 41, 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

Prova en manuellt först

Det tar ungefär en minut och visar exakt vad JSON beskriver.

Hämta en testadress