Skip to content
Coritan Docs

Send emails automatically with automations

Start a series of waits, emails, conditions and actions when a contact joins a list, gets a tag, fills in a form or orders, and read what each step did.

View as Markdown

Automations holds the emails and actions that start when a contact does something, such as joining a list, getting a tag, filling in a form or placing an order. An automation is a trigger and a flow of steps. When the trigger happens to a contact, that contact goes through the steps one at a time. Once an automation is on, it runs for each contact on its own.

  • You need Tier 1 support or higher to read automations and Tier 3 support or higher to change them.
  • Set up the sending domain (Set up your sending domain and warm-up). You can build and save an automation before that, but its emails cannot go out, and a test email needs it.
  • Make what the trigger and the steps name first: the list, the form, the tag or the date field, and the saved designs.
  • An automation reaches only subscribed contacts. Manage your email contacts, lists and segments covers how contacts become subscribed.

The store's flows and automations

Section titled The store's flows and automations

The store's own emails for a cart left behind, a checkout that went unpaid and an order to reorder stay under Flows. They are three fixed emails with their own timing, and they keep working as they are. Automations are for everything that starts from your audience: a welcome series, a thank you after a first order, a win-back for quiet customers, a reminder before a date.

Flows and automations share one suppression list. An address that unsubscribes from either gets nothing from the other. An address can get both a flow email and an automation email, so avoid two series that say the same thing to the same shopper.

  1. In the dashboard, open the organization, then Commerce, then Email, then Automations.
  2. Select New automation….
  3. Enter a Name. Only you see it.
  4. Choose Starts when, and fill in what the trigger needs.
  5. Choose How often a contact can start: Once per contact or Every time.
  6. Select Create automation. The builder opens on a draft.

Add steps from Add first step and Add step after. A step opens in its own card when you select Edit. Each card has an actions menu (Actions for step) with Move up, Move down and Delete step…. Select Save to keep your changes, then Turn on.

An automation is Draft until you turn it on, On while it runs, Paused while stopped, and Archived when you are done with it. The list filters by these, with All.

Trigger When a contact starts
Joins a list A subscribed contact joins the list you choose, from a form, an import or a person adding them.
Gets a tag The tag you name is added to a contact.
Fills in a form Someone signs up through the form you choose. With a confirmation email, they start once they confirm.
A date field comes around Every year on the day held in a custom date field, such as a renewal date. Set Days after the date: a negative number starts before the date, a positive one after it, and 0 on the day. A contact starts once a year, whatever the entry limit says.
Places a first order A subscribed contact places the first order they have placed in your store.
Places an order A subscribed contact places an order. Set the entry limit to Every time to start again after each order.
Buys a product A subscribed contact orders the product you choose, by its product ID or a variant's SKU.
Has not ordered for a while A subscribed contact's last order is the number of days old you set, from 1 to 730. It checks once a day.

A contact enters only while subscribed. A contact does not enter an automation twice unless the entry limit is Every time and their earlier run is over. An order starts a contact once, however many times the order's event arrives.

Step What it does
Wait Holds the contact for a number of Days, Hours and Minutes. Set at least one, up to 365 days in all.
Wait until a time of day Holds the contact until the clock next shows the Time of day, such as 09:00, in the Time zone you choose. UTC is the default.
Send an email Queues an email to the contact. It needs a Subject of up to 200 characters, and a design or a Saved design. Preview text and Sender name are optional.
If / else Sends the contact down a Yes path or a No path. See Conditions.
Add a tag, Remove a tag Puts a tag on the contact, or takes it off. A tag is created when it does not exist.
Add to a list, Remove from a list Adds the contact to a list, or takes it off. A contact who left a list stays off it.
Call a webhook Posts the contact and the run to your address as signed JSON. See Webhook steps.
End Ends the contact's run here.

An automation has at most 40 steps, and a series cannot loop back. A step with nothing after it ends the run.

The Send an email step opens the designer on its own page: select Design the email, then Save email. It has the same blocks and merge tags as a campaign (Write, test and send email campaigns). Choose Use a saved design instead to pick a saved design, and Design the email here instead to go back. An automation's emails count opens and clicks, and they carry your postal address and an unsubscribe link like every marketing email.

A condition is a step that splits the flow in two by a test. Under What to check, choose:

  • Opened the last email: yes when the contact opened the last email this automation sent them, and no when they did not. Opens by mail privacy tools do not count.
  • Matches a rule: a rule or group of rules built as in a segment, over the contact's details, tags, lists, engagement and orders (The rule fields).

Add steps to the Yes and No paths with Add step to yes and Add step to no. A condition ends its path unless you add steps to it.

A Call a webhook step posts to an https address on a public host. The address is checked when you save it and again before each request. The body is compact JSON:

