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.
When to use this cookbook
You’re building an AI agent (or any LLM-powered workflow) that should manage Brew automations without the dashboard UI. The Brew SDK exposes every authoring, lifecycle, and execution path through typed deterministic methods. AI authoring stays scoped to email body generation (brew.emails.generate({ emailType, prompt })); the rest
of the surface — triggers, automation graphs, publish, fire — works
on explicit shapes so the agent’s intent is always inspectable.
Mental model
Brew has three primary entities the SDK works with:| Entity | What it is | SDK resource |
|---|---|---|
| Trigger event | A schema contract (payloadSchema.fields) plus a stable id. Long-lived. Brand-scoped. | brew.triggers |
| Automation | A graph of nodes (trigger, wait, filter, split, sendEmail) that fires on one trigger. Versioned. | brew.automations |
| Automation run | One workflow run started by a fire / test / replay. | brew.automationRuns |
Recipe 1: End-to-end deterministic flow
The canonical recipe. Define the trigger explicitly, mint the email bodies in parallel, then assemble and publish the graph.Recipe 2: Reuse an existing trigger
When your codebase already wires a stable trigger id (auth, billing, or platform webhook), skip step 1 and reuse it across multiple automations:Recipe 3: Discover existing automation-typed bodies before authoring
brew.emails.list({ emailType: 'automation' }) returns every body
already minted for the brand so the agent can reuse instead of
re-generating duplicates:
Recipe 4: Fire a trigger from your backend
After publishing, your application code callsbrew.automationRuns.fire
whenever the real-world event happens. Always pass an
idempotencyKey so retries don’t double-fire. metadata is NOT
accepted — the trigger payload carries everything the workflow
runtime sees.
automationRunIds so you can
correlate analytics. Retries with the same idempotencyKey replay
the original automationRunIds without starting new workflow runs.
Recipe 5: Test an automation against synthetic data
Usebrew.automationRuns.test to run an automation with
mode: 'test' (no real mail is sent — sendEmail nodes simulate).
Returns a real run row you can inspect via
brew.automationRuns.get + ?include=logs.
Recipe 6: Edit a published automation safely
Usebrew.automations.patch({ automationId, nodes, connections })
to publish a new version of the graph deterministically. The
previously-published row stays live until you publish the new
version explicitly.
Recipe 7: Dry-run validate before publishing
PassdryRun: true on create (or patch) to get the same
validateAutomationForPublish result the publish flow runs — without
touching Convex:
Error matrix
Every method throwsBrewApiError on transport / auth / business
errors. The error envelope carries code, type, message,
suggestion, docs URL, and the offending param when relevant.
| Code | When |
|---|---|
AUTHENTICATION_REQUIRED / INVALID_API_KEY / API_KEY_REVOKED | Auth fails. |
BRAND_SCOPE_MISMATCH | API key brand differs from the resource brand. |
INVALID_REQUEST | Body fails Zod validation — typically a missing emailType on brew.emails.generate, an unknown field (including the removed provider on brew.triggers.create, metadata on brew.automationRuns.fire/.test, or emails[] on brew.sends.create), or trying to send the removed prompt field on brew.triggers.create / brew.automations.create. |
PAYLOAD_SCHEMA_EMAIL_REQUIRED | payloadSchema.fields is missing the required email field. |
TRIGGER_EVENT_NOT_FOUND | The supplied triggerEventId doesn’t exist in the brand. |
TRIGGER_IMMUTABLE | Tried to PATCH an integration trigger. |
TRIGGER_HAS_DEPENDENT_AUTOMATIONS | DELETE refused — detach automations first. |
AUTOMATION_NOT_FOUND | Unknown automationId in this brand. |
AUTOMATION_NOT_PUBLISHED | Tried to unpublish an automation that’s not live. |
PUBLISH_VALIDATION_FAILED | Publish blocked — the message describes the blocker. |
AUTOMATION_RUN_NOT_FOUND | Unknown automationRunId in this brand. |
NOT_IMPLEMENTED | Replay + cancel (currently behind P7). |
IDEMPOTENCY_CONFLICT | Same idempotency key reused with a different request body. |
RATE_LIMITED | Window exhausted — back off using Retry-After. |
Determinism vs AI authoring — what lives where
The public SDK / HTTP surface is intentionally deterministic for graph authoring. AI is scoped to email body content only viabrew.emails.generate({ emailType, prompt }).
| Layer | AI involved? |
|---|---|
Trigger payload schema (brew.triggers.create) | Never — caller supplies explicit { key, type, required } fields. |
Automation graph (brew.automations.create / patch) | Never — caller supplies explicit { nodes, connections }. |
Email body (brew.emails.generate) | Yes — the email subagent renders HTML from the prompt. |
Subject / preview line (sendEmail.config.subject) | Optional {{variable | fallback}} interpolation against the trigger payload, evaluated at fire time. |
/chat in the dashboard) — that
surface still exposes the routeToAutomationAgent /
createTriggerEvent tools internally.
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:- Self-Service Tools
- Talk to Our Team
Search Documentation
Type in the “Ask any question” search bar at the top left to instantly find relevant documentation pages.
ChatGPT/Claude Integration
Click “Open in ChatGPT” at the top right of any page to analyze documentation with ChatGPT or Claude for deeper insights.