Three spam complaints and your SaaS is in the spam folder

oliviapp.com · 2026-10-04 · by Long Nguyen ·generic
Three months after launch, someone used my invoicing tool to send phishing. Why a small product is the better target, and why its numbers are worse.

Three spam complaints and your SaaS is in the spam folder

8 min read

Three spam complaints and your SaaS is in the spam folder

Three months after launch, someone used my invoicing tool to send phishing. Why a small product is the better target, and why its numbers are worse.

Written by Yevgen Lilik · freelancer, invoices through Olivi

Oct 4, 2026

An inbox tray full of letters, one of them stamped SPAMSPAMINBOX!

On 20 September, three months after launch, someone signed up to Olivi, the invoicing tool I build for freelancers, with a disposable email address. Eight minutes later two emails had gone out through the product: an invoice dressed up as a message from Etsy, with a shortened link in it.

Olivi lets a freelancer email an invoice to a client straight from the app. At that point it took four steps: sign up, confirm the address, add the recipient as a client, press Send. Nothing stood between a brand new account and a stranger's inbox except the confirmation email.

I spent the rest of the day closing that gap. This post is about what I learned while doing it. Mostly two things: a small product is a better target than a big one, and the numbers are much worse than I thought.

They come for your reputation, not your data

Nobody hacked anything. The person signed up like any customer would. What they wanted was not my database but my domain: a young, clean sending domain with SPF, DKIM and DMARC all set up, whose mail lands in the inbox.

Big platforms know this well. In 2020, Brian Krebs wrote about stolen SendGrid accounts being sold to spammers, and the seller put the appeal plainly: SendGrid's servers keep a good reputation with mailbox providers, so the content is “much more likely to get into the inbox”. Two years later the same trick showed up as phishing sent as real PayPal invoices. An invoice from a trusted platform is about the most convincing thing you can put in someone's inbox.

A small invoicing tool is the same thing, just smaller. They came for my deliverability.

The arithmetic

Gmail measures complaints as a share of what you send. Google's sender guidelines ask every sender, not only bulk senders, to keep the spam rate below 0.3%, and recommend staying under 0.1%. Here is what 0.3% means at different sizes:

| Emails a month | Complaints that reach 0.3% | | -------------- | -------------------------- | | 300 | 1 | | 1,000 | 3 | | 3,000 | 9 | | 5,000,000 | 15,000 |

A big sender can absorb thousands of angry clicks. A product that sends a few hundred emails a month has a budget of one to three.

Now picture one bad account on a free plan that allows three emails a day. In a week it sends 21. If five of the people who receive them press “Report spam”, and everyone else on the platform sent another 130 legitimate emails that week, the complaint rate is above 3%. More than ten times the line. One account, one week.

You won't see it coming

Google's Postmaster Tools is where you would normally watch your reputation. It shows nothing until you send enough mail to Gmail every day. Google doesn't publish the threshold; in practice it is hundreds of Gmail recipients a day, and a young product isn't anywhere near it. The dashboard is empty exactly when it would matter most.

What does work at small volume is the complaint webhook from the service that sends your email (Resend, SendGrid, Postmark and so on). It arrives in real time, one event per complaint. At this size, two or three of them in a month are not noise. They are the whole story.

There is one big hole, and I only found it while writing this post: Gmail doesn't send per-message complaints to senders at all. Yahoo, Outlook and most others report each “Report spam” click; Gmail only gives aggregate numbers, in the same Postmaster Tools that stays empty at your volume. So the biggest mailbox provider is the one whose complaints you never see, and any protection that waits for a complaint is blind to it. Limits that work without any complaints matter more than the ones that react to them.

Size protects the big ones. Nothing protects you

