> ## 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.

# Audit an Email

> Audit an email before sending to catch broken links, missing unsubscribe content, oversized assets, copy problems, and accessibility issues.

An email audit checks whether a finished email is ready to send. Brew checks
the exact HTML, subject, preview text, and sending purpose that you provide.
The result combines deterministic checks with link, image, compatibility,
accessibility, and copy reviews.

An audit reports findings. It does not change your HTML.

## Run an Audit in the App

<Steps>
  <Step title="Open the send or export dialog">
    Open the email that you plan to send or export. The audit uses the live
    HTML, subject, preview text, version, and sending purpose shown in the
    dialog.
  </Step>

  <Step title="Click Audit">
    Click **Audit · 5 credits** next to **Test**. For exports, the button sits
    next to **Export**. Brew opens the **Audit** tab and starts the checks.
  </Step>

  <Step title="Review the result">
    Start with the readiness status and score. Then review check coverage,
    loaded size, and findings grouped by category. Each finding explains what
    failed and how to fix it.
  </Step>

  <Step title="Fix and run again">
    Edit the email, then click **Run again · 5 credits**. Any change to the
    HTML, subject, preview text, purpose, or audit rules makes the prior result
    stale.
  </Step>
</Steps>

<Note>
  A complete audit costs 5 [credits](/api-reference/api/credits). A partial
  audit costs 0 credits because one or more required checks did not finish.
  Never treat a partial audit as ready.
</Note>

## Understand the Result

The `completion` field tells you whether every required check finished.

| Completion | Readiness      | Meaning                                                                             |
| ---------- | -------------- | ----------------------------------------------------------------------------------- |
| `complete` | `ready`        | No blocker, error, or warning findings.                                             |
| `complete` | `needs_review` | The email has warnings but no blocker or error findings.                            |
| `complete` | `not_ready`    | The email has at least one blocker or error finding.                                |
| `partial`  | `unknown`      | A required check was unavailable, and deterministic checks found no blocker.        |
| `partial`  | `not_ready`    | A required check was unavailable, and deterministic checks already found a blocker. |

Complete audits score from 0 to 100. Partial audits return
`completion.score: null`.
Brew subtracts 20 points per blocker, 10 per error, and 3 per warning, then
floors the score at 0. Repeated targets can apply at most three penalties per
rule. Provider scores do not change the Brew score.

A complete audit stays fresh for 15 minutes. A content change or a ruleset
change makes it stale sooner.

The audit checks:

* unsubscribe content for marketing email;
* empty, malformed, placeholder, and unreachable links;
* missing, unreachable, non-image, and oversized images or GIFs;
* HTML size and the loaded size of directly referenced assets;
* subject and preview length, clarity, duplication, and placeholders;
* alt text, contrast, document language, headings, and link text;
* unsupported markup, scripts, forms, iframes, and client compatibility;
* common email practices such as a postal address, image dimensions, and
  text-to-image balance.

The copy review can add warning or info findings. It cannot decide compliance,
URL validity, or whether the final action is allowed.

Loaded size is exact only when Brew can measure every directly referenced
asset. Otherwise, the result reports a lower bound and the number of unknown
assets. It never invents a total.

## Choose the Sending Purpose

Use `marketing` for newsletters, announcements, promotions, and lifecycle
email. Marketing audits check for visible unsubscribe content. The public API
defaults to `marketing` when you omit `sendingPurpose` and reports that default
in `policy.source`.

A missing visible marketing unsubscribe is a warning. Direct marketing sends
still insert Brew's unsubscribe fallback before delivery.

Use `transactional` only for a message sent because of something the recipient
did, such as a receipt, verification email, or password reset. The unsubscribe
check is not applicable to transactional email.

In the app, Brew derives the purpose from the selected sending domain.
Transactional email creation always uses `transactional`. A generic export
without a sending-domain purpose uses the internal `unknown` purpose, skips
unsubscribe compliance, and does not insert unsubscribe content.

## Continue After a Warning

Confirmed dead links or images, an image that returns non-image content, and a
known loaded size above 5 MB pause the final action. You can click **Continue
Anyway** after reviewing these findings. Brew logs the override without
storing the HTML or full URLs.

Authentication failures, throttling, server errors, bot protection, timeouts,
and unknown resource sizes remain warnings. Brew does not report them as dead
links or images.

Deterministic blockers cannot be overridden. These include missing or invalid
destinations, unresolved URL merge tags, invalid image sources, a missing or
overlong subject, and overlong preview text.

## Run an Audit from MCP

If Brew is [connected to your AI client](/api-reference/mcp/quickstart), ask it
to audit a saved design:

> "Audit the welcome email before we send it."

The agent calls `audit_email` with `emailId`. It can also pin an
`emailVersionId` and set `sendingPurpose` to `marketing` or `transactional`.
The tool loads that exact saved version and returns the typed, capped result.

## Run an Audit from the CLI

Pass the rendered HTML and the inbox copy that you plan to use:

```bash theme={null}
brew-cli emails audit \
  --file newsletter.html \
  --subject "Your August account update" \
  --preview-text "A quick look at what changed this month." \
  --sending-purpose marketing
```

Use `--file -` to read HTML from stdin. Use `--input -` to read the complete
JSON request from stdin.

## Run an Audit from the TypeScript SDK

```ts theme={null}
const result = await brew.emails.auditEmail({
  emailHtml,
  subject: 'Your August account update',
  previewText: 'A quick look at what changed this month.',
  sendingPurpose: 'marketing',
})

if (result.completion.status === 'partial') {
  console.log('Audit incomplete. Retry before claiming readiness.')
} else {
  console.log(result.completion.readiness, result.completion.score)
}
```

Pass `{ raw: true }` as the second argument to read `X-Credit-Cost` and the
other response headers.

## Run an Audit from the API

`POST /v1/emails/audit` accepts raw content rather than a saved email id:

```bash theme={null}
curl "https://brew.new/api/v1/emails/audit" \
  -H "Authorization: Bearer $BREW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: audit-august-newsletter" \
  -d '{
    "emailHtml": "<!doctype html><html lang=\"en\"><body>...</body></html>",
    "subject": "Your August account update",
    "previewText": "A quick look at what changed this month.",
    "sendingPurpose": "marketing"
  }'
```

The endpoint returns `200` for both complete and partial audits. Reuse the same
idempotency key when retrying a partial result. See the generated API reference
for the complete versioned schema and transport limits. Audit calls have a
separate admission policy. See [Rate Limits](/api-reference/api/rate-limits)
for the current caller, organization, and concurrency limits.

## Checks That Need Send Context

An HTML audit cannot verify SPF, DKIM, DMARC, one-click unsubscribe headers,
the plaintext MIME part, consent or suppression state, or inbox placement.
Use [domain health](/get-started/verify-your-sending-domain), contact
validation, and an [inbox placement test](/api-reference/api/api-catalog) for
those checks.

Before every send, transactional creation, and export, Brew runs the free
content checks again on the exact email. Missing online results alone do not
stop the action when an audit is missing, stale, or partial. Deterministic
blockers still stop it. Marketing sends keep Brew's unsubscribe insertion as
the last safety check.

## 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>
