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

# Create automation

> Set up an automation from a [template](/automations/api/list-templates) on one of your
[stores](/automations/api/list-stores), with the template's inputs and a schedule.

- With a schedule (`daily`, `weekly` and the other cadences), the automation is `active` and its runs are
  queued at the times the schedule gives, in the store's timezone unless you send `timezone`.
- With `schedule.cadence: manual`, it is a `draft` that runs only when you
  [run it now](/automations/api/run-now).
- A template that starts when the store sends an event (it has a `trigger`) takes only
  `schedule.cadence: manual`, and its automation is `active` at once.

The automation is set up even when the template is not ready yet (its `readiness` says why, such as a
connection your organisation does not have). Its runs then end `refused` (`connection_missing`), saying what
to connect, until that connection is there.

The automation is recorded as created by the person you logged in as, through the API (`created_via:
api-token`, with your `api_client_id`). Answers `404` when the template or the store is not your
organisation's, and `422` when the store is not connected, or an input or the schedule is not valid.

Needs the `automations:write` scope.



## OpenAPI

````yaml automations/api/openapi.json POST /v1/automations
openapi: 3.1.0
info:
  title: Vortex IQ Automations API
  version: 1.0.0
  description: >
    REST API for Vortex IQ Automations. List the templates your organisation can
    use, set automations up on your

    stores, schedule them, run them, and follow every run, from your own tools
    instead of the Automations screens.


    The API is served from `https://automations-api.vortexiq.ai`; the login that
    gives you a token is on

    `https://app.vortexiq.ai`. Every call acts as the person who logged in,
    within their organisation, and every

    answer is JSON. See [Authentication](/automations/api/authentication).
  contact:
    name: Vortex IQ Support
    url: https://www.vortexiq.ai/contact-us
servers:
  - url: https://automations-api.vortexiq.ai
    description: Vortex IQ Automations (production)
security:
  - bearerAuth: []
  - apiCredential: []
tags:
  - name: Authentication
    description: >-
      Exchange your identity and your organisation's API credential for a bearer
      token.
  - name: Templates & stores
    description: What you can set up, and what it can run on.
  - name: Automations
    description: Set automations up, read them and change them.
  - name: Automation controls
    description: Pause, resume, archive and restore.
  - name: Runs
    description: Run an automation now, follow a run, read the history.
  - name: Schedules & calendar
    description: Preview a schedule, list the coming runs, move or skip one.
  - name: Approvals
    description: >-
      The runs waiting for a decision. Deciding happens in the Vortex IQ app
      only.
  - name: Imported workflows
    description: >-
      Bring an n8n or Shopify Flow workflow in, see how it would run, and run it
      as your own automation.
  - name: Status
    description: >-
      Whether Automations are on for your organisation, and how the service is
      doing.
paths:
  /v1/automations:
    post:
      tags:
        - Automations
      summary: Create automation
      description: >-
        Set up an automation from a [template](/automations/api/list-templates)
        on one of your

        [stores](/automations/api/list-stores), with the template's inputs and a
        schedule.


        - With a schedule (`daily`, `weekly` and the other cadences), the
        automation is `active` and its runs are
          queued at the times the schedule gives, in the store's timezone unless you send `timezone`.
        - With `schedule.cadence: manual`, it is a `draft` that runs only when
        you
          [run it now](/automations/api/run-now).
        - A template that starts when the store sends an event (it has a
        `trigger`) takes only
          `schedule.cadence: manual`, and its automation is `active` at once.

        The automation is set up even when the template is not ready yet (its
        `readiness` says why, such as a

        connection your organisation does not have). Its runs then end `refused`
        (`connection_missing`), saying what

        to connect, until that connection is there.


        The automation is recorded as created by the person you logged in as,
        through the API (`created_via:

        api-token`, with your `api_client_id`). Answers `404` when the template
        or the store is not your

        organisation's, and `422` when the store is not connected, or an input
        or the schedule is not valid.


        Needs the `automations:write` scope.
      operationId: createAutomation
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AutomationCreate'
            example:
              template_id: shopify-catalogue-quality
              integration_id: 101
              name: Weekly catalogue check
              inputs: {}
              schedule:
                cadence: manual
      responses:
        '201':
          description: >-
            Created. The automation, with its first run time when it has a
            schedule.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AutomationResponse'
              example:
                success: true
                contract_version: 1
                data:
                  automation:
                    id: 01M520GSDQH5TQ3CAAQ584TTKH
                    version: 1
                    kind: template
                    import_id: null
                    template_id: shopify-catalogue-quality
                    template_version: 4
                    platform: shopify
                    integration_id: 101
                    store_label: Example Shopify store
                    name: Weekly catalogue check
                    state: draft
                    trigger:
                      kind: schedule
                    paused_by: null
                    paused_reason: null
                    inputs: {}
                    bindings: {}
                    plan_version: 1
                    connections: []
                    schedule:
                      cadence: manual
                      run_at: null
                      day_of_week: null
                      day_of_month: null
                      date: null
                      days: null
                      week_of_month: null
                    timezone: Europe/London
                    spread_minutes: 2
                    next_run_at: null
                    last_run_at: null
                    consecutive_failures: 0
                    send_mode: ask
                    created_at: '2026-10-16T09:26:03.448Z'
                    updated_at: '2026-10-16T09:26:03.448Z'
                    created_by: 7
                    created_via: api-token
                    api_client_id: viq_auto_Ab12Cd34Ef56Gh78Ij90Kl12
        '401':
          $ref: '#/components/responses/Unauthorised'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/ValidationFailed'
        '429':
          $ref: '#/components/responses/TooManyRequests'
      security:
        - bearerAuth:
            - automations:write
        - apiCredential:
            - automations:write
