# Delivery and retries

Understand job states, idempotency, and billing usage.

## Job lifecycle

`queued`

Waiting for its first attempt or an automatic retry.

`processing`

Sendy is attempting to send the message.

`accepted`

The sending provider accepted the message. This does not confirm inbox delivery.

`failed`

Sending stopped after a permanent failure or exhausted attempts.

Temporary provider failures return the job to the queue with increasing delays. Permanent failures or an exhausted attempt limit end the job. Completed jobs remain available for status lookup.

## HTTP idempotency

Every HTTP send request requires an `Idempotency-Key` header. Reuse it when retrying the same email:

Same key, same message

Returns the existing job and its current status. Replaying a failed job does not queue another attempt.

Same key, different message

Returns HTTP `409`.

Request timeout or server error

Retry the unchanged request with the same key. Use a new key only for a separate email.

Scope

Your account. Switching API keys within that account does not change the scope.

## SMTP idempotency

SMTP supports an optional email header. Add it to the message and reuse its value for retries:

Email header

```
Sendy-Idempotency-Key: welcome/user-123
```

A matching retry returns `250` with the original job IDs, without creating jobs, reserving credits again, or restarting a failed job. Without the header, resubmitting after a lost response can create duplicate jobs. Reusing a key for different content or recipients returns `554 5.5.0`.

SMTP keys are scoped to your account across its API keys, separately from HTTP keys. Preserve the envelope sender, recipient set, and composed MIME message when retrying. See [SMTP idempotency requirements](https://usesendy.com/docs/smtp#smtp-idempotency-heading) for key limits and the headers excluded from matching.

HTTP and SMTP idempotency prevent duplicate job creation. If a sending attempt succeeds but its confirmation is lost, a retry can still deliver the message again. Idempotency does not guarantee exactly-once delivery.

## Acceptance and usage

Sendy reserves one available credit per job when it enters the queue. SMTP creates one job per distinct envelope recipient and reserves the credits together. If there are not enough available credits, Sendy rejects the submission without creating jobs.

Provider acceptance finalizes the charge and counts once toward billing usage. Retries add no extra units. A terminal failure before provider acceptance releases the reservation; a bounce after acceptance does not return the credit. Matching idempotent retries do not create another reservation or charge.

An HTTP `202` or SMTP `250` confirms that Sendy queued the message. The job’s `accepted` status confirms provider acceptance. Neither confirms inbox delivery. The `delivery_status` field records later delivery events. A `delivered` event confirms receiving-server acceptance, but does not guarantee inbox placement. Delivery updates do not consume additional email credits.

## Bounces and suppressed recipients

A hard bounce means the receiving server permanently rejected delivery. A spam complaint means the recipient reported your email as spam. Both outcomes automatically block future sends to the address for your account. Temporary bounces do not permanently block the address.

Open [Suppressed recipients](https://usesendy.com/suppressions) to review the suppression list. An address can remain blocked even if it is absent from this page or removed from the list. If sends still fail with `recipient_suppressed`, contact support.

A blocked job fails with `recipient_suppressed` before provider acceptance and releases its reserved credit. If the suppression check is unavailable, Sendy retries with `suppression_check_unavailable`.

## Domain changes

`sender_identity_unavailable`

The domain was deleted, lost verification, or changed ownership before a sending attempt.

`domain_transferred`

An ownership transfer pauses sending and fails remaining queued emails. Historical jobs and usage stay with the original account.
