Create an automation
Deterministic create, the body carries the full graph ({ name, triggerEventId?, nodes, connections }). Returns 201 with the bare AutomationRow.
Trigger binding (exactly one): for an EVENT automation pass triggerEventId (then publish with PATCH … { "published": true }). For a MANUAL-AUDIENCE automation OMIT triggerEventId and give the trigger node config: { "mode": "manualAudience", "audienceId": "aud_…" }. It is launched on demand with POST /v1/automations/{automationId}/run rather than published.
Chain POST /v1/emails { prompt } first to mint the design each sendEmail node references, every sendEmail node MUST carry emailId, emailVersionId, domainId, subject, previewText.
Dry-run. Add dryRun: true to validate without persisting; returns 200 with { valid, blockers[], warnings[], blockingIssues[], nodeCounts }. blockingIssues[] lists per-node references to a trigger-payload variable the bound trigger cannot provide ({ nodeId, nodeLabel, surface, variable, reason, fatal }), e.g. after swapping the trigger or removing a payload field. fatal: true (filter/split conditions and triple-brace {{{ }}} body tokens) fails publish; fatal: false (subject/previewText/fromName/replyTo and double-brace body tags) renders empty at send time and is advisory only. valid is false when any fatal blocking issue is present.
Authorizations
Send your Brew API key as Authorization: Bearer brew_xxx.
Headers
Optional idempotency key for safe retries. Reusing the same key with the same request body returns the original response for 24 hours.
1 - 100Body
Response
Dry-run result (no writes). valid indicates whether the graph would publish cleanly.