Request IDs
Every successful send returns a uniquerequest_id that identifies the transmission. This ID is your primary handle for tracking the email through delivery, webhooks, and the dashboard:
Using Request IDs
Store therequest_id alongside your business record (order, user, ticket) so you can reference it later. The request ID lets you query the email’s delivery status through the API, look it up in the dashboard, trace it through webhook events, and provide it to Lettr support if you need to investigate a delivery issue.
Preventing Duplicate Sends
The simplest way to prevent duplicates is to check a flag in your database before sending. If the email has already been sent for a given business event (order confirmed, password reset requested), skip the API call:Distributed Idempotency
For distributed systems where multiple workers might process the same event, use a shared cache or database lock to coordinate. Store a unique idempotency key derived from the business event and check it before sending:Safe Retry Pattern
When a send request fails with a server error (5xx) or network timeout, it’s safe to retry — but only if the error was transient. Client errors (4xx) indicate a problem with the request itself and should not be retried. This pattern implements exponential backoff for retryable errors while immediately re-throwing client errors:Request ID in Webhooks
Every webhook event includes therequest_id from the original send. This lets your webhook handler look up the corresponding business record (order, user, ticket) and update its status based on the delivery outcome:
Best Practices
Always Store Request IDs
Always Store Request IDs
Persist the
request_id alongside the business record that triggered the email (e.g., an order row, a user record, a support ticket). This gives you a direct lookup path when investigating delivery issues, correlating webhook events, or providing information to support.Use Meaningful Idempotency Keys
Use Meaningful Idempotency Keys
Construct keys from the email’s purpose and the entity it relates to, such as
order-confirmation-{order_id} or password-reset-{user_id}-{token}. Avoid generic keys like email-123 — the key should make it impossible for a different email type to collide with the same value.Check Before Sending
Check Before Sending
For critical emails like order confirmations and password resets, always verify that the email hasn’t already been sent before calling the API. A database flag check is fast and prevents unnecessary API calls, even before metadata-based deduplication comes into play.
Handle Timeouts Carefully
Handle Timeouts Carefully
A network timeout does not mean the email wasn’t sent — the request may have reached Lettr successfully, but the response was lost. Before retrying, query the API using your idempotency key to check whether the email was already accepted for delivery.
Timeout Handling
A timeout (ETIMEDOUT) or connection reset (ECONNRESET) means your client didn’t receive a response, but Lettr may have already accepted and queued the email. Before retrying, check your local idempotency records (database flag or cache) to see if the send was already recorded. If it wasn’t, you can safely retry — but be aware the email may have been sent despite the timeout: