---
title: "Patch automation workflow"
method: PATCH
path: "/automations/{id}"
tags: ["Automations"]
---

# Patch automation workflow

`PATCH /automations/{id}`

## Request

- Base URL: `https://api.omnisend.com/api`
- URL: `https://api.omnisend.com/api/automations/{id}`
- Auth: one of:
  - OAuth 2
    - Client credentials
    - Token URL: `https://app.omnisend.com/oauth2/token` scopes: `automations.write`
  - API key in header `Authorization`

Partially update an automation workflow. Only the fields provided in the request body are updated.

Enabled automations cannot be patched. Disable the automation via
`POST /automations/{id}/disable`, make changes, then re-enable via
`POST /automations/{id}/enable` when ready. When disabling, `contactsInWorkflow`
controls whether contacts already in the workflow continue through the remaining
blocks (`keep`) or exit immediately (`exit`). Enable/disable state is controlled
exclusively via the `/automations/{id}/enable` and `/automations/{id}/disable`
endpoints.

`trigger` sub-fields (condition, audienceFilterGroup, inactivitySettings) are patched
individually — each provided sub-field replaces the corresponding sub-field in full.
`exitConditions` are **replaced in full** when provided. `blocks` are patched individually.

**Scopes:**
`automations.write`

**Rate Limiting:**
This endpoint is rate limited to 400 requests per minute.

## Audience filter group examples

The `trigger.audienceFilterGroup` field in PATCH requests replaces the existing audience filter group in full (or sets it for the first time). Omit it to leave the existing audience filter group unchanged.

### Supported fields

| Field | Operators | Value shape |
|---|---|---|
| `segmentID`  | `eq`, `neq` | Segment ID string, e.g. `"000000000000000000000001"` |
| `tag`        | `eq`, `neq` | Tag name, e.g. `"vip"` |
| `dateAdded`  | `eq`, `neq`, `gt`, `lt` | ISO-8601 date, e.g. `"2025-03-15"` |
| `firstName`  | `eq`, `neq`, `contains`, `notContains` | Free string, e.g. `"John"` |
| `lastName`   | `eq`, `neq`, `contains`, `notContains` | Free string, e.g. `"Smith"` |
| `gender`     | `eq` | `"m"` or `"f"` |
| `country`    | `eq`, `neq`, `contains`, `notContains` | ISO-2 country code, e.g. `"US"` |
| `state`      | `eq`, `neq`, `contains`, `notContains` | State / region name, e.g. `"California"` |
| `city`       | `eq`, `neq`, `contains`, `notContains` | City name, e.g. `"New York"` |
| `postalCode` | `eq`, `neq`, `contains`, `notContains` | Postal code string, e.g. `"10001"` |

### Where it fits

`audienceFilterGroup` sits inside `trigger` in the PATCH request body, alongside `condition` and `inactivitySettings`:

```json
{
  "trigger": {
    "audienceFilterGroup": { ... }
  }
}
```

Each example below shows only the `audienceFilterGroup` value — slot it into the skeleton above.

<details id="example-patch-replace-audience-filter">
<summary>Replace audience filter without touching trigger event or blocks</summary>

```json
{
  "logicalOperator": "or",
  "filters": [
    {"field": "tag", "operator": "eq", "value": "vip"},
    {"field": "tag", "operator": "eq", "value": "beta"}
  ]
}
```

</details>

<details id="example-patch-narrow-audience">
<summary>Narrow to US women</summary>

```json
{
  "logicalOperator": "and",
  "filters": [
    {"field": "country", "operator": "eq", "value": "US"},
    {"field": "gender",  "operator": "eq", "value": "f"}
  ]
}
```

</details>

<details id="example-patch-swap-segment-for-tag">
<summary>Swap a segment-based audience for a tag-based one</summary>

```json
{
  "logicalOperator": "and",
  "filters": [
    {"field": "tag", "operator": "eq",  "value": "vip"},
    {"field": "tag", "operator": "neq", "value": "beta-churned"}
  ]
}
```

</details>

## Path parameters

- `id` string, required

## Headers

- `Omnisend-Version` string, required

## Request body

