---
title: "Create an automation"
method: POST
path: "/api/board/{boardId}/configuration/automations"
tags: ["Board"]
---

# Create an automation

`POST /api/board/{boardId}/configuration/automations`

## Request

- Base URL: `https://core-api.getaptly.com`
- URL: `https://core-api.getaptly.com/api/board/{boardId}/configuration/automations`
- Auth: one of:
  - API key in header `x-token`
  - HTTP bearer
- TypeScript: <https://skmtc.dev/getaptly/apis/aptly-api/docs/api/board/:boardId/configuration/automations/post.ts> (a function with typed inputs; its response is checked against the schema)

Creates an Automation on the board (the board's `workflows`). Requires `update` permission and
the key's "Automations" access (a separate toggle on the key, off by default, independent of
"Edit Boards"); a key's board allowlist applies.

**Always created paused.** Nothing runs until the automation is switched on in the Aptly app,
so the API can't set one live. Existing cards are not enrolled: once it is switched on a stage
automation applies to cards that enter the stage afterwards.

**Validated strictly - the request is refused outright on the first problem.** Unknown
properties, a stage / field / template / inbox / contact type / user / team that doesn't exist
(or is archived) on this board or organization, an email template used for an SMS (or the
reverse), an inbox of the wrong type or with no users, conditions that are empty, on a missing
field, with an unsupported operator or a bad value, a delay with business hours, or a task or
due-date action with business days, when none are configured, a webhook to anything but a public https address, and a pair of stage-moving
automations that would send cards round in a circle are all rejected with `400`. Shape problems
come back as `VALIDATION_ERROR` with the offending path in `meta.issues`; problems found by
checking against your data come back as `INVALID_DATA` with a message that names the path
(for example `actions[1].templateId: template "abc" was not found`).

Supported triggers: `stage`, `segment` (conditions), `reply`. Supported actions: `email`, `sms`,
`task`, `assign`, `update_fields`, `stage`, `due_date`, `notify`, `archive`, `archive_convos`,
`webhook`. Task-completion and field-group triggers and the Yardi, e-sign, PDF, team-access and
related-card actions aren't available through the API.

The response is the stored automation (the same shape `GET .../automations` returns).

## Path parameters

- `boardId` string, required

## Request body

