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

# TypeScript Resource Surface

> Complete list of resources and methods in the Brew TypeScript SDK — contacts, emails, sends, automations, triggers, and more — with the HTTP endpoints each method maps to.

## Current Client Surface

The TypeScript SDK is resource-oriented.

```ts theme={null}
import { createBrewClient } from '@brew.new/sdk'

const brew = createBrewClient({
  apiKey: process.env.BREW_API_KEY!,
})
```

## Resources And Methods

| Resource                          | Methods                                                                                                                                      |
| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `brew.analytics`                  | `campaigns()`, `automations()`, `events()`, `eventsAll()`                                                                                    |
| `brew.analytics.sends`            | `list()`, `listAll()`                                                                                                                        |
| `brew.analytics.triggerInstances` | `list()`, `listAll()`                                                                                                                        |
| `brew.audiences`                  | `list()`, `create()`, `update()`, `delete()`                                                                                                 |
| `brew.automations`                | `create()`, `list()`, `patch()`, `publish()` / `unpublish()` (convenience wrappers over `patch({ published })`), `delete()`, `test()`        |
| `brew.automations.triggers`       | `create()`, `list()`, `patch()`, `delete()`, `fire()`                                                                                        |
| `brew.automations.runs`           | `list()`, `listAll()`                                                                                                                        |
| `brew.brand`                      | `get()` (`{ include }` embeds identity / emailDesign / imageStyle / logos), `patch()` / `update()`, `getImages({ q?, type?, aspectRatio? })` |
| `brew.contacts`                   | `upsert()`, `upsertMany()`, `patch()`, `delete()`, `deleteMany()`, `search()`, `searchAll()`, `validate()`, `importCsv()`                    |
| `brew.content`                    | `generateImage()`, `gif({ from })`, `transform({ operation })`, `htmlToPng()`, `addImage()`                                                  |
| `brew.domains`                    | `list()`, `add()`, `verify()`, `updateSettings()`, `delete()`                                                                                |
| `brew.emails`                     | `list()`, `generate()`, `import()`, `edit()`, `auditAccessibility()`, `restore()`, `delete()`, `send()`                                      |
| `brew.sends`                      | `cancel()`                                                                                                                                   |
| `brew.fields`                     | `list()`, `create()`, `delete()`                                                                                                             |
| `brew.help`                       | `get()`                                                                                                                                      |
| `brew.templates`                  | `list()`                                                                                                                                     |
| `brew.usage`                      | `get()`                                                                                                                                      |

Reads are **flat**: every resource has exactly one `list()`. Pass the
resource's id key for a single row, and `include` to embed heavier
detail:

| Read                                     | Single-row form                                    | `include` opt-ins   |
| ---------------------------------------- | -------------------------------------------------- | ------------------- |
| `brew.emails.list()`                     | `list({ emailId })` (carries `previewImage`)       | `html`, `versions`  |
| `brew.audiences.list()`                  | `list({ audienceId })`                             | `count`             |
| `brew.automations.list()`                | `list({ automationId })`                           | `graph`, `versions` |
| `brew.automations.runs.list()`           | `list({ automationRunId })`                        | `logs`              |
| `brew.automations.triggers.list()`       | `list({ triggerEventId })`                         | —                   |
| `brew.analytics.triggerInstances.list()` | `list({ triggerInstanceId })`                      | —                   |
| `brew.analytics.sends.list()`            | `list({ sendId })` (also filter by `{ emailId }`)  | `events`            |
| `brew.domains.list()`                    | `list({ domainId })` (or `{ sendableOnly: true }`) | —                   |

The contact read is `brew.contacts.search({ filters, audienceId?, search?, sort, count?, cursor })` —
look up one address with a `{ field: 'email', operator: 'equals', value }`
filter.

The public SDK surface is **deterministic-only** — `brew.automations`
and `brew.automations.triggers` do not expose AI authoring methods. AI
body generation is still available on `brew.emails.generate({ prompt })`;
chain it with `brew.automations.create({ … })` to assemble automations
programmatically. To ingest existing markup as an editable design, use
`brew.emails.import({ format, content })`.

Every list method accepts `{ limit, cursor }` and returns the uniform
`{ data, pagination }` envelope — loop `while (pagination.cursor !== null)`.
`contacts.searchAll`, `analytics.sends.listAll`, `automations.runs.listAll`,
`analytics.triggerInstances.listAll`, and `analytics.eventsAll` are async
iterators that page through the whole result set for you via the shared
`autoPaginate` helper.

`brew.brand.get()` is read-only — there is no brand *management*
resource. It returns the single brand bound to your API key plus its
extraction readiness.

`brew.help.get()` hits `GET /v1/help` — a no-auth, machine-readable
catalog (auth, scopes, rate limits, per-operation credit metering, the error
envelope, and the full endpoint list) any MCP server or agent can parse
to self-discover the API.

## Common Flow — Trigger → Emails → Automation → Publish → Fire

End-to-end deterministic recipe: create a custom trigger, mint each
email body in parallel, assemble the graph referencing those `emailId`s,
publish, and fire. Every step returns a typed result.

