---
title: "Copy automation workflow"
method: POST
path: "/automations/{id}/copy"
tags: ["Automations"]
---

# Copy automation workflow

`POST /automations/{id}/copy`

Create a copy of an existing automation workflow.

The copy is always created in a disabled state, regardless of the source automation's status.

The request body is optional. When provided, you can specify a custom name for the copy.
When omitted (or when name is empty), the copy is named "Copy of: <original name>".

**Scopes:**
`automations.write`

## Path parameters

- `id` string, required

## Headers

- `Omnisend-Version` string, required

## Request body

- CopyAutomationRequest — Copy automation workflow request.
  - `name` string — Custom name for the copied automation workflow. When omitted, defaults to "Copy of: <original name>".

## Response `201`

Copied automation workflow

- Automation — Automation workflow resource
  - `blocks` Block[] — Automation workflow blocks (actions, delays, splits, A/B tests)
    - `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)

## 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
- `410` — API version has been retired
- `429` — Rate limit exceeded
- `500` — Unexpected error occurred

---

[API](https://skmtc.net/omnisend/apis/events-api.md) · [All operations](https://skmtc.net/omnisend/apis/events-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/omnisend/events-api/versions/50214fbc283f/schema)
