Why We Are Moving Our Transactional Email to AgentiSend
A decision record, not a results post. We send 24 kinds of notification email, some of them triggered by detectors rather than people. Here is why we are moving that mail, and what we will watch.
This is a decision record, not a results post. The move has not happened yet, and no part of it has started. We are writing it now because the reasoning is the useful part, and because we would rather publish the plan and be held to it than publish the outcome and be believed on trust.
Key takeaways
- We send 24 kinds of notification email, split across sign-in, lifecycle, operational alerts and team invites. One of them, the sign-in code, locks people out of the product if it is late.
- Some of that mail is now triggered by detectors, not by people. A detector that starts re-firing sends the same message to the same person again and again, and the only thing between it and a customer inbox is code we wrote ourselves.
- We are moving for the controls, not the delivery. A separate key and a spending ceiling per kind of mail, repeat-send detection we do not maintain, and a stop switch we can reach without shipping code.
- AgentiSend is built by the same team as WarmySender. We are not a neutral witness, and it has not sent customer mail yet, so we are going first because it is ours.
- Nothing has moved. Every step below is planned. We will publish what actually happened once it has.
What we actually send
WarmySender runs cold emailing, email warmup, LinkedIn outreach and multichannel campaigns for other people. Our own outbound mail is small, boring and load-bearing: 24 notification emails in total. They fall into four groups.
- Sign-in. The sign-in link and the sign-in code. If this mail is late, a customer cannot get into the product at all. Nothing else we send has that property.
- Lifecycle. Welcome, the day-two onboarding note, trial started, trial ending soon, trial expired, subscription activated, cancelled, ended, account downgraded, payment failed, and the win-back note.
- Operational alerts. Mailbox health alerts, campaign bounce cooldown notices, campaign error digests, the daily digest, and the LinkedIn health summaries.
- Team. Workspace invites.
Every one of them carries a one-click unsubscribe header and a signed opt-out link, because we built that before we needed it.
What actually drove the decision
Two things, and neither of them is an incident. We have nothing to report against the way we send today.
The first is that our mail is now partly sent by software that decides for itself when to send. The campaign error digest, the bounce cooldown notice and the mailbox health alert are not triggered by a person clicking a button. They are triggered by detectors. A detector that starts re-firing sends the same message to the same person repeatedly, and the only thing standing between a misbehaving detector and a customer inbox is code we wrote ourselves.
We already learned this on the operator side, where chronic detectors fired the same alert over and over. We fixed it inside our own application: alerts now fold into one open row per workspace, per type, per key, with a counter for how many times the condition recurred. That fix lives in our code. It does not live in the sending layer, which will happily deliver whatever we hand it.
The second is that the sending layer has no idea which of our 24 senders it is carrying. A sign-in code and a win-back note are the same request with the same key. If something goes wrong with the win-back job at two in the morning, the blast radius includes sign-in.
The decision
We are moving to AgentiSend, and we are moving because of the controls rather than the delivery. The parts we want are these.
A key per kind of mail, with a budget on the key. A key that can send and do nothing else, with a ceiling per period and a rate ceiling per minute. Lifecycle mail gets a budget. Sign-in mail gets its own key and is never the thing that hits a ceiling set by a marketing job.
Repeat-send detection that is not ours to maintain. Near-identical sends inside a short window stop being delivered and are held for a person to approve, and the refusal names the step that resolves it. That is the fold-and-count discipline we wrote by hand, moved down a layer, where it protects mail we have not thought about yet.
A stop switch we can reach without shipping code. One call halts every key on the account. Today, stopping our own outbound mail in a hurry means a deploy or a settings change.
Published enforcement numbers. The thresholds are on a public page: a warning at 2% bounces and 0.05% complaints, an automatic pause at 4% and 0.08%, measured over a rolling seven-day window, with no automatic step until that window holds at least 100 delivered or bounced sends. We sell deliverability. We are not going to run our own mail on lines we cannot read.
Refusals that name the fix. Every refusal carries a plain description and the action that clears it. A fair amount of our integration work, everywhere we have sent from, has been translating a terse failure into something a person can act on.
The honest negative
AgentiSend is built by the same team as WarmySender, so we are not a neutral witness and there is no point pretending otherwise. It is live and has no customers yet: real sending is still switched off while its sending addresses are warmed, which is the same process we run for our own customers and it takes weeks, not days. Until that finishes, nothing of ours has moved, and this post describes a plan.
We would not recommend that anyone migrate transactional mail onto a sending path that has not sent yet. We are going first because it is ours.
The migration, in the order we will do it
None of this has started. When it does, the dates will go in this section.
- Verify the sending domain and publish the authentication records, then confirm the bounce-handling record so returned mail lands on our own subdomain rather than a shared one.
- Create one key per kind of mail, each able to send and nothing else, each with a budget and a rate ceiling.
- Move the least important mail first. The win-back note and the day-two onboarding note. If they break, nobody is locked out.
- Move the operational alerts, because they are the ones with detectors behind them, and they are the reason we want the repeat-send guard.
- Move lifecycle, in one batch, with the previous path still configured and one setting away.
- Move sign-in last, keeping a fallback path live for a full billing cycle.
- Point delivery reporting at the same receiver we use now, and reconcile delivered, bounced and complained counts against our own records for two weeks before we retire the old path.
What we will watch afterwards
Two lines, the same two we publish to our own customers: bounce rate and complaint rate over a rolling seven-day window, against 2% and 0.05% for a warning and 4% and 0.08% for an automatic pause, with the 100-send floor so a tiny sample cannot trip anything. Our standing is readable on demand with the reason attached, so our operational dashboard reads the same number the enforcement ladder reads. There is no version of this where we find out from a support ticket.
We will also watch the thing we cannot get from our current setup: how many sends the repeat-send guard refuses. If that number is ever above zero, we have a detector to fix, and we would rather learn it from a held message than from a customer.
If you want the technical side, the budget, repeat-send and stop-switch behaviour is written up at email for AI agents, and the product is at agentisend.com.