JSON
{"event": "marketing.automation.step", "run_id": 912, "automation_id": 41, "step_id": "notify",
 "livemode": true, "contact": {"id": 3307, "email": "alex@example.com"}}

The request carries X-Coritan-Signature: t=<unix seconds>,v1=<hex>. The hex is the HMAC-SHA256, made with your automation secret, of the value of t, a full stop, and the body as sent. This is the scheme of organization webhooks, under another header name. In the step's card, select Show signing secret to read the secret. It never changes, and Tier 3 support or higher can read it.

Python
import hashlib, hmac

def verified(secret: str, header: str, body: bytes) -> bool:
    parts = dict(item.split("=", 1) for item in header.split(","))
    expected = hmac.new(secret.encode(), parts["t"].encode() + b"." + body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, parts.get("v1", ""))

Each attempt has a limit of 5 seconds, and there is one retry. A failed call is written to the run's error and the automation goes on to the next step.

Turn on checks the whole flow first. It refuses an automation with no steps, a step that is not valid, a loop, or a list, form or saved design that no longer exists, and it names the step. Contacts who were paused inside the automation go on from where they stopped.

An automation that is On does not take changes to its trigger or steps. Select Pause… first. You can change its name and its entry limit at any time. Pause… stops every run where it is, and nobody new enters. Emails already queued still go out. Turn it on again to continue. While an automation is paused, contacts inside it keep their place when you change its steps.

Open Automation actions and choose Send test…. Enter an address under Send to and select Send test. It sends the first email of the automation to that address, with a sample contact's details and [Test] in the subject. It starts no run and records no tracking. An address on the suppression list is skipped. A person or key can send 30 tests an hour, and a test needs sending to be ready.

Results shows Entered, Inside now, Completed, Left early, Failed, Emails sent, Opens, Clicks and Revenue. Opens and clicks leave out machine opens (Machine opens).

Under Flow, each step shows how many contacts are waiting there, and an email step shows how many it sent, and how many were opened and clicked.

Runs lists the contacts that entered, newest first, with their Status, the step they are At, the date of their Next step and when they Started. Filter by Any status, Running, Waiting, Completed, Left early or Failed. A run that ends early shows why: the contact was deleted, is no longer subscribed, or cannot be mailed at an email step, such as an address on the suppression list. A step that fails is tried again after 5 minutes, then after 10, and after three tries the run is Failed with the reason.

Archive or delete an automation

Section titled Archive or delete an automation
  • Archive automation… ends every run inside it and skips the emails not yet sent. Its numbers stay. An archived automation cannot be turned on again, so make a new one.
  • Delete automation… removes an automation that was never turned on. One that has run answers that it has history. Archive it instead.

Each example uses the triggers and steps above. Names are for a board game shop and a coffee roaster.

Welcome new subscribers
Trigger Joins a list with your newsletter list. Steps: Send an email that says thanks and what to expect, Wait 3 days, Send an email with a product grid of your best sellers.
Thank a first-time buyer
Trigger Places a first order. Steps: Wait 7 days, Send an email that asks how the first order went, Add a tag first-order. Use the tag later in a segment.
Win back a quiet customer
Trigger Has not ordered for a while with 90 days. Steps: Send an email with a coupon block, Wait 7 days, If / else on Opened the last email. On Yes, Add a tag warm. On No, Send an email that reminds them the code is about to end.
Remind before a renewal
A custom date field renewal_date on each coffee subscriber. Trigger A date field comes around with Days after the date set to -7. Step: Send an email that reminds them their next bag is on its way.
  • A contact who matches the trigger appears under Runs and moves through the steps. Each email it sends counts under Emails sent.
  • Pausing stops every run where it is, and turning the automation on again lets them continue.
Turn on names a step
That step is not valid, or it names a list, form or design that is gone. Fix the step and select Turn on again.
The trigger and steps cannot be changed
The automation is On. Select Pause…, change it, then turn it on again.
Nobody enters
The contact must be subscribed and match the trigger. A contact who entered before does not enter again with Once per contact. Has not ordered for a while and A date field comes around check once a day.
A run is Left early
Open the run's reason. The contact was deleted, unsubscribed, or cannot be mailed, such as an address on the suppression list.
A run is Failed
A step failed three times. The run's reason says why, such as a design that no longer exists.
Send test… says sending is not ready
Set up the sending domain first (Set up your sending domain and warm-up).
An automation cannot be deleted
It has been turned on, so it has history. Archive it.

The routes are under https://api.coritan.com/api/v1/orgs/{org_slug}/marketing/automations. Reading takes marketing.automations:read and changing takes marketing.automations:write (API key scopes).

GET /automations/catalog lists every trigger and step with its label, its params and, for a step, the branches it leads out of (next, or yes and no). It also lists the entry_limits and limits.max_steps.

POST /automations makes a draft and answers 201 with {automation}:

