Guides

Addresses we do not send to

Why an address is refused before sending, not_sent_reason, and cleaning your list.

Mailyte refuses to send to some addresses: ones we already know do not exist, misspelt domains like gmail.con, addresses on your own suppression list, and throwaway addresses for marketing. Nothing is sent, so these never bounce and never count against your sending. But your app is told every time, and it should stop trying.

If your app keeps a list of users and emails all of them, the same dead addresses come back every day. This guide shows how to find them and clean them out.

What your app sees

Over SMTP, the refusal comes back straight away, before any message is accepted:

550 5.1.1 <ada@gmail.com>: Recipient address rejected: Recipient address <ada@gmail.com> does not exist (checked before sending). Nothing was sent to it.
550 5.1.2 <ada@gmail.con>: Recipient address rejected: Recipient domain looks misspelt (did you mean gmail.com?)

Most SMTP libraries raise this as an error naming the recipient. Treat a 550 on one recipient as "remove or fix this address", not as "retry later".

Over the API, POST /api/v1/messages answers 422 and names the address.

Either way, an email.rejected (SMTP) or email.dropped (API) webhook arrives with a not_sent_reason field, so you can handle it in one place:

{
  "id": "01JBT8XQ2M9WYC3K4F6R7S8T9V",
  "event": "email.rejected",
  "created_at": "2026-10-02T18:40:11.000000Z",
  "data": { "recipient": "ada@gmail.con", "detail": "550 5.1.2 ... looks misspelt (did you mean gmail.com?)" },
  "recipient": "ada@gmail.con",
  "not_sent_reason": "misspelt_domain",
  "suggested_domain": "gmail.com",
  "log_level": "warn"
}

not_sent_reason and suggested_domain sit at the top level, beside data, like the other fields described in Receiving webhooks.

The reasons

not_sent_reason What it means What to do
does_not_exist The mailbox does not exist. Remove the address, or ask the person for a new one.
dead_domain The domain cannot receive email at all. Remove the address.
misspelt_domain A typo of a big provider, like gmail.con. suggested_domain says the likely fix. Ask the person to confirm their email. Do not change it for them.
disposable A throwaway address (marketing only). Stop sending marketing to it.
suppressed It is on your suppression list. Nothing, unless you meant to remove it from the list.
not_a_contact / not_checked A marketing key sends only to checked contacts. Add them as a contact first. See Checking contacts added through the API.
inbox_full Their inbox is full (marketing). We try again later. Nothing.

The field is absent on every other event, so if (event.not_sent_reason) is the whole test.

Clean your list automatically

// Your webhook handler
if (event.not_sent_reason === 'does_not_exist' || event.not_sent_reason === 'dead_domain') {
  await users.markEmailInvalid(event.recipient); // stop emailing them, ask them to update it
}
if (event.not_sent_reason === 'misspelt_domain') {
  await users.askToConfirmEmail(event.recipient, event.suggested_domain);
}

Stop it at the door

The cheapest fix is never saving a bad address. Check an address at signup catches a typo while the person is still on the page.

The weekly list

Every Monday, the account owner gets an email listing the addresses your app tried that do not work, with all of them in a CSV. In the dashboard, Email Activity › Not sent (we stopped it) shows the same mail as it happens.