---
title: "Create Automation"
method: POST
path: "/automations"
tags: ["Automations"]
---

# Create Automation

`POST /automations`

Create a new automation

## Request body

- AutomationInput
  - `name` string, required — The name of the automation.
  - `trigger` 'advertising_slot.inquiry' | 'advertising_slot.purchased' | 'automation.invoked' | 'date.day.started' | 'date.month.started' | 'date.week.started' | 'date.year.started' | 'bigcommerce.customer.created' | 'bigcommerce.customer.updated' | 'bigcommerce.order.created' | 'bigcommerce.order.updated' | 'email.created' | 'email.deleted' | 'email.sent' | 'email.status.changed' | 'email.updated' | 'external_feed_item.created' | 'export.completed' | 'export.created' | 'export.failed' | 'firewall.blocked' | 'mention.created' | 'memberful.member.updated' | 'memberful.subscription.created' | 'memberful.subscription.deleted' | 'note.created' | 'note.deleted' | 'patreon.member.updated' | 'patreon.membership.created' | 'patreon.membership.deleted' | 'shopify.customer.created' | 'shopify.customer.updated' | 'social_mention.created' | 'stripe.checkout.session.completed' | 'stripe.customer.updated' | 'stripe.invoice.upcoming' | 'stripe.subscription.activated' | 'stripe.subscription.churning' | 'stripe.subscription.deactivated' | 'subscriber.activation_bounced' | 'subscriber.activation_clicked' | 'subscriber.activation_complained' | 'subscriber.activation_deferred' | 'subscriber.activation_delivered' | 'subscriber.activation_opened' | 'subscriber.activation_rejected' | 'subscriber.bounced' | 'subscriber.changed_email' | 'subscriber.churned' | 'subscriber.clicked' | 'subscriber.commented' | 'subscriber.complained' | 'subscriber.confirmed' | 'subscriber.created' | 'subscriber.deferred' | 'subscriber.deleted' | 'subscriber.delivered' | 'subscriber.opened' | 'subscriber.paid' | 'subscriber.paused' | 'subscriber.resumed' | 'subscriber.referred' | 'subscriber.referred.paid' | 'subscriber.rejected' | 'subscriber.replied' | 'subscriber.sent' | 'subscriber.responded_to_survey' | 'subscriber.tags.changed' | 'subscriber.trial_ended' | 'subscriber.trial_started' | 'subscriber.type.changed' | 'subscriber.unsubscribed' | 'subscriber.updated' | 'subscriber.viewed_checkout_page' | 'survey.cleared_responses' | 'survey.created' | 'survey.deleted' | 'survey.updated' | 'form.created' | 'form.deleted' | 'form.updated', required — Various types of events that are recorded by Buttondown, both in terms of exogenous systems like Stripe and Memberful, and endogenous ones like email opens and clicks. (In general, if anything important ever happens that could be relevant to your newsletter, we have an event type for it!) These event types power lots of things within Buttondown. They're used to trigger automations, webhooks, and analytics. (Note that the `/v1/events` API speaks an older, shorter vocabulary for subscriber engagement — `clicked` rather than `subscriber.clicked` — a relic of a previous events system. Each of those names maps onto one of the `subscriber.*` types below.) In general, our event namespacing tries to hew to the following pattern: `<source>.<object>.<action>` When wondering which object we are referring to, default to the _more granular_ object. For instance, an email being sent to a subscriber is `subscriber.delivered`, not `email.sent`.
  - `actions` ActionInput[], required — The actions to perform when the trigger fires.
    - `type` 'add_tags' | 'remove_tags' | 'send_email' | 'add_metadata' | 'remove_metadata' | 'change_email_address' | 'gift_premium_subscription' | 'ungift_premium_subscription' | 'send_discord_invitation' | 'send_github_invitation' | 'create_subscriber' | 'unsubscribe_subscriber' | 'shopify_unsubscribe' | 'shopify_resubscribe' | 'shopify_set_tags' | 'shopify_create_customer' | 'send_notification' | 'forward_reply' | 'create_arena_post' | 'create_bluesky_post' | 'create_linkedin_post' | 'create_mastodon_post' | 'create_tumblr_post' | 'create_twitter_post' | 'create_export' | 'create_gift_subscriber' | 'send_post_request' | 'send_confirmation_reminder' | 'update_email_type', required — The action that is triggered when the automation is successfully run.
    - `metadata` object — Configuration specific to the action type.
    - `timing` TimingInput — Request payload controls for when an automation action executes.
      - `time` 'immediate' | 'delay', required — Whether the action should execute immediately or after a delay.
      - `delay` DelayInput — Request payload configuration for delaying an automation action.
        - `value` string, required — The number of time units to delay.
        - `unit` 'minutes' | 'hours' | 'days' | 'weeks', required — The unit of time for the delay.
        - `time_of_day` 'morning' | 'evening' | '', nullable — If set, the action will be executed at this time of day after the delay has passed.
  - `filters` FilterGroup — Buttondown's filtering schema can be used for multiple things: - Filtering [the audience of an email](/api-emails-create) to a specific subset - Creating [finely-tuned automations](/api-automation-introduction) Filters are fractal; they can be nested in groups, and groups can be nested in other groups. This is accomplished through a tree-like structure. Every "FilterGroup" has a "predicate" field, which is either "and" or "or", which determines how the filters and groups within the group are combined, a "groups" field, which is a list of "FilterGroup" objects (that's that recursive bit!), and a "filters" field, which are the leaf-level filters themselves. Let's say you want a simple filter: all subscribers who have a tag whose ID is `sub_tag_0j6hb7h40j6hb7h40j6hb7h40j`. You can do that like this: ```json { "filters": [{"field": "subscriber.tags", "operator": "contains", "value": "sub_tag_0j6hb7h40j6hb7h40j6hb7h40j"}], "groups": [], "predicate": "and" } ``` Now, let's say you want to filter for subscribers who have that tag and a tag whose ID is `sub_tag_0j6hb7h40j6hb7h40j6hb7h40k`. You can do that like this: ```json { "filters": [{"field": "subscriber.tags", "operator": "contains", "value": "sub_tag_0j6hb7h40j6hb7h40j6hb7h40j"}, {"field": "subscriber.tags", "operator": "contains", "value": "sub_tag_0j6hb7h40j6hb7h40j6hb7h40k"}], "groups": [], "predicate": "and" } ``` If you wanted to change that `and` to an `or`, you can do that like this: ```json { "filters": [{"field": "subscriber.tags", "operator": "contains", "value": "sub_tag_0j6hb7h40j6hb7h40j6hb7h40j"}, {"field": "subscriber.tags", "operator": "contains", "value": "sub_tag_0j6hb7h40j6hb7h40j6hb7h40k"}], "groups": [], "predicate": "or" } ``` Now, let's say you want to filter for subscribers who have the first tag _or_ both the second tag and a third tag whose ID is `sub_tag_0j6hb7h40j6hb7h40j6hb7h40m`. This is where the whole nested thing comes in handy. You can do that like this: ```json { "filters": [{"field": "subscriber.tags", "operator": "contains", "value": "sub_tag_0j6hb7h40j6hb7h40j6hb7h40j"}], "groups": [ { "filters": [{"field": "subscriber.tags", "operator": "contains", "value": "sub_tag_0j6hb7h40j6hb7h40j6hb7h40k"}, {"field": "subscriber.tags", "operator": "contains", "value": "sub_tag_0j6hb7h40j6hb7h40j6hb7h40m"}], "groups": [], "predicate": "and" } ], "predicate": "or" } ``` You can read more about the specific filter construction in the [Filter documentation](/api-emails-filter).
    - `filters` Filter[], required — The leaf-level filters to apply to the audience.
      - `field` string, required
      - `operator` 'equals' | 'not_equals' | 'contains' | 'not_contains' | 'is_empty' | 'is_not_empty' | 'greater_than' | 'less_than', required — An enumeration.
      - `value` string, required
    - `groups` FilterGroup[], required — The nested groups to apply to the audience.
    - `predicate` 'and' | 'or', required — The logical operator to use when combining filters (either 'and' or 'or').
  - `metadata` object — Additional metadata for the automation.
  - `should_evaluate_filter_after_delay` boolean — If true, filters are re-evaluated after the delay has passed.