Shell
curl -X POST "https://api.coritan.com/api/v1/orgs/acme/marketing/automations" \
  -H "X-API-Key: $ORG_API_KEY" -H "Content-Type: application/json" \
  -d '{"name": "Welcome series", "entry_limit": "once",
       "trigger": {"type": "list_joined", "list_id": 3},
       "steps": [
         {"id": "hello", "type": "send_email", "next": "pause", "subject": "Welcome to the shop",
          "template_id": 12},
         {"id": "pause", "type": "wait", "next": "check", "days": 3},
         {"id": "check", "type": "condition", "yes": "tag", "no": "again",
          "rule": {"field": "opened_last_email", "op": "is_true"}},
         {"id": "tag", "type": "tag", "tag": "warm"},
         {"id": "again", "type": "send_email", "subject": "In case you missed it", "template_id": 13}]}'

The first step is steps[0]. next names the step that follows, and a condition names yes and no. A step with no next ends the run. An id is 1 to 32 letters, digits, dashes or underscores. The trigger takes the parameters the catalog lists:

Trigger type Parameters
list_joined list_id
tag_added tag
form_submitted form_id
field_date field (a date field's key) and offset_days from -365 to 365
first_order, order_placed None.
product_purchased One of product_id or sku.
no_order days, from 1 to 730
Step type Parameters
wait days, hours and minutes, at least a minute and at most 365 days in all.
wait_until time as 09:00, and an optional tz such as Europe/Berlin.
send_email subject, optional preheader and from_name, and a design or a template_id.
condition yes, no and a rule: a segment rule or group, or {"field": "opened_last_email", "op": "is_true"}.
tag, untag tag
add_to_list, remove_from_list list_id
webhook url, an https address on a public host.
exit None.

An automation is {id, name, status, trigger, steps, entry_limit, activated_at, stats, created_at, updated_at}. status is draft, active, paused or archived. stats holds entered, active, completed, exited, failed, emails_sent, opens, clicks, orders and revenue in minor units. A refused setting answers 422 with invalid and a field such as steps.check.rule.

  • GET /automations lists automations, newest first, as {total, limit, offset, automations}. status filters. Archived automations are left out unless you ask for archived.
  • GET /automations/{automation_id} reads one. PATCH changes the name and entry_limit at any time, and the trigger and steps while the automation is a draft or paused. An active one answers 409 with automation_active.
  • POST /automations/{automation_id}/activate turns it on, .../pause pauses it and .../archive archives it. Pausing an automation that is not on answers 409 with automation_not_active, and turning on an archived one answers 409 with automation_archived.
  • DELETE /automations/{automation_id} answers {deleted: true, id}, or 409 with automation_has_history once it has run.
  • GET /automations/{automation_id}/runs lists the runs, newest first. status is active, waiting, completed, exited or failed. A run is {id, contact_id, status, current_step, next_run_at, error, context, livemode, started_at, completed_at}, with the contact's email when your key or role can also read contacts.
  • GET /automations/{automation_id}/stats answers {stats, steps}, where each step shows waiting, emails_sent, opens, clicks, orders and revenue.
  • POST /automations/{automation_id}/test takes {"email": "owner@example.com"} and answers {sent, skipped}. It answers 422 when the automation has no email step, 429 after 30 tests an hour, and 409 with sending_not_ready when sending cannot start.
  • GET /automations/webhook-secret answers {secret, header, algorithm, signed_payload}. It takes marketing.automations:write.

API operations on this page

MethodPathWhat it does
GET/api/v1/orgs/{org_slug}/marketing/automationsYour automations, newest first, each with its stats
POST/api/v1/orgs/{org_slug}/marketing/automationsMake a draft automation
GET/api/v1/orgs/{org_slug}/marketing/automations/catalogEvery trigger and step an automation can use, with its settings and a short help text
GET/api/v1/orgs/{org_slug}/marketing/automations/webhook-secretThe secret that signs your automation webhook steps
GET/api/v1/orgs/{org_slug}/marketing/automations/{automation_id}One automation with its trigger, steps and stats
PATCH/api/v1/orgs/{org_slug}/marketing/automations/{automation_id}Update automation
DELETE/api/v1/orgs/{org_slug}/marketing/automations/{automation_id}Delete an automation that was never turned on
POST/api/v1/orgs/{org_slug}/marketing/automations/{automation_id}/activateTurn an automation on
POST/api/v1/orgs/{org_slug}/marketing/automations/{automation_id}/archiveArchive an automation
POST/api/v1/orgs/{org_slug}/marketing/automations/{automation_id}/pausePause an automation
GET/api/v1/orgs/{org_slug}/marketing/automations/{automation_id}/runsThe contacts that entered the automation, newest first
GET/api/v1/orgs/{org_slug}/marketing/automations/{automation_id}/statsAutomation stats
POST/api/v1/orgs/{org_slug}/marketing/automations/{automation_id}/testSend test email