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

# API Changelog

> Breaking changes, new endpoints, and SDK updates for the Brew Public API.

<Note>
  Looking for user-facing product updates? See the
  [main changelog](/changelog/overview). Everything below is scoped to the
  Public API v1 surface and the TypeScript SDK.
</Note>

<Update label="July 2026" description="API v1 — accessibility audits & contact deliverability validation">
  ## Public API v1 — Check an Email and Your List Before You Send

  Two pre-send quality checks are now on the Public API, the MCP tools, and
  the in-app agent:

  * **`POST /v1/emails/{emailId}/accessibility-audit`** runs a WCAG 2.1 audit
    of a design's rendered HTML — colour contrast, image alt text, link text,
    heading structure, font size, language — and returns a `score` (0–100), a
    `summary`, and the specific `issues` with their WCAG criterion. Fixed
    **5 credits**, charged only on success. *(This endpoint is now a `POST`
    and credit-metered; it previously returned a lightweight local result.)*
  * **`POST /v1/contacts/validate`** now runs a real deliverability check on
    up to 100 addresses at once — each comes back `valid`, `risky` (role
    account, disposable, catch-all), or `invalid`, with a machine-readable
    `reason` and a `didYouMean` typo correction. Metered **2 credits per
    address**, charged only on success.
  * Both are value-aligned: if the check can't complete, you get a retryable
    `503` and are **not** billed. Also available as the
    `audit_email_accessibility` and `validate_contacts` MCP tools.
</Update>

<Update label="July 2026" description="API v1 — preview a design across real inboxes & devices">
  ## Public API v1 — See How an Email Renders in Real Inboxes

  New **`POST /v1/emails/{emailId}/client-previews`** renders a design's
  latest version across real email clients & devices — Gmail, Outlook,
  Apple Mail, iOS (with dark-mode variants), plus Yahoo — and returns a
  screenshot per client, rehosted on the Brew CDN.

  * Pass `clients` (ids from the supported catalogue) to target specific
    inboxes/devices — e.g. `outlook2021_win11_dm_dt` for Outlook 2021 on
    Windows in dark mode — or send `{}` for a popular default spread.
  * Fixed cost of 10 credits, **charged only when at least one client
    renders** (`X-Credit-Cost: 10`). A batch where zero clients finish in
    time returns a retryable `503` and is not billed; unknown client ids
    are rejected with a `422` before any paid work.
  * Slow clients that outlive the bounded render window come back in
    `pending` — call again to retry just those.
  * Also available as the `preview_email_across_clients` MCP tool and as
    `brew.emails.previewClients(...)` in the SDK.
</Update>

<Update label="June 2026" description="API v1 — POST /v1/emails accepts an optional marketing category">
  ## Public API v1 — Steer Email Design with a Category

  `POST /v1/emails` ("Create an email design") now accepts an optional
  **`category`** so a create gets the same category-tailored treatment the
  in-app agent applies — exemplars, hero recipe, and personalization — instead
  of a generic default.

  * Marketing categories only: `welcome`, `newsletter`, `promotional`,
    `product-launch`, `product-update`, `cart-abandonment`,
    `event-invitation`, `event-reminder`, `feedback-request`,
    `re-engagement`, `referral`, `business`, `internal`, `general`.
    Transactional emails (receipts, password resets, order confirmations)
    are sent from automations with a trigger, not this endpoint, so those
    categories are not accepted.
  * Backward compatible — omit `category` for the previous behavior. The
    same field is available on the `create_email_design` MCP tool and as
    `brew.emails.generate({ prompt, category })` in the SDK.
</Update>

<Update label="June 2026" description="API v1 — new POST /v1/sends/{sendId}/cancel">
  ## Public API v1 — Cancel a Send

  New endpoint to pull back a send before it goes out.

  * **`POST /v1/sends/{sendId}/cancel`** ("Cancel a send"). Cancels a
    scheduled or queued send → `200 { sendId, status: 'canceled' }`.
    Idempotent — an already-`canceled` send returns `200`. Once the send
    is `sending`, `sent`, or `failed` it is `409 SEND_NOT_CANCELLABLE`;
    an unknown / cross-brand id is `404 SEND_NOT_FOUND`. `sends`
    scope. The SDK method is `brew.sends.cancel(sendId)`.
</Update>

