MailFlatDocs
Documentation/Common test cases/Spam score

Checking the spam score of a message

Every incoming message is run through SpamAssassin, so a test can assert that your mail lands under the threshold instead of finding out from an angry customer.

How it works

Delivery is not the same thing as arrival. A message can reach the inbox and still be filtered on the other side, and the reason is usually a missing signature or a rule you have never heard of. Each message carries a spam object with the score, the threshold it was judged against, and every rule that fired with its own weight — so a failing test can say which rule cost you the points. Nothing is blocked or hidden here: the score is information attached to a message that was delivered normally.

Assert the message is under the threshold

This is the assertion worth having in CI: your own mail should stay comfortably clean, and a regression in your SPF or DKIM setup shows up as a rising number.
msg = inbox.wait_for_message(timeout=30)
spam = msg.raw["spam"]
assert spam["is_spam"] is False
assert spam["score"] < 3.0

Find out which rule cost you the points

Every rule that fired comes back with its own weight, and negative weights are the ones working in your favour. SPF_PASS or DKIM_VALID pulling the score down is the sign your sending setup is doing its job.
for rule in sorted(msg.raw["spam"]["rules"], key=lambda r: -r["score"]):
print(rule["score"], rule["name"], rule["description"])
# 1.8 HTML_IMAGE_ONLY_28 BODY: HTML: images with 1600-2800 bytes of words
# -0.1 DKIM_VALID Message has at least one valid DKIM signature

When the field is null

A null spam object means the message was never scanned — not that it came back clean. Messages that arrived before scanning was switched on, or while the scanner was unreachable, look like this. A score of 0.0 is a real result; null is the absence of one.
curl
curl -s "$MAILFLAT_API/inboxes/$ADDRESS/latest" \
-H "X-API-Key: $MAILFLAT_API_KEY" | jq '.email.spam'
# null ← not scanned. Treat it as "unknown", never as "clean".

Worth knowing

The score stays readable on encrypted inboxes
Subject and body are sealed on an end-to-end encrypted inbox, but the spam score and rule names are not: rule names carry no message content, and hiding the score would leave an encrypted inbox with no way to answer why mail was filtered. It sits at the same level as the sender address.