Automations turn hub events into actions. Instead of a single linear drip, you build a flowchart: a trigger starts a run, and each contact moves through nodes — send an email, wait, branch on a condition, add or remove a tag, hand off to a drip sequence, call a webhook, or exit.
A drip sequence becomes one node inside an automation. A one-step automation (one trigger, one action) is a “rule”. Same engine for both.
How it works
- Triggers subscribe an automation to an event type (e.g. a member joining, a purchase, a tag being applied, or a custom event you fire yourself).
- Each matching contact gets an enrollment — an independent run through the published graph. Enrollments are idempotent (one event enrolls a contact at most once) and honor a per-automation re-entry policy (
never, after_exit, interval).
- A published version is an immutable snapshot. Editing a draft and re-publishing creates a new version; in-flight enrollments keep running on the version they started on.
Node types
Authoring lifecycle
Automations are hub-scoped and require a team owner. The lifecycle is draft → publish (snapshot + validate) → activate.
A create body carries the graph in attributes.definition:
publish validates the graph (reachability, branch edges must be labeled, condition trees compile against your tags/segments) and returns a versioned snapshot. Branch tag_slug values are resolved to IDs at publish time, so the referenced tags must already exist.
add_tag / remove_tag node configs take a raw tag_id (a tag’s UUID — copy it from mio tags list), not a tag_slug: the config schema is { "tag_id": "<uuid>" } and rejects any other key ({"tag_slug": …} → “Extra inputs are not permitted”). Only branch has_tag conditions (and segment conditions) accept a tag_slug, which is resolved to an id at publish time.
Most enrollments happen automatically when a trigger event fires. You can also enroll manually, or fire your own custom event from an integration.
Custom events require an idempotency_key (deduplicated per team) and identify the contact:
Returns 202 on a new event, 200 on a duplicate. Use /test to dry-run a contact through the published graph: it runs the real branch logic and reports the step trace without sending email, applying tags, or firing webhooks.
/test is the safe way to confirm routing before you turn an automation on — branches evaluate for real, but every side effect is stubbed.
Webhook endpoints
The webhook node POSTs a signed JSON payload to an endpoint you register. Targets are validated against an SSRF guard (private, loopback, link-local, and cloud-metadata addresses are rejected), the signing secret is encrypted at rest and never returned, and delivery is asynchronous with exponential-backoff retries.
Reliability
- Triggers are delivered from a durable event outbox, so a server hiccup never silently drops an enrollment.
- Each node executes at most once per enrollment (idempotency keys); failed steps retry, then move to a dead-letter queue rather than looping.
wait is real scheduling — a run resumes when its timer is due, even days later.