<Update label="June 2026" description="API v1 renames — /v1/account → /v1/usage, host-image → add-image">
  ## Public API v1 — Two Operation Renames

  Two endpoints (and their SDK methods) were renamed for clarity. The
  request and response shapes are unchanged.

  * **`GET /v1/account` → `GET /v1/usage`** ("Get usage"). The
    billing/quota surface — `{ plan, credits, emailSends, period }` —
    keeps the same shape and the `emails` scope. The SDK method moves
    from `brew.account.get()` to `brew.usage.get()`.
  * **`POST /v1/content/host-image` → `POST /v1/content/add-image`**
    ("Add image"). Still optimizes the source image and saves it to the
    brand image library (fixed credit cost). The SDK method moves from
    `brew.content.hostImage()` to `brew.content.addImage()`.
</Update>

<Update label="June 2026" description="API v1 read-collapse — flat reads, polymorphic send, email import">
  ## Public API v1 — Flat Reads + Unified Send

  The v1 surface collapsed from 71 to 55 endpoints around one rule:
  **one flat read per resource, identity in the query, `?include=`
  opt-ins for the heavy detail.** Plus a new way to bring existing
  designs into Brew.

  * **Reads are flat.** The per-resource get-one paths are gone — pass
    the id key to the list endpoint instead: emails
    `GET /v1/emails?emailId=` (`?include=html,versions`), domains
    `?domainId=`, audiences `?audienceId=` (`?include=count`),
    automations `?automationId=` (`?include=graph,versions`),
    automation runs `GET /v1/automations/runs?automationRunId=`
    (`?include=logs`), triggers `?triggerEventId=`, trigger instances
    `?triggerInstanceId=`, and sends
    `GET /v1/analytics/sends?sendId=` (`?include=events`, also
    `?emailId=`). The single-send detail row carries `previewImage`,
    so `POST /v1/emails/{emailId}/preview`,
    `GET /v1/emails/{emailId}/versions`, and
    `GET /v1/emails/{emailId}/sends` were removed (on-demand rendering
    is `POST /v1/content/html-to-png`).
  * **One polymorphic send.** `POST /v1/sends/test` folded into
    `POST /v1/sends` — pass `{ test: true }` for the synchronous
    one-off QA send (`200 { recipient }`); omit it for the campaign
    send (`202 { sendId }`).
  * **One contact read.** `GET /v1/contacts` and
    `GET /v1/contacts/{email}` were replaced by
    `POST /v1/contacts/search` (`{ filters, audienceId?, search?, sort,
    count?, cursor }`); a by-email lookup is a
    `{ field: 'email', operator: 'equals' }` filter.
  * **New — `POST /v1/emails/import`.** Bring existing `html`, `mjml`, or `jsx`
    into an editable Brew design (external images are re-hosted on the
    CDN). Usage-metered.
  * **Semantic brand-image search.** `GET /v1/brand/images?q=` runs a
    credit-metered vector search (plus `?type` / `?aspectRatio`); the
    no-`q` browse stays free.
  * **Also removed:** `POST /v1/audiences/{audienceId}/duplicate`.

  The TypeScript SDK keeps its factory names: every read is one
  `list()` (id/include/filters in the args), `send`/`sendTest` merged
  into `send(input)` with `test?`, the contact read is `search()`, and
  `emails.import()` is new. See the updated
  [API Introduction](/api-reference/api/api-introduction),
  [SDK Overview](/sdks/overview), and the `@brew.new/sdk` changelog.
</Update>

<Update label="June 2026" description="API v1 restructure — decoupled sends, 3-domain surface, /v1/help">
  ## Public API v1 — Decoupled-Send Restructure

  A breaking restructure of the v1 surface around a single insight:
  **emails are pure designs, and a send is the unit of delivery and
  analytics.** A design now carries no type and no send state — it can
  be sent any number of times.

  * **Sends, unified.** Campaign sends and automation sends are one
    entity. A campaign records one send; an automation records one send
    per recipient. Every delivery event attaches to its `sendId`.
  * **Three clear domains.** `automations` owns
    `/v1/automations/*` plus `/v1/automations/triggers(/{id}/fire)`
    (renamed from `/v1/triggers`) and `/v1/automations/runs(/{runId})`
    (moved from `/v1/analytics/automations/runs`). `analytics` owns all
    reporting, including `/v1/analytics/sends(/{sendId}/events)` (send
    reads, moved off `GET /v1/sends`) and
    `/v1/analytics/trigger-instances` (the fired-trigger log, moved off
    `/v1/events`). `sends` is the action only —
    `POST /v1/sends` and `POST /v1/sends/test`.
  * **`POST /v1/sends`** now takes either a saved `audienceId` or an
    inline `to` list (≤ 50) and returns a `sendId` you poll under
    `/v1/analytics/sends`.
  * **`GET /v1/help`** — a no-auth, structured-JSON catalog of the whole
    API (scopes, credits, rate limits, every endpoint) for MCP / agent
    discovery, alongside `GET /v1/llms.txt`.
  * **No more `dry_run`.** Credit-metered operations just charge on
    success (`402 INSUFFICIENT_CREDITS` when short); check your balance
    with `GET /v1/account`.
  * **`POST /v1/content/host-image`** is now credit-metered and saves
    the image into the brand image library.
  * **Removed:** `/v1/me`, `/v1/usage` (use `GET /v1/account`),
    `/v1/integrations`, the single-template `GET /v1/templates/{emailId}`
    (the list `GET /v1/templates` stays and now returns `html` +
    `previewImage` per row), and automation-run replay.

  See the updated [API Introduction](/api-reference/api/api-introduction)
  and the `@brew.new/sdk` changelog. The entries below describe earlier
  iterations of the v1 surface — paths noted there have since moved as
  summarized above.
