v1
latestOpenAPI 3.1.02026-07-2670105729.6 KBCreate 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.
Typed conditions: every filter and condition-mode split uses a non-empty conditions array. Each condition requires field, type (string, number, date, or bool), and a canonical snake_case operator. Unary operators omit value; comparisons require a type-correct scalar, non-empty array, or exact two-value between tuple as documented by AutomationNode.
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.
Headers
Optional idempotency key for safe retries. Reusing the same key with the same request body returns the original response for 24 hours.
Request body
Response
Dry-run result (no writes). valid indicates whether the graph would publish cleanly.