---
title: "Create sequence"
method: POST
path: "/sequences"
tags: ["Sequences"]
---

# Create sequence

`POST /sequences`

Creates a draft automation sequence using either AI-generated content or explicit email/action steps. Discount action steps dynamically generate Stripe or Shopify codes that later emails can reference with discount merge tags.

## Request body

- SequenceCreateRequest
  - `fromEmail` string, email — From address for every email in this sequence. Its domain must be configured and verified.
  - `fromName` string — Display name for a newly created sender profile. Requires fromEmail.
  - `senderProfileId` string — Existing sender profile ID. Mutually exclusive with fromEmail.
  - `replyTo` string, email — Reply-To address for every email in this sequence. A profile is created when needed.
  - `replyToName` string — Display name for a newly created reply profile. Requires replyTo.
  - `replyProfileId` string — Existing reply profile ID. Mutually exclusive with replyTo.
  - `name` string, required
  - `trigger` 'contact_added' | 'tag_added' | 'segment_entered' | 'event_received' | 'inactivity' | 'frequency', required
  - `listId` string — List ID for contact_added triggers. If omitted, contact_added can match any list.
  - `tagName` string — Tag name for tag_added triggers.
  - `segmentId` string — Segment ID for segment_entered triggers.
  - `eventName` string — Event name for event_received, inactivity, and frequency triggers.
  - `propertyFilters` SequenceTriggerPropertyFilter[] — Event property filters for event_received triggers. The sequence only starts when the triggering event's properties match all filters. Use [] in the path to match items inside arrays.
    - `path` string, required — Dot-path into the event properties. Use [] to match items inside arrays.
    - `operator` 'exists' | 'not_exists' | 'equals' | 'not_equals' | 'one_of' | 'contains' | 'greater_than' | 'less_than', required — Comparison operator. Value is required for every operator except exists and not_exists. `one_of` matches when the property equals any entry of the value array.
    - `value` union — Value to compare against. For `one_of`, pass a non-empty array of strings or numbers (maximum 50 values); all other operators take a single value.
      - string
      - number
      - boolean
      - union[]
        - union
          - string
          - number
  - `inactiveDays` number — Days of inactivity before the sequence starts.
  - `inactivityBaseline` 'sequence_created_at' | 'subscriber_created_at' — For inactivity triggers, controls when to start counting for subscribers who have never performed the event. Defaults to sequence_created_at.
  - `minCount` number — Minimum event count for frequency triggers.
  - `timeWindowDays` number — Time window in days for frequency triggers.
  - `enrollmentMode` 'unlimited' | 'one_time' | 'matching_field' — Controls sequence re-entry. `unlimited` allows re-entry after completion but prevents concurrent active runs. `one_time` allows one enrollment ever. `matching_field` is only valid for event-triggered sequences and allows concurrent active runs only when the trigger payload resolves to a different event field value.
  - `enrollmentFieldPath` string — Scalar dot-path event property used by matching_field enrollment, such as order.id or product.providerVariantId. Array traversal with [] is not supported; use propertyFilters for array matching. Only applies to event_received triggers. Leave empty for built-in Shopify product/variant defaults.
  - `sendingWindow` SequenceSendingWindow — Optional local-time sending window applied to every email step in a sequence. Email steps that become due outside the window wait until the next allowed local time.
    - `enabled` boolean
    - `timezone` string — IANA timezone for the window.
    - `startTime` string — Earliest local send time in 24-hour HH:mm format.
    - `endTime` string — Latest local send cutoff in 24-hour HH:mm format. Must be later than startTime.
    - `days` string[] — Allowed local days. Omit days when creating or updating to allow every day.
  - `emailCount` number — Number of emails for AI-generated content. Defaults to 5. Maximum is 10.
  - `durationDays` number — Total duration in days used to space AI-generated emails. Omit this to use the default sequence delay schedule.
  - `goal` string — Goal for AI-generated sequence content. Provide either goal or steps.
  - `stopCondition` SequenceStopCondition
    - `type` 'none' | 'has_tag' | 'does_not_have_tag' | 'added_to_list' | 'removed_from_list' | 'entered_segment' | 'field_changed' | 'event_received'
    - `value` string, nullable
  - `steps` SequenceStepInput[] — Explicit email and action steps. Provide either steps or goal.
    - `type` 'email' | 'sms' | 'create_discount' | 'discount' | 'update_subscriber' — Step type. Omit or use email for email content; use sms for a native SMS step; use create_discount for a dynamic discount; use update_subscriber for an Update Subscriber action.
    - `nodeType` 'action_email' | 'action_sms' | 'action_create_discount' | 'action_update_attributes' — Internal node-type alias for clients that work with automation nodes. Use action_update_attributes with config for Update Subscriber steps.
    - `config` SubscriberUpdateConfig — Update Subscriber config. String values may use standalone trigger-event merge tags such as {{event.plan}}, {{event.amount}}, or {{event.active}}. Number and boolean values are coerced after resolution.
      - `label` string
      - `firstName` string, nullable
      - `lastName` string, nullable
      - `status` 'active' | 'unsubscribed' | 'bounced'
      - `customAttributeUpdates` object[]
        - `name` string, required
        - `value` union, required — Literal scalar, null to delete, or one standalone merge tag.
          - string
          - number
          - boolean
        - `valueType` 'text' | 'number' | 'boolean'
    - `subject` string — Email subject line for email steps.
    - `previewText` string — Optional email preview text.
    - `text` string — SMS steps only. Plain-text message body; merge tags like {{FIRST_NAME}} work. Do not include opt-out text or a brand prefix - Sequenzy adds both automatically at send time.
    - `imageUrls` string[] — SMS steps only. Up to 2 publicly reachable image URLs sent as MMS media.
    - `ineligibleAction` 'skip' | 'exit' — SMS steps only. skip (default) continues the sequence when the contact can't receive SMS; exit removes them from the sequence.
    - `blocks` EmailBlock[] — Structured Sequenzy email blocks. Provide either blocks or html. Put visual styling under styles; top-level style keys such as backgroundColor, backgroundOpacity, borderColor, borderWidth, and borderRadius are normalized into styles.
      - `id` string
      - `type` 'text' | 'html' | 'heading' | 'list' | 'button' | 'spacer' | 'divider' | 'image' | 'columns' | 'conditional-group' | 'repeat' | 'card' | 'cta' | 'social' | 'logo' | 'header' | 'footer' | 'video' | 'product' | 'discount-code' | 'code' | 'countdown' | 'poll', required
      - `content` string — Content for text, html, and heading-like blocks.
      - `styles` object — Per-block visual styles. For compatibility, style fields such as backgroundColor, backgroundOpacity, borderColor, borderWidth, and borderRadius can also be supplied at the block top level and are normalized into this object.
        - `paddingTop` number
        - `paddingBottom` number
        - `paddingLeft` number
        - `paddingRight` number
        - `backgroundColor` string
        - `backgroundOpacity` number — Background opacity percentage from 0 to 100.
        - `textColor` string
        - `textAlign` 'left' | 'center' | 'right'
        - `borderRadius` number
        - `borderColor` string
        - `borderWidth` number
      - `conditions` object[] — Optional per-block display rules. The block renders only when every rule matches. The same shape is used for a conditional-group block's top-level `conditions`.
        - `id` string, required
        - `field` 'variable' | 'attribute' | 'email' | 'firstName' | 'lastName', required — `variable` resolves a merge-tag path from the transactional send `variables` or an automation `event` payload (nested paths like `order.total` or `event.plan` work). `attribute` reads a stored subscriber attribute. `email`, `firstName`, and `lastName` read core subscriber fields.
        - `operator` 'is' | 'is_not' | 'contains' | 'not_contains' | 'gt' | 'gte' | 'lt' | 'lte' | 'is_empty' | 'is_not_empty', required
        - `value` string, required — For `variable` and `attribute`, use `name:value` - the part before the colon is the variable path or attribute name, and the part after it is the comparison value. For `email`, `firstName`, and `lastName`, provide the plain comparison string.
    - `html` string — Raw HTML preserved as one HTML block. Provide either html or blocks.
    - `delay` SequenceDelayInput — Delay before this step runs. Use duration fields for fixed waits, or mode until_date with untilDateField for event/date-field waits.
      - `mode` 'duration' | 'until_date' — Delay mode. Defaults to duration.
      - `days` number
      - `hours` number
      - `minutes` number
      - `untilDateField` string — Event/subscriber date field path to wait until when mode is until_date.
      - `field` string — Alias for untilDateField.
      - `untilOffsetDirection` 'before' | 'after' — Whether the offset runs before or after the date field. Defaults to after.
      - `direction` 'before' | 'after' — Alias for untilOffsetDirection.
      - `untilMissingAction` 'continue' | 'exit' — What to do when the date field is missing or invalid. Defaults to continue.
      - `missingAction` 'continue' | 'exit' — Alias for untilMissingAction.
    - `waitUntil` SequenceWaitUntilInput — Wait until a date from the enrollment event/subscriber data, optionally offset before or after that date.
      - `field` string — Event/subscriber date field path to wait until.
      - `untilDateField` string — Alias for field.
      - `offset` SequenceDelayOffsetInput — Relative offset for a delay.
        - `days` number
        - `hours` number
        - `minutes` number
      - `days` number — Shorthand offset days when offset is omitted.
      - `hours` number — Shorthand offset hours when offset is omitted.
      - `minutes` number — Shorthand offset minutes when offset is omitted.
      - `direction` 'before' | 'after' — Whether the offset runs before or after the field date. Defaults to after.
      - `untilOffsetDirection` 'before' | 'after' — Alias for direction.
      - `missingAction` 'continue' | 'exit' — What to do when the date field is missing or invalid. Defaults to continue.
      - `untilMissingAction` 'continue' | 'exit' — Alias for missingAction.
    - `delayMs` number — Delay before this step in milliseconds. Prefer delay for human-authored requests; use delayMs when importing provider waits.
    - `name` string — Optional email template name for email steps.
    - `discount` SequenceDiscountInput — Discount configuration for dynamic create_discount steps.
      - `label` string — Builder label for discount steps.
      - `provider` 'stripe' | 'shopify' — Discount provider. Use stripe to dynamically create a Stripe coupon plus promotion code, or shopify to dynamically create a Shopify Admin discount code.
      - `discountType` 'percent' | 'amount' — Discount type for create_discount steps.
      - `percentOff` number — Percent discount. Required when discountType is percent.
      - `amountOff` number — Fixed discount amount in the smallest currency unit, for example 500 for $5. Required when discountType is amount.
      - `currency` string — ISO currency for fixed-amount discounts. Defaults to usd.
      - `duration` 'once' | 'forever' | 'repeating' — Discount duration. Defaults to once.
      - `durationInMonths` number — Required for repeating discounts.
      - `appliesToAllPlans` boolean — Whether the discount applies to all plans. Defaults to true.
      - `planIds` string[] — Provider product IDs when appliesToAllPlans is false. Stripe uses IDs like prod_abc123; Shopify accepts numeric product IDs or gid://shopify/Product/... IDs.
      - `codePrefix` string — Optional prefix for generated dynamic codes. The final code also includes a subscriber/token suffix.
      - `maxRedemptions` number — Maximum redemptions for each generated code. Use 1 for subscriber-specific codes.
      - `lockToSubscriber` boolean — Stripe-only. Restrict each generated promotion code to the matched subscriber's Stripe customer.
      - `expiresAt` string — Optional future expiration date or ISO timestamp. Mutually exclusive with expiresInHours.
      - `expiresInHours` number — Optional relative expiration in hours, resolved when each subscriber's code is created. Takes precedence over expiresAt.
      - `name` string — Optional display name for each dynamically generated provider discount.
    - `label` string — Legacy top-level builder label for discount steps. Prefer discount.label.
    - `provider` 'stripe' | 'shopify' — Legacy top-level discount provider. Prefer discount.provider. Supports stripe and shopify.
    - `discountType` 'percent' | 'amount' — Legacy top-level discount type. Prefer discount.discountType.
    - `percentOff` number — Percent discount. Required when discountType is percent.
    - `amountOff` number — Fixed discount amount in the smallest currency unit, for example 500 for $5. Required when discountType is amount.
    - `currency` string — ISO currency for fixed-amount discounts. Defaults to usd.
    - `duration` 'once' | 'forever' | 'repeating' — Discount duration. Defaults to once.
    - `durationInMonths` number — Required for repeating discounts.
    - `appliesToAllPlans` boolean — Whether the discount applies to all plans. Defaults to true.
    - `planIds` string[] — Provider product IDs when appliesToAllPlans is false. Stripe uses IDs like prod_abc123; Shopify accepts numeric product IDs or gid://shopify/Product/... IDs.
    - `codePrefix` string — Optional prefix for generated dynamic codes. The final code also includes a subscriber/token suffix.
    - `maxRedemptions` number — Maximum redemptions for each generated code. Use 1 for subscriber-specific codes.
    - `lockToSubscriber` boolean — Legacy top-level Stripe-only flag. Prefer discount.lockToSubscriber.
    - `expiresAt` string — Optional future expiration date or ISO timestamp. Mutually exclusive with expiresInHours.
    - `expiresInHours` number — Optional relative expiration in hours, resolved when each subscriber's code is created. Takes precedence over expiresAt.

