Looking for user-facing product updates? See the
main changelog. Everything below is scoped to the
Public API v1 surface and the TypeScript SDK.
Set an email's subject line from the API, MCP, and CLI
Subject Lines on Every Email Write
Every design carries a default inbox subject (subjectLine), and until
now only the app could set it, so designs created through the API, MCP,
or CLI landed without one. All four write surfaces now accept an
optional subjectLine of 1 to 250 characters:POST /v1/emails(MCPcreate_email_design). The email agent also sees the subject, so the preview text and opening copy complement it instead of repeating it.POST /v1/emails/import(MCPimport_email_design)POST /v1/emails/figma(MCPimport_figma_design)PATCH /v1/emails/{emailId}(MCPedit_email_with_ai)
subjectLine, and
GET /v1/emails?emailId= already returns it on the detail row.prompt is now optional on PATCH /v1/emails/{emailId}. Send
subjectLine on its own and Brew sets the subject in place: no AI run,
no new version, no credits. Send both and the subject lands on the new
version the edit produces. At least one of the two is required, and
emailVersionId still requires prompt, because pinning a source
version means nothing for a subject change.A subject line is the design’s default, not the send.
POST /v1/sends still takes its own subject per delivery.In the CLI this is --subject-line on emails generate,
emails import, emails import-figma, and emails edit.Run and copy any API capability from the dashboard
The API Catalog
The dashboard now has an API tab at brew.new/api that runs eleven v1 capabilities against your own brand and hands you the exact call afterwards. No endpoints changed, and nothing here is new API surface.- Covers Generate Email, Edit Email, Figma to Email, HTML to PNG, Image to GIF, Optimize Image, Resize Image, Validate Contacts, Accessibility Audit, Email Inbox Preview, and Inbox Placement, with each one’s credit cost on the row.
- Every parameter you set rewrites a live request snippet, switchable
between cURL, TypeScript (SDK), TypeScript, and
Python. Copied snippets always carry the
brew_your_api_keyplaceholder rather than the key the in-app run used. - Each capability also carries a copyable implementation prompt for
a coding agent: endpoint, docs link, cost, the
BREW_API_KEYauth pattern, the SDK method, the equivalent MCP tool, every request field, and an example body.
Validate contacts on ingestion & write-back; validationStatus rename
Public API v1: Validate Contacts as You Add Them
Contact deliverability validation now persists and reaches the ingestion endpoints:POST /v1/contacts/validatenow writes the verdict back onto matching contacts (it was read-only before), and each result addsrisk,isDisposable, andisRolesignals alongside the existingreasonanddidYouMean.POST /v1/contactsandPOST /v1/contacts/import-csvaccept an optionalvalidate: true, each address is deliverability-checked as it’s ingested and the verdict is saved. Metered 2 credits per address, charged only on success. Up to 100 addresses validate inline (the response carries avalidationcount summary); larger submissions upsert first and validate as a background job, returning avalidationJobId.- The contact’s verdict field is renamed
verificationStatus→validationStatus.verificationStatusis dual-emitted with the same value for back-compat, so existing integrations keep working. - Also available via the
create_contact,import_contacts_csv, andvalidate_contactsMCP tools.
Figma imports on the API, and full SDK parity
Figma to Email on the API, MCP, and SDK
Converting a Figma frame into an editable email was previously only possible in chat. It is now a first-class operation on every surface:POST /v1/emails/figmatakes{ figmaUrl, title?, format?: 'jsx' | 'html' }and returns201 { emailId, emailVersionId, title, format, content, warningCount, exportedNodeCount, previewImage? }. ThefigmaUrlmust include anode-id, which is the link to one specific frame rather than the whole file.- The conversion is deterministic, with no model in the loop, so the same frame always converts the same way and the call is free.
- Every surface uses the API-key brand’s connected Figma integration.
Credentials are never accepted in the request or retained in API/MCP
history. Without a usable connection you get
422 FIGMA_NOT_CONNECTED.
import_figma_design MCP tool and as
brew.emails.importFigma(...) in the SDK.Every v1 operation now has an SDK method
The TypeScript SDK had drifted behind the API. These methods are new:brew.emails.importFigma(),brew.emails.clone(),brew.emails.export()brew.emails.createInboxPlacementTest()andbrew.emails.getInboxPlacementResults(), the seed-list test of whether a design lands in the inbox or in spambrew.sends.pause()andbrew.sends.resume(), the reversible pair for an in-flight gradual sendbrew.analytics.overview()for the exact totals, rates, and timeseries shown in Brewbrew.automations.run()plusbrew.automations.audienceRuns.list()and.control()for manual-audience launch, scheduling, pause, resume, and cancelbrew.domains.health()for the aggregate deliverability score and signals
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-auditruns 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 ascore(0-100), asummary, and the specificissueswith their WCAG criterion. Fixed 5 credits, charged only on success. (This endpoint is now aPOSTand credit-metered; it previously returned a lightweight local result.)POST /v1/contacts/validatenow runs a real deliverability check on up to 100 addresses at once, each comes backvalid,risky(role account, disposable, catch-all), orinvalid, with a machine-readablereasonand adidYouMeantypo correction. Metered 2 credits per address, charged only on success.- Both are value-aligned: if the check can’t complete, you get a retryable
503and are not billed. Also available as theaudit_email_accessibilityandvalidate_contactsMCP tools.
API v1, preview a design across real inboxes & devices
Public API v1: See How an Email Renders in Real Inboxes
NewPOST /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_dtfor 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 retryable503and is not billed; unknown client ids are rejected with a422before 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_clientsMCP tool and asbrew.emails.previewClients(...)in the SDK.
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-canceledsend returns200. Once the send issending,sent, orfailedit is409 SEND_NOT_CANCELLABLE; an unknown / cross-brand id is404 SEND_NOT_FOUND.sendsscope. The SDK method isbrew.sends.cancel(sendId).
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 theemailsscope. The SDK method moves frombrew.account.get()tobrew.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 frombrew.content.hostImage()tobrew.content.addImage().
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 runsGET /v1/automations/runs?automationRunId=(?include=logs), triggers?triggerEventId=, trigger instances?triggerInstanceId=, and sendsGET /v1/analytics/sends?sendId=(?include=events, also?emailId=). The single-send detail row carriespreviewImage, soPOST /v1/emails/{emailId}/preview,GET /v1/emails/{emailId}/versions, andGET /v1/emails/{emailId}/sendswere removed (on-demand rendering isPOST /v1/content/html-to-png). - One polymorphic send.
POST /v1/sends/testfolded intoPOST /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/contactsandGET /v1/contacts/{email}were replaced byPOST /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 existinghtml,mjml, orjsxinto 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-qbrowse stays free. - Also removed:
POST /v1/audiences/{audienceId}/duplicate.
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,
SDK Overview, and the @brew.new/sdk changelog.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.
automationsowns/v1/automations/*plus/v1/automations/triggers(/{id}/fire)(renamed from/v1/triggers) and/v1/automations/runs(/{runId})(moved from/v1/analytics/automations/runs).analyticsowns all reporting, including/v1/analytics/sends(/{sendId}/events)(send reads, moved offGET /v1/sends) and/v1/analytics/trigger-instances(the fired-trigger log, moved off/v1/events).sendsis the action only:POST /v1/sendsandPOST /v1/sends/test. POST /v1/sendsnow takes either a savedaudienceIdor an inlinetolist (≤ 50) and returns asendIdyou 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, alongsideGET /v1/llms.txt.- No more
dry_run. Credit-metered operations just charge on success (402 INSUFFICIENT_CREDITSwhen short); check your balance withGET /v1/account. POST /v1/content/host-imageis now credit-metered and saves the image into the brand image library.- Removed:
/v1/me,/v1/usage(useGET /v1/account),/v1/integrations, the single-templateGET /v1/templates/{emailId}(the listGET /v1/templatesstays and now returnshtml+previewImageper row), and automation-run replay.
@brew.new/sdk changelog. The entries below describe earlier
iterations of the v1 surface, paths noted there have since moved as
summarized above.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 byrecipientEmailfor a contact’s full timeline), andGET /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/cursorand returns apaginationenvelope. - Lean lists +
include=:GET /v1/templatesandGET /v1/automationsare lean by default. Pass?include=html/?include=graphto opt into the heavy fields. - Granular scopes: new least-privilege
domains,sends, andaudiencesscopes; the coarse scopes still satisfy them, so existing keys are unaffected.
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, and the @brew.new/sdk changelog.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 theirfilters, membercount, and ISO timestamps. - Domains gained a full lifecycle: add → verify → set sender defaults → delete.
GET /v1/domainsnow lists every domain (incl.pendingrows + the DNSrecordsto publish);?sendableOnly=truereturns just the send-ready set. - Analytics is now queryable:
GET /v1/analytics/campaigns(lifetime per-campaign KPIs) andGET /v1/analytics/automations(windowed per-automation performance + totals). - Emails gained delete, version history (
?include=versions), and non-destructive version restore.
POST/PATCH /v1/triggers (since renamed to /v1/automations/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.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).