## Response `201`

Created

- Automation — A rule that automatically performs actions in response to events.
  - `id` string, required — A unique TypeID associated with the object.
  - `creation_date` string, date-time, required — The date and time at which the object was first created.
  - `name` string, required — The name of the automation.
  - `status` 'active' | 'inactive', required — An enumeration.
  - `trigger` 'advertising_slot.inquiry' | 'advertising_slot.purchased' | 'automation.invoked' | 'date.day.started' | 'date.month.started' | 'date.week.started' | 'date.year.started' | 'bigcommerce.customer.created' | 'bigcommerce.customer.updated' | 'bigcommerce.order.created' | 'bigcommerce.order.updated' | 'email.created' | 'email.deleted' | 'email.sent' | 'email.status.changed' | 'email.updated' | 'external_feed_item.created' | 'export.completed' | 'export.created' | 'export.failed' | 'firewall.blocked' | 'mention.created' | 'memberful.member.updated' | 'memberful.subscription.created' | 'memberful.subscription.deleted' | 'note.created' | 'note.deleted' | 'patreon.member.updated' | 'patreon.membership.created' | 'patreon.membership.deleted' | 'shopify.customer.created' | 'shopify.customer.updated' | 'social_mention.created' | 'stripe.checkout.session.completed' | 'stripe.customer.updated' | 'stripe.invoice.upcoming' | 'stripe.subscription.activated' | 'stripe.subscription.churning' | 'stripe.subscription.deactivated' | 'subscriber.activation_bounced' | 'subscriber.activation_clicked' | 'subscriber.activation_complained' | 'subscriber.activation_deferred' | 'subscriber.activation_delivered' | 'subscriber.activation_opened' | 'subscriber.activation_rejected' | 'subscriber.bounced' | 'subscriber.changed_email' | 'subscriber.churned' | 'subscriber.clicked' | 'subscriber.commented' | 'subscriber.complained' | 'subscriber.confirmed' | 'subscriber.created' | 'subscriber.deferred' | 'subscriber.deleted' | 'subscriber.delivered' | 'subscriber.opened' | 'subscriber.paid' | 'subscriber.paused' | 'subscriber.resumed' | 'subscriber.referred' | 'subscriber.referred.paid' | 'subscriber.rejected' | 'subscriber.replied' | 'subscriber.sent' | 'subscriber.responded_to_survey' | 'subscriber.tags.changed' | 'subscriber.trial_ended' | 'subscriber.trial_started' | 'subscriber.type.changed' | 'subscriber.unsubscribed' | 'subscriber.updated' | 'subscriber.viewed_checkout_page' | 'survey.cleared_responses' | 'survey.created' | 'survey.deleted' | 'survey.updated' | 'form.created' | 'form.deleted' | 'form.updated', required — Various types of events that are recorded by Buttondown, both in terms of exogenous systems like Stripe and Memberful, and endogenous ones like email opens and clicks. (In general, if anything important ever happens that could be relevant to your newsletter, we have an event type for it!) These event types power lots of things within Buttondown. They're used to trigger automations, webhooks, and analytics. (Note that the `/v1/events` API speaks an older, shorter vocabulary for subscriber engagement — `clicked` rather than `subscriber.clicked` — a relic of a previous events system. Each of those names maps onto one of the `subscriber.*` types below.) In general, our event namespacing tries to hew to the following pattern: `<source>.<object>.<action>` When wondering which object we are referring to, default to the _more granular_ object. For instance, an email being sent to a subscriber is `subscriber.delivered`, not `email.sent`.
  - `actions` Action[], required — The actions to perform when the trigger fires.
    - `type` 'add_tags' | 'remove_tags' | 'send_email' | 'add_metadata' | 'remove_metadata' | 'change_email_address' | 'gift_premium_subscription' | 'ungift_premium_subscription' | 'send_discord_invitation' | 'send_github_invitation' | 'create_subscriber' | 'unsubscribe_subscriber' | 'shopify_unsubscribe' | 'shopify_resubscribe' | 'shopify_set_tags' | 'shopify_create_customer' | 'send_notification' | 'forward_reply' | 'create_arena_post' | 'create_bluesky_post' | 'create_linkedin_post' | 'create_mastodon_post' | 'create_tumblr_post' | 'create_twitter_post' | 'create_export' | 'create_gift_subscriber' | 'send_post_request' | 'send_confirmation_reminder' | 'update_email_type', required — The action that is triggered when the automation is successfully run.
    - `metadata` object, required — Configuration specific to the action type.
    - `timing` Timing — Controls when an automation's action executes after the trigger fires.
      - `time` 'immediate' | 'delay', required — Whether the action should execute immediately or after a delay.
      - `delay` Delay — Configuration for how long to wait before executing the automation's action.
        - `value` string, required — The number of time units to delay.
        - `unit` 'minutes' | 'hours' | 'days' | 'weeks', required — The unit of time for the delay.
        - `time_of_day` 'morning' | 'evening' | '', nullable — If set, the action will be executed at this time of day after the delay has passed.
  - `filters` FilterGroup, required — Buttondown's filtering schema can be used for multiple things: - Filtering [the audience of an email](/api-emails-create) to a specific subset - Creating [finely-tuned automations](/api-automation-introduction) Filters are fractal; they can be nested in groups, and groups can be nested in other groups. This is accomplished through a tree-like structure. Every "FilterGroup" has a "predicate" field, which is either "and" or "or", which determines how the filters and groups within the group are combined, a "groups" field, which is a list of "FilterGroup" objects (that's that recursive bit!), and a "filters" field, which are the leaf-level filters themselves. Let's say you want a simple filter: all subscribers who have a tag whose ID is `sub_tag_0j6hb7h40j6hb7h40j6hb7h40j`. You can do that like this: ```json { "filters": [{"field": "subscriber.tags", "operator": "contains", "value": "sub_tag_0j6hb7h40j6hb7h40j6hb7h40j"}], "groups": [], "predicate": "and" } ``` Now, let's say you want to filter for subscribers who have that tag and a tag whose ID is `sub_tag_0j6hb7h40j6hb7h40j6hb7h40k`. You can do that like this: ```json { "filters": [{"field": "subscriber.tags", "operator": "contains", "value": "sub_tag_0j6hb7h40j6hb7h40j6hb7h40j"}, {"field": "subscriber.tags", "operator": "contains", "value": "sub_tag_0j6hb7h40j6hb7h40j6hb7h40k"}], "groups": [], "predicate": "and" } ``` If you wanted to change that `and` to an `or`, you can do that like this: ```json { "filters": [{"field": "subscriber.tags", "operator": "contains", "value": "sub_tag_0j6hb7h40j6hb7h40j6hb7h40j"}, {"field": "subscriber.tags", "operator": "contains", "value": "sub_tag_0j6hb7h40j6hb7h40j6hb7h40k"}], "groups": [], "predicate": "or" } ``` Now, let's say you want to filter for subscribers who have the first tag _or_ both the second tag and a third tag whose ID is `sub_tag_0j6hb7h40j6hb7h40j6hb7h40m`. This is where the whole nested thing comes in handy. You can do that like this: ```json { "filters": [{"field": "subscriber.tags", "operator": "contains", "value": "sub_tag_0j6hb7h40j6hb7h40j6hb7h40j"}], "groups": [ { "filters": [{"field": "subscriber.tags", "operator": "contains", "value": "sub_tag_0j6hb7h40j6hb7h40j6hb7h40k"}, {"field": "subscriber.tags", "operator": "contains", "value": "sub_tag_0j6hb7h40j6hb7h40j6hb7h40m"}], "groups": [], "predicate": "and" } ], "predicate": "or" } ``` You can read more about the specific filter construction in the [Filter documentation](/api-emails-filter).
    - `filters` Filter[], required — The leaf-level filters to apply to the audience.
      - `field` string, required
      - `operator` 'equals' | 'not_equals' | 'contains' | 'not_contains' | 'is_empty' | 'is_not_empty' | 'greater_than' | 'less_than', required — An enumeration.
      - `value` string, required
    - `groups` FilterGroup[], required — The nested groups to apply to the audience.
    - `predicate` 'and' | 'or', required — The logical operator to use when combining filters (either 'and' or 'or').
  - `metadata` object, required — Additional metadata for the automation.
  - `should_evaluate_filter_after_delay` boolean, required — If true, filters are re-evaluated after the delay has passed.

## Other responses

- `400` — Bad Request
- `401` — Unauthorized
- `403` — Forbidden
- `409` — Conflict
- `422` — Unprocessable Entity
- `429` — Too Many Requests

---

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