## Response `200`

Sequence created successfully

- SequenceCreateResponse
  - `success` boolean
  - `message` string
  - `sequence` object
    - `id` string
    - `name` string
    - `status` 'draft' | 'active' | 'paused' | 'archived'
    - `trigger` string
    - `emailCount` number
    - `discountCount` number
    - `subscriberUpdateCount` number
    - `nodeCount` number
    - `enrichmentStatus` string
    - `stopCondition` SequenceStopCondition
      - `type` 'none' | 'has_tag' | 'does_not_have_tag' | 'added_to_list' | 'removed_from_list' | 'entered_segment' | 'field_changed' | 'event_received'
      - `value` string, nullable
    - `sendingWindow` SequenceSendingWindow — Optional local-time sending window applied to every email step in a sequence. Email steps that become due outside the window wait until the next allowed local time.
      - `enabled` boolean
      - `timezone` string — IANA timezone for the window.
      - `startTime` string — Earliest local send time in 24-hour HH:mm format.
      - `endTime` string — Latest local send cutoff in 24-hour HH:mm format. Must be later than startTime.
      - `days` string[] — Allowed local days. Omit days when creating or updating to allow every day.
  - `eventTrackingCode` string — Code snippet returned for custom event triggers.
  - `eventTracking` object — Endpoint, payload contract, example, documentation, and integration-guide pointer returned for custom event triggers.
    - `endpoint` string
    - `method` string
    - `docsUrl` string
    - `integrationGuide` object
      - `tool` string
      - `arguments` object
    - `payloadContract` object
      - `required` string[]
      - `identity` string
      - `event` string
      - `properties` string
      - `requiredPropertyPaths` string[]
      - `propertyFilters` SequenceTriggerPropertyFilter[] — Normalized trigger filters that the event properties must satisfy before the sequence can enroll the subscriber.
        - `path` string, required — Dot-path into the event properties. Use [] to match items inside arrays.
        - `operator` 'exists' | 'not_exists' | 'equals' | 'not_equals' | 'one_of' | 'contains' | 'greater_than' | 'less_than', required — Comparison operator. Value is required for every operator except exists and not_exists. `one_of` matches when the property equals any entry of the value array.
        - `value` union — Value to compare against. For `one_of`, pass a non-empty array of strings or numbers (maximum 50 values); all other operators take a single value.
          - string
          - number
          - boolean
          - union[]
            - union
              - …
    - `examplePayload` object
    - `examplePayloadMatchesFilters` boolean — Whether examplePayload already satisfies every normalized property filter. When false, adapt properties using payloadContract before sending the sample.
    - `examplePayloadNote` string — Present when the generated example needs manual property adaptation before it satisfies every filter.
  - `requiredEvents` string[]

