Protect your sender reputation with suppressions and events
How account health is measured, what suppression does for you, and how to use bounce and complaint events to keep your own data clean.
Mailbox providers decide whether your email reaches the inbox largely from how recipients react to it. Bounces and spam complaints are the signals they weigh most. iResendly watches both for you and acts on them, but the best results come when your own app listens too.
How account health is measured#
Every hour we look at your last 7 days of sending, once you've sent at least 100 emails in that time. If your rates cross these lines, we warn you, and then pause sending:
| Rate | Warning email | Sending paused |
|---|---|---|
| Bounces | Above 4% | Above 8% |
| Spam complaints | Above 0.08% | Above 0.16% |
While sending is paused, sends return 403 suspended. Contact support to review it and lift the pause. The warning email is your chance to act before that happens, so make sure it reaches someone who'll read it.
What suppression does for you#
- A hard bounce suppresses the address for your account and across iResendly. It bounced once; it would bounce again.
- A spam complaint suppresses the address for your account, and unsubscribes the contact.
- Suppressed recipients are skipped and reported with an
email.suppressedevent. They don't count towards your quota. - If every recipient of an email is suppressed, the email is still created, with status
failed. - Unsubscribes from broadcasts don't block transactional email, so a password reset still reaches someone who opted out of your newsletter.
Listen to the events in your app#
Suppression protects your sending, but your own database still thinks those addresses are fine. Subscribe a webhook to email.bounced, email.complained and email.suppressed, and update your records when they arrive:
// Called after the signature has been verified.
export async function handleEvent(event) {
switch (event.type) {
case "email.bounced":
// Permanent bounce: the address is already suppressed on our side.
for (const address of event.data.bounce.recipients) {
await db.users.update({ email: address }, { emailStatus: "bounced" })
}
break
case "email.complained":
for (const address of event.data.complaint.recipients) {
await db.users.update({ email: address }, { marketingOptIn: false, emailStatus: "complained" })
}
break
case "email.suppressed":
// We skipped a recipient that was suppressed earlier. Check your data is in step.
await log.warn("Suppressed recipient", event.data)
break
case "email.delivery_delayed":
// We keep trying; nothing to do yet.
break
}
}email.bouncedincludesbouncewithtype,subType,messageandrecipients.email.complainedincludescomplaintwithtypeandrecipients.email.delivery_delayedcovers soft bounces too. We keep trying, so there's usually nothing to do.
Good practice that keeps rates low#
- Authenticate your domain. Verify DKIM and add a DMARC record, starting with
v=DMARC1; p=none;, so receivers can tell your mail is really yours. - Only email people who asked. Confirm addresses at sign-up, and never send to bought or scraped lists.
- Send marketing as broadcasts. They add unsubscribe links and List-Unsubscribe headers for you, which gives unhappy readers an easier option than the spam button.
- Keep transactional email clean. Receipts, password resets and alerts are the mail people want most; don't mix promotions into them.
- Use clear, consistent senders. A recognisable from name and address makes people less likely to mark your mail as spam.
Keep an eye on it#
The Metrics page in the console shows delivery, open and click rates over 7 to 90 days, along with sender health, and exports to CSV. Open and click tracking are off by default; turn them on per domain with PATCH /domains/{id} or in the console if you need them. A sudden rise in bounces after a release is often a sign of a bug, such as sending to an empty or malformed address field.