Automations

Intro

Endpoint: https://api.omnisend.com/api/automations

Build event-driven workflows that send messages, apply tags, and branch logic based on contact behavior. Automations are created disabled and must be explicitly enabled to start processing trigger events.

Blocks

Workflows are composed of ordered blocks. Each block has a type discriminator and exactly one type-specific field populated.

Block typeDescription
delayPause the workflow before continuing to the next block
actionExecute an operation (send a message, manage tags)
splitBranch contacts based on event, contact, or message engagement conditions
abTestingRandomly split contacts between two variant paths by percentage

Action types

TypeDescription
sendEmailSend an email using a template (Email Templates API)
sendSmsSend an SMS or MMS message
sendPushSend a web push notification
sendWebhookSend an HTTP POST to an external URL
addTagAdd a tag to the contact
removeTagRemove a tag from the contact

Each send-action block has an isSkipAllowed flag (default true). When true, ineligible contacts skip the block and continue. When false, the workflow is canceled for that contact.

Delay modes

ModeDescription
durationWait for a specified amount of time (duration.amount + duration.units: m/h/d/w/M)
immediateNo wait — proceed to the next block immediately
specificTimeWait until a time of day in the brand's timezone (time in HH:MM 24h format)

All delay modes support optional allowedWeekdays to restrict resolution to specific days.

Split filters

A split evaluates a filterGroup of mixed-type filters:

Filter typefieldoperator examplesvalue
eventEvent property patheq, neq, gt, contains, exists, in, …Property value
contactContact attribute (tag, country, segmentID, …)Same set as audience contact filtersAttribute value
messageAlways "blockID"openedEmail, clickedEmail, clickedSms, openedPush, clickedPushID of a send block above this split

Note: A split owns its continuation through trueBlocks and falseBlocks. Do not place sibling blocks after a split — move downstream blocks into each branch.

Triggers

trigger.condition.event specifies the event that enrolls contacts. Most events use standard Events API names (e.g. "placed order", "started checkout") and may require origin. Built-in events ("birthday", "product back in stock") do not use origin.

Optional trigger.condition.filterGroups narrow enrollment by event properties. Multiple filter groups combine with AND logic.

Audience filter group

trigger.audienceFilterGroup restricts which contacts enter the workflow when the trigger fires. It does not trigger the automation — it only gates enrollment. Supported fields: segmentID, tag, dateAdded, firstName, lastName, gender, country, state, city, postalCode.

Inactivity settings

trigger.inactivitySettings.duration delays the workflow start until the contact has been inactive (no new triggering events) for the specified period. Each re-trigger resets the timer.

Note: Use inactivity settings for abandoned-flow patterns — e.g. 30 min after "added product to cart" with no follow-up cart event.

Exit Conditions

exitConditions remove contacts from the automation when a matching event occurs. Multiple exit conditions are evaluated with OR logic. Each condition specifies an event (and optional origin and filterGroup).

Note: Built-in trigger events ("birthday", "product back in stock") cannot be used as exit conditions.

Settings

Sending thresholds

Control which contacts receive messages at send blocks based on subscription status.

LevelDescription
subscribedOnly contacts who opted in to marketing (default)
nonSubscribedSubscribed + non-subscribed, excluding those who explicitly unsubscribed
allAll contacts regardless of subscription status (transactional use)

Set per channel (email, sms). Push is always restricted to subscribed contacts.

Note: US SMS is always restricted to subscribed contacts regardless of the sms threshold (CTIA regulation).

Frequency limiter

Restricts how often the same contact can re-enter the automation.

ModeDescription
onceContact enters the automation only once per lifetime
intervalContact can re-enter after a specified duration since last entry

Send null to clear an existing limiter.

Overlap limiter

Prevents a contact from entering when they are already in (or recently completed) other specified automations.

ModeDescription
currentlyInSkip if the contact is currently active in any listed automation
recentlyInSkip if the contact completed any listed automation within withinDays days (1–7)