- CreateAutomationRequest
  - `title` string, required
  - `trigger` union, required: What starts the automation. Exactly one `type`.
    - AutomationStageTrigger
      - `type` 'stage', required
      - `stage` string, required: A stage of the board, spelled exactly as it is on the board (case and spacing included). A stage trigger fires at most once per card.
    - AutomationSegmentTrigger
      - `type` 'segment', required
      - `conditions` object[], required: Rules a card must meet, ANDed together - the same rule format as board segments (`fieldUuid`, `operator`, `value`, ...; see `GET /api/board/{boardId}/segments`). At least one rule is required, because an automation with no conditions would run on every card. A rule on an unknown field, an operator the field doesn't support, a missing or malformed value, a stage or option that isn't on the board, or a user who isn't in the company is rejected, as are rules on `archived`/`deleted` and `valueSource: currentUser` (an automation runs without a signed-in user). The rules are saved as a segment named `Automation - <title>`.
      - `frequency` 'everyTime' | 'once': `once` fires the first time a card matches; `everyTime` fires again each time it stops and starts matching.
    - AutomationReplyTrigger
      - `type` 'reply', required
      - `stages` string[]: Only fire for cards in these stages. Empty means any stage.
      - `frequency` 'everyTime' | 'once'
      - `audience` 'anyone' | 'relatedContacts': `relatedContacts` requires the sender to be a contact related to the card.
      - `reopenArchived` boolean: Reopen an archived card when a reply arrives.
  - `timing` union: When the actions run after the trigger. Defaults to `{ "mode": "now" }`. A trigger with `frequency: once` can only use `now` or `after`. Times of day are hours (0-23) in the organization's time zone, and the automation fires within four hours after that time.
    - object
      - `mode` 'now', required
      - `useBusinessHours` boolean: Only fire while the board or organization is open. Rejected when no business hours are configured, because it would never run.
    - object
      - `mode` 'after', required
      - `amount` integer, required
      - `unit` 'minutes' | 'hours' | 'days' | 'months', required
      - `anchor` string: What the delay counts from - `stageUpdatedAt`, `conditionMet`, `createdAt`, or the uuid of a date field on the board.
      - `timeOfDay` integer: Only for `days` or `months`.
      - `useBusinessHours` boolean: Only for `minutes` or `hours`.
    - object
      - `mode` 'dayOfWeek', required
      - `day` 'sunday' | 'monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday', required
      - `timeOfDay` integer, required
    - object
      - `mode` 'daysOfWeek', required
      - `days` integer[], required: 0 = Sunday ... 6 = Saturday. No repeats.
      - `timeOfDay` integer, required
    - object
      - `mode` 'dayOfMonth', required
      - `day` integer, required: 31 means the last day of the month.
      - `timeOfDay` integer, required
    - object
      - `mode` 'dateRange', required
      - `startDay` integer, required
      - `endDay` integer, required: Must be after startDay.
      - `timeOfDay` integer, required
    - object
      - `mode` 'everyXDays', required
      - `interval` integer, required
      - `startImmediately` boolean
      - `timeOfDay` integer
  - `actions` AutomationAction[], required
    - union: One thing the automation does. Actions run in order. At most one `stage`, one `due_date` and one archive action per automation. Every id, stage and field named here must exist on the board / organization or the whole request is rejected.
      - object: Send an email.
        - `type` 'email', required
        - `inbox` string, required: The sending inbox id, or "assignee" for the card assignee's inbox. Must be an active email inbox with users.
        - `templateId` string, required: An active email template of the organization.
        - `to` union, required: Who an email or SMS goes to.
          - object
            - `type` 'assignee', required
          - object
            - `type` 'relatedContacts', required
          - object
            - `type` 'contactTypes', required
            - `contactTypeIds` string[], required: Contact type ids of the organization. Related contacts of these types receive the message.
          - object
            - `type` 'specific', required
            - `addresses` string[], required: Email addresses for an email, E.164 phone numbers (+15551234567) for an SMS. No repeats.
          - object
            - `type` 'field', required
            - `fieldUuid` string, required: An email, user or contact field of the board (an SMS needs a user or contact field).
        - `cc` string[]
        - `deliveryMode` 'multiple' | 'single': `single` sends one email to all recipients; `multiple` sends each their own.
        - `fallback` object: Send an SMS instead to recipients with no email address. Needs an active phone inbox and an SMS template.
          - `inbox` string, required
          - `templateId` string, required
      - object: Send a text message.
        - `type` 'sms', required
        - `inbox` string, required: The sending phone inbox id, or "assignee".
        - `templateId` string, required: An active SMS template of the organization.
        - `to` union, required: Who an email or SMS goes to.
          - object
            - `type` 'assignee', required
          - object
            - `type` 'relatedContacts', required
          - object
            - `type` 'contactTypes', required
            - `contactTypeIds` string[], required: Contact type ids of the organization. Related contacts of these types receive the message.
          - object
            - `type` 'specific', required
            - `addresses` string[], required: Email addresses for an email, E.164 phone numbers (+15551234567) for an SMS. No repeats.
          - object
            - `type` 'field', required
            - `fieldUuid` string, required: An email, user or contact field of the board (an SMS needs a user or contact field).
        - `fallback` object: Send an email instead to recipients with no phone number.
          - `inbox` string, required
          - `templateId` string, required
      - object: Create tasks on the card, from a task template or defined inline.
        - `type` 'task', required
        - `source` 'template' | 'manual', required
        - `templateId` string: Required for `template`. A task template of this board.
        - `tasks` object[]: Required for `manual`.
          - `title` string, required
          - `description` string
          - `userId` string: An active user of the organization. Defaults to the card assignee.
          - `dueInDays` integer
          - `dueFrom` string: "now" (default) or a date field uuid. Needs dueInDays.
        - `fieldUuid` string: A task list (checkboxlist) field to put the tasks on. Defaults to the card's checklist.
        - `useBusinessDays` boolean: Count the tasks' due dates in business days. Rejected when no business hours are configured, because the due dates would fall on calendar days instead.
      - object: Assign the card.
        - `type` 'assign', required
        - `mode` 'user' | 'team' | 'roundRobin' | 'contactField', required
        - `userId` string: Required for `user`.
        - `teamId` string: Required for `team`. An active team.
        - `contactFieldUuid` string: Required for `contactField`. A contact or user field of the board.
        - `onlyIfUnassigned` boolean
      - object: Set field values. Supported field types and the value each takes: `string`/`text` (text), `email`, `url` (http/https), `tel` (E.164), `number`, `percent` (a fraction, 0.25 = 25%), `money` (`{ amount: whole cents, currency?: "USD" }`), `boolean`, `singleselect` (an option), `multiselect` (array of options), `tags` (added to the existing tags), `user` (a user id), and `date`/`datetime-local` (`{ from: "now" | <date field uuid>, days: integer }` or `{ clear: true }`). Read-only and computed fields, and every other field type, are rejected.
        - `type` 'update_fields', required
        - `fields` object[], required: Each field at most once.
          - `fieldUuid` string, required
          - `value` unknown, required
      - object: Move the card to a stage of the board. Can't be the stage that triggered a stage automation.
        - `type` 'stage', required
        - `stage` string, required
      - object: Set or clear the card's due date.
        - `type` 'due_date', required
        - `from` string: "now", "clear", or a date field uuid.
        - `days` integer: Required unless `from` is "clear".
        - `useBusinessDays` boolean: Count `days` in business days. Not valid when `from` is "clear". Rejected when no business hours are configured, because the due date would fall on calendar days instead.
      - object: Post a notification comment on the card. At least one of userIds, teamIds, fieldUuids or notifyCardCreator is required.
        - `type` 'notify', required
        - `userIds` string[]
        - `teamIds` string[]
        - `fieldUuids` string[]: User fields of the board.
        - `notifyCardCreator` boolean
        - `message` string: Plain text (no < or >).
      - object: Archive the card.
        - `type` 'archive', required
      - object: Archive the card and its conversations.
        - `type` 'archive_convos', required
      - object: POST the card to a URL. The URL must be a public https address - localhost, private/internal addresses, credentials and non-default ports are rejected.
        - `type` 'webhook', required
        - `url` string, required

## Response `201`

The created automation (paused).

- object
  - `data` object: The stored automation. `archived: true` means paused.
    - `uuid` string
    - `title` string
    - `archived` boolean
    - `triggerOn` string
    - `timingMode` string
    - `description` string
    - `actions` object[]

## Other responses

- `400`: `VALIDATION_ERROR` (shape) or `INVALID_DATA` (a reference or rule that doesn't hold).
- `401`: Invalid or missing API key.
- `403`: The key lacks `update` permission or the "Automations" access, or the board isn't API-enabled.
- `404`: Board not found.

---

[API](https://skmtc.dev/getaptly/apis/aptly-api.md) - [All operations](https://skmtc.dev/getaptly/apis/aptly-api/llms.txt) - [OpenAPI document](https://skmtc.dev/getaptly/apis/aptly-api/revisions/75c367e0b8e5?raw)
