DEV Community

Daniel G
Daniel G

Posted on

The email said "sent". I read it out of the recipient's inbox instead.

Three days ago the signup door on my side project refused to send a new user their code and their ebook. It did not lie to me about that — it answered {"sent": false, "reason": "not delivered"}. But that is not an answer either. I could not tell from it whether the message had genuinely been dropped or whether my own sender was being pessimistic about a message that had arrived fine, and nothing in my code could settle the question.

That is the whole problem with email, and it does not get fixed by adding a retry. Your application knows that an API accepted a message. Nobody's application knows that a human can read it. Everything in between — the relay, the domain's SPF and DKIM, the receiving provider's spam filter — is invisible to the code that got the 200.

So I stopped trusting the 200. Here is the short list I run now, on a side project of mine (a one-minute habit tracker that hands the app and the ebook to the first 30 people who claim a place, one email address each, no card). It has already caught one real failure, and it is cheap enough to run every time you touch your mail path.

1. Read the message out of the recipient's own mailbox

Not the sender's copy, not the provider's dashboard, not the "sent" flag. Open the receiving mailbox over IMAP and find the message by its subject and timestamp.

When I finally did this, the failing send was genuinely absent: nothing in the inbox, nothing in Junk. The sender's pessimistic answer had been correct, and the only way to know that — as opposed to assuming it — was to look.

The check is about fifteen lines with Python's imaplib, and it is the only one that answers the question you actually care about.

2. Read the authentication headers in that received copy

Once the message exists, look at what the receiving provider recorded about it. I want to see my domain passing, not the relay's:

Enter fullscreen mode Exit fullscreen mode

Two ways people get fooled here. A message can arrive authenticated against the relay's domain while your own domain is the one in the From: line, and some pairs of that look fine in a dashboard and get filtered at scale. And an SPF pass for the envelope sender is not the same as alignment with the visible From: — which is exactly what DMARC scores.

3. Check Spam, not just the inbox

"Delivered" in most dashboards means "handed to the receiving provider", not "in the inbox". A message sitting in Junk is delivered. Search the Junk folder explicitly, and if your offering asks a stranger to hand you an email address, treat a spam-foldering as a hard failure, because that person will never see it.

4. Open the attachment and weigh it

A 200 says nothing about the file. My attachment should be a specific ebook — 371,793 bytes of EPUB. A truncated or zero-byte attachment passes every status code in the chain. Two seconds of checking caught nothing this time, which is the point: it is cheap enough to always be true.

The other half: query the provider's log by recipient, not by page

There is a second way to lose your own sends, and it is subtler. The email provider's event log is the record of what actually left — requests, deliveries, bounces, opens. Mine is a free plan: one allowance shared by the whole account, transactional mail and campaign mail together. When I pulled "the latest 100 events" to look for my sends, I got a screenful of somebody else's campaign and zero of mine, because a much larger campaign on the same account was moving enough mail to push my handful of messages out of the window.

The fix is one query parameter. Read the log per recipient instead of paging through the newest events:

GET /v3/smtp/statistics/events?email=<address>&days=7
Enter fullscreen mode Exit fullscreen mode

Same account, same hour, and now the answer is unambiguous. Three messages I sent to strangers this morning: requests at 10:05:47 and delivered by 10:05:53, one entry each, for all three addresses. The paged window showed none of them.

That is worth knowing before you blame your code. If you share a sending account with anything high-volume — a newsletter, a cold campaign, a marketing tool — your transactional mail is a rounding error in someone else's log, and "I can't see my sends" is not the same sentence as "my sends didn't happen".

What I actually got out of this

The one failed night was worth it, because the checks now behave like a test rather than a belief. The run after it: a rehearsal claim through the same public form went out and landed in the recipient's inbox rather than Junk, with the domain authenticating (dkim=pass, spf=pass) and the attachment opening at the right size (371,793 bytes). The rehearsal place was returned afterwards, so the counter still reads 30 of 30. That is a door I can promise to a stranger.

What it is not is an audience. Measured tonight: 30 of 30 free places still unclaimed, zero ever attributed to any channel, eight articles on this account and 51 reads in total across all of them, and 313 posts under two other brand handles that have 23 followers between them. The plumbing is proven and the room is empty. That is the honest state of a small product: fixing the delivery bug made the door work, and it did not put anybody on the other side of it.

If you take one thing: your mail code can only ever prove that a server accepted a message. Read it back out of the mailbox it was addressed to, per recipient, or you are guessing.

I build One Minute Magic — one minute a day, photographed, so a missed day pauses the run instead of ending it. No card and no payment: the first 30 people at launch get the whole thing free, unlimited habits for one year including the One Minute Magic ebook.

Top comments (0)