Skip to Content
Automations

Automations

An automation is a published flow a contact runs through: a welcome series, an onboarding sequence, a win-back. You build the steps, waits and emails on the canvas in the app. The API does the one part only your backend knows: who enters, and when.

trial started -> POST /automations/{id}/enroll -> day3 sends the whole series

The Automation object

{ "id": "aut_9x4v0dz1k2m7", "object": "automation", "name": "Trial onboarding", "status": "active", "trigger": "api", "audience_id": "aud_7k2m9x4v0dz1", "live_version": 3, "sandbox": false, "created_at": "2026-09-01T09:00:00.000Z", "updated_at": "2026-09-08T11:20:00.000Z" }
FieldNotes
statusdraft, active, paused or archived.
triggeraudience_join: the flow also fires on its own as people join the audience. api: only enrolling starts it.
audience_idThe audience the flow runs over. The contact must already be in it, or be created by the same call.
live_versionThe published version number. null if never published, and a draft cannot be enrolled into.
sandboxtrue when the flow only mails members of your own organization. Re-stamped on every publish, so it follows your plan.

List automations

GET/v1/automations

Newest first, cursor-paginated. No scope needed: it names flows, not people.

ParamNotes
statusdraft, active, paused or archived. Archived flows are hidden unless you ask for them.
limit, afterStandard pagination.

An unknown status is 400 invalid_request, not an empty list.

curl "https://go.day3.app/api/v1/automations?status=active" \ -H "Authorization: Bearer $DAY3_API_KEY"

Enroll a contact

POST/v1/automations/{automation_id}/enrollneeds automations:enroll

Puts one person into the flow. day3 then sends them every email in it, on the flow’s schedule, with no further call from you.

FieldTypeRequiredNotes
emailstringYesTrimmed and lowercased first.
attributesobjectNoFlat string to string. Creates the contact if it is new to the audience, merges into it if not.
curl -X POST https://go.day3.app/api/v1/automations/aut_9x4v0dz1k2m7/enroll \ -H "Authorization: Bearer $DAY3_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: trial-start-user-8412" \ -d '{ "email": "jane@acme.com", "attributes": { "plan": "trial", "company": "Acme" } }'
{ "object": "enrollment_result", "outcome": "enrolled", "enrollment_id": "aen_4v0dz1k9x2m7" }

attributes decides whether a stranger is created

  • With attributes, an unknown address is created in the flow’s audience as subscribed, then enrolled. Contacts rules apply: values must be strings, unknown keys register as fields, null deletes a key, and the merge is shallow.
  • Without attributes, an unknown address returns not_subscribed. Nothing is created, nothing is sent.

Enrolling never grows a list by accident. Send attributes, even {}, when you mean “create this person if they are new”.

Outcomes

Any understood call returns 200. Only enrolled started a run. Branch on outcome, not on the status code.

outcomeWhat happened
enrolledA run started. enrollment_id is set.
already_enrolledThe flow’s re-entry rule says this person is already in it.
not_subscribedNot in the audience, or not subscribed. Unsubscribed, bounced and pending contacts land here.
suppressedThe address is on the account’s suppression list.
entry_filter_no_matchThe flow’s entry filter does not match this contact.
sandbox_not_memberThe flow is in sandbox mode and the address is not a member of your organization.
wrong_audienceThe contact exists, but in a different audience than the flow.
automation_not_activeThe published version is unusable. Rare, and worth reporting.

Always send Idempotency-Key. Lifecycle events fire twice all the time, and a duplicate enrollment sends the whole series twice. See Idempotency.

A paused flow still accepts enrollments

Enrolling into a paused automation succeeds and the person waits at the trigger until you resume. Pausing to fix a typo must not drop every signup in the meantime.

A draft or archived automation is 409 invalid_request: nothing published to run.

Why this needs a scope

Enroll requires the automations:enroll scope. Without it: 403 insufficient_scope. Mint a new key; scopes cannot be added to an existing one.

An enrollment promises a contact every email in the flow, with no further call from the key holder. That is a bigger commitment than one campaign send, not a smaller one. Listing is unscoped because flow names reach nobody.

Errors

StatusCodeCause
400invalid_emailThe address is not valid.
400invalid_requestAn unknown status filter, or an attributes value that is not a string.
403insufficient_scopeThe key lacks automations:enroll.
404not_foundNo such automation on this account.
409invalid_requestThe automation is a draft or archived. Publish it first.
409email_suppressedThe address is suppressed, so creating the contact was refused.

409 email_suppressed only happens when you sent attributes: the contact write was refused. The suppressed outcome is a 200: the contact exists and was not enrolled. Both mean the address is unmailable.

From an AI editor

MCP exposes the same two operations as day3_list_automations and day3_enroll_in_automation, with the same scope on enroll.

Not in the API

The canvas. Creating flows, editing nodes, wait steps, entry filters, re-entry rules, the enrollment browser and automation statistics are app-only. If you need one from code, it does not exist yet.

Last updated on