Idempotency Keys
Relevant source files
The following files were used as context for generating this wiki page:
Idempotency keys prevent unintended duplicate operations when an API request executes multiple times. If you send a request with an existing idempotency key, the Resend API returns the result of the original successful request rather than creating a duplicate resource. This mechanism ensures safety during network retries or distributed system failures.
Sources: src/idempotent.rs:1-35, src/error.rs:115-135
Core Architecture and Implementation
The SDK implements idempotency through a wrapper pattern. The Idempotent<T> struct encapsulates any data type T that supports idempotent operations and associates it with an optional string key.
Data Structures
The primary structure for managing keys is the Idempotent wrapper.
| Field | Type | Description |
|---|---|---|
idempotency_key | Option<String> | The unique key sent in the Idempotency-Key HTTP header. |
data | T | The underlying request payload (e.g., email options). |
Sources: src/idempotent.rs:43-48
The IdempotentTrait
The IdempotentTrait<T> provides a convenient interface to convert standard request objects into idempotent ones. It adds the with_idempotency_key method to supported types.
pub trait IdempotentTrait<T> {
fn with_idempotency_key(self, idempotency_key: &str) -> Idempotent<T>;
}
Sources: src/idempotent.rs:72-75
Request Flow and Header Injection
When you invoke a service method with an Idempotent object, the internal client extracts the key and injects it into the HTTP request headers.
The diagram shows how the service layer intercepts the Idempotent wrapper to apply the header before transmission.
Sources: src/emails.rs:36-44, src/batch.rs:56-60
Supported Operations
Specific request types support idempotency through From implementations or explicit trait attachments.
Supported Types
- Single Emails:
CreateEmailBaseOptions - Batch Emails:
Vec<CreateEmailBaseOptions> - Inbox Drafts:
CreateInboxDraftOptionsandSendInboxDraftOptions - Inbox Threading:
ReplyInboxThreadEmailOptionsandForwardInboxThreadEmailOptions
Sources: src/idempotent.rs:64-70, src/idempotent.rs:77-85
Error Handling
The API validates idempotency keys and returns specific errors if requirements are not met.
| Error Kind | Status Code | Description |
|---|---|---|
InvalidIdempotencyKey | 400 | The key must be between 1-256 characters. |
ConcurrentIdempotentRequests | 409 | A request with the same key is already in progress. |
InvalidIdempotentRequest | 409 | The same key is used with a different request payload. |
Sources: src/error.rs:54-61, src/error.rs:115-135
Technical Constraints
- Key Length: The Resend API requires keys to be between 1 and 256 characters.
- Atomic Batching: When sending batch emails, the entire batch consumes exactly one idempotency key. This ensures the entire set of emails is treated as a single idempotent unit.
- Payload Consistency: If you reuse a key with a modified request body, the API returns an
invalid_idempotent_requesterror.
Sources: src/error.rs:54-61, src/CHANGELOG.md:410-412, src/batch.rs:56-60
Summary
Idempotency keys in the Resend Rust SDK provide a type-safe wrapper for ensuring operation uniqueness. By using IdempotentTrait, you can attach unique identifiers to email sends and batch operations, allowing the SDK to automatically handle Idempotency-Key header injection and protection against duplicate resource creation.
Sources: src/idempotent.rs:1-35, src/emails.rs:125-135