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

# Create an automation

`POST /automations`

## Request

- Base URL: `https://api.omnisocials.com/v1`
- URL: `https://api.omnisocials.com/v1/automations`
- Auth: HTTP bearer

Creates a comment-to-DM automation on the connected Instagram account (default) or on the connected Facebook Page (`platform: facebook`). When somebody comments a keyword on the post (or sends it in a DM, or in an Instagram story reply, see `trigger.kinds`), the account sends them `actions.dm.text` as a private message, once per person, and optionally posts one of `actions.public_reply.variations` under the comment. On Facebook the DM lands in Messenger. Meta's rules are the same on both: one private reply per comment, within 7 days of the comment; a follow-up is only possible after the person answers (24-hour window). OmniSocials caps sends at 180 DMs an hour per account and platform; an answer over the cap waits in a queue for up to an hour. On X (`platform: x`) only `trigger.kinds: ["dm"]` exists: the account answers a DM with the keyword (or any first message with `match: any`), once per person, after X DMs are turned on for the workspace in the dashboard; X allows 15 answers per 15 minutes per account, and each answer ends with "Reply STOP to stop automatic messages.". For `scope` `post`, pass one of `post_id` (an OmniSocials post that goes to the platform; a scheduled post starts listening once it is live), `instagram_media_id` (an Instagram post published outside OmniSocials) or `facebook_post_id` (a Page post published outside OmniSocials). Needs the opt-in `automations:write` scope and a connected Instagram account, Facebook Page or X account; an active X automation also needs X DMs on (else `409 x_dms_off`; `status: paused` always saves).

## Request body

- object: The fields of an automation. POST /automations requires `actions`; PATCH /automations/{id} takes any subset.
  - `name` string: A label for the automations list (max 120 characters).
  - `platform` 'instagram' | 'facebook' | 'x': The channel the automation runs on. Default `instagram`. `instagram_media_id` implies `instagram` and `facebook_post_id` implies `facebook`; a body that names another platform answers 400 `validation_error`. On PATCH it cannot change: another platform answers 400 `platform_immutable`. `x` answers DMs to the connected X account: only the `dm` kind (X allows an automated DM only after the person DMed you), the workspace needs X DMs turned on in the dashboard (else 409 `x_dms_off` for an active automation; `status: paused` saves it), every answer ends with the line "Reply STOP to stop automatic messages.", and a person who replies STOP gets no automatic DM from the account again. X does not give apps the messages of an encrypted X Chat conversation, so those get no answer.
  - `trigger` AutomationTrigger
    - `kinds` string[]: What starts the automation. `comment` = a comment on an Instagram post or reel, or on a Facebook Page post (needs `scope`). `dm` = a keyword in a DM to the Instagram account, in a Messenger message to the Facebook Page, or in a DM to the X account. `story_reply` = a keyword in a reply to an Instagram story (Instagram only: Facebook has no story replies, and a Facebook automation with `story_reply` answers 400 `validation_error`). On X only `dm` exists. One automation can listen to several. Default `["comment"]` (pass `["dm"]` on X).
    - `scope` 'post' | 'next_post' | 'any': For the `comment` kind: `post` = one post (pass `post_id`, `instagram_media_id` or `facebook_post_id` on the request), `next_post` = the next post the workspace publishes on the automation's platform, `any` = every post of the account or Page. Default `post`.
    - `keywords` string[]: Up to 20 keywords (60 characters each), matched case-insensitively. Required unless `match` is `any`.
    - `match` 'word' | 'contains' | 'any': `word` (default) = the keyword stands on its own ("guide", "Guide!" match; "linkedin" does not match "link"), `contains` = the keyword appears anywhere, `any` = every comment or message with text.
  - `post_id` string: For `scope` `post`: an OmniSocials post (scheduled or live) that goes to the automation's platform. A post that does not go there answers 400 `post_not_instagram` or `post_not_facebook`. One automation per post and platform: a post that goes to Instagram and Facebook can have one of each.
  - `instagram_media_id` string: For `scope` `post` on Instagram: the numeric id of a post or reel that was published outside OmniSocials (from the Instagram API, `GET /me/media`). The post is read from Instagram to check it belongs to the connected account.
  - `facebook_post_id` string: For `scope` `post` on Facebook: the id of a post that was published on the connected Facebook Page outside OmniSocials. Pass `{page-id}_{post-id}` or the post id alone (the Page id is put in front). The post is read from Facebook with the Page token; a post of another Page answers 404 `facebook_post_not_found`. Implies `platform: facebook`. Pass one of `post_id`, `instagram_media_id` or `facebook_post_id`.
  - `actions` AutomationActions, required
    - `dm` object, required
      - `text` string, required: The DM sent to the person (max 1000 characters). Sent once per person per automation. On Facebook it lands in Messenger.
    - `public_reply` object: A public reply under the comment, only for the `comment` kind. One of `variations` is picked at random per comment.
      - `enabled` boolean
      - `variations` string[]: Up to 10 replies of 300 characters.
  - `limits` AutomationLimits
    - `max_sends` integer, nullable: Stop after this many DMs (the automation becomes `completed`). Omit for no limit.
    - `stop_at` string, date-time, nullable: Stop at this time. Omit for no end.
  - `status` 'active' | 'paused': `paused` creates the automation without turning it on. Default `active`.

## Response `201`

Automation created

