# Brew

by Thomas Park - Marketing - Verified publisher

Connect to email marketing infrastructure and memory. Create on-brand emails and sequences with Brew.

- TOOLS: 69 available
- AUTHENTICATION: OAuth

## Tools

- `add_image`: Host an external image URL into the brand image library (optimized) so it can be reused in designs. Fixed 2 credits.
- `audit_email_accessibility`: Audit a design's latest version for accessibility issues against WCAG 2.1 -- colour contrast, image alt text, link text, heading structure, font size, language -- so you can fix them before sending. Returns a `score` (0-100), a `summary`, and the specific `issues` with their WCAG criterion. Costs 5 credits, charged only on success (if the audit can't complete, you get a retryable error and are not charged).
- `batch_delete_contacts`: Delete many contacts at once by an `emails` list. Returns how many were deleted.
- `cancel_send`: Cancel a scheduled or queued campaign send before it goes out (`sendId` from `send_email`), or STOP any in-flight campaign send -- a campaign in `sending`/`paused` is canceled and drops its remainder; already-sent recipients stay sent. Stopping an in-flight send is a tourniquet, not an undo: delivery re-checks liveness at regular points (smart per time bucket, gradual and plain blast at bounded chunk intervals), so a small tail may still deliver after the cancel lands -- never report an in-flight cancel as "nobody else received it". Idempotent -- an already-canceled send returns success; a send already `sent`/`failed`, or a non-campaign send, returns `409 SEND_NOT_CANCELLABLE`.
- `clone_email_design`: Create a NEW design as an exact, LLM-free clone of an existing Brew design. JSX, rendered HTML, images, layout, and preview are copied byte-for-byte; only ids, timestamps, and the `Copy of ...` title change. Omit `emailVersionId` to clone latest, or pass a version pin from `list_email_designs { emailId, include: ["versions"] }`. ALWAYS use this tool for clone/copy/duplicate requests -- never use `create_email_design`, `import_email_design`, or `edit_email_with_ai`, because those invoke AI and may alter the design.
- `control_audience_run`: Control an in-flight manual-audience run (from `run_automation` / `list_audience_runs`). `action: "pause"` holds delivery at the next step boundary (resumable); `action: "resume"` continues a paused run; `action: "cancel"` stops it for good (emails already sent are NOT recalled, and a canceled run can't be resumed). 409 if the run isn't in a state that allows the action (e.g. resuming a run that isn't paused); 404 for an unknown `audienceRunId`.
- `create_audience`: Create an audience -- a SAVED FILTER over your contacts. Membership is computed live at query/send time by matching the filter against contacts (it is NOT a frozen list), served by auto-generated MongoDB indexes, so it always reflects current data. Pass `filters`: a list of `{ field, operator, value }` clauses (fields are contact attributes -- core like `email` or custom) + a top-level `logicalOperator` ("and"/"or"). To target a group NO existing field describes (e.g. webinar attendees, an uploaded list): first stamp a field on those contacts with `import_contacts_csv` (bulk), `create_contact`, or `update_contact` -- e.g. set `segment="webinar"` -- then create the audience filtering on it (`segment equals "webinar"`); prefer one categorical field with many values over a separate boolean field per group. To target specific addresses, add an `{ field: "email", operator: "in", value: ["a@x.com", ...] }` clause (OR-combine with property clauses for a blend). Returns the new `audienceId` (for `send_email`) and a real member `count`.
- `create_automation`: Create an automation graph (`nodes` + `connections`). Filter nodes support two modes. `mode: "payload"` (default) filters on trigger-payload fields: its conditions require an explicit `type` (`string`, `number`, `date`, or `bool`) and a canonical snake_case `operator` -- omit `value` for `is_empty`, `is_not_empty`, `is_true`, and `is_false` (condition-mode `split` follows the same rules). `mode: "engagement"` is EVENT-CONDITIONAL branching -- hold up to a window and route by whether the contact opened/clicked an UPSTREAM sendEmail node's email, incl. per-link branches via `{ kind: "clicked_link", url, position: "any"|"first"|"last" }`; one outgoing edge per branch id + optional `branch: "else"` (engagement filters take `branches`, NOT `conditions`). For an EVENT automation pass `triggerEventId`; for a MANUAL-AUDIENCE automation OMIT `triggerEventId` and give the trigger node `config: { mode: "manualAudience", audienceId }` (launch it later with `run_automation`). Every sendEmail node requires the exact `emailId` + `emailVersionId` returned by the email tools, plus a verified `domainId`, `subject`, and `previewText`. Event automations start as a draft -- publish with `update_automation { published: true }`. QA the whole flow anytime (draft or published, either trigger type) with `test_automation` -- it runs every node and can deliver real test emails to a `testRecipient`.
- `create_contact`: Create or upsert a contact by email (standard fields + a custom `fields` map). Returns the created/updated contact. Set `validate: true` to also run a real deliverability check on the address (2 credits, charged on success) and save the verdict to the contact. For bulk loads use `import_contacts_csv`.
- `create_custom_field`: Define a new custom contact field (name + type). Then set its value via a contact's `fields` map.
- `create_domain`: Register a sending domain. Returns the DNS records to add at your registrar; then call `verify_domain` once they propagate.
- `create_email_design`: Generate a NEW on-brand email design from a natural-language `prompt` (optionally `contentUrls` to ground it, or `referenceEmailId` to match a design). Set `category` (promotional, product-launch, newsletter, welcome, ...) so the design gets the same category-tailored treatment the in-app agent uses -- pick the closest marketing category to the email you are creating. For EXISTING HTML/MJML/JSX use `import_email_design`; to edit a design that already exists use `edit_email_with_ai`. Returns the `emailId` + a `previewImage` -- show the user the preview and the Open-in-Brew link. Usage-metered (billed by tokens).
- `create_gif`: Create an animated GIF from a `prompt` (20 credits), an `imageUrl` (10), or a `videoUrl` (10). Returns a hosted URL. Fixed credit cost by source.
- `create_inbox_placement_test`: Test where a design's latest version lands -- inbox vs spam vs missing -- across real mailbox providers (Gmail, Outlook, Yahoo, Apple, ...). Sends the email to a Mailgun seed list through your REAL send pipeline on a VERIFIED sending `domainId`, so the result reflects that domain's true deliverability (plus SPF/DKIM/DMARC). Returns a `testId` immediately with `status: "collecting"`; results accrue over a few minutes -- poll `get_inbox_placement_results`. This performs a real (small) send in addition to the 10-credit test fee.
- `create_trigger`: Create a named event trigger that automations can listen for. Returns the `triggerEventId` to wire into an automation + fire.
- `delete_audience`: Delete a saved audience. Idempotent. Does not delete the contacts in it.
- `delete_automation`: Delete an automation. Idempotent.
- `delete_contact`: Delete a single contact by email. Idempotent.
- `delete_custom_field`: Delete a custom field definition by `fieldName`. Idempotent. Cannot delete core system fields.
- `delete_domain`: Remove a sending domain. Idempotent.
- `delete_email_design`: Permanently delete a design and all its versions. Idempotent -- deleting an already-gone design still returns success.
- `delete_trigger`: Delete an event trigger. Idempotent. Fails if automations still depend on it.
- `edit_email_with_ai`: Apply a natural-language `prompt` edit to an existing design, producing a new latest version (the old versions are preserved). Optionally pin `emailVersionId` as the edit base. Usage-metered (billed by tokens). Returns a `previewImage` -- it renders inline via the Brew preview widget where supported -- include the Open-in-Brew link.
- `export_email_design`: Export a finished email DESIGN (by `emailId`) to a CONNECTED third-party ESP as a reusable template. `provider` is one of klaviyo, mailchimp, hubspot, braze, iterable, postmark, onesignal, sendgrid, mailgun. This is NOT a Brew send -- it creates a template in the destination platform, does not deliver to recipients, and is unrelated to Brew sending domains or audiences. The ESP must already be connected for the brand (connect it in the Brew app first) -- otherwise this returns a not-connected error. The HTML is automatically made ESP-portable, so destination template-parser errors are handled here. Optional `templateName` defaults to the design title. Pass `dry_run: true` to validate the design + ESP connection without creating a template. For EXISTING markup use `import_email_design`; to send from Brew use `send_email`.
- `fire_trigger_event`: Fire a published trigger (by `triggerEventId`) with an event `payload` to start its automation(s) -- the payload's fields must match the trigger's schema. Returns the trigger instance id + started automation run ids; 404 if the trigger is unknown, 403 if it isn't your brand, 422 if no published automation listens for it. ALWAYS pass a unique `idempotency_key` so a retry never fires twice.
- `generate_image`: Generate an on-brand image from a prompt, returning a hosted URL to use in a design. Usage-metered (billed by image generation).
- `get_analytics_overview`: The brand analytics OVERVIEW -- the exact read behind the in-app /analytics dashboard (identical numbers): windowed totals (sent/delivered/unique opens/unique human clicks/bounced/complained/...), rates, and a zero-filled timeseries. Defaults to the last 7 days (`from`/`to` to change). Scope with ANY COMBINATION of: `source` (csv of audience|api|automation_manual|automation_integration|automation_custom), `automationId`, `emailId`, `audienceId` (csv -- sends to those saved audiences), `triggerEventId` (csv -- integration trigger events, via their wired automations), or `domain` (sending domain) -- they all compose, so "the welcome automation's spring-sale email sent from mail.acme.com" is one call. Combined filters are answered from raw events under a scan cap; check `truncated` on wide windows. WHICH ANALYTICS TOOL: start HERE for "how is my email doing" questions; drill into rows with `get_event_analytics`, one send with `get_send_analytics`.
- `get_automation_analytics`: Windowed automation performance (per-automation send + engagement metrics over a time range). WHICH ANALYTICS TOOL: use this for AUTOMATION/flow performance; for one-off campaign sends use `get_send_analytics` or `get_campaign_analytics`.
- `get_brand`: Get the brand this connection is scoped to -- name, colors, voice, logos, and `ready` status. Add `include` for richer fields. Check `ready` before generating emails.
- `get_brew_capabilities`: Return the machine-readable Brew capability catalog -- auth, permission scopes, rate limits, per-operation credit costs, pagination, the error envelope -- PLUS the end-to-end workflows (create -> send -> analyze, segment, automate, personalize-with-CRM). Call this first to learn how Brew bills and how to chain the tools.
- `get_campaign_analytics`: Lifetime per-campaign KPIs (sent, delivered, opened, clicked, bounced, etc.) across the brand. Page with `cursor`/`limit`; filter by date. WHICH ANALYTICS TOOL: use this for campaign TOTALS over time; for one send's live status/stats use `get_send_analytics`; for individual recipient events use `get_event_analytics`.
- `get_chat_context`: Load a Brew chat to resume it here. Pass the `chatId` from the handoff prompt; returns the chat title, the emails + automations it created/referenced (latest version, with preview), the trigger events it touched, and a trimmed transcript of what was discussed. Then load the referenced entities with the email/automation/brand tools. Read-only; scoped to the connected brand (a chat in another brand returns not-found).
- `get_domain_health`: The domain's deliverability health in one FREE read: a `verdict` (healthy / at_risk / critical) with actionable `signals` (each names the fix + the tool for it), DNS/auth state incl. DMARC (with the exact record to add when missing), active warmup ramps + daily volume, sampled bounce/complaint rates, workspace reputation, and recent inbox-placement history. START HERE for any deliverability / spam / reputation question -- run a placement test only when content-level placement is the actual question.
- `get_event_analytics`: The unified per-recipient event feed (sent/delivered/opened/clicked/bounced/complained/unsubscribed) across the brand. Filter by `eventType`, `recipientEmail`, date -- and slice by SEND OBJECT: `source` (csv of audience|api|automation_manual|automation_integration|automation_custom), `audienceId`, `emailId` (design), `domain` (sending domain), `triggerEventId` (csv of integration trigger events); send-object facets return email events only, each row enriched with `sendSource` + `sendContext` (the audience name / 'API triggered' / automation name) + `triggerProvider`/`triggerTitle` (the wired integration). Machine/bot clicks are EXCLUDED by default (matching the overview's rollups) -- pass `includeMachineClicks: true` for the raw audit view. WHICH ANALYTICS TOOL: use this for the raw event STREAM (who opened/clicked, when); for windowed brand totals+rates start with `get_analytics_overview`; for one send's aggregated stats use `get_send_analytics`; for per-campaign lifetime totals use `get_campaign_analytics`.
- `get_inbox_placement_results`: Fetch inbox-placement test results (from `create_inbox_placement_test`). With `testId`: one test -- while `status` is `collecting` this live-refreshes from the provider (re-poll every ~30s until `completed`/`partial`); returns per-provider inbox/spam/missing tallies with ACTUAL folders (e.g. Gmail Promotions, Yahoo bulk), each provider's OWN SPF/DKIM/DMARC verdicts, Microsoft's SCL junk score, a spoofing check, a `spamFilter` content verdict with triggered rules, and a `diagnosis` array -- per-provider findings with concrete remediation (RELAY the relevant fixes to the user). WITHOUT `testId`: lists the design's recent tests (lean rows, persisted snapshots -- poll a testId to refresh) for comparing variants side by side. Free.
- `get_send_analytics`: The unified send read. LIST sends (filter `status`, `from`/`to`, `emailId`), or pass `sendId` for one send's lifecycle status + aggregated stats. Add `include: ["events"]` (with `sendId`) for the per-recipient event feed. This is how you poll a send started by `send_email`. WHICH ANALYTICS TOOL: use this for a SINGLE campaign send; `get_campaign_analytics` for lifetime totals per campaign; `get_event_analytics` for the brand-wide raw event stream; `get_automation_analytics` for automation flows.
- `get_usage`: Get the org billing + quota surface: current `plan`, remaining `credits`, and the `emailSends` allowance/usage for the period. Check this before metered operations.
- `html_to_png`: Render an HTML string to a hosted PNG image (e.g. an on-demand email preview). Fixed 1 credit.
- `import_contacts_csv`: Bulk-import contacts from CSV content with a column->field mapping. Returns an import summary (created/updated/skipped). Set `validate: true` to also run a real deliverability check on each address (2 credits per row, charged on success) and save the verdicts to the contacts; imports over 100 rows validate as a background job (`validationJobId` in the response).
- `import_email_design`: Import existing HTML, MJML, or React-Email JSX (as a string) into an editable Brew design. Returns the new `emailId` + version + a `previewImage` -- it renders inline via the Brew preview widget where supported -- include the Open-in-Brew link. Usage-metered (billed by tokens).
- `import_figma_design`: Deterministically convert a selected Figma frame into an editable Brew email design and return React Email JSX or rendered HTML. The API-key brand must have Figma connected, and `figmaUrl` must contain a `node-id`. Returns the created email ids, source content, conversion diagnostics, and a preview when capture succeeds. Free; no model or credits are used.
- `list_audience_runs`: List manual-audience automation runs (each "Run" of a manual-audience automation), or fetch one by `audienceRunId`. Shows status, recipient totals, and the per-node funnel (entered -> sent). Filter by `automationId`.
- `list_audiences`: List the brand's saved audiences (each is a saved FILTER over contacts), or fetch one by `audienceId`. The `count` on each row is a cached member snapshot; pass `include: ["count"]` (with an `audienceId`) to recompute the exact, current member total a send would target. Page with `cursor`/`limit`.
- `list_automation_runs`: List automation runs (each execution), or fetch one by `automationRunId`. Add `include: ["logs"]` (detail-only) for per-node logs. Filter by automation/status/date.
- `list_automations`: List automations, or fetch one by `automationId`. Add `include: ["graph","versions"]` (detail-only) for the node graph + version history. Page with `cursor`/`limit`.
- `list_custom_fields`: List the brand's custom contact-field definitions (name, type). Use these keys in a contact's `fields` map. Pass include=coverage to also get per-field fill stats (% of contacts with a non-empty value + most common values; add audienceId to scope to one saved audience) -- check this BEFORE using a field as a {{ field | fallback }} merge tag so you personalize on fields contacts actually have.
- `list_domains`: List the brand's sending domains, or fetch one by `domainId`. Each row carries verification status + the DNS records to add. Pass `sendableOnly: true` for only verified, sendable domains.
- `list_email_designs`: List the brand's email designs, newest first -- or fetch ONE by passing `emailId`. Add `include: ["html"]` or `["versions"]` (only valid with `emailId`) for the rendered HTML or version history. Page with `cursor`/`limit`; filter by status/date. Returns design metadata + `previewImage`, never the heavy HTML unless requested.
- `list_templates`: List the public Brew template gallery (org-wide, not brand-specific) to start a design from. Page with `cursor`/`limit`; filter by `category`.
- `list_trigger_instances`: The fired-trigger audit log -- each time a trigger fired, with its payload + the runs it started. Filter by trigger/date; page with `cursor`/`limit`.
- `list_triggers`: List event triggers, or fetch one by `triggerEventId`. A trigger is the named event an automation listens for; fire one with the `fire_trigger_event` tool.
- `pause_send`: Manually pause an in-flight GRADUAL (domain-warmup) send. The workflow parks the active batch's unsent tail at its next gate poll (≤120s) and holds until `resume_send` (or `cancel_send`). Resuming re-spreads that tail and shifts later batches to prevent a burst. A send that is not a delivering (`sending`) gradual send returns `409 SEND_NOT_PAUSABLE`.
- `preview_email_across_clients`: See how a design's latest version actually renders in real inboxes & devices -- Gmail, Outlook, Apple Mail, iOS (with dark-mode variants), plus Yahoo. Pass `clients` (ids from the supported set) to target a SPECIFIC inbox/device, or omit for a popular spread. Returns a screenshot image per client -- SHOW the user each `![label](imageUrl)`. Rendering is bounded: any clients still processing come back in `pending` (re-run to retry). Costs 10 credits, billed only when at least one preview renders -- a zero-preview batch returns a retryable error and is NOT charged.
- `restore_email_version`: Restore a previous `version` of a design as a new latest version (non-destructive). Use `list_email_designs` with `include: ["versions"]` to find version numbers. Returns a `previewImage` -- it renders inline via the Brew preview widget where supported -- include the Open-in-Brew link.
- `resume_send`: Resume a manually paused gradual send. The unsent tail is re-spread and later batches shift so missed intervals never compress into a burst. A send that is not a `paused` gradual send returns `409 SEND_NOT_RESUMABLE`.
- `run_automation`: Launch a MANUAL-AUDIENCE automation against its bound audience. Pass `dry_run: true` to preview, `scheduledAt` to launch later, and percentage-based `gradualSend` to deliver each send step in custom batches. The config supports hour or calendar-day intervals and manual pause/resume/cancel. Returns `audienceRunId`; 400 if the resolved plan exceeds 50,000 recipients, 30 batches, or 30 elapsed days. ALWAYS pass a unique `idempotency_key`.
- `search_brand_images`: Browse or semantically SEARCH the brand image library. Pass `q` for a natural-language semantic search (metered, 1 credit), or omit `q` to browse/filter for free. Filter by `type`/`aspectRatio`; page with `cursor`/`limit`.
- `search_contacts`: The canonical contacts READ. Pass a filter DSL (`filters[]` + `logic`), an `audienceId`, and/or a text `search`; sort + page with `cursor`. Filter operators are MongoDB-style -- `equals`, `not_equals`, `contains`, `in`, `gt`/`gte`/`lt`/`lte`, `exists`, ... -- e.g. `{ field: "email", operator: "equals", value: "a@b.com" }` fetches one contact by email. Set `count: true` for just the total.
- `send_email`: Send a design as a one-off CAMPAIGN to a saved `audienceId` or inline `to` list (≤50) via a verified `domainId` -> `202 { sendId }`. For QA, `test: true` + one `to` -> a single test email. ALWAYS pass a unique `idempotency_key`. Real campaigns send to real people -- confirm the recipient count + preview with the user first; already-delivered recipients can never be un-sent, though `cancel_send` pulls a scheduled/queued send and stops the remainder of one already in flight. Poll results with `get_send_analytics`. For recurring/triggered sends use an automation + `fire_trigger_event`, NOT a `send_email` loop. For a NEW or cold sending domain, prefer percentage-based `gradualSend` over a full blast.
- `test_automation`: Test-run an automation END-TO-END through the real workflow -- the canonical way to QA a flow. Works on DRAFTS (no publish needed) and for BOTH trigger types (event and manual-audience); every node executes (payload filters/splits evaluate against your `payload`, wait nodes fast-forward). ENGAGEMENT-mode filters can't be exercised in a test run -- no real opens/clicks exist, so their window fast-forwards and every contact takes the everyone-else output; QA those branches with a published run + real engagement. Pass `testRecipient` to DELIVER each send-email node's email for real to that address (real subject/preview/sender name via the Brew test domain; customer addresses are never hit) -- omit it for a silent dry-run. Poll `list_automation_runs` (add `include: ["logs"]`) for per-node status. Test runs never touch analytics or send quotas.
- `transform_image`: Transform a hosted image: `optimize` (compress, 1 credit) or `resize` to widthxheight (2 credits). Returns a hosted URL.
- `update_audience`: Update a saved audience (e.g. rename or change its filter).
- `update_automation`: Update an automation graph, or change its runtime state. Graph filter/split conditions use the same explicit typed, canonical snake_case contract as `create_automation`; unary operators omit `value`. `{ published: true|false }` publishes/unpublishes: publishing validates the graph and pins design versions (a bad graph returns `PUBLISH_VALIDATION_FAILED` with `details.blockers`); unpublishing stops the trigger firing NEW runs, while contacts already mid-sequence keep receiving the rest of it unless you also pass `{ stop_in_flight: true }`, which permanently stops them (already-sent emails stay sent). `{ paused: true|false }` instead FREEZES a live automation: contacts mid-sequence stop receiving email and hold where they are, resuming from the same point -- use this for a temporary "stop the emails while I fix something". New contacts keep entering a paused flow for 24h, then stop. Pause and publish are separate actions; send them as separate requests -- and note that unpublishing RELEASES any pause (held contacts resume draining unless you also pass `stop_in_flight: true`).
- `update_brand`: Update the brand's identity fields (name, colors, voice, etc.). Partial -- only the fields you pass change.
- `update_contact`: Update a contact by email -- standard fields and/or custom `fields`. Partial; only the keys you pass change.
- `update_domain`: Update a domain (e.g. its default from/reply-to sender addresses).
- `update_trigger`: Update an event trigger (e.g. rename or change its schema).
- `validate_contacts`: Check whether email addresses are deliverable before importing or sending -- up to 100 at once. Each address comes back as `valid`, `risky` (deliverable but flagged: role account, disposable, catch-all), or `invalid` (undeliverable), with a machine-readable `reason` and a `didYouMean` typo suggestion when the address looks mistyped. Verdicts are also saved onto matching contacts (`validationStatus` + details); addresses with no contact record are just checked. Costs 2 credits per address, charged only on success (if the check can't complete, you get an unbilled 503 -- its suggestion says whether retrying soon can help).
- `verify_domain`: Trigger DNS verification for a domain after adding its records. Returns the updated verification status.

## Links

- [Connect](https://app.usenotra.com/integrations/brew)
- [Website](https://brew.new/?ref=usenotra.com)
- [All integrations](https://www.usenotra.com/integrations.md?ntr=HwjeojEEn0hnxTcp)