A large sender recovers by volume: a million good emails pull the rate back down. A small one has no such lever. And some damage needs no rate at all: one email to a spam trap (an address that exists only to catch senders who shouldn't be writing to it) can be enough to get your domain onto a blocklist.

Recovery takes time even for the big ones. SendGrid's own guide for compromised accounts says the reputation with receiving servers can take up to a month to recover.

There is also an asymmetry nobody mentions. When SendGrid was abused, some organisations started blocking it. But nobody can block a provider that large completely: too much legitimate mail comes through it. Blocking the domain of a small SaaS forever costs nobody anything.

So for a small product that sends email on behalf of its users, reputation doesn't wear out slowly from normal use. One event can tip it over. So abuse prevention and deliverability are the same job, and you find that out the day your own users' invoices start landing in spam because of somebody else's.

What I built

I'm describing the layers, not the exact rules. A filter that publishes its patterns is a filter with instructions for getting around it.

  • Who can send at all. I can block an account from sending with one click, and the block also stops the automatic payment reminders that would otherwise keep going out on their own. It survives the account being deleted and recreated with the same address.
  • How much. The free plan sends three invoice emails a day, paid plans ten an hour. Olivi can also send payment reminders on a user's behalf, automatically; those have their own, separate daily allowance.
  • What an email can contain. The text a user writes can't include links, email addresses or phone numbers, because a lure needs at least one of them to work. The only clickable thing allowed is a “Pay now” button, and it can only lead to a real payment provider such as Stripe, PayPal or Wise. The rule is checked again at the moment the email is sent, not only when the text is typed: anything checked in the browser can be skipped by someone who sends the request by hand.
  • A way out for the recipient. Every email names the person who sent it, says it came through Olivi, and has a “Didn't expect this email? Report it” link. Anything is better than the spam button: a complaint counts against the domain every user shares.
  • Separate addresses, for now on one domain. Invoices go out from one address, Olivi's own mail from another. That tells them apart, but it doesn't protect one from the other: reputation follows the domain, not the address. Moving users' mail to a domain of its own is the next step.
  • What I decided not to build

    This part was harder than the list above, and I think more useful.

  • Disposable email detection. Once a message can't carry a link, an address or a phone number, and a new account can't send much, a throwaway address gives an attacker nothing. Meanwhile the false positives are real: Hide My Email, SimpleLogin, Fastmail aliases. People who use those are exactly the privacy-minded freelancers I want as users.
  • A list of impersonated brands. I sketched about 35 brands, lookalike letters and leetspeak. Without a link, an address or a phone number, an email from “Etsy Support” has nowhere to send its victim. A brand list would mostly catch honest users with unlucky company names.
  • A first-week limit for paying users. After the other checks, volume buys an attacker nothing, and someone who just paid should not hit a wall on day one.

The second one was a harder call

Four days later another account caught my eye. Nothing it did broke a rule. It cleared the sender name, so the email would carry no person behind it, and sent a single test invoice. Not to a client, but to the public inbox of a free deliverability checker, the kind of service that tells you whether a message lands in the inbox or in spam.

A careful developer does exactly this before trusting a new tool with their invoices. So does someone shopping for a platform to send spam from. From the outside you can't tell them apart, and four days after the first incident I wasn't feeling generous. I banned the account.

I'm not sure that was right. If it was an honest person, they got a login error and no explanation. I wouldn't want to be treated like that. What I'd do now is narrower: pause sending only, leave the rest of the account working, and write to them first. People who are testing usually answer. People shopping for a place to send spam rarely do.

The bigger lesson was about attention. Working this out took an hour, and I went through three wrong explanations first. An hour per suspicious account is fine at today's size and impossible at ten sign-ups a day. The layers above have to work while I'm asleep, not only while I'm watching.

If your product sends email for its users

1. You are a target because your domain is clean, not because your product is interesting. 2. Work out your line. Monthly volume times 0.003. It is probably smaller than five. That is your complaint budget. 3. Wire up the complaint webhook before any analytics, and remember that it doesn't hear Gmail. Against Gmail, only limits that work without complaints protect you. 4. Put the decisive check where data leaves your system, not where it is saved. 5. Send your users' mail from a different domain than your own. Separate addresses are not enough: otherwise one bad account can take your sign-up confirmations down with it. 6. Block quietly, not silently. Tell the person their sending is paused and how to reach you. Just don't tell them which rule fired, or the next attempt will go around it.

oliviapp.com · 5 images · 31 links

Comments (0)

No comments yet