> ## Documentation Index
> Fetch the complete documentation index at: https://apidoc.mailercloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create Automation

> API to create an advanced automation in a single request. `name` and `nodes` are required. `auto_publish` is optional (defaults to `false` = draft). `timezone`, `start_time`, `end_time`, `allow_re_enrollment`, `re_enroll_interval`, `re_enroll_unit` are optional.

The automation is declared as a directed graph of nodes: exactly one trigger node, plus any number of action / wait / condition nodes wired via `parent_id`. Caller-supplied node ids (`id`, `parent_id`, `target_id`) are short strings used only to wire the graph in the request; they are not stored.

**Plan gate:** the caller's plan must include advanced automation, otherwise a `403` is returned.



## OpenAPI

````yaml /openapi-v1.json post /automations
openapi: 3.1.0
info:
  title: Mailercloud Marketing API
  version: 1.0.0
  description: >-
    Campaigns, contacts, lists, segments, automations, and webhooks for the
    Mailercloud Marketing Platform.
servers:
  - url: https://cloudapi.mailercloud.com/v1
security:
  - apiKey: []
tags:
  - name: Campaigns
  - name: Contacts
  - name: Lists
  - name: Tags
  - name: Segments
  - name: Custom Properties
  - name: Senders
  - name: Templates
  - name: Automations
  - name: Webhooks
  - name: Webforms
  - name: Inbox Tracker
  - name: Account