Note: Self-referencing (listing the automation's own ID in automationIDs) is rejected with 400.

Lifecycle: Enable / Disable

Automations are always created disabled. The isEnabled field is read-only — use the dedicated enable/disable endpoints to change state.

Warning: Enabled automations cannot be patched or have blocks replaced — the API returns 409 Conflict. Disable the automation first, make changes, then re-enable.

Enable (POST /automations/{id}/enable): starts processing trigger events. enrollExisting optionally enrolls contacts who already qualify:

  • Event-based triggers: contacts whose event occurred within the first delay block's time window are enrolled. The workflow must start with a delay block — otherwise 409 enroll-existing-not-applicable.
  • "entered segment" trigger: all contacts currently in the trigger segments are enrolled. Only works on the first enable.
  • "birthday", "product back in stock": not supported with enrollExisting.

Disable (POST /automations/{id}/disable): stops accepting new trigger events. contactsInWorkflow controls in-flight contacts:

ValueDescription
keepContacts remain and continue through remaining blocks
exitAll contacts are immediately removed from the workflow

Other Lifecycle Actions

ActionEndpointDescription
CopyPOST /automations/{id}/copyCreate a disabled copy. Optional name field; defaults to "Copy of: <original name>"

UTM Tracking

UTM tags can be managed per send-action block or read in aggregate.

EndpointDescription
GET /automations/{id}/blocks/{blockID}/utmRead UTM tags for a single block
PUT /automations/{id}/blocks/{blockID}/utmSet UTM tags for a single block
GET /automations/{id}/utmRead aggregated UTM tags for all send-action blocks

All three tag fields (source, medium, campaign) are replaced atomically on write. Send an empty string to clear a field — the next read returns its default value.

For a complete walkthrough, see How to configure UTM tags for automations.

Examples

For trigger condition and audience filter group examples, see the endpoint documentation:

Example: Create an automation with a welcome email

curl --request POST \
     --url https://api.omnisend.com/api/automations \
     --header 'Authorization: Omnisend-API-Key YOUR-API-KEY' \
     --header 'Omnisend-Version: 2026-03-15' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '{
  "name": "Welcome Series",
  "trigger": {
    "condition": {
      "event": "subscribed to marketing"
    }
  },
  "blocks": [
    {
      "temporaryID": "wait-1h",
      "type": "delay",
      "delay": {
        "mode": "duration",
        "duration": {
          "amount": 1,
          "units": "h"
        }
      }
    },
    {
      "temporaryID": "welcome-email",
      "type": "action",
      "action": {
        "type": "sendEmail",
        "sendEmail": {
          "subject": "Welcome to our store!",
          "senderName": "My Store",
          "preheader": "Thanks for subscribing",
          "language": "en_US",
          "templateID": "000000000000000000000001"
        }
      }
    }
  ]
}'

Creates a disabled automation that triggers on marketing subscription, waits 1 hour, then sends a welcome email.

Example: Enable an automation

curl --request POST \
     --url https://api.omnisend.com/api/automations/000000000000000000000001/enable \
     --header 'Authorization: Omnisend-API-Key YOUR-API-KEY' \
     --header 'Omnisend-Version: 2026-03-15' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '{
  "enrollExisting": false
}'

Example: Disable an automation

curl --request POST \
     --url https://api.omnisend.com/api/automations/000000000000000000000001/disable \
     --header 'Authorization: Omnisend-API-Key YOUR-API-KEY' \
     --header 'Omnisend-Version: 2026-03-15' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '{
  "contactsInWorkflow": "keep"
}'

Example: Replace automation blocks

curl --request PUT \
     --url https://api.omnisend.com/api/automations/000000000000000000000001/blocks \
     --header 'Authorization: Omnisend-API-Key YOUR-API-KEY' \
     --header 'Omnisend-Version: 2026-03-15' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '{
  "blocks": [
    {
      "temporaryID": "wait-30m",
      "type": "delay",
      "delay": {
        "mode": "duration",
        "duration": {
          "amount": 30,
          "units": "m"
        }
      }
    },
    {
      "temporaryID": "tag-engaged",
      "type": "action",
      "action": {
        "type": "addTag",
        "addTag": {
          "value": "engaged"
        }
      }
    }
  ]
}'

Replaces the entire block tree. Blocks with temporaryID are created as new; blocks with id update existing ones. Existing blocks not included are removed.

Note: The automation must be disabled before replacing blocks.

Example: Update UTM tags for a block

curl --request PUT \
     --url https://api.omnisend.com/api/automations/000000000000000000000001/blocks/000000000000000000000002/utm \
     --header 'Authorization: Omnisend-API-Key YOUR-API-KEY' \
     --header 'Omnisend-Version: 2026-03-15' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '{
  "tags": {
    "source": "omnisend",
    "medium": "email",
    "campaign": "welcome-series"
  }
}'

See Also