Skip to main content
Lettr doesn’t score, filter or quarantine inbound mail. Every message accepted for your inbound domain is posted to your forwarding URL, spam included. There is no spam score in the payload and no spam setting in the dashboard. If you want spam handling, you build it into the handler behind your forwarding URL. This page shows common techniques for doing that with the fields you actually receive.
Answer each request with a 2xx, including for messages you decide to drop. The mail has already been accepted by the time it reaches your endpoint, so an error response can’t reject it back to the sender. It only makes the delivery to your endpoint look failed.

What You Have to Work With

Your forwarding URL receives a JSON array of events. Each event carries one message in event.msys.relay_message (see Email Parsing for the full payload). The fields that matter for spam handling are: Both sender fields are set by whoever sent the message, so treat them as claims, not proof of identity. Headers come as an array like [{ "Received": "..." }, { "Subject": "..." }], and a name can appear more than once. A small helper makes them easier to read:

Check Authentication Results

Some messages carry an Authentication-Results or Received-SPF header, added by a mail server that checked SPF, DKIM or DMARC along the way. Don’t assume these headers are present, and remember that a sender can put a fake one in their own message. Use them as one signal among several, never as the only check.

Build Your Own Heuristics

A simple approach is to add up points for suspicious signals and act on the total. The point scale below belongs to this example code. It isn’t a Lettr score, so tune the weights and thresholds to your own traffic.
If you’d rather not write your own rules, your handler can pass the raw message in content.email_rfc822 to a third-party spam filter. When content.email_rfc822_is_base64 is true, base64-decode it first.

Allow and Block Lists

Keep your own lists of trusted and blocked senders, for example in your database, and check them before any other rule:
Because a sender address can be forged, an allowlist entry is safest when the message also shows a passing authentication result for that sender.

Rate Limiting by Sender

Limit how many messages one sender or sender domain can push through your pipeline:
RateLimiterMemory counts per process. If you run more than one instance of your handler, use a shared store such as Redis.

Quarantine in Your Own Storage

Lettr doesn’t keep inbound messages, so a quarantine has to live in your own storage. Key each record on the Message-ID header, which also lets you ignore a message that arrives twice:
Decide how long to keep quarantined messages and delete them on your own schedule.

Learning From Reports

When spam gets through, let your users report it and add the sender to your blocklist:

Best Practices

Start by quarantining suspicious mail instead of discarding it. Once you know your false positive rate, you can drop the clearest cases.
Record why each message was allowed, quarantined or dropped. Lettr doesn’t keep a copy of inbound mail, so your logs are the only way to trace a missing email.
No single check is reliable on its own. Combine allow and block lists, authentication results when present, rate limits and content rules.
Answer the request quickly and run expensive checks, such as a third-party filter, from a queue.
Release false positives promptly and use them to tune your rules.
Be careful with aggressive filtering. False positives can make you miss important emails from customers or partners.

Email Parsing

The full inbound payload

Routing

Route emails in your handler

Security

Security best practices

Best Practices

Overall inbound best practices