- object
  - `data` Automation
    - `id` string
    - `type` 'comment_to_dm'
    - `platform` 'instagram' | 'facebook' | 'x': The channel the automation runs on: the connected Instagram account, the connected Facebook Page, or the connected X account. Set at create; it never changes.
    - `status` 'active' | 'paused' | 'completed': `completed` = `max_sends` or `stop_at` was reached. A new limit or trigger starts it again.
    - `name` string, nullable
    - `post_id` string, nullable: The OmniSocials post the automation listens on, for the `post` scope. `null` for a post published outside OmniSocials and for the other scopes.
    - `instagram_media_id` string, nullable: The Instagram media id the automation listens on. Set once the post is live on Instagram. Always `null` for a Facebook automation.
    - `facebook_post_id` string, nullable: The Facebook Page post id (`{page-id}_{post-id}`) the automation listens on. Set once the post is live on the Page. Always `null` for an Instagram automation.
    - `post` object, nullable: A snapshot of the post: `source` (`omnisocials`, `instagram` or `facebook`: a post picked by id is read from that platform), `id`, `caption`, `thumbnail_url`, `permalink`, `media_type` and, for an OmniSocials post, `status` and `live`.
    - `trigger` AutomationTrigger
      - `kinds` string[]: What starts the automation. `comment` = a comment on an Instagram post or reel, or on a Facebook Page post (needs `scope`). `dm` = a keyword in a DM to the Instagram account, in a Messenger message to the Facebook Page, or in a DM to the X account. `story_reply` = a keyword in a reply to an Instagram story (Instagram only: Facebook has no story replies, and a Facebook automation with `story_reply` answers 400 `validation_error`). On X only `dm` exists. One automation can listen to several. Default `["comment"]` (pass `["dm"]` on X).
      - `scope` 'post' | 'next_post' | 'any': For the `comment` kind: `post` = one post (pass `post_id`, `instagram_media_id` or `facebook_post_id` on the request), `next_post` = the next post the workspace publishes on the automation's platform, `any` = every post of the account or Page. Default `post`.
      - `keywords` string[]: Up to 20 keywords (60 characters each), matched case-insensitively. Required unless `match` is `any`.
      - `match` 'word' | 'contains' | 'any': `word` (default) = the keyword stands on its own ("guide", "Guide!" match; "linkedin" does not match "link"), `contains` = the keyword appears anywhere, `any` = every comment or message with text.
    - `actions` AutomationActions
      - `dm` object, required
        - `text` string, required: The DM sent to the person (max 1000 characters). Sent once per person per automation. On Facebook it lands in Messenger.
      - `public_reply` object: A public reply under the comment, only for the `comment` kind. One of `variations` is picked at random per comment.
        - `enabled` boolean
        - `variations` string[]: Up to 10 replies of 300 characters.
    - `limits` AutomationLimits
      - `max_sends` integer, nullable: Stop after this many DMs (the automation becomes `completed`). Omit for no limit.
      - `stop_at` string, date-time, nullable: Stop at this time. Omit for no end.
    - `stats` AutomationStats
      - `matched` integer
      - `sent` integer
      - `skipped` integer
      - `failed` integer
      - `last_event_at` string, date-time, nullable
    - `created_at` string, date-time
    - `updated_at` string, date-time

## Other responses

- `400`: Invalid input (`validation_error`: also `story_reply` on Facebook, `comment` or `story_reply` on X, or two of `post_id` / `instagram_media_id` / `facebook_post_id`), or the post does not go to the platform (`post_not_instagram`, `post_not_facebook`), or no post was given for the `post` scope (`post_required`)
- `404`: `post_not_found`, `instagram_media_not_found` (Instagram has no such post on this account), or `facebook_post_not_found` (the id is not a post of the connected Page)
- `409`: `instagram_not_connected`, `instagram_needs_reauth`, `facebook_not_connected` (no Facebook Page connected), `facebook_needs_reauth` (the Page connection must be reconnected), `x_not_connected` (no X account connected), `x_dms_off` (X DMs are off for the workspace; turn them on in the dashboard, or create the automation with `status: paused`), or `automation_exists` (the post already has one on this platform; the response carries its `automation_id`)

## Changes

- **2026-10-25** `4e6e28d10892`: 1 warning, 1 info
  - added the new `x` enum value to the `data/platform` response property for the response status `201`
  - added the new `x` enum value to the request property `allOf[#/components/schemas/AutomationInput]/platform`
- **2026-10-22** `1e06adee390e`: 1 warning, 3 info
  - added the new `facebook` enum value to the `data/platform` response property for the response status `201`
  - added the new optional request property `allOf[#/components/schemas/AutomationInput]/facebook_post_id`
  - added the new optional request property `allOf[#/components/schemas/AutomationInput]/platform`
  - added the optional property `data/facebook_post_id` to the response with the `201` status
- **2026-10-21** `3aff2f2e3458`: 2 breaking, 7 warning
  - added `#/components/schemas/AutomationInput, subschema #2` to the request body `allOf` list
  - the request's body type changed from `object` to no type
  - removed the request property `actions`
  - removed the request property `instagram_media_id`
  - …5 more
- **2026-10-11** `b64e4a7a8c4b`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/omnisocials/apis/omnisocials-api/changes/automations/post.md)

---

[API](https://skmtc.dev/omnisocials/apis/omnisocials-api.md) - [All operations](https://skmtc.dev/omnisocials/apis/omnisocials-api/llms.txt) - [OpenAPI document](https://skmtc.dev/omnisocials/apis/omnisocials-api/revisions/46e479c09474?raw)
