Email

What are transactional email best practices?

Send transactional email from authenticated identities, preserve one send per business event, enforce link expiry and monitor each recipient's outcome.

A password reset has to arrive while its link still works. A receipt has to describe the right order without appearing again after a retry.

Those requirements start in your application and continue after the email service accepts the message.

What should a transactional message contain?

Give the recipient the information or action needed for the event that caused the email. A receipt confirms an order. A reset message provides a way to regain access.

Use a recognizable sender name. Write a subject that identifies the event. Send replies to an address your team monitors when the workflow needs support.

For an illustrative receipt, use a subject such as Receipt for order 8472. Include the order reference, purchased items and a support contact. For a reset message, put the reset action first and state when it expires.

Test both HTML and plain-text content. Check that the main action remains understandable on a narrow screen and with images disabled.

Keep promotions separate from necessary account messages. Transactional versus marketing email explains how message purpose affects recipient controls and sending policy.

How should you authenticate and separate senders?

Authenticate the sending domain before production traffic. Gmail's sender requirements require SPF or DKIM for all senders to personal Gmail accounts. Senders exceeding 5,000 messages a day need SPF, DKIM and DMARC.

Use separate sending identities for operational and marketing mail. Yahoo's guidance recommends separating bulk marketing from transactional traffic by IP or DKIM signing domain. Both carry reputation signals, so a different From address alone does not separate the infrastructure.

Increase sending volume gradually. Google's guidance warns against sudden spikes. Check deferrals and bounces during an increase so you can reduce the rate when receivers struggle with the traffic.

The deliverability checklist covers the wider authentication and sender-reputation work.

How should you handle suppressions and preferences?

Check why a recipient is blocked before deciding whether another send is appropriate. A marketing opt-out and an undeliverable address call for different actions.

Bird's category policy allows transactional mail after a marketing-only opt-out. Hard bounces, manual suppressions and an opt-out covering all messages block both categories.

A transactional category therefore does not override every recipient restriction. When Bird reports recipient_suppressed, inspect the suppression record and the recipient's preferences. Repeating the same send does not repair the address or change that policy.

Enforce expiry in the application that validates the link or code. Text in the email cannot prevent an expired credential from being accepted.

OWASP, the application-security community, recommends randomly generated reset tokens or codes with a suitable expiry period. It also recommends single use. Invalidate the credential after successful use so the same message cannot authorize another reset.

Choose a lifetime for the account action and show that lifetime in the message. Account for the time spent waiting in your application and in delivery. An email received after expiry needs a route to request a fresh reset.

Before retrying an unsent reset job, check whether its credential is still valid. Do not extend a credential's expiry merely because a sending attempt failed. Otherwise retries can keep the credential usable beyond the lifetime you chose.

For reset URLs, OWASP recommends HTTPS and a trusted destination domain. It also recommends limiting reset requests per account to prevent inbox flooding.

How do retries avoid duplicate sends?

Keep a durable record of the business event and its sending operation. A repeated order event should find the existing receipt job instead of creating another one.

Use the same idempotency key when retrying the same API request after an uncertain response. Bird's idempotency contract keeps a completed response for three hours. After that window, another request with the same key can create another message.

That limit makes your own event record necessary for older retries. Save the returned message ID against the event before treating submission as complete.

A delivery deferral is different from an uncertain API response. Bird retries deferred delivery automatically. Creating another send for each deferral can add duplicate messages while the original is still in progress.

What should you monitor and alert on?

Track each expected message through submission. Record each recipient's outcome. Measure whether the user completes the intended action.

Bird's delivery events distinguish acceptance, delivery, deferral, bounce and rejection. Delivery means the receiving server accepted the message. It does not establish inbox placement or reading.

Record the business-event time alongside the send time and recipient outcome. For reset messages, compare elapsed time with the credential's remaining lifetime. Measure completed resets in your application. An open-tracking event does not prove that a person read the message.

Set alerts around the workflow's operating limits:

  • Unsent jobs approach their expiry.
  • Failures rise above your normal range.
  • Webhook processing falls behind.

Assign an owner who can act on each alert.

FailureEvidence to inspectOwner and next action
No send after an order eventApplication job and event recordApplication team: recover the missing job without duplicating an existing send
Suppressed recipientRejection reason, suppression and preferencesSupport or sending team: investigate the block before another attempt
Rising delivery deferralsRecipient events and sending volumeSending team: inspect receiver responses and reduce a traffic spike
Expired reset on arrivalCredential expiry and event timestampsApplication team: investigate delay and provide a fresh-request path
Repeated webhook deliveryWebhook identifier and processing recordApplication team: skip work already completed for that event

Verify webhook signatures before accepting events. Bird's webhook guide uses webhook-id for deduplication, so a retried notification does not repeat your application's work.

What should you check before sending through Bird?

Test the workflow through submission, recipient outcome and application recovery before using it for live account messages.

  1. Verify the sending domain. Check that operational traffic uses the intended identity and pool.
  2. Publish the template. Test the receipt details or reset action with representative parameters.
  3. Set category: "transactional" for operational content. Apply the documented suppression and preference policy.
  4. Preserve the business-event record and idempotency key. Keep the message ID returned by the send endpoint.
  5. Exercise failure handling with the mail sandbox. Its simulated outcomes pass through the normal event and webhook paths without reaching a real inbox.
  6. Inspect the per-recipient timeline in the email log. Confirm that your application handles the same outcomes and routes alerts to their owners.

Build on the same network.

A test API key is yours immediately. Production unlocks when you add a payment method and verify a sender.

Start with one channel.
Add the others when you're ready.

A test API key is yours immediately. Production unlocks when you add a payment method and verify a sender.

Using Claude Code, Cursor, or Codex? Copy a setup prompt and your agent installs the Bird CLI and skills for you. Pick yours:

Cursor