</Update>

<Update label="June 2026" description="API v1 hardening — 7 new endpoints, pagination, scopes">
  ## Public API v1 — Hardening Pass

  Seven new endpoints plus cross-cutting normalization across the whole API.

  * **New observability + discovery endpoints:** `GET /v1/sends` (campaign send list + stats), `GET /v1/brand` (the key's brand + readiness), `GET /v1/usage` (API request volume + trend), `GET /v1/analytics/events` (unified event explorer — filter by `recipientEmail` for a contact's full timeline), and `GET /v1/integrations` (triggerable integration-event catalog).
  * **Test/preview sends:** `POST /v1/sends { mode: 'test' }` sends a one-off preview to a single inbox — no verified domain or audience required, and it doesn't consume the email's live-send slot.
  * **Automation run replay:** `POST /v1/automations/runs { automationRunId, mode: 'replay' }` re-runs a prior run against the current saved draft.
  * **Uniform cursor pagination:** every list endpoint now accepts `limit`/`cursor` and returns a `pagination` envelope.
  * **Lean lists + `include=`:** `GET /v1/templates` and `GET /v1/automations` are lean by default — pass `?include=html` / `?include=graph` to opt into the heavy fields.
  * **Granular scopes:** new least-privilege `domains`, `sends`, and `audiences` scopes; the coarse scopes still satisfy them, so existing keys are unaffected.

  New TypeScript SDK methods: `brew.brand.get()`, `brew.usage.get()`, `brew.integrations.list()`, `brew.analytics.sends.{list,listAll,get}()` + `brew.emails.sendTest()`, and `brew.analytics.{events,eventsAll}()`. See the updated API reference, the new [API Guides](/api-reference/guides/monitor-campaign-sends), and the `@brew.new/sdk` changelog.
</Update>

<Update label="June 2026" description="API v1 lifecycle expansion">
  ## Public API v1 — Full Lifecycle

  The v1 API now covers the whole loop end-to-end for an org + brand API key.

  * **Audiences** are now full CRUD (`POST`/`PATCH`/`DELETE` + single fetch), and rows carry their `filters`, member `count`, and ISO timestamps.
  * **Domains** gained a full lifecycle: add → verify → set sender defaults → delete. `GET /v1/domains` now lists every domain (incl. `pending` rows + the DNS `records` to publish); `?sendableOnly=true` returns just the send-ready set.
  * **Analytics** is now queryable: `GET /v1/analytics/campaigns` (lifetime per-campaign KPIs) and `GET /v1/analytics/automations` (windowed per-automation performance + totals).
  * **Emails** gained delete, version history (`?include=versions`), and non-destructive version restore.

  **Breaking:** `POST`/`PATCH /v1/triggers` now return the uniform `{ triggers: [row] }` envelope (was `{ trigger }`); contact timestamps are ISO-8601 strings. See the updated API reference + the `@brew.new/sdk` changelog.
</Update>

<Update label="January 2026" description="OpenAPI 3.1 spec + TypeScript SDK">
  ## API Specification

  Published OpenAPI 3.1 specification covering contacts, automations, triggers, automation runs, emails, sends, audiences, domains, fields, and templates. Official TypeScript SDK (`@brew.new/sdk`) is available; generate clients for other languages from the OpenAPI spec at `https://brew.new/openapi/public-api-v1.yaml` (see [Generate Your Own SDK](/sdks/openapi-codegen)).
</Update>
