> ## Documentation Index
> Fetch the complete documentation index at: https://docs.brew.new/llms.txt
> Use this file to discover all available pages before exploring further.

# Transactional Email

> Send password resets, receipts, and verification codes from Brew. A transactional email is an automation whose send step uses a transactional-purpose domain.

Transactional emails send one real-time message, such as a password reset or an order confirmation. They reach unsubscribed contacts because they carry essential account information, and they skip the unsubscribe footer. A suppressed address, such as one that hard-bounced, is still skipped.

## The Domain Decides

**In Brew, a transactional email is an automation.** There is no separate transactional email object to create. What makes an automation transactional is the sending domain.

A domain with `sendingPurpose: 'transactional'` removes the unsubscribe requirement and delivers to unsubscribed contacts. The same automation on a marketing-purpose domain is a marketing send that respects unsubscribes. You pick the class by picking the domain.

Automations on marketing-purpose domains still cover the marketing side of event-driven email: welcome flows, onboarding, abandoned cart, win-back. Those respect unsubscribes, which is what you want for marketing, and not what you want for a password reset. That is why a reset flow's send step belongs on a transactional-purpose domain.

## Set It Up

<Steps>
  <Step title="Add a transactional domain">
    Add a sending domain with the **Transactional** purpose in the Brew app, or from code with `POST /v1/domains` and `sendingPurpose: "transactional"`. The MCP `create_domain` tool adds marketing domains only. [Verify Your Sending Domain](/get-started/verify-your-sending-domain) covers the DNS records and both purposes. Run marketing and transactional mail on separate subdomains.
  </Step>

  <Step title="Create the trigger">
    Build a custom trigger, or use one an integration provisions. Declare the payload fields the email needs. [Build an Automation](/create-emails/build-an-automation) covers triggers and payload contracts.
  </Step>

  <Step title="Build and publish the automation">
    Wire the trigger to an automation. Point its Send Email step at the transactional domain, then publish.
  </Step>

  <Step title="Fire it from your product">
    Send the event from your backend, as shown below.
  </Step>
</Steps>

## Fire It from Your Product

Fire the trigger with a JSON `payload` (nested objects and arrays supported). Reference payload fields in the email as `{{ trigger.* }}` variables:

```bash theme={null}
curl -X POST "https://brew.new/api/v1/automations/triggers/tri_password_reset/fire" \
  -H "Authorization: Bearer $BREW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "payload": { "email": "jane@example.com", "resetUrl": "https://app.example.com/reset/abc123" } }'
```

The email design references `{{ trigger.resetUrl }}`. The payload's `email` field is the contact the automation runs for. [Merge Tags](/create-emails/merge-tags) covers the variable syntax.

## What to Know Before You Ship One

* **Suppressed addresses are skipped.** A fire to a hard-bounced address answers `202` with `counts.skipped: 1` and starts no run. The events feed records why.
* **A fire for a new address creates a contact.** It's subscribed, like a contact added with only an email. Send that person marketing only if they opted in.
* **Keep one-time codes off the contact.** Nest them in the payload, such as `{ "verification": { "code": "482913" } }`, and write `{{ trigger.verification.code }}`. A nested value renders but isn't saved on the contact.
* **The subject line is stored.** The events feed keeps each email's subject, so put a code in the body, not the subject.
* **Tracking still applies.** Click and open tracking follow the domain's settings, so links go through the tracking domain and an open pixel is added.
* **Retries don't send twice.** Send an `Idempotency-Key` header with a stable value per event, such as the reset request's ID. A retry with the same key answers with the original runs instead of sending again.
* **Redact secrets in logs.** In the trigger's payload schema, set `pii: "high"` on fields such as codes and reset links. Brew then hides their values in execution logs and the inbound log.
* **Encode values inside links.** A token with `+` or `&` breaks in a raw link. Write `{{ trigger.reset.token | url_encode }}`, or pass the whole link already encoded. See [Merge Tags](/create-emails/merge-tags#liquid-templating).
* **MCP won't fire to a contact who opted out of marketing.** The email itself has no unsubscribe link, but an agent still can't send it to that contact. `fire_trigger_event` answers `RECIPIENT_UNSUBSCRIBED` even for a transactional automation. Fire receipts and resets from your backend over the API.

## Change a Domain's Purpose

`PATCH /v1/domains/{domainId}` with `sendingPurpose` changes a domain's purpose. Published automations on that domain follow the new purpose on their next send. After a switch to transactional, they send with no unsubscribe link and reach unsubscribed contacts.

Emails can't send from a transactional domain. If one still points at the domain, it's blocked at send time.

## Next Steps

* [Build an Automation](/create-emails/build-an-automation)
* [Verify Your Sending Domain](/get-started/verify-your-sending-domain)
* [What You Can Send](/get-started/what-you-can-send)

## Need Help?

Our team is ready to support you at every step of your journey with Brew. Choose the option that works best for you:

<Tabs>
  <Tab title="Self-Service Tools">
    <CardGroup cols="2">
      <Card title="Search Documentation" icon="magnifying-glass" color="#c44925">
        Type in the "Ask any question" search bar at the top left to instantly find relevant documentation pages.
      </Card>

      <Card title="ChatGPT/Claude Integration" icon="robot" color="#c44925">
        Click "Open in ChatGPT" at the top right of any page to explore it further with ChatGPT or Claude.
      </Card>
    </CardGroup>
  </Tab>

  <Tab title="Talk to Our Team">
    <CardGroup cols="2">
      <Card title="Schedule a Call" icon="calendar" color="#c44925" href="https://calendar.google.com/calendar/u/0/appointments/schedules/AcZssZ1iYoRUG1J792XQpbuQLjSRRDupr7MwraFK-HQRCtTYdBmrQi8nZu2qXfzKQigb8gbKJK3KN3-R">
        Book time with our founders for personalized guidance on strategy, best practices, or complex implementation questions.
      </Card>

      <Card title="Call Us Directly" icon="phone" color="#c44925">
        Need immediate assistance? Reach us at **+1-(332)-203-2145** for urgent issues or time-sensitive questions.
      </Card>

      <Card title="Slack Channel" icon="slack" color="#c44925">
        Our preferred support channel. You'll receive an invite after signup for direct founder support and fast responses.
      </Card>

      <Card title="Email Support" icon="envelope" color="#c44925" href="mailto:support@brew.new">
        Contact us at **[support@brew.new](mailto:support@brew.new)** for detailed inquiries or if you prefer not to use Slack.
      </Card>
    </CardGroup>
  </Tab>
</Tabs>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.