Headers & Spam¶
3 endpoints for email header forensics, content-based spam scoring, and form submission spam detection.
| Method | Endpoint | Purpose |
|---|---|---|
POST |
/v1/email/headers |
Parse raw email headers — hops, SPF/DKIM/DMARC, spoofing risk |
POST |
/v1/email/spam-score |
Score email subject + body for spam signals (0–10) |
POST |
/v1/email/form-spam-score |
Score a contact form submission for bot/spam likelihood (0–1) |
Python SDK Examples¶
Parse raw email headers¶
parse_headers extracts the full routing chain, authentication results (SPF, DKIM, DMARC), originating IP, and an overall spoofing risk assessment.
from toolkitapi import Email
# Paste the full raw header block from an email client (View Source / Show Original)
raw_headers = """Received: from mail.attacker.example (203.0.113.42)
by mx.toolkitapi.io with ESMTP; Mon, 21 Apr 2026 10:00:00 +0000
Authentication-Results: mx.toolkitapi.io;
spf=fail (sender IP is 203.0.113.42) smtp.mailfrom=legit-bank.com;
dkim=fail header.d=legit-bank.com;
dmarc=fail action=none header.from=legit-bank.com
From: "Legit Bank Security" <[email protected]>
To: [email protected]
Subject: Urgent: Verify your account
Date: Mon, 21 Apr 2026 10:00:00 +0000
Message-ID: <[email protected]>
Return-Path: <[email protected]>"""
with Email(api_key="tk_...") as email:
result = email.parse_headers(raw_headers)
print(f"From: {result['from_address']}")
print(f"Return-Path: {result['return_path']}")
print(f"Originating IP: {result['originating_ip']}")
print(f"Spoofing risk: {result['spoofing_risk']}")
print(f"Received hops: {len(result['received_hops'])}")
for auth in result["auth_results"]:
print(f" {auth['method']:6} = {auth['result']}")
Output:
From: "Legit Bank Security" <[email protected]>
Return-Path: <[email protected]>
Originating IP: 203.0.113.42
Spoofing risk: high
Received hops: 1
SPF = fail
DKIM = fail
DMARC = fail
Check authentication alignment¶
from toolkitapi import Email
def check_auth_alignment(raw_headers: str) -> dict:
"""Return a summary of SPF, DKIM, and DMARC pass/fail status."""
with Email(api_key="tk_...") as email:
result = email.parse_headers(raw_headers)
auth_map = {r["method"]: r["result"] for r in result["auth_results"]}
return {
"spf": auth_map.get("SPF", "missing"),
"dkim": auth_map.get("DKIM", "missing"),
"dmarc": auth_map.get("DMARC", "missing"),
"risk": result["spoofing_risk"],
"hops": len(result["received_hops"]),
}
Score email content for spam¶
spam_score runs heuristic rules over the subject line and body, returning a score from 0 (clean) to 10 (very spammy) with the triggered rules listed.
from toolkitapi import Email
emails_to_score = [
{
"subject": "Invoice #1042 from Acme Corp",
"body": "Please find attached your invoice for services rendered in March 2026.",
},
{
"subject": "CONGRATULATIONS!!! You have WON $1,000,000 FREE MONEY!!!",
"body": "Click here NOW to claim your PRIZE. Act now! Limited time offer! Buy now!",
},
]
with Email(api_key="tk_...") as email:
for msg in emails_to_score:
result = email.spam_score(subject=msg["subject"], body=msg["body"])
print(f"Subject: {msg['subject'][:50]}")
print(f" Score: {result['score']}/10 — {result['verdict'].upper()}")
for rule in result["triggered_rules"]:
print(f" ✗ {rule}")
print()
Output:
Subject: Invoice #1042 from Acme Corp
Score: 0/10 — HAM
Subject: CONGRATULATIONS!!! You have WON $1,000,000 FREE...
Score: 8.5/10 — SPAM
✗ subject_all_caps_words
✗ subject_excessive_punctuation
✗ body_spam_phrases: click here, act now, limited time, buy now, free money
✗ body_excessive_caps
✗ body_excessive_punctuation
Pre-flight check before sending a marketing email¶
from toolkitapi import Email
def is_safe_to_send(subject: str, body: str, threshold: float = 4.0) -> bool:
"""Return True if the email is unlikely to be flagged as spam."""
with Email(api_key="tk_...") as email:
result = email.spam_score(subject=subject, body=body)
if result["score"] >= threshold:
print(f"Spam score {result['score']}/10 — review before sending:")
for rule in result["triggered_rules"]:
print(f" - {rule}")
return False
return True
Score a contact form submission¶
form-spam-score applies heuristic rules to form fields and returns a probability between 0 (ham) and 1 (spam), together with the signals that triggered the score.
The SDK does not currently include a form_spam_score method — call the endpoint directly:
import httpx
def score_form_submission(
name: str,
email: str,
body: str,
*,
honeypot: str = "",
elapsed_seconds: float | None = None,
api_key: str,
) -> dict:
"""Score a contact form submission and return the spam analysis."""
payload = {
"name": name,
"email": email,
"body": body,
"honeypot": honeypot,
"elapsed_seconds": elapsed_seconds,
}
response = httpx.post(
"https://email.toolkitapi.io/v1/email/form-spam-score",
json=payload,
headers={"X-API-Key": api_key},
timeout=10,
)
response.raise_for_status()
return response.json()
Integrate form spam scoring into a contact endpoint¶
import httpx
from fastapi import HTTPException
SPAM_THRESHOLD = 0.65
async def handle_contact_form(
name: str,
email: str,
message: str,
honeypot: str, # Hidden field — bots fill it, humans don't
elapsed_seconds: float,
api_key: str,
) -> None:
"""Submit form only if the spam score is below the threshold."""
result = score_form_submission(
name=name,
email=email,
body=message,
honeypot=honeypot,
elapsed_seconds=elapsed_seconds,
api_key=api_key,
)
if result["score"] >= SPAM_THRESHOLD:
signals = [s["rule"] for s in result["signals"]]
raise HTTPException(
status_code=422,
detail=f"Submission flagged as spam: {', '.join(signals)}",
)
# ... proceed with saving/emailing the submission
Response Fields¶
headers response:
| Field | Type | Description |
|---|---|---|
subject |
string | null | Email subject |
from_address |
string | null | From header value |
to_address |
string | null | To header value |
date |
string | null | Date header value |
message_id |
string | null | Message-ID header |
return_path |
string | null | Return-Path header |
received_hops |
list | Routing hops with from_host, by_host, protocol, timestamp |
auth_results |
list | {method, result, detail} for each of SPF, DKIM, DMARC, ARC |
originating_ip |
string | null | First non-internal IP in the routing chain |
spoofing_risk |
string | low, medium, or high |
header_count |
int | Total number of headers found |
spam-score response:
| Field | Type | Description |
|---|---|---|
score |
float | 0–10 spam score |
verdict |
string | ham, suspicious, or spam |
triggered_rules |
list | Rule names that contributed to the score |
rule_count |
int | Number of triggered rules |
form-spam-score response:
| Field | Type | Description |
|---|---|---|
score |
float | 0–1 spam probability |
verdict |
string | ham, suspicious, or spam |
total_weight |
float | Sum of signal weights before normalisation |
signals |
list | {rule, description, weight} for each triggered signal |
form-spam-score signal rules:
| Rule | Description |
|---|---|
honeypot_filled |
Hidden field was filled (bot indicator) |
fast_submit |
Form submitted in under 3 seconds |
spam_phrases |
Body contains known spam trigger phrases |
excessive_urls |
Body contains 3 or more URLs |
email_mismatch |
Body contains different email addresses than submitter's |
excessive_caps |
Body has 4+ ALL-CAPS words |
excessive_punctuation |
Body contains !!! or ??? |
very_short_body |
Body is under 10 characters |
url_in_name |
Name field contains a URL |
high_non_ascii |
More than 50% of body is non-ASCII characters |
Tip
For contact forms, always include a honeypot field — a hidden input that real users never fill but bots do. Pass its value to form-spam-score via the honeypot field. A filled honeypot alone contributes a weight of 5.0, which typically pushes the score above the spam threshold without any other signals.