- PatchAutomationRequest: Patch automation workflow request. All fields are optional — only provided fields are updated. `trigger` fields are patched individually — only sub-fields within trigger that are provided are updated. `exitConditions` are **replaced in full** when provided; send `null` or `[]` to clear, omit to leave unchanged. `blocks` are patched individually by id — only fields within each block that are provided are updated.
  - `blocks` PatchBlockRequest[]: Automation workflow blocks. Each entry updates an existing block matched by `id`; fields within each block are applied as a partial update. The array does **not** reshape the block list — adding or removing blocks is not supported through this endpoint (use the dedicated block endpoints for that). An empty array (`[]`) is rejected with `400`; omit the field to leave blocks unchanged.
    - `abTesting` PatchABTestingRequest: A/B test block configuration for PATCH — only aBlocksPercentage is patchable. Branches (aBlocks, bBlocks) cannot be changed via PATCH. Use PUT /automations/{id}/blocks to restructure branches.
      - `aBlocksPercentage` integer, required: Percentage of contacts routed to branch A. Branch B receives the remainder.
    - `action` PatchActionRequest: Action block configuration for partial update. Only the fields explicitly provided are updated.
      - `addTag` InputTagAction: Tag action configuration.
        - `value` string, required: Tag value. Case-insensitive — normalized to lowercase before persistence.
      - `removeTag` InputTagAction: Tag action configuration.
        - `value` string, required: Tag value. Case-insensitive — normalized to lowercase before persistence.
      - `sendEmail` PatchSendEmailRequest: Send email action configuration for partial update. All fields are optional — only the fields explicitly provided are updated. `replyToEmail` accepts `null` or `""` to clear the existing value.
        - `isSkipAllowed` boolean: Whether skipping this block is allowed when the contact is not eligible to receive this message.
        - `language` string: Email language locale in xx_XX format. Must be a supported language.
        - `preheader` string: Email preheader text displayed after the subject line. Supports personalization tags.
        - `replyToEmail` string: Reply-to email address. Must be a verified email. Send `null` or an empty string to clear the reply-to address.
        - `senderEmail` string: Sender email address. For branded sending, must be hosted on a domain verified for the brand. Omit only when the brand is configured to use Omnisend's shared sender domain.
        - `senderName` string: Sender display name shown in the recipient's inbox
        - `subject` string: Email subject line. Supports personalization tags, e.g. [[contact.first_name]]
      - `sendPush` PatchSendPushRequest: Send push notification action configuration for partial update. All fields are optional — only the fields explicitly provided are updated. `iconID` and `imageID` accept `null` or `""` to clear the existing value.
        - `body` string: Push notification body. Supports personalization tags.
        - `clickUrl` string: Click-through URL the recipient is taken to when tapping the notification.
        - `iconID` string: Optional icon image ID obtained from the Images API. Send `null` or an empty string to remove the existing icon.
        - `imageID` string: Optional image ID displayed below the push notification body. Send `null` or an empty string to remove the existing image.
        - `isSkipAllowed` boolean: Whether skipping this block is allowed when the contact is not eligible to receive this message. When true (default), the contact bypasses this block and continues to the next block in the workflow. When false, the workflow is canceled for this contact.
        - `title` string: Push notification title. Supports personalization tags, e.g. [[contact.first_name]]
      - `sendSms` PatchSendSmsRequest: SMS action configuration for partial update. All fields are optional — only the fields explicitly provided are updated. `imageID` accepts `null` or `""` to remove the existing MMS image. `compliance` does not accept `null` — provide an object or omit the field.
        - `compliance` UpdateSmsCompliance: SMS compliance settings for PATCH (full replacement of the compliance object). Both toggle fields are required when this object is provided. Cannot be aliased to SmsComplianceRequest: PATCH toggles are required; POST/PUT toggles are optional.
          - `isStopKeywordIncluded` boolean, required: Whether to append the opt-out keyword to the message.
          - `isUnsubscribeLinkIncluded` boolean, required: Whether to append an unsubscribe link to the message.
          - `stopKeywordText` string: Text appended as the opt-out keyword. Supports personalization tags.
          - `unsubscribeLinkText` string: Text used for the unsubscribe link. Must contain [[unsubscribe_link]].
        - `imageID` string: MMS image ID. Send `null` or an empty string to remove the existing image.
        - `isLinkShorteningEnabled` boolean: Whether link shortening is enabled.
        - `isSkipAllowed` boolean: Whether skipping this block is allowed when the contact is not eligible to receive this message.
        - `message` string: SMS message body. Supports personalization tags, e.g. [[contact.first_name]]
      - `sendWebhook` PatchSendWebhookRequest: Send webhook action configuration for partial update. All fields are optional — only the fields explicitly provided are updated. Send `null` or an empty array (`[]`) to clear all headers; omit `headers` to leave them unchanged.
        - `body` string: Request body template (JSON). Supports personalization tags, e.g. [[contact.email]]
        - `callbackUrl` string: Destination URL that receives the HTTP POST request. Must be HTTPS.
        - `headers` WebhookHeader[]: Custom HTTP headers sent with the webhook request. Replaced atomically when provided; send `null` or `[]` to clear.
          - `key` string: Header name
          - `value` string: Header value. The configured value is returned verbatim under the read scope.
      - `type` 'sendEmail' | 'sendPush' | 'sendSms' | 'sendWebhook' | 'addTag' | 'removeTag', required: Action type discriminator. Required — asserts the stored action type; cannot be changed via PATCH.
    - `delay` UpdateDelayRequest: Delay block configuration for full replacement (PUT and PATCH). All fields of the delay are replaced atomically — this is not a partial update. Re-send the complete delay spec when changing any field, including mode.
      - `allowedWeekdays` string[]: Days of the week when the delay is allowed to resolve. Omit to allow all days.
      - `duration` UpdateDurationRequest: Duration configuration for delay replacement (PUT and PATCH).
        - `amount` integer, required: Duration amount — must be at least 1
        - `units` 'm' | 'h' | 'd' | 'w' | 'M', required: Duration unit
      - `mode` 'duration' | 'immediate' | 'specificTime', required: Delay mode discriminator
      - `time` string: Time in HH:MM 24-hour format — required when mode is "specificTime"
    - `id` string, required: Server-assigned block ID. Required — identifies the target block to update.
    - `split` PatchSplitRequest: Split block configuration for PATCH — only the filterGroup is replaced. Branches (trueBlocks, falseBlocks) cannot be changed via PATCH. Use PUT /automations/{id}/blocks to restructure branches.
      - `filterGroup` SplitFilterGroupRequest, required: Split filter group containing one or more filters of mixed types (event, contact, message) combined by a logical operator.
        - `filters` SplitFilterRequest[], required: Filters within this group (each filter specifies its type). At least one filter is required.
          - `field` string, required: Property or attribute to filter on. For event filters: event property path. For contact filters: contact attribute name. For message filters: must be "blockID".
          - `operator` string, required: Comparison or engagement operator. Allowed values depend on the filter type and field.
          - `type` 'event' | 'contact' | 'message', required: Filter type discriminator
          - `urlMatch` UrlMatchRequest: URL match condition for clicked message filters (clickedEmail, clickedSms, clickedPush). When operator is "any", value may be omitted. For all other operators, value is required.
            - `operator` 'any' | 'is' | 'contains' | 'startsWith' | 'endsWith', required: URL match operator
            - `value` string: URL string to match against. Required when operator is not "any".
          - `value` unknown
        - `logicalOperator` 'and' | 'or', required: Logical operator combining filters within this group
    - `type` 'delay' | 'action' | 'split' | 'abTesting', required: Block type discriminator. Required — asserts the stored block's type; cannot be changed via PATCH.
  - `exitConditions` ExitConditionRequest[]: Exit condition list. Replaces all existing exit conditions when provided. Send `null` or an empty array (`[]`) to clear all exit conditions; omit to leave unchanged.
    - `event` string, required: Event system name that triggers the exit (e.g. "placed order", "started checkout"). Built-in trigger events ("birthday", "product back in stock") are not allowed.
    - `filterGroup` EventFilterGroupRequest: Event filter group containing one or more event property filters combined by a logical operator.
      - `filters` EventFilterRequest[], required: Event filters within this group. At least one filter is required.
        - `field` string, required: Event property path to filter on
        - `operator` 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'contains' | 'notContains' | 'startsWith' | 'endsWith' | 'exists' | 'notExists' | 'in' | 'notIn', required: Comparison operator
        - `value` unknown
      - `logicalOperator` 'and' | 'or', required: Logical operator combining filters within this group
    - `origin` string: Integration platform that generated the event (e.g. "shopify", "omnisend", "api"). When the event supports multiple origins, this field is required and must match one of them. When the event has a single origin, this field can be omitted — the origin is selected automatically. Omit for the "subscribed to marketing" event.
  - `name` string: Automation workflow name
  - `settings` PatchSettingsRequest: Automation settings patch. Each sub-field follows partial-update semantics: omit to leave unchanged, send a value to replace. `sendingThresholds` does not accept `null` — sending `null` returns `400`. `frequencyLimiter` accepts `null` to clear (disable) the existing limiter. `overlapLimiter` accepts `null` to clear the configured limiter (engine performs no overlap check).
    - `frequencyLimiter` FrequencyLimiterRequest: Frequency limiter — restricts how often the same contact can re-enter the automation. Provide an object to enable; omit or send `null` to disable. The `mode` field determines the limiting behavior: - "once": the contact can enter the automation only once per lifetime - "interval": requires `duration`; the contact can re-enter only after the configured period has elapsed since the last entry
      - `duration` FrequencyIntervalDurationRequest: Frequency interval duration. Per-unit caps: 8760 hours, 365 days, 52 weeks.
        - `amount` integer, required: Number of time units. Must be at least 1 and within the per-unit cap.
        - `units` 'h' | 'd' | 'w', required: Time unit
      - `mode` 'once' | 'interval', required: Frequency limiter mode
    - `overlapLimiter` OverlapLimiterRequest: Overlap limiter — prevents enrolling a contact who is already in (or recently completed) one of the listed automations. The `mode` field selects the check: - "currentlyIn": skip the contact if they are currently active in any of the listed automations. `withinDays` must be omitted. - "recentlyIn": skip the contact if they completed any of the listed automations within the last `withinDays` days. `withinDays` is required and must be between 1 and 7. When provided, both `mode` and a non-empty `automationIDs` array are required. Each ID must reference an existing automation in the same brand and must not be the automation being patched (self-reference is rejected with `400`).
      - `automationIDs` string[], required: Automation IDs to check for overlap. Must be non-empty when an OverlapLimiter object is provided.
      - `mode` 'currentlyIn' | 'recentlyIn', required: Overlap check mode
      - `withinDays` integer: Number of days to check — required when mode is "recentlyIn", forbidden when mode is "currentlyIn".
    - `sendingThresholds` SendingThresholdsRequest: Sending thresholds — controls which contacts receive messages at each send block (email, SMS) based on subscription status. When provided, both `email` and `sms` are required. Push notifications are always restricted to subscribed contacts and are not exposed here. When omitted, all channels default to `subscribed`. To deliver SMS blocks only to SMS subscribers, set `sms` to `"subscribed"` (the default) — `nonSubscribed` and `all` will route SMS to non-subscribed contacts as well, which is rarely desired. Note: due to US regulations (CTIA), SMS to US contacts is always restricted to subscribed contacts only — US non-subscribers will not be reached on the SMS channel regardless of the `sms` value.
      - `email` 'subscribed' | 'nonSubscribed' | 'all', required: Email subscription threshold
      - `sms` 'subscribed' | 'nonSubscribed' | 'all', required: SMS subscription threshold. US non-subscribers are never reached on SMS regardless of this value — CTIA regulations restrict SMS to US contacts to subscribed only.
  - `trigger` PatchTriggerRequest: Trigger configuration for PATCH. Tri-state per field — omit to leave unchanged, send a value to replace, send `null` to clear (where the schema marks the field nullable). Sending `null` for `condition` returns `400`. When condition is provided, the entire trigger condition (event, origin, and filter groups) is replaced in full.
    - `audienceFilterGroup` ContactFilterGroupRequest: Contact filter group containing one or more contact filters combined by a logical operator.
      - `filters` ContactFilterRequest[], required: Filters within this group. At least one filter is required.
        - `field` 'segmentID' | 'tag' | 'dateAdded' | 'firstName' | 'lastName' | 'gender' | 'country' | 'state' | 'city' | 'postalCode', required: Contact property name to filter on
        - `operator` 'eq' | 'neq' | 'gt' | 'lt' | 'contains' | 'notContains', required: Comparison operator — allowed values depend on the field; see the type description.
        - `value` string, required: Filter value as a string. For "gender" must be "m" or "f"; for "dateAdded" an ISO-8601 date in YYYY-MM-DD format. Required and non-empty for all contact filters.
      - `logicalOperator` 'and' | 'or', required: Logical operator combining filters within this group
    - `condition` PatchTriggerCondition: Trigger condition for PATCH. When sent, the entire trigger condition (event, origin, and filter groups) is replaced in full — partial updates of individual condition fields are not supported. Omit `condition` to leave the existing trigger condition unchanged. Use the [event metadata endpoint](https://api-docs.omnisend.com/v2026-preview/reference/post_event_metadata_query) to look up the event names, origins, and property paths available for the brand. The event field identifies what triggers the automation workflow. Most events are standard events received via the Events API (e.g. "placed order", "started checkout"). In addition, the following built-in trigger events are available without the Events API: "birthday" (contact birthday anniversary), "product back in stock". Built-in event notes: "product back in stock" — only supported for Shopify, BigCommerce, and WooCommerce stores; it will have no effect for any other integration.
      - `event` string, required: Event system name that triggers the automation workflow (e.g. "placed order", "started checkout"). See the parent struct description for available built-in trigger events.
      - `filterGroups` EventFilterGroupRequest[]: Event filter groups — multiple groups are combined with AND logic.
        - `filters` EventFilterRequest[], required: Event filters within this group. At least one filter is required.
          - `field` string, required: Event property path to filter on
          - `operator` 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'contains' | 'notContains' | 'startsWith' | 'endsWith' | 'exists' | 'notExists' | 'in' | 'notIn', required: Comparison operator
          - `value` unknown
        - `logicalOperator` 'and' | 'or', required: Logical operator combining filters within this group
      - `origin` string: Integration platform that generated the event (e.g. "shopify", "omnisend", "api"). When the event supports multiple origins, this field is required and must match one of them. When the event has a single origin, this field can be omitted — the origin is selected automatically. Omit for built-in trigger events and for the "subscribed to marketing" event.
    - `inactivitySettings` InactivitySettingsRequest: Inactivity settings — fires the workflow only after the contact has gone quiet (no new triggering events) for the given duration. Each new triggering event resets the timer. Use this for abandoned-flow patterns where you want to wait for the contact to *not* complete the next step. Common pairings: abandoned cart (30m after "added to cart"), abandoned checkout (1h after "started checkout"), browse abandonment (30m after "viewed product"), or win-back / re-engagement (e.g. 7d after a key event). Example: `{"duration": {"amount": 30, "units": "m"}}`
      - `duration` DurationRequest, required: Duration amount and unit for inactivity settings.
        - `amount` integer, required: Number of time units (must be > 0)
        - `units` 'm' | 'h' | 'd' | 'w', required: Time unit

## Response `200`

Updated automation workflow

- Automation: Automation workflow resource
  - `blocks` Block[]: Automation workflow blocks (actions, delays, splits, A/B tests). Omitted from list responses with `view=summary` unless `include=blocks` is passed.
    - `abTesting` ABTesting: A/B testing block configuration. Splits contacts randomly between two variants based on `aBlocksPercentage`. `bBlocks` receives the remaining percentage (100 - aBlocksPercentage). Each contact is assigned independently when reaching this block. To pick a winner, set `aBlocksPercentage` to 100 (all contacts go to `aBlocks`) or 0 (all contacts go to `bBlocks`).
      - `aBlocks` Block[]: Blocks for variant A
      - `aBlocksPercentage` integer: Percentage of contacts allocated to aBlocks (bBlocks gets 100 - aBlocksPercentage)
      - `bBlocks` Block[]: Blocks for variant B
    - `action` Action: Action block configuration. Exactly one action-specific field is populated based on the type discriminator.
      - `addTag` TagAction: Tag action configuration. Used by both addTag and removeTag action types.
        - `value` string: Tag value. Case-insensitive — values are normalized to lowercase on create.
      - `removeTag` TagAction: Tag action configuration. Used by both addTag and removeTag action types.
        - `value` string: Tag value. Case-insensitive — values are normalized to lowercase on create.
      - `sendEmail` SendEmail: Send email action configuration. `contentID` references an Email Template entity documented in the [Email Templates API](https://api-docs.omnisend.com/reference/email-templates).
        - `contentID` string: Email content unique identifier referencing the automation's email design (read-only). See [Email Templates API](https://api-docs.omnisend.com/reference/email-templates).
        - `isSkipAllowed` boolean: Whether skipping this block is allowed when the contact is not eligible to receive this message — for example, the contact has not opted in for this channel or does not meet the automation's `sendingThresholds`. When true (default), the contact bypasses this block and continues to the next block in the workflow. When false, the workflow is canceled for this contact.
        - `language` string: Email language locale in xx_XX format. Must be a supported language
        - `preheader` string: Email preheader text displayed after the subject line in the recipient's inbox. Supports personalization tags, e.g. [[contact.first_name]]
        - `replyToEmail` string: Reply-to email address for recipient responses. Must be a verified email
        - `senderEmail` string: Sender email address shown in the recipient's inbox. Must belong to a verified brand domain. Omit when using a shared domain — brand default will be used
        - `senderName` string: Sender display name shown in the recipient's inbox
        - `subject` string: Email subject line displayed in the recipient's inbox. Supports personalization tags, e.g. [[contact.first_name]]
      - `sendPush` SendPush: Send push notification action configuration.
        - `body` string: Push notification body text. Supports personalization tags, e.g. [[contact.first_name]]
        - `clickUrl` string: Destination URL where the customer is redirected when clicking the push notification. Supports personalization tags.
        - `iconID` string: Optional icon image ID obtained from the Images API. Recommended size: 192x192 pixels. When omitted, the browser default icon is used.
        - `imageID` string: Optional image ID obtained from the Images API displayed below the push notification body. Recommended size: 360x180 pixels (2:1 aspect ratio). Not supported on iOS devices.
        - `isSkipAllowed` boolean: Whether skipping this block is allowed when the contact is not eligible to receive this message — for example, the contact has not opted in for this channel or does not meet the automation's `sendingThresholds`. When true (default), the contact bypasses this block and continues to the next block in the workflow. When false, the workflow is canceled for this contact.
        - `title` string: Push notification title. Supports personalization tags, e.g. [[contact.first_name]]
      - `sendSms` SendSms: Send SMS action configuration.
        - `compliance` SmsCompliance: SMS compliance text settings. Controls opt-out and unsubscribe text appended to the SMS body. By default, both stop keyword and unsubscribe link are enabled. When enabled, the corresponding text field is required.
          - `isStopKeywordIncluded` boolean: Whether stop keyword text is included in the SMS (default: true). When true, stopKeywordText is required.
          - `isUnsubscribeLinkIncluded` boolean: Whether unsubscribe link text is included in the SMS (default: true). When true, unsubscribeLinkText is required.
          - `stopKeywordText` string: STOP keyword text appended to the SMS for US/CA recipients. Required when isStopKeywordIncluded is true.
          - `unsubscribeLinkText` string: Unsubscribe link text appended to the SMS for non-US/CA recipients. Required when isUnsubscribeLinkIncluded is true.
        - `discountSettings` DiscountSettings: Discount configuration. The `type` field determines the discount behavior and how `value` is interpreted: - "percentage": `value` is a whole number string representing the percentage (1-100), e.g. "10" - "fixedAmount": `value` is a currency amount string, e.g. "9.99" - "freeShipping": `value` is omitted (no discount amount needed) The `scope` object determines what orders or products the discount applies to.
          - `combinesWith` DiscountCombinesWith: Discount combination rules.
            - `isOrderCompatible` boolean: Whether this discount is compatible with order discounts
            - `isProductCompatible` boolean: Whether this discount is compatible with product discounts
            - `isShippingCompatible` boolean: Whether this discount is compatible with shipping discounts. Not applicable when discount type is "freeShipping" — always false in that case.
          - `expiry` DiscountExpiry: Discount expiry configuration.
            - `dateFormat` string: Date format for displaying the expiration date in the discount message. Valid values: "MMM DD, YYYY", "YYYY-MM-DD", "DD/MM/YYYY".
            - `expirationText` string: Expiration display text shown before the expiration date in the discount message, e.g. "expires on Jan 15, 2026"
            - `expiresInDays` integer: Number of days until the discount expires
          - `isItemsOnSaleExcluded` boolean: Whether items already on sale are excluded from this discount. False when not applicable for the connected store.
          - `scope` DiscountScope: Discount scope — determines what orders or products the discount applies to. The `conditions` field controls scoping behavior: - "allOrders": discount applies to all orders, no extra fields needed - "minimumOrderAmount": discount requires a minimum order total, `minimumOrderAmount` is required - "collection": discount applies to a specific product collection, `collectionType` and `collectionID` are required
            - `collectionID` integer: Collection identifier. Required when conditions is "collection".
            - `collectionType` 'smart' | 'custom': Collection type. Required when conditions is "collection".
            - `conditions` 'allOrders' | 'minimumOrderAmount' | 'collection': Scope conditions type.
            - `minimumOrderAmount` string: Minimum order amount (currency string). Required when conditions is "minimumOrderAmount".
          - `type` 'percentage' | 'fixedAmount' | 'freeShipping': Discount type. Determines discount behavior and how `value` is interpreted.
          - `value` string: Discount value. Interpretation depends on `type`: - percentage: whole number string "1" to "100" (e.g. "10" = 10% off) - fixedAmount: currency amount string (e.g. "9.99") - freeShipping: omitted
        - `imageID` string: Image ID obtained from the Images API. When set, the message is delivered as MMS to US/CA recipients; other countries receive SMS without the image.
        - `isLinkShorteningEnabled` boolean: Whether links in the SMS body are automatically shortened
        - `isSkipAllowed` boolean: Whether skipping this block is allowed when the contact is not eligible to receive this message — for example, the contact has not opted in for this channel or does not meet the automation's `sendingThresholds`. When true (default), the contact bypasses this block and continues to the next block in the workflow. When false, the workflow is canceled for this contact.
        - `message` string: SMS message body. Supports personalization tags, e.g. [[contact.first_name]]
      - `sendWebhook` SendWebhook: Sends an HTTP POST request to the specified URL with the provided headers and body.
        - `body` string: Request body template (JSON). Supports personalization tags, e.g. [[contact.email]]
        - `callbackUrl` string: Webhook callback URL — destination that receives the HTTP POST request
        - `headers` WebhookHeader[]: Custom HTTP headers sent with the webhook request
          - `key` string: Header name
          - `value` string: Header value. The configured value is returned verbatim under the read scope.
      - `type` 'sendEmail' | 'sendSms' | 'sendPush' | 'sendWebhook' | 'addTag' | 'removeTag': Action type discriminator
    - `delay` Delay: Delay block configuration. The `mode` field determines the delay behavior: - "duration": wait for the specified amount of time units - "immediate": no wait, proceed to the next block - "specificTime": wait until the specified time of day in the brand's timezone `allowedWeekdays` is optional for all modes. When set, the delay resolution advances to the nearest matching weekday (preserving the time of day).
      - `allowedWeekdays` string[]: Restrict delay resolution to specific weekdays
      - `duration` Duration: Duration configuration for a relative delay.
        - `amount` integer: Number of time units to wait
        - `units` 'm' | 'h' | 'd' | 'w' | 'M': Time unit
      - `mode` 'duration' | 'immediate' | 'specificTime': Delay mode discriminator
      - `time` string: Time of day in brand's timezone (HH:MM, 24h format) — required when mode is "specificTime". If the target time has already passed today, resolves the next day.
    - `id` string: Block identifier
    - `split` Split: Conditional split block configuration.
      - `falseBlocks` Block[]: Blocks executed when split condition is not met (false path)
      - `filterGroup` SplitFilterGroup: Split filter group containing one or more filters of mixed types (event, contact, message) combined by a logical operator. At least one filter is required.
        - `filters` SplitFilter[]: Filters within this group (each filter specifies its type)
          - `field` string: Property to filter on (event: property path; contact: property name; message: always "blockID")
          - `operator` string: Operator (event/contact: comparison operator; message: engagement operator such as "openedEmail", "clickedEmail", "clickedSms", "openedPush", "clickedPush")
          - `type` 'event' | 'contact' | 'message': Filter type discriminator
          - `urlMatch` UrlMatch: URL match condition for clicked message filters.
            - `operator` 'any' | 'is' | 'contains' | 'startsWith' | 'endsWith': URL match operator
            - `value` string: URL string to match against
          - `value` unknown
        - `logicalOperator` 'and' | 'or': Logical operator combining filters within this group
      - `trueBlocks` Block[]: Blocks executed when split condition is met (true path)
    - `type` 'delay' | 'action' | 'split' | 'abTesting': Block type discriminator
  - `brandID` string: Brand identifier (read-only)
  - `createdAt` string: Automation creation timestamp (read-only)
  - `disabledAt` string: Timestamp when automation was disabled (read-only)
  - `enabledAt` string: Timestamp when automation was enabled (read-only)
  - `exitConditions` ExitCondition[]: Exit conditions that remove contacts from the automation workflow (evaluated with OR logic)
    - `event` string: Event name that triggers the exit
    - `filterGroup` EventFilterGroup: Event filter group containing one or more event filters combined by a logical operator.
      - `filters` EventFilter[]: Event filters within this group
        - `field` string: Event property path to filter on
        - `operator` 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'contains' | 'notContains' | 'startsWith' | 'endsWith' | 'exists' | 'notExists' | 'in' | 'notIn': Comparison operator
        - `value` unknown
      - `logicalOperator` 'and' | 'or': Logical operator combining filters within this group
    - `origin` string: Integration platform that generated the event (e.g. "shopify", "omnisend", "api"). Each event supports a specific set of origins depending on the brand's e-commerce platform. Empty for built-in trigger events and the "subscribed to marketing" event
  - `id` string: Automation workflow unique identifier (read-only)
  - `isEnabled` boolean: Whether the automation workflow is enabled (read-only). Controlled via enable/disable actions.
  - `name` string: Automation workflow name
  - `settings` Settings: Automation settings.
    - `discount` DiscountSettings: Discount configuration. The `type` field determines the discount behavior and how `value` is interpreted: - "percentage": `value` is a whole number string representing the percentage (1-100), e.g. "10" - "fixedAmount": `value` is a currency amount string, e.g. "9.99" - "freeShipping": `value` is omitted (no discount amount needed) The `scope` object determines what orders or products the discount applies to.
      - `combinesWith` DiscountCombinesWith: Discount combination rules.
        - `isOrderCompatible` boolean: Whether this discount is compatible with order discounts
        - `isProductCompatible` boolean: Whether this discount is compatible with product discounts
        - `isShippingCompatible` boolean: Whether this discount is compatible with shipping discounts. Not applicable when discount type is "freeShipping" — always false in that case.
      - `expiry` DiscountExpiry: Discount expiry configuration.
        - `dateFormat` string: Date format for displaying the expiration date in the discount message. Valid values: "MMM DD, YYYY", "YYYY-MM-DD", "DD/MM/YYYY".
        - `expirationText` string: Expiration display text shown before the expiration date in the discount message, e.g. "expires on Jan 15, 2026"
        - `expiresInDays` integer: Number of days until the discount expires
      - `isItemsOnSaleExcluded` boolean: Whether items already on sale are excluded from this discount. False when not applicable for the connected store.
      - `scope` DiscountScope: Discount scope — determines what orders or products the discount applies to. The `conditions` field controls scoping behavior: - "allOrders": discount applies to all orders, no extra fields needed - "minimumOrderAmount": discount requires a minimum order total, `minimumOrderAmount` is required - "collection": discount applies to a specific product collection, `collectionType` and `collectionID` are required
        - `collectionID` integer: Collection identifier. Required when conditions is "collection".
        - `collectionType` 'smart' | 'custom': Collection type. Required when conditions is "collection".
        - `conditions` 'allOrders' | 'minimumOrderAmount' | 'collection': Scope conditions type.
        - `minimumOrderAmount` string: Minimum order amount (currency string). Required when conditions is "minimumOrderAmount".
      - `type` 'percentage' | 'fixedAmount' | 'freeShipping': Discount type. Determines discount behavior and how `value` is interpreted.
      - `value` string: Discount value. Interpretation depends on `type`: - percentage: whole number string "1" to "100" (e.g. "10" = 10% off) - fixedAmount: currency amount string (e.g. "9.99") - freeShipping: omitted
    - `frequencyLimiter` FrequencyLimiter: Frequency limiter controls how often the same contact can enter the automation. When present, the limiter is active. Omit or set to null to disable. The `mode` field determines the limiting behavior: - "once": the contact can enter the automation only once per lifetime - "interval": the contact can re-enter after the specified duration has elapsed since the last entry
      - `duration` FrequencyIntervalDuration: Frequency interval duration. The response always reports the duration in the largest time unit that divides it evenly: weeks when the interval is a whole number of weeks, otherwise days when it is a whole number of days, otherwise hours. For example, an input of `{amount: 7, units: "d"}` is returned as `{amount: 1, units: "w"}`, and `{amount: 48, units: "h"}` is returned as `{amount: 2, units: "d"}`. The normalized value represents the same interval as the submitted value.
        - `amount` integer: Number of time units, expressed in the normalized `units`.
        - `units` 'h' | 'd' | 'w': Time unit. Reflects the largest unit that evenly divides the configured interval (`w` > `d` > `h`) and may differ from the unit submitted on write.
      - `mode` 'once' | 'interval': Frequency limiter mode
    - `overlapLimiter` OverlapLimiter: Overlap limiter prevents a contact from entering this automation when they are already in, or were recently in, other specified automations. When present, the limiter is active. Omit or set to null to disable. The `mode` field determines the check: - "currentlyIn": skip the contact if they are currently active in any of the specified automations - "recentlyIn": skip the contact if they are currently active in, or have finished any of the specified automations within the last `withinDays` days
      - `automationIDs` string[]: Automation IDs to check for overlap
      - `mode` 'currentlyIn' | 'recentlyIn': Overlap check mode
      - `withinDays` integer: Number of days to check — required when mode is "recentlyIn"
    - `sendingThresholds` SendingThresholds: Sending thresholds control which contacts receive messages at each send block (email, SMS, push) based on their subscription status. These settings do not affect which contacts enter the automation — only who receives messages when they reach a send block. Contacts who don't meet the threshold are either skipped or stopped depending on the message block configuration. Threshold levels (from most restrictive to least): - "subscribed": send only to contacts who opted in to receive marketing content. Use for newsletters, promotions, and product updates. - "nonSubscribed": send to subscribed and non-subscribed contacts, excluding those who explicitly unsubscribed. Use for behavior-triggered messages like abandoned cart reminders and post-purchase follow-ups. - "all": send to all contacts regardless of subscription status. Use for transactional content like order confirmations and shipping updates. Push notifications are always restricted to subscribed contacts. When omitted, all channels default to "subscribed". Note: due to US regulations, SMS to US contacts is restricted to subscribed contacts only, regardless of this setting.
      - `email` 'subscribed' | 'nonSubscribed' | 'all': Email subscription threshold
      - `sms` 'subscribed' | 'nonSubscribed' | 'all': SMS subscription threshold. US non-subscribers are never reached on SMS regardless of this value — CTIA regulations restrict SMS to US contacts to subscribed only.
  - `trigger` Trigger: Automation trigger configuration.
    - `audienceFilterGroup` ContactFilterGroup: Contact filter group containing one or more contact filters combined by a logical operator.
      - `filters` ContactFilter[]: Contact filters within this group
        - `field` string: Contact property name to filter on
        - `operator` 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'contains' | 'notContains' | 'startsWith' | 'endsWith' | 'exists' | 'notExists' | 'any': Comparison operator
        - `value` unknown
      - `logicalOperator` 'and' | 'or': Logical operator combining filters within this group
    - `condition` TriggerCondition: Trigger condition — the event that triggers the automation workflow, together with optional event-property filters. The `event` field identifies what triggers the automation workflow. Most events are standard events received via the Events API (e.g. "placed order", "started checkout"). In addition, the following built-in trigger events are available without the Events API: "birthday" (contact birthday anniversary), "product back in stock". "product back in stock" — only supported for Shopify, BigCommerce, and WooCommerce stores; it will have no effect for any other integration.
      - `event` string: Event name that triggers the automation workflow
      - `filterGroups` EventFilterGroup[]: Event filter groups — multiple groups are combined with AND logic. Each group combines its filters using the group's logicalOperator.
        - `filters` EventFilter[]: Event filters within this group
          - `field` string: Event property path to filter on
          - `operator` 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'contains' | 'notContains' | 'startsWith' | 'endsWith' | 'exists' | 'notExists' | 'in' | 'notIn': Comparison operator
          - `value` unknown
        - `logicalOperator` 'and' | 'or': Logical operator combining filters within this group
      - `origin` string: Integration platform that generated the event (e.g. "shopify", "omnisend", "api"). Always populated for events received via the Events API — reflects the resolved origin, even when it was auto-selected because the event has a single origin. Empty for built-in trigger events and the "subscribed to marketing" event.
    - `inactivitySettings` InactivitySettings: Trigger inactivity time defines how long a contact must remain inactive before the automation triggers. The contact must first match the trigger filters. If the trigger event fires again before the timer expires, the timer resets — ensuring the workflow starts only after the contact has finished their activity. For example, with an "added product to cart" trigger and inactivity set to 1 hour, each cart update resets the timer. The automation triggers only after the cart has not been updated for 1 hour, ensuring the email reflects the shopper's complete cart.
      - `duration` Duration: Duration configuration for a relative delay.
        - `amount` integer: Number of time units to wait
        - `units` 'm' | 'h' | 'd' | 'w' | 'M': Time unit
  - `updatedAt` string: Automation last update timestamp (read-only)
  - `url` string: Link to the automation workflow editor in the Omnisend app (read-only)

## Other responses

- `400`: Request contains invalid or missing fields
- `401`: Authentication is missing or invalid
- `403`: Insufficient permissions for this operation
- `404`: Automation workflow not found
- `409`: Cannot update an enabled automation
- `410`: API version has been retired
- `429`: Rate limit exceeded
- `500`: Unexpected error occurred

---

[API](https://skmtc.dev/omnisend/apis/automations-api.md) - [All operations](https://skmtc.dev/omnisend/apis/automations-api/llms.txt) - [OpenAPI document](https://skmtc.dev/omnisend/apis/automations-api/revisions/2419d261f3a8?raw)
