# What does resend.email.bounced prove?

> Prove that the recipient mail server rejected the email. Version 1.0.0, certification Community.

Canonical: https://provely.sh/verify/resend/resend.email.bounced  
Last reviewed: 2026-09-05  
Skill version: 0.1.0  
Certification: community  

**Prove that the recipient mail server rejected the email. The bounced level proves the bounced state on the email record and the email.bounced event. Use it when the intent is to confirm a rejection, for example before a suppression.**

*Contract identity.*

| Fact | Value |
| --- | --- |
| Contract id | `resend.email.bounced` |
| Version | `1.0.0` |
| Hash | `56703353a6dbfaf3` |
| Completion level | `bounced` |
| Certification | Community |
| Skill | [Resend 0.1.0](/verify/resend) |
| Valid for provider API versions | `1.5.1` |

## What is the intent?

Confirm that the email bounced.

## What is the subject and the action?

| Member | Value |
| --- | --- |
| Subject type | `resend.email` |
| Subject identity | email_id = `$action.result.id` |
| Canonical effect | `message.send` |
| Provider operation | `POST /emails` |
| Idempotency | idempotency_key through `Idempotency-Key`, retry is safe |

## How does the evidence correlate with this operation?

| Strategy | Assurance | Keys | Required |
| --- | --- | --- | --- |
| `resource_id` | strong | email_id from `$action.result.id` | yes |
| `idempotency_key` | strong | idempotency_key from `$operation.id` | no |
| `fingerprint` | weak | to from `$input.to`; subject from `$input.subject` | no |

## Which evidence does the contract require?

Minimum evidence level `E2`. An independent channel is required. Minimum channels: 1.

| Channel | Level | Independence | Verifier | Description |
| --- | --- | --- | --- | --- |
| `email_readback` | E2 | provider readback | `http` | Read the email record. The http verifier returns the parsed Email object, so a condition path is $observed.email_readback.last_event. |
| `sent_events_by_intent` | E3 | provider event | `webhook` | The email.sent events for the same recipient and subject since the operation started. A count above one shows a second send. The webhook verifier returns {events, count, latest, earliest, types, duplicates_dropped}, so a condition reads the count. |
| `bounced_events` | E3 | provider event | `webhook` | The email.bounced events of this email. The resource id is the data.email_id of the payload. The webhook verifier returns {events, count, latest, earliest, types, duplicates_dropped}, so a condition reads the count. |

## Which conditions must all hold for VERIFIED?

| Condition | Meaning | Path | Operator | Expected | Evidence |
| --- | --- | --- | --- | --- | --- |
| `record_created_in_window` | The provider created the email record after the operation started. | `$observed.email_readback.created_at` | `time_after` | `$operation.created_at` | `email_readback` |
| `readback_shows_bounced` | The record shows the bounced state. | `$observed.email_readback.last_event` | `eq` | `bounced` | `email_readback` |
| `bounce_event_present` | At least one email.bounced event of this email arrived. | `$observed.bounced_events.count` | `gte` | `1` | `bounced_events` |

## Which conditions give CONTRADICTED?

| Condition | Class | Reason | Path | Operator | Expected |
| --- | --- | --- | --- | --- | --- |
| `wrong_recipient` | wrong subject | The message went to a different recipient. | `$observed.email_readback.to` | `ne` | `$input.to` |
| `record_predates_operation` | pre existing state | The provider record is older than the operation. It proves nothing. | `$observed.email_readback.created_at` | `time_before` | `$operation.created_at` |
| `more_than_one_recipient` | partial completion | The record lists more than one recipient. This contract proves the outcome for one recipient. Use one operation per recipient. | `$observed.email_readback.to` | `array_length` | `{"min":2}` |
| `duplicate_email_present` | duplicate side effect | Resend sent more than one email for this recipient and subject since the operation started. Do not retry. | `$observed.sent_events_by_intent.count` | `gt` | `1` |

## Which observed states map to a verdict before completion?

| Rule | Match | Verdict | Reason |
| --- | --- | --- | --- |
| `terminal_failure` | `$observed.email_readback.last_event` in `["failed","suppressed"]` | FAILED | The provider reports that the message failed, bounced, or was suppressed. |
| `still_transitional` | `$observed.email_readback.last_event` in `["queued","scheduled","sent","delivery_delayed"]` | PENDING | The message is on the way. The runtime observes again later. |
| `canceled` | `$observed.email_readback.last_event` eq `"canceled"` | CONTRADICTED | The schedule of the message was canceled. The provider will not send it. |
| `delivered` | `$observed.email_readback.last_event` in `["delivered","opened","clicked","complained"]` | CONTRADICTED | The recipient mail server accepted the message. It did not bounce. |

## How long does the runtime observe?

| Timing member | Value |
| --- | --- |
| Initial delay | 2000 ms |
| Poll interval | 10000 ms |
| Backoff | exponential factor 2, max 120000 ms |
| Maximum attempts | 60 |
| Timeout | 3600000 ms |
| Stale read window | 30000 ms |
| On timeout | UNVERIFIABLE (`evidence_unavailable_before_timeout`) |

## Where do these rules come from?

- `resend.openapi#/paths/~1emails/post`: [resend.openapi](https://raw.githubusercontent.com/resend/resend-openapi/main/resend.yaml), retrieved 2026-09-05
- `resend.openapi#/components/schemas/Email/properties/last_event`: [resend.openapi](https://raw.githubusercontent.com/resend/resend-openapi/main/resend.yaml), retrieved 2026-09-05
- `resend.openapi#/webhooks/email.bounced`: [resend.openapi](https://raw.githubusercontent.com/resend/resend-openapi/main/resend.yaml), retrieved 2026-09-05
- `resend.openapi#/components/schemas/Email/properties/created_at`: [resend.openapi](https://raw.githubusercontent.com/resend/resend-openapi/main/resend.yaml), retrieved 2026-09-05
- `resend.docs.webhooks#webhooks/event-types/p4`: [resend.docs.webhooks](https://resend.com/docs/dashboard/webhooks/introduction), retrieved 2026-09-05
- `resend.openapi#/components/schemas/OutboundEmailEventData/properties/email_id`: [resend.openapi](https://raw.githubusercontent.com/resend/resend-openapi/main/resend.yaml), retrieved 2026-09-05

### Can resend.email.bounced return VERIFIED from the action response alone?

No. The minimum evidence level is E2. The action response is E1. The completion conditions read `email_readback` and `bounced_events`.

### What happens after the timeout?

The verdict is UNVERIFIABLE with the reason `evidence_unavailable_before_timeout`. The operation ends.

## Read next

- [Read the Resend verification page](https://provely.sh/verify/resend)
- [Read the resend.email.accepted contract](https://provely.sh/verify/resend/resend.email.accepted)
- [Read the resend.email.delivered contract](https://provely.sh/verify/resend/resend.email.delivered)
- [Read the resend.email.sent contract](https://provely.sh/verify/resend/resend.email.sent)
- [Read what a completion contract contains](https://provely.sh/contracts)
- [Read what a receipt proves](https://provely.sh/receipts)