```ts theme={null}
import { createBrewClient } from '@brew.new/sdk'

const brew = createBrewClient({ apiKey: process.env.BREW_API_KEY! })

// 1. Create the trigger (deterministic shape — provider is hardcoded brew_api).
//    Create returns the bare trigger row (HTTP 201).
const trigger = await brew.automations.triggers.create({
  title: 'Subscription Renewed',
  description: 'Fires when a subscription is renewed.',
  payloadSchema: {
    type: 'object',
    fields: [
      { key: 'email', type: 'string', required: true },
      { key: 'plan', type: 'string', required: true },
      { key: 'amount', type: 'int', required: true },
    ],
  },
})

// 2. Pre-mint each email body. These rows are referenced by sendEmail
//    nodes inside the automation graph.
const [welcome, gettingStarted] = await Promise.all([
  brew.emails.generate({
    prompt: 'Thank-you email for a successful renewal.',
  }),
  brew.emails.generate({
    prompt:
      'Getting-started tips for renewed subscribers — focus on the Pro features.',
  }),
])

// 3. Assemble the automation graph; sendEmail nodes reference the
//    pre-minted emailIds + emailVersionIds.
const automation = await brew.automations.create({
  name: 'Renewal welcome flow',
  triggerEventId: trigger.triggerEventId,
  nodes: [
    {
      id: 'trg',
      label: 'On renewal',
      type: 'trigger',
      config: { triggerEventId: trigger.triggerEventId },
    },
    {
      id: 'send_welcome',
      label: 'Welcome',
      type: 'sendEmail',
      config: {
        emailId: welcome.emailId,
        emailVersionId: welcome.emailVersionId,
        domainId: 'dom_brand_primary',
        subject: 'Welcome back, {{firstName | there}}!',
        previewText: 'Quick thanks + 2 things to try first.',
      },
    },
    {
      id: 'wait_2d',
      label: 'Wait 2 days',
      type: 'wait',
      config: { duration: 2, unit: 'days' },
    },
    {
      id: 'send_getting_started',
      label: 'Getting started',
      type: 'sendEmail',
      config: {
        emailId: gettingStarted.emailId,
        emailVersionId: gettingStarted.emailVersionId,
        domainId: 'dom_brand_primary',
        subject: 'Getting started with Pro',
        previewText: 'Three feature tips for your first week.',
      },
    },
  ],
  connections: [
    { from: 'trg', to: 'send_welcome' },
    { from: 'send_welcome', to: 'wait_2d' },
    { from: 'wait_2d', to: 'send_getting_started' },
  ],
})

// 4. Publish (convenience wrapper over patch({ published: true })).
await brew.automations.publish({ automationId: automation.automationId })

// 5. Fire the trigger with a real payload.
const fire = await brew.automations.triggers.fire({
  triggerEventId: trigger.triggerEventId,
  payload: {
    email: 'jane@example.com',
    plan: 'Pro',
    amount: 4200,
  },
  idempotencyKey: 'renewal-jane-2026-04-08',
})
console.log('Started automation runs:', fire.details?.automationRunIds)

// 6. Poll the run lifecycle (reads live under automations.runs).
const { data: runs } = await brew.automations.runs.list({
  automationRunId: fire.details!.automationRunIds[0]!,
  include: 'logs',
})
console.log('Status:', runs[0]!.status)
```

## Reading sends + trigger instances

Send delivery splits in two: the **write** is `brew.emails.send(input)`
(pass `test: true` for a one-off QA send), and every **read** lives on
`brew.analytics.sends.list()` — one flat read, identity in the query. To
pull back a scheduled or queued send before it goes out, call
`brew.sends.cancel(sendId)`.

```ts theme={null}
// Send an email design to a target (write).
const accepted = await brew.emails.send({
  emailId: 'eml_x',
  domainId: 'dom_y',
  audienceId: 'aud_z',
  subject: 'Launch update',
  scheduledAt: '2026-07-01T09:00:00Z',
})

// Pull it back before it goes out (idempotent — already-canceled is a no-op).
const { status } = await brew.sends.cancel(accepted.sendId) // → 'canceled'

// Poll its lifecycle + stats, with the per-recipient event feed inlined (read).
const { data: sends } = await brew.analytics.sends.list({
  sendId: accepted.sendId,
  include: 'events',
})
const send = sends[0]!
console.log(send.status, send.stats?.delivered)
for (const ev of send.events ?? []) {
  console.log(ev.eventType, ev.recipientEmail)
}

// All sends for one design.
const { data: forEmail } = await brew.analytics.sends.list({ emailId: 'eml_x' })

// Fired-trigger instances (the audit trail of every trigger fire).
const instances = await brew.analytics.triggerInstances.list({ triggerEventId: 'tri_signup' })
```

## AutomationNodeInput — per-kind discriminated union

`AutomationNodeInput` is a discriminated union by `type`; setting
`node.type` narrows `node.config` automatically. The five node kinds
map 1:1 to the server-side Zod schemas:

| `node.type` | `node.config` shape                                                               |
| ----------- | --------------------------------------------------------------------------------- |
| `trigger`   | `{ triggerEventId? }`                                                             |
| `sendEmail` | `{ emailId, emailVersionId, domainId, subject, previewText }` (all five required) |
| `wait`      | `{ duration, unit: 'minutes' \| 'hours' \| 'days' \| 'weeks' }`                   |
| `filter`    | `{ logicalOperator, conditions[] }`                                               |
| `split`     | `{ mode: 'percentage' \| 'condition', … }`                                        |

Each `sendEmail` node's `subject` / `previewText` support
`{{variable | fallback}}` interpolation against the trigger payload.

## Source Of Truth

The SDK follows the Brew OpenAPI contract. If you want the raw HTTP
shape behind any method, use the API reference in this docs site.

## 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 analyze documentation with ChatGPT or Claude for deeper insights.
      </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>