components:
  schemas:
    AutomationCreate:
      type: object
      required:
        - template_id
        - name
        - inputs
        - schedule
      properties:
        template_id:
          $ref: '#/components/schemas/TemplateId'
        integration_id:
          type: integer
          description: >-
            The store or account it runs on. Required unless its template runs
            on nothing, and refused when it does.
        connections:
          type: array
          minItems: 1
          maxItems: 20
          uniqueItems: true
          description: >-
            For a template that runs on nothing, the connections it reads, by
            id, in

            the order to read them: each the organisation's own, connected, and
            of a

            kind in the template's `connections`. Refused for any other
            template.
          items:
            type: integer
            minimum: 1
        timezone:
          type: string
          minLength: 1
          maxLength: 64
          description: >-
            The timezone its schedule runs in (IANA name, such as
            Europe/London); the store's when absent.
        name:
          type: string
          minLength: 1
          maxLength: 120
        inputs:
          type: object
          additionalProperties: true
        schedule:
          $ref: '#/components/schemas/Schedule'
    AutomationResponse:
      type: object
      required:
        - success
        - data
        - contract_version
      properties:
        success:
          type: boolean
          const: true
        contract_version:
          $ref: '#/components/schemas/ContractVersion'
        data:
          type: object
          required:
            - automation
          properties:
            automation:
              $ref: '#/components/schemas/Automation'
    TemplateId:
      type: string
      description: The template's id, such as `shopify-catalogue-quality`.
      pattern: ^[a-z0-9][a-z0-9-]{1,80}$
    Schedule:
      type: object
      required:
        - cadence
      properties:
        cadence:
          $ref: '#/components/schemas/Cadence'
        run_at:
          type:
            - string
            - 'null'
          description: >-
            The time of day in the automation's timezone, `HH:MM`. Required for
            once, daily, weekdays, weekly and monthly.
          pattern: ^([01][0-9]|2[0-3]):[0-5][0-9]$
        day_of_week:
          type:
            - integer
            - 'null'
          minimum: 1
          maximum: 7
          description: >-
            1 is Monday. Required for weekly, and for monthly with
            `week_of_month`.
        day_of_month:
          type:
            - integer
            - 'null'
          minimum: 1
          maximum: 31
          description: >-
            For monthly, unless `week_of_month` is given. 31 runs on the last
            day of a shorter month.
        date:
          type:
            - string
            - 'null'
          pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}$
          description: >-
            Required for once; the local calendar day it runs on, in the
            automation's timezone. A day and time already passed are refused.
        days:
          type:
            - array
            - 'null'
          items:
            type: integer
            minimum: 1
            maximum: 7
          minItems: 1
          maxItems: 7
          uniqueItems: true
          description: >-
            For weekdays; which days, 1 is Monday. Absent means Monday to
            Friday.
        week_of_month:
          type:
            - integer
            - 'null'
          enum:
            - 1
            - 2
            - 3
            - 4
            - -1
            - null
          description: >-
            For monthly, with `day_of_week`; the first to fourth, or -1 the
            last, such weekday of the month, instead of `day_of_month`.
    ContractVersion:
      type: integer
      minimum: 1
      description: >-
        The version of the API this answer follows. It changes only for a
        breaking change.
    Automation:
      type: object
      required:
        - id
        - version
        - kind
        - import_id
        - template_id
        - template_version
        - platform
        - integration_id
        - store_label
        - name
        - state
        - paused_by
        - paused_reason
        - inputs
        - schedule
        - timezone
        - spread_minutes
        - next_run_at
        - last_run_at
        - consecutive_failures
        - created_at
        - updated_at
      properties:
        id:
          $ref: '#/components/schemas/Id'
        kind:
          type: string
          enum:
            - template
            - workflow
          description: >-
            `template` runs one of Vortex IQ's templates. `workflow` runs your
            own imported n8n workflow, and runs only once every step that needs
            a connection has one.
        import_id:
          description: >-
            The import a `workflow` automation was made from; null for a
            template. The automation keeps its own copy of the plan, so the
            import may since have been deleted.
          oneOf:
            - $ref: '#/components/schemas/Id'
            - type: 'null'
        source:
          type: string
          enum:
            - n8n
            - shopify_flow
          description: >-
            Where a `workflow` automation's workflow came from, `n8n` or
            `shopify_flow`, kept with the automation so it still answers once
            the import is deleted. Absent for a template.
        bindings:
          $ref: '#/components/schemas/StepBindings'
          description: >-
            A workflow automation's steps bound to your connections; empty for a
            template.
        plan_version:
          type: integer
          minimum: 1
          description: >-
            The `version` at which a workflow automation's steps or bindings
            last changed. A run queued on an earlier one is refused as
            `superseded`.
        readiness:
          $ref: '#/components/schemas/Readiness'
          description: >-
            A `workflow` automation's readiness to be turned on or run now, on
            the answers about one automation (get, set-up, change). Absent from
            lists, and for a template.
        version:
          type: integer
          minimum: 1
          description: >-
            Raised on every change. Update automation must carry the version you
            last read.
        template_id:
          $ref: '#/components/schemas/TemplateId'
        template_version:
          type: integer
          minimum: 1
        platform:
          description: >-
            What it runs on, by kind; null when its template runs on nothing,
            and it reads `connections` instead.
          oneOf:
            - $ref: '#/components/schemas/Platform'
            - type: 'null'
        integration_id:
          type:
            - integer
            - 'null'
          description: >-
            The id of the store or account it runs on; null when its template
            runs on nothing.
        store_label:
          type: string
          description: >-
            The name of what it runs on; for an automation that reads several
            connections, their names as they were when they were last set.
        connections:
          type: array
          description: >-
            The connections an automation of a template that runs on nothing
            reads,

            by id and kind, in the order they were set; empty for any other.
            Part of

            its version. Each one's name and state are on `GET /connections`. A

            run is refused, naming it, while one of them is not connected.
            Absent

            from an older service.
          items:
            $ref: '#/components/schemas/AutomationConnection'
        name:
          type: string
          maxLength: 120
        state:
          $ref: '#/components/schemas/AutomationState'
        paused_by:
          type:
            - string
            - 'null'
          enum:
            - merchant
            - system
            - null
        paused_reason:
          type:
            - string
            - 'null'
          description: Plain words, kept until resumed.
        inputs:
          type: object
          additionalProperties: true
        schedule:
          $ref: '#/components/schemas/Schedule'
        timezone:
          type: string
          description: The timezone its schedule runs in (IANA name).
        spread_minutes:
          type: integer
          minimum: 0
          maximum: 9
          description: >-
            The fixed offset added to every slot, so "08:00" means "at about
            08:00, starts within ten minutes".
        next_run_at:
          oneOf:
            - $ref: '#/components/schemas/Timestamp'
            - type: 'null'
        last_run_at:
          oneOf:
            - $ref: '#/components/schemas/Timestamp'
            - type: 'null'
        consecutive_failures:
          type: integer
          minimum: 0
        send_mode:
          type: string
          enum:
            - ask
            - send
          description: >-
            How a workflow automation sends: `ask` (the default) collects a
            run's sends and waits for approval in the Vortex IQ app; `send`
            sends at the step.
        send_mode_allowed:
          type: boolean
          description: >-
            Whether `send_mode: send` would be accepted now (see `send_mode`).
            On the answers about one `workflow` automation (get and change), as
            `readiness` is; absent on set-up, where nothing is approved yet,
            from lists, for a template, and from an older service.
        trigger:
          $ref: '#/components/schemas/AutomationTrigger'
          description: 'How it starts: on its schedule, or when its store sends an event.'
        created_at:
          $ref: '#/components/schemas/Timestamp'
        updated_at:
          $ref: '#/components/schemas/Timestamp'
        created_by:
          type:
            - integer
            - 'null'
          description: >-
            The id of the person who set it up: with this API, the person named
            at login. Null for one Vortex IQ made itself.
        created_via:
          description: >-
            How it was set up: `ui` in the Vortex IQ app, `api-token` through
            this API. Null for one Vortex IQ made itself.
          oneOf:
            - type: string
              enum:
                - ui
                - api-token
            - type: 'null'
        api_client_id:
          type:
            - string
            - 'null'
          description: >-
            The API credential's client id when `created_via` is `api-token`;
            null otherwise.
    ErrorResponse:
      type: object
      required:
        - success
        - message
        - contract_version
      properties:
        success:
          type: boolean
          const: false
        contract_version:
          $ref: '#/components/schemas/ContractVersion'
        message:
          type: string
          description: Plain words saying what happened and what to do.
        code:
          type: string
          description: >-
            A stable code to act on, such as `wrong_state`, `stale_version` or
            `allowance_spent`.
        errors:
          type: object
          description: Field name to messages, for 422.
          additionalProperties:
            type: array
            items:
              type: string
    Cadence:
      type: string
      description: >-
        How often an automation runs. `once` runs on one date and time and then
        has no next run.
      enum:
        - manual
        - once
        - hourly
        - every_6_hours
        - daily
        - weekdays
        - weekly
        - monthly
    Id:
      type: string
      description: A public id (a ULID).
      pattern: ^[0-9A-HJKMNP-TV-Z]{26}$
    StepBindings:
      type: object
      description: >-
        A workflow automation's steps bound to connections, by the n8n step's
        name (unique in a workflow).
      maxProperties: 500
      additionalProperties:
        $ref: '#/components/schemas/StepBinding'
    Readiness:
      type: object
      description: >-
        Whether your organisation can set the template up right now; for a
        workflow automation, whether it can be turned on or run now.
      required:
        - ready
        - missing
      properties:
        ready:
          type: boolean
        unconfigured:
          type: array
          description: >-
            A workflow automation's steps still without a connection they can
            use, in order. Absent for a template.
          items:
            $ref: '#/components/schemas/UnconfiguredStep'
        missing:
          type: array
          description: >-
            Connections not present, by kind, always a subset of the template's
            `connections`; never a key of Vortex IQ's own. Empty when ready.
          items:
            $ref: '#/components/schemas/ConnectionPlatform'
    Platform:
      type: string
      pattern: ^[a-z][a-z0-9_]{1,63}$
      description: >-
        What an automation runs on: a store's platform (`shopify`,
        `bigcommerce`), or an account a template runs on, such as a cloud
        account (`aws`).
      example: shopify
    AutomationConnection:
      type: object
      description: One connection an automation of a template that runs on nothing reads.
      required:
        - integration_id
        - kind
      additionalProperties: false
      properties:
        integration_id:
          type: integer
          minimum: 1
        kind:
          $ref: '#/components/schemas/ConnectionPlatform'
    AutomationState:
      type: string
      enum:
        - draft
        - active
        - paused
        - archived
    Timestamp:
      type: string
      format: date-time
      description: A time in UTC (ISO 8601).
    AutomationTrigger:
      description: >-
        How the automation starts: `schedule`, on its schedule; or `event`, when
        its store sends one of `topics`.
      oneOf:
        - type: object
          additionalProperties: false
          required:
            - kind
          properties:
            kind:
              type: string
              const: schedule
        - type: object
          additionalProperties: false
          required:
            - kind
            - topics
            - words
            - listening
            - reason
            - events_dropped
            - events_dropped_at
          properties:
            kind:
              type: string
              const: event
            topics:
              type: array
              minItems: 1
              maxItems: 8
              items:
                type: string
                minLength: 1
                maxLength: 80
            words:
              type: string
            listening:
              type: string
              enum:
                - 'yes'
                - not_yet
                - failed
                - 'off'
              description: >-
                `yes` when the store's subscription for every topic is in place;
                `not_yet` while it is being made; `failed` with `reason`; `off`
                while the automation is not active, whether or not another
                automation keeps the subscription.
            reason:
              type:
                - string
                - 'null'
              description: >-
                Why it is not listening, in plain words, when `listening` is
                `failed`; null otherwise.
            events_dropped:
              type: integer
              minimum: 0
              description: >-
                How many store events were not run: each is a run of this
                automation that never started, refused as `too_many_waiting`
                (200 of its runs were already waiting) or `event_too_large` (the
                event was over 256 KB).
            events_dropped_at:
              oneOf:
                - $ref: '#/components/schemas/Timestamp'
                - type: 'null'
    StepBinding:
      type: object
      additionalProperties: false
      required:
        - integration_id
        - kind
        - target
      properties:
        integration_id:
          type: integer
          minimum: 1
          description: >-
            The id of one of your organisation's connections (see List
            destinations).
        kind:
          type: string
          enum:
            - google_sheets
            - teams
          description: >-
            The kind of connection, never `store`: the store is the automation's
            own.
        target:
          description: >-
            For a Google sign-in Sheets connection, the spreadsheet (and tab)
            the step writes to, which it may reach; a service-account connection
            is one spreadsheet already. Null for the other kinds.
          oneOf:
            - $ref: '#/components/schemas/StepTarget'
            - type: 'null'
    UnconfiguredStep:
      type: object
      required:
        - step
        - kind
        - target
        - why
      properties:
        step:
          type: string
        kind:
          $ref: '#/components/schemas/StepNeedKind'
        target:
          oneOf:
            - $ref: '#/components/schemas/StepTarget'
            - type: 'null'
        why:
          type: string
          enum:
            - no_connection
            - wrong_target
            - needs_reconnecting
            - not_arrived
          description: >-
            `no_connection`: none bound, or the bound one is not yours or not of
            the step's kind. `wrong_target`: it leads to another spreadsheet.
            `needs_reconnecting`: the connection is disconnected; connect it
            again in the Vortex IQ app. `not_arrived` is reserved and not used
            yet.
    ConnectionPlatform:
      type: string
      pattern: ^[a-z][a-z0-9_]{1,63}$
      description: >-
        What a connection is for, by connector id: a store (`shopify`,
        `bigcommerce`), or an account a template reads beside its store
        (`google_ads`, `klaviyo`, ...).
      example: klaviyo
    StepTarget:
      type: object
      additionalProperties: false
      description: >-
        Where a step's connection must lead, as far as the plan can read it from
        the step. A field the step decides only while running is null or absent.
      properties:
        spreadsheet_id:
          type:
            - string
            - 'null'
          description: The spreadsheet a Google Sheets step writes to or reads.
        sheet:
          type:
            - string
            - 'null'
          description: The tab, by its name.
    StepNeedKind:
      type: string
      enum:
        - store
        - google_sheets
        - teams
      description: >-
        What a step needs to run: `store`, the automation's own store, always
        there; or a Google Sheets or Microsoft Teams connection you bind.
  responses:
    Unauthorised:
      description: >-
        The token is missing, has expired, or is no longer valid (for example,
        the API credential was rotated or disabled). The answer carries
        `WWW-Authenticate`; log in again for a new token.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Forbidden:
      description: >-
        Your token is valid but may not do this: it lacks the scope, the
        operation is not part of the Automations API, or Automations are
        switched off for your organisation.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    NotFound:
      description: >-
        Not found. Anything that belongs to another organisation is answered the
        same way.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    ValidationFailed:
      description: The request was not valid; `errors` names the fields.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    TooManyRequests:
      description: >-
        Too many calls in a minute from you or your organisation; nothing was
        done. `Retry-After` says how many seconds to wait.
      headers:
        Retry-After:
          schema:
            type: integer
            minimum: 1
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        A bearer token from [Login](/automations/api/login), sent as
        `Authorization: Bearer <token>`. Valid for 60 minutes; it acts as the
        person named at login, within their organisation, and never approves.
        Rotating or disabling the organisation's API credential ends every token
        made with it on its next call. See
        [Authentication](/automations/api/authentication).
    apiCredential:
      type: oauth2
      description: >-
        Your organisation's API credential, exchanged at
        [Login](/automations/api/login) for the bearer token above: an OAuth 2.0
        client-credentials request, with the `username`, `email` and
        `organization_name` of the person the token acts as sent as extra
        fields, as Postman's OAuth 2.0 helper can send them. The token never
        holds `automations:approve`.
      flows:
        clientCredentials:
          tokenUrl: https://app.vortexiq.ai/v2/api/automations/login
          scopes:
            automations:read: >-
              Read automations, templates, stores, runs, the calendar, approvals
              and imports.
            automations:write: >-
              Set automations up, change, pause, resume, archive, restore and
              run them; move and skip coming runs; keep and delete imports.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.