## Other responses

- `400` — Validation error
- `401` — Unauthorized
- `403` — No company selected
- `500` — Internal server error

## Changes

- **2026-07-14** `83e7fd773745` — 7 info
  - added the new `code` enum value to the request property `steps/items/blocks/items/type`
  - added the new `countdown` enum value to the request property `steps/items/blocks/items/type`
  - added the new `discount-code` enum value to the request property `steps/items/blocks/items/type`
  - added the new `header` enum value to the request property `steps/items/blocks/items/type`
  - …3 more
- **2026-07-13** `91f9f0e15bd0` — 4 info
  - added the new optional request property `steps/items/config`
  - added the new `action_update_attributes` enum value to the request property `steps/items/nodeType`
  - added the new `update_subscriber` enum value to the request property `steps/items/type`
  - added the optional property `sequence/subscriberUpdateCount` to the response with the `200` status
- **2026-07-12** `d103f2b71fca` — 6 info
  - added the new optional request property `fromEmail`
  - added the new optional request property `fromName`
  - added the new optional request property `replyProfileId`
  - added the new optional request property `replyTo`
  - …2 more
- **2026-07-10** `1b0d5fa83cd8` — 5 info
  - added the new optional request property `steps/items/imageUrls`
  - added the new optional request property `steps/items/ineligibleAction`
  - added the new optional request property `steps/items/text`
  - added the new `action_sms` enum value to the request property `steps/items/nodeType`
  - …1 more
- …earlier changes not shown

[Full history](https://skmtc.dev/sequenzy/apis/sequenzy-api/changes/sequences/post.md)

---

[API](https://skmtc.dev/sequenzy/apis/sequenzy-api.md) · [All operations](https://skmtc.dev/sequenzy/apis/sequenzy-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/sequenzy/sequenzy-api/revisions/83e7fd773745/schema)
