Request & Response Lifecycle
Relevant source files
The following files were used as context for generating this wiki page:
The request and response lifecycle manages all communication between the Python SDK and the Resend API. It handles header construction, HTTP method execution, JSON parsing, and structured error reporting for both synchronous and asynchronous operations.
The system uses the Request and AsyncRequest classes as the primary drivers for API interactions. These classes abstract the underlying HTTP client, ensuring consistent authentication and versioning across all service modules such as Topics and Automations.
Sources: resend/request.py:20-35, resend/async_request.py:22-38
Request Architecture
The SDK handles requests through specialized generic classes that define the path, parameters, and HTTP verb. It automatically injects required metadata and authentication tokens into every outgoing call.
Request Components and Initialization
Both Request and AsyncRequest store session-specific data required to build a valid HTTP call.
| Attribute | Type | Description |
|---|---|---|
path | str | The API endpoint relative to the base URL. |
params | ParamsType | Query parameters or JSON body data. |
verb | RequestVerb | The HTTP method (GET, POST, PUT, PATCH, DELETE). |
options | Optional[Dict] | Additional request settings like idempotency keys. |
Sources: resend/request.py:20-35, resend/async_request.py:22-38
Header Construction
The internal __get_headers method constructs the necessary HTTP headers. It includes the API key, content type requirements, and SDK version information. If the request is a POST and provides an idempotency_key, the SDK adds the Idempotency-Key header.
Sources: resend/request.py:73-88, resend/async_request.py:77-92
The SDK generates headers dynamically based on the operation type and provided options. Sources: resend/request.py:73-88
Execution Flow
The SDK distinguishes between synchronous and asynchronous execution paths while maintaining identical logic for processing results.
Synchronous Execution
The perform method in resend/request.py coordinates the sync lifecycle:
- Calls
make_requestto execute the HTTP call via thedefault_http_client. - Captures the status code and response headers.
- Validates the
Content-Typeisapplication/json. - Decodes the JSON body.
- Injects response headers into the resulting dictionary if applicable.
Sources: resend/request.py:37-71
Asynchronous Execution
The AsyncRequest class implements a similar flow using await. It prioritizes the default_async_http_client and falls back to a legacy client if configured. It raises an AsyncClientNotConfigured error if no suitable async client is available.
Sources: resend/async_request.py:40-75, resend/async_request.py:94-118
The sequence demonstrates the standard flow from a high-level API module down to the network layer. Sources: resend/request.py:37-71, resend/async_request.py:40-75
Response Processing
Responses are processed into structured types to provide developer-friendly interfaces.
Base Response Structure
Every successful API response that returns an object inherits from BaseResponse. This class ensures the presence of a dictionary interface while allowing for specific attribute definitions in subclasses like CreateTopicResponse or UpdateAutomationResponse.
Sources: resend/_base_response.py:3-10, resend/topics/_topics.py:19-27, resend/automations/_automations.py:108-117
Error Handling
The SDK evaluates both the HTTP status code and the statusCode field within the JSON body. If an error is detected (status >= 400), it calls raise_for_code_and_type.
- HttpClientError: Raised when the underlying HTTP library fails to connect or execute.
- JSONDecodeError: Raised when the API returns a success status but the body is not valid JSON.
- ApplicationError: Raised when the
Content-Typeis notapplication/jsondespite a successful status.
Sources: resend/request.py:46-59, resend/request.py:126-146, resend/async_request.py:49-62
Webhook Signature Verification
The Webhooks class provides a verify method to validate incoming data from Resend. This process occurs entirely locally and does not trigger an external API request.
Verification Steps
- Validation: Checks for the presence of the payload, secret, and Svix headers (
id,timestamp,signature). - Tolerance Check: Rejects requests where the
svix-timestampdiffers from current time by more than 300 seconds. - Content Signing: Constructs a string in the format
{id}.{timestamp}.{payload}. - HMAC Calculation: Computes an HMAC-SHA256 signature using the decoded
webhook_secret. - Comparison: Uses constant-time comparison (
hmac.compare_digest) against the signatures provided in thesvix-signatureheader.
Sources: resend/webhooks/_webhooks.py:421-507
Manual verification workflow for incoming webhooks. Sources: resend/webhooks/_webhooks.py:471-507
Summary
The Request & Response lifecycle provides a robust foundation for the Resend Python SDK. By centralizing request preparation and response validation in Request and AsyncRequest classes, the SDK ensures that all API features—including templates, topics, and webhooks—behave predictably. The system handles authentication, idempotency, and error parsing automatically, allowing developers to focus on high-level API interactions.