Skip to content

Questions · Published 2026-09-23 · Updated 2026-09-28 · AgentiSend

Why did my email bounce?

An email bounced when the receiving server refused it. GET /emails/{id}/explain returns verdict bounce, and the email.bounced event from GET /emails/{id}/events carries the diagnostic the server sent.

An email bounced when the receiving server refused it. GET /emails/{id}/explain returns verdict bounce, and its evidence carries the receiver's words (response), the SMTP code (smtp_code), the class (bounce_class) and whether the address is now on the suppression list (suppressed, with suppression_id). A dead address says "The receiving server refused this address permanently: it does not exist or no longer takes mail." A temporary refusal says "The receiving server refused this message for now: a full mailbox, greylisting or a brief outage. The address itself is fine." GET /emails/{id}/events has the email.bounced event with the same fields.

The four classes

Every bounce lands in one class. The meaning and the fix are on the docs page, and the Deliverability screen links to the same ids:

  • hard — the receiving server says the address does not exist.
  • soft — a temporary refusal, such as a full mailbox or greylisting.
  • block — refused on reputation or content, not on the address.
  • policy — the address is real, and this message was refused for size, an attachment, or the suppression list.

Deliverability states that hard bounces and complaints add the recipient to the suppression list. GET /suppressions lists the address and why. A later POST /emails to a suppressed address is refused with suppressed_recipient.

curl -sS -X GET https://api.agentisend.com/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/explain \
  -H "Authorization: Bearer $AGENTISEND_API_KEY"
200
{
  "actions": [],
  "evidence": {},
  "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42",
  "retryable": false,
  "status": "example",
  "verdict": "example",
  "what_happened": "example"
}
Response

What to change

Read evidence.response before changing anything else. GET /emails/{id}/explain sets retryable to true only for a temporary refusal; a dead address, a block and a policy refusal are all false, because the same message would be refused the same way. A retry is a new send with a new Idempotency-Key: the key the first send used replays its first answer and sends nothing. The class fixes are the ones on /docs: a hard bounce is already on the suppression list, a soft bounce can be sent again later, a block is the class that ends in a blocklist, and a policy bounce is the message — shrink it, drop the attachment, or inspect GET /suppressions when the reason is suppression. A bounce from bounced@simulator.agentisend.com is simulated and suppresses nothing; Test addresses lists what each simulator address does.

No sentence here is an inbox-placement rate.

Next