paths:
  /automations:
    post:
      tags:
        - Automations
      summary: Create Automation
      description: >-
        API to create an advanced automation in a single request. `name` and
        `nodes` are required. `auto_publish` is optional (defaults to `false` =
        draft). `timezone`, `start_time`, `end_time`, `allow_re_enrollment`,
        `re_enroll_interval`, `re_enroll_unit` are optional.


        The automation is declared as a directed graph of nodes: exactly one
        trigger node, plus any number of action / wait / condition nodes wired
        via `parent_id`. Caller-supplied node ids (`id`, `parent_id`,
        `target_id`) are short strings used only to wire the graph in the
        request; they are not stored.


        **Plan gate:** the caller's plan must include advanced automation,
        otherwise a `403` is returned.
      operationId: create-automation
      parameters:
        - name: Content-Type
          in: header
          required: true
          description: Request body type
          schema:
            type: string
            default: application/json
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
                - nodes
              properties:
                name:
                  type: string
                  minLength: 1
                  maxLength: 150
                  description: |-
                    Automation display name. HTML is stripped server-side.

                    Minimum: 1
                    Maximum: 150
                timezone:
                  type: string
                  description: >-
                    IANA timezone (e.g. Asia/Kolkata, America/New_York, UTC).
                    Defaults to the caller's account timezone.
                auto_publish:
                  type: boolean
                  default: false
                  description: >-
                    If true, the automation is published immediately and the
                    response returns status=active. If false (default), it is
                    saved as a draft and returns status=draft.
                allow_re_enrollment:
                  type: boolean
                  default: false
                  description: >-
                    Allow the same contact to re-enter this automation after
                    completing or exiting.
                re_enroll_interval:
                  type: integer
                  minimum: 1
                  maximum: 30
                  description: >-
                    Minimum wait before a contact can re-enroll. Required when
                    allow_re_enrollment is true.


                    Minimum: 1

                    Maximum: 30
                re_enroll_unit:
                  type: string
                  enum:
                    - hours
                    - days
                    - weeks
                  description: >-
                    Unit for re_enroll_interval. Required when
                    allow_re_enrollment is true.


                    Supported values: hours, days, weeks
                start_time:
                  type: string
                  description: |-
                    Earliest UTC moment the automation will accept new contacts.

                    Format: YYYY-MM-DD HH:mm:ss

                    Must be in the future.
                end_time:
                  type: string
                  description: |-
                    Latest UTC moment the automation will accept new contacts.

                    Format: YYYY-MM-DD HH:mm:ss

                    Must be in the future and >= start_time.
                nodes:
                  type: array
                  minItems: 1
                  maxItems: 500
                  description: >-
                    DAG of trigger + downstream action / condition nodes.
                    Exactly one trigger node is required; no orphans and no
                    cycles allowed.


                    Minimum items: 1

                    Maximum items: 500
                  items:
                    type: object
                    required:
                      - id
                      - type
                    properties:
                      parent_id:
                        type: string
                        description: >-
                          Parent node's id. Required on every node except the
                          trigger.
                      type:
                        type: string
                        enum:
                          - trigger
                          - wait_for_period
                          - wait_until_time
                          - wait_for_event
                          - if_else
                          - random_split
                          - goto
                          - delete_contact
                          - update_contact_property
                          - add_tag
                          - remove_tag
                          - add_to_list
                          - remove_from_list
                        description: >-
                          Node type. The trigger type must appear exactly once
                          at the root.


                          Supported types: trigger, wait_for_period,
                          wait_until_time, wait_for_event, if_else,
                          random_split, goto, delete_contact,
                          update_contact_property, add_tag, remove_tag,
                          add_to_list, remove_from_list
                      branch:
                        type: string
                        enum:
                          - 'yes'
                          - 'no'
                        description: >-
                          Required on direct children of if_else and
                          random_split.


                          Supported values: yes, no
                      target_id:
                        type: string
                        description: >-
                          Target node id for goto nodes. Must reference an
                          existing caller id that is NOT in this node's ancestor
                          chain.
                      trigger:
                        type: string
                        enum:
                          - list_subscribed
                          - audience_subscribed
                          - webform_submitted
                          - contact_added_via_api
                          - any_property_changed
                          - list_property_changed
                          - campaign_opened
                          - campaign_not_opened
                          - campaign_clicked
                          - campaign_not_clicked
                          - campaign_sent
                          - date_property
                          - tag_added
                        description: >-
                          Trigger type. Required when type=trigger.


                          Supported triggers: list_subscribed,
                          audience_subscribed, webform_submitted,
                          contact_added_via_api, any_property_changed,
                          list_property_changed, campaign_opened,
                          campaign_not_opened, campaign_clicked,
                          campaign_not_clicked, campaign_sent, date_property,
                          tag_added
                      list:
                        type: string
                        description: >-
                          List name (cid-scoped). Required for list_subscribed,
                          contact_added_via_api, any_property_changed,
                          list_property_changed triggers AND for add_to_list /
                          remove_from_list nodes.
                      webform:
                        type: string
                        description: >-
                          Webform name (cid-scoped). Required for
                          webform_submitted trigger.
                      campaign:
                        type: string
                        description: >-
                          Campaign name (cid-scoped). Required for all 5
                          campaign_* triggers and for wait_for_event when the
                          event is a campaign trigger.
                      tag:
                        type: string
                        maxLength: 100
                        description: >-
                          Tag name (cid-scoped). Required for tag_added trigger
                          and add_tag / remove_tag nodes. Also accepted as the
                          single-tag form of the if_else contact_tag filter.


                          Maximum: 100
                      property:
                        type: string
                        description: >-
                          Custom field mapping_name (e.g. custom_1, country).
                          Required for any_property_changed,
                          list_property_changed, date_property triggers;
                          update_contact_property node; and contact_property
                          if_else filter.


                          Allowed characters: ^[A-Za-z0-9_]+$
                      property_condition:
                        type: string
                        enum:
                          - equals
                          - not_equals
                          - is_known
                          - is_unknown
                          - contains
                          - does_not_contain
                          - starts_with
                          - ends_with
                        description: >-
                          Property comparison operator. Required for property
                          triggers and update_contact_property.


                          Supported values: equals, not_equals, is_known,
                          is_unknown, contains, does_not_contain, starts_with,
                          ends_with
                      property_value:
                        type: string
                        description: >-
                          Comparison value for property triggers. Not required
                          when property_condition is is_known or is_unknown.
                      value:
                        description: >-
                          Used by update_contact_property (new value to assign)
                          and as the generic value slot for some if_else
                          condition operators.


                          Type depends on operator (string / number / object
                          {from, to} for between / object {from_date, to_date}
                          for between_dates).
                      allow_import:
                        type: boolean
                        description: >-
                          If true, contacts imported via CSV / API also trigger
                          this automation. Applies to list_subscribed,
                          audience_subscribed, contact_added_via_api, property
                          triggers and tag_added.
                      set_time_limit:
                        type: boolean
                        description: >-
                          If true, the trigger waits at most wait_for /
                          wait_unit before evaluating. Optional on property and
                          campaign_opened / campaign_clicked triggers.
                      wait_for:
                        type: integer
                        minimum: 1
                        description: >-
                          How long to wait before triggering. Required for
                          campaign_not_opened and campaign_not_clicked. Optional
                          for property and campaign_opened / campaign_clicked
                          triggers when set_time_limit is true.
                      wait_unit:
                        type: string
                        enum:
                          - hours
                          - days
                          - weeks
                        description: |-
                          Unit for wait_for.

                          Supported values: hours, days, weeks
                      when:
                        type: string
                        enum:
                          - same_day
                          - before
                          - after
                        description: |-
                          Required for date_property trigger.

                          Supported values: same_day, before, after
                      day:
                        type: integer
                        description: >-
                          For date_property trigger when when != same_day: 1-90
                          days before/after. For wait_until_time node with
                          mode=day_of_month: 1-31.
                      time:
                        type: string
                        description: >-
                          HH:mm for date_property trigger. HH:mm:ss (must not be
                          00:00:00) for wait_until_time node.
                      is_recurring:
                        type: boolean
                        description: Optional on date_property trigger.
                      days:
                        type: integer
                        minimum: 0
                        maximum: 90
                        description: >-
                          wait_for_period delay (days). At least one of days /
                          hours / minutes must be > 0.


                          Minimum: 0

                          Maximum: 90
                      hours:
                        type: integer
                        minimum: 0
                        maximum: 24
                        description: |-
                          wait_for_period delay (hours).

                          Minimum: 0
                          Maximum: 24
                      minutes:
                        type: integer
                        minimum: 0
                        maximum: 60
                        description: |-
                          wait_for_period delay (minutes).

                          Minimum: 0
                          Maximum: 60
                      mode:
                        type: string
                        enum:
                          - time_of_day
                          - day_of_week
                          - day_of_month
                          - specific_date
                        description: >-
                          Required for wait_until_time node.


                          Supported values: time_of_day, day_of_week,
                          day_of_month, specific_date
                      weeks:
                        type: array
                        minItems: 1
                        items:
                          type: string
                          enum:
                            - mon
                            - tue
                            - wed
                            - thu
                            - fri
                            - sat
                            - sun
                        description: |-
                          Required when wait_until_time mode=day_of_week.

                          Supported values: mon, tue, wed, thu, fri, sat, sun
                      date:
                        type: string
                        description: |-
                          Required when wait_until_time mode=specific_date.

                          Format: YYYY-MM-DD (must be >= today).
                      event:
                        type: string
                        description: >-
                          Trigger name to wait for. Required for wait_for_event
                          node. Use one of the trigger values. The matching
                          trigger's required fields must also be supplied on the
                          same node (e.g. event=campaign_opened requires
                          campaign).
                      tags:
                        type: array
                        items:
                          type: string
                        maxItems: 100
                        description: |-
                          Multi-tag form of the if_else contact_tag filter.

                          Maximum: 100 entries
                      filters:
                        type: array
                        maxItems: 3
                        description: >-
                          if_else filter groups. The outer array is OR (max 3
                          groups). Each inner array is AND (>=1 condition per
                          group).
                        items:
                          type: array
                          minItems: 1
                          items:
                            type: object
                            required:
                              - condition
                              - operator
                            properties:
                              condition:
                                type: string
                                enum:
                                  - contact_property
                                  - subscriber_status
                                  - contact_rating
                                  - domain
                                  - subscriber_opened
                                  - global_openers
                                  - campaign_tag
                                  - campaign_activity
                                  - contact_tag
                                  - contact_details
                                description: >-
                                  Filter condition type.


                                  Supported values: contact_property,
                                  subscriber_status, contact_rating, domain,
                                  subscriber_opened, global_openers,
                                  campaign_tag, campaign_activity, contact_tag,
                                  contact_details
                              operator:
                                type: string
                                description: >-
                                  Allowed values depend on condition.


                                  contact_property: equals, not_equals,
                                  is_known, is_unknown, contains,
                                  does_not_contain, starts_with, ends_with


                                  subscriber_status: is, is_not


                                  contact_rating: equals, between


                                  domain: equals, not_equals, is_empty,
                                  is_not_empty


                                  subscriber_opened: count, in_last_days,
                                  not_in_last_days


                                  global_openers: equals, not_equals, less_than,
                                  greater_than, between


                                  campaign_tag, campaign_activity, contact_tag,
                                  contact_details: any_time, between_dates,
                                  in_last_days
                              status_value:
                                type: string
                                enum:
                                  - active
                                  - unknown
                                  - valid
                                  - opened
                                  - clicked
                                description: >-
                                  Required when condition=subscriber_status. Use
                                  this key (not the generic value).


                                  Supported values: active, unknown, valid,
                                  opened, clicked
                              value:
                                description: >-
                                  Operator-shaped value.


                                  between: {from: int, to: int}

                                  between_dates: {from_date: YYYY-MM-DD,
                                  to_date: YYYY-MM-DD}

                                  in_last_days / not_in_last_days: int 1-365

                                  is_known / is_unknown / is_empty /
                                  is_not_empty: omit value entirely
                              tag:
                                type: string
                                description: Single-tag form of the contact_tag filter.
                              tags:
                                type: array
                                items:
                                  type: string
                                maxItems: 100
                                description: |-
                                  Multi-tag form of the contact_tag filter.

                                  Maximum: 100 entries
                              property:
                                type: string
                                description: >-
                                  Custom field mapping_name. Required when
                                  condition=contact_property.


                                  Allowed characters: ^[A-Za-z0-9_]+$
            examples:
              Example-1---Welcome-series:
                value:
                  name: Welcome series for new subscribers
                  timezone: Asia/Kolkata
                  auto_publish: true
                  nodes:
                    - id: n1
                      type: trigger
                      trigger: list_subscribed
                      list: Newsletter Subscribers
                    - id: n2
                      parent_id: n1
                      type: wait_for_period
                      days: 1
                    - id: n3
                      parent_id: n2
                      type: if_else
                      filters:
                        - - condition: subscriber_status
                            operator: is
                            status_value: active
                    - id: n4
                      parent_id: n3
                      branch: 'yes'
                      type: add_tag
                      tag: Welcomed-Active
                    - id: n5
                      parent_id: n3
                      branch: 'no'
                      type: add_tag
                      tag: Welcomed-Inactive
              Example-2---Birthday-A-B-test:
                value:
                  name: Birthday wishes - A/B variant test
                  timezone: Asia/Kolkata
                  auto_publish: true
                  allow_re_enrollment: true
                  re_enroll_interval: 1
                  re_enroll_unit: weeks
                  nodes:
                    - id: n1
                      type: trigger
                      trigger: date_property
                      property: birthday
                      when: same_day
                      time: '09:00'
                      is_recurring: true
                    - id: n2
                      parent_id: n1
                      type: random_split
                    - id: n3
                      parent_id: n2
                      branch: 'yes'
                      type: add_tag
                      tag: Birthday-Variant-A
                    - id: n4
                      parent_id: n2
                      branch: 'no'
                      type: add_tag
                      tag: Birthday-Variant-B
              Example-3---Re-engage-non-openers:
                value:
                  name: Re-engage Spring Sale non-openers
                  timezone: America/New_York
                  auto_publish: false
                  start_time: '2026-06-01 00:00:00'
                  end_time: '2026-07-31 23:59:59'
                  nodes:
                    - id: n1
                      type: trigger
                      trigger: campaign_not_opened
                      campaign: Spring Sale 2026
                      wait_for: 3
                      wait_unit: days
                    - id: n2
                      parent_id: n1
                      type: wait_until_time
                      mode: day_of_week
                      time: '10:00:00'
                      weeks:
                        - mon
                        - tue
                        - wed
                        - thu
                        - fri
                    - id: n3
                      parent_id: n2
                      type: if_else
                      filters:
                        - - condition: subscriber_status
                            operator: is
                            status_value: active
                          - condition: contact_rating
                            operator: between
                            value:
                              from: 3
                              to: 5
                        - - condition: contact_tag
                            operator: any_time
                            tag: VIP
                    - id: n4
                      parent_id: n3
                      branch: 'yes'
                      type: add_to_list
                      list: Re-engagement Pool
                    - id: n5
                      parent_id: n3
                      branch: 'no'
                      type: remove_tag
                      tag: Engaged
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    enum:
                      - draft
                      - active
                    description: >-
                      draft when auto_publish=false. active when
                      auto_publish=true and all publish gates pass.
              examples:
                Example-1---draft:
                  value:
                    id: wHKw
                    status: draft
                Example-2---active:
                  value:
                    id: wHKH
                    status: active
        '400':
          description: >-
            Bad Request - validation, entity-name resolution, or publish gate
            failure
          content:
            application/json:
              schema:
                type: object
                properties:
                  errors:
                    type: array
                    items:
                      type: object
                      properties:
                        field:
                          type: string
                        message:
                          type: string
              examples:
                Example-1:
                  value:
                    errors:
                      - field: nodes[2].tag
                        message: tag "VIP" not found
                      - field: settings.start_time
                        message: must be in the future
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                type: object
                properties:
                  errors:
                    type: array
                    items:
                      type: object
                      properties:
                        field:
                          type: string
                        message:
                          type: string
              examples:
                Example-1:
                  value:
                    errors:
                      - field: ''
                        message: Authorization failed
        '403':
          description: Forbidden - caller's plan does not include advanced automation
          content:
            application/json:
              schema:
                type: object
                properties:
                  errors:
                    type: array
                    items:
                      type: object
                      properties:
                        field:
                          type: string
                        message:
                          type: string
              examples:
                Example-1:
                  value:
                    errors:
                      - field: ''
                        message: Plan does not include advanced automation
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
              examples:
                Example-1:
                  value:
                    message: Internal server error
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        Your Mailercloud API key (plain text, no Bearer prefix). Create keys in
        Settings → API.

````