---
title: "Create an Auto Messages campaign"
method: POST
path: "/api/v0/accounts/{account_id}/auto-message-campaigns"
tags: ["auto-message-campaigns"]
---

# Create an Auto Messages campaign

`POST /api/v0/accounts/{account_id}/auto-message-campaigns`

## Request

- Base URL: `https://omapi.onlymonster.ai`
- URL: `https://omapi.onlymonster.ai/api/v0/accounts/{account_id}/auto-message-campaigns`
- Auth: API key in header `x-om-auth-token`

**Rate limit:** 5 requests per second

The campaign starts running as soon as it is created: it begins matching fans the moment this request is answered. There is no way to stage one — use the status endpoint to pause it.

An empty `audience_filters` targets every fan that fires the trigger. Campaigns here are trigger-driven and send one message per fan event, so this is the ordinary shape of a welcome campaign rather than a broadcast.

`audience_filters[].options.lists[].name` is accepted and never published back: a name is required for each fan list, while the read endpoints carry identifiers alone.

**This endpoint is not idempotent.** A request that times out may still have created a running campaign. Before retrying, list the account campaigns and look for one already there; a duplicate can be stopped with the status endpoint. Listing the campaigns needs `auto_messages.view` in addition to `auto_messages.edit`.

**Required permission:** `auto_messages.edit`

## Path parameters

- `account_id` string, required

## Request body

- object
  - `trigger` 'welcome_message' | 'online_message' | 'has_expired_message' | 'will_expire_in_message', required
  - `action` 'send_message' | 'start_mimic', required
  - `name` string: Campaign name. Required for a sequence and for a message that carries media but no text.
  - `rules` object, required
    - `send_delay_interval` object
      - `min_sec` 60 | 180 | 300 | 900 | 1800, required: How long to wait before sending. One of the published delays; each one fixes its own `range_sec`.
      - `range_sec` 120 | 600 | 900 | 1800, required: The spread added to the delay. It is decided by `min_sec` rather than chosen freely — 60 and 180 take 120, 300 takes 600, 900 takes 900, 1800 takes 1800.
    - `send_after_expire_min` 1440 | 2880 | 7200 | 10080 | 14400 | 20160: How long after a subscription expires the campaign fires.
    - `send_before_expire_min` 1440 | 2880 | 7200 | 10080 | 14400 | 20160: How long before a subscription expires the campaign fires.
    - `unsend_delay_sec` integer
    - `unsend_if_not_read_enabled` boolean
    - `unsend_if_not_replied_enabled` boolean
    - `retry_after_unsend_min` 1440 | 4320 | 10080 | 14400 | 21600 | 28800 | 43200: How long before the campaign may reach the same fan again.
    - `end_at` string, date-time: When the campaign stops firing, as an ISO 8601 instant. An instant needs no timezone of its own.
    - `mimic_on_reply_enabled` boolean
  - `audience_filters` union[], required: Filters evaluated per fan when the trigger fires. An empty list targets every fan that fires the trigger. `start_mimic` refuses `verified_account` with `MIMIC_CAMPAIGN_FILTER_NOT_ALLOWED`: a Mimic chat does not apply it. Send-time filters (`verified_account`, like `active_chatted`) do not fall through to an older campaign on the same trigger: the newest matching campaign takes the fan, and a send-time skip ends there.
    - union
      - object
        - `kind` 'purchased_from_organisation' | 'purchased_from_account', required
        - `mode` 'include' | 'exclude', required
        - `options` object, required: A purchase window stated either as a date range (`from_at`/`to_at`) or as a range of days ago (`from_days`/`to_days`), never as both at once. A range of days ago that starts today (`from_days: 0`) also states `to_days`.
          - `from_at` string, date-time
          - `to_at` string, date-time
          - `from_days` integer
          - `to_days` integer
      - object
        - `kind` 'spent_within_organisation' | 'spent_within_account' | 'buying_power_between', required
        - `mode` 'include' | 'exclude', required
        - `options` object, required
          - `from_amount_gross` number
          - `to_amount_gross` number
      - object
        - `kind` 'belongs_platform_lists' | 'belongs_dynamic_lists', required
        - `mode` 'exclude', required
        - `options` object, required
          - `lists` object[], required
            - `id` string, required: Identifier of the fan list.
            - `name` string, required: Name of the fan list. Stored and shown in the panel; never published back here.
      - object
        - `kind` 'active_chatted', required
        - `mode` 'exclude', required
        - `options` object, required
          - `within_last_min` integer, required
      - object
        - `kind` 'verified_account', required
        - `mode` 'exclude', required
        - `options` object, required
      - object
        - `kind` 'send_within_time_range', required
        - `mode` 'include' | 'exclude', required
        - `options` object, required
          - `from_time` string, required
          - `to_time` string, required
          - `timezone_mode` 'utc' | 'organisation', required
  - `messages` object[]: Messages to send, in order. Required for `send_message` and refused for `start_mimic`.
    - `text` string, required: Text the fan receives, rendered per fan. Null for a message that carries only media. A message carries text, at least one attachment, or both.
    - `price_gross` union, required: Price the fan pays for this message, before any platform deduction. 0 makes it free; any other amount is between 3 and 200. A price requires something behind the paywall — `text_is_paid` or an attachment with `is_paid` — and either of those requires a price.
      - 0
      - number
    - `delay_sec` integer: Delay after the previous message before this one is sent. Accepted on follow-ups only — the first message is timed by the campaign rules. Up to 3600 seconds (one hour).
    - `attachments` object[], required: Media to attach. Empty for a message that carries none.
      - `id` string, required: Identifier of the media on the platform.
      - `type` 'image' | 'video' | 'audio' | 'gif', required
      - `is_paid` boolean, required: True to put the attachment behind the paywall, hiding it from the preview the fan sees before paying.
    - `text_is_paid` boolean, required: True to put the text itself behind the paywall, so the fan buys the message to read it. Requires text that is not empty or whitespace.
    - `tagged_platform_account_ids` string[], required: Platform accounts to tag in this message, by their identifier on the platform.

## Response `201`

One Auto Messages campaign of the account.

- object: One Auto Messages campaign of the account.
  - `id` string, required: Campaign identifier.
  - `account_id` string, required: OnlyMonster account the campaign belongs to.
  - `name` string, required: Campaign name as the account owner set it. Null when the campaign has none.
  - `trigger` 'welcome_message' | 'online_message' | 'has_expired_message' | 'will_expire_in_message', required
  - `action` 'send_message' | 'start_mimic', required: What the campaign does when the trigger fires. `send_message` — sends the messages listed in `messages`. `start_mimic` — opens a Mimic chat instead of sending; such a campaign has no messages. Null when this version of the API does not name the action. Such a campaign reports no messages either, since what its content means depends on what it does with it.
  - `status` 'active' | 'paused' | 'archived' | 'unsending' | 'unsent', required
  - `created_by` object, required: Who created the campaign.
    - `type` 'user' | 'api_key', required
    - `id` string, required: For `user`, the id of the member who created the campaign in OnlyMonster; for `api_key`, the id of the API key that created it. Null when the creator is unknown.
  - `created_at` string, date-time, required: When the campaign was created (ISO 8601 Zulu).
  - `rules` object, required: When the campaign fires, and on what terms it recalls what it sent.
    - `send_delay_interval` object, required: How long the campaign waits between the trigger firing and the send. Null for the expiry triggers, which fire at a fixed offset instead.
      - `min_sec` integer, required: Shortest the campaign waits after the trigger fires.
      - `range_sec` integer, required: Span the delay is drawn from, on top of `min_sec`: a send happens between `min_sec` and `min_sec + range_sec` seconds after the trigger. 0 makes the delay fixed.
    - `send_after_expire_min` integer, required: Minutes after a subscription expired at which the campaign fires. Non-null only for trigger `has_expired_message`.
    - `send_before_expire_min` integer, required: Minutes before a subscription expires at which the campaign fires. Non-null only for trigger `will_expire_in_message`.
    - `unsend_delay_sec` integer, required: Delay after which a sent message is recalled. Null when the campaign never recalls.
    - `unsend_if_not_read_enabled` boolean, required: Whether the recall is skipped for a message the fan has already opened. False means the message is recalled whatever the fan did.
    - `unsend_if_not_replied_enabled` boolean, required: Whether the recall is skipped for a message the fan replied to. A fan who opened the message without replying keeps it too, the same as with `unsend_if_not_read_enabled`.
    - `retry_after_unsend_min` integer, required: Minutes after a recall before the same fan may be targeted again. Null when a fan is targeted at most once, which is the default.
    - `end_at` string, date-time, required: When the campaign stops firing (ISO 8601 Zulu). Null when it runs until stopped by hand.
    - `mimic_on_reply_enabled` boolean, required: Whether a reply from the fan opens a Mimic chat.
  - `audience_filters` object[], required: Filters evaluated per fan when the trigger fires. Empty when the campaign targets every fan.
    - `kind` 'purchased_from_organisation' | 'spent_within_organisation' | 'purchased_from_account' | 'spent_within_account' | 'buying_power_between' | 'active_chatted' | 'belongs_platform_lists' | 'belongs_dynamic_lists' | 'send_within_time_range' | 'verified_account', required
    - `mode` 'include' | 'exclude', required
    - `options` union, required
      - object: Absolute date range.
        - `from_at` string, date-time, required
        - `to_at` string, date-time, required
      - object: Range expressed in days back from now.
        - `from_days` integer, required
        - `to_days` integer, required
      - object: Monetary range, before platform deductions.
        - `from_amount_gross` number, required
        - `to_amount_gross` number, required
      - object: Hour of the day the campaign may send in, as `HH:00`. `timezone_mode` says whose clock the hours are read on: `utc`, or `organisation` for the timezone configured on the organisation.
        - `from_time` string, required
        - `to_time` string, required
        - `timezone_mode` 'utc' | 'organisation', required
      - object: Identifiers of the fan lists the filter selects on.
        - `list_ids` string[], required
      - object: Window, in minutes back from the moment the trigger fires.
        - `within_last_min` integer, required
      - object: No parameters: the filter kind alone decides what it selects.
  - `messages` object[], required: Messages the campaign sends, in send order. Empty for a campaign that starts a Mimic chat.
    - `step` integer, required: Position of the message in the campaign: 0 is the first message, 1 and up are its follow-ups.
    - `text` string, required: Text the fan receives. Null for a message that carries only media.
    - `price_gross` number, required: Price the fan pays for this message, before any platform deduction. 0 when the message is free.
    - `delay_sec` integer, required: Delay after the previous message of the campaign before this one is sent. Null for the first message, which is timed by the campaign rules instead.
    - `attachments` object[], required: Media attached to this message. Empty when it carries none.
      - `id` string, required: Identifier of the media on the platform.
      - `type` 'image' | 'video' | 'audio' | 'gif', required
      - `is_paid` boolean, required: True when the attachment sits behind the paywall and is hidden from the preview the fan sees before paying.
    - `text_is_paid` boolean, required: True when the text itself sits behind the paywall, so the fan buys the message to read it rather than only to open its media. False when the text is visible before paying, including when the message carries no price at all.
    - `tagged_platform_account_ids` string[], required: Platform accounts tagged in this message, by their identifier on the platform. Empty when it tags none.
  - `targeted_sends_count` integer, required: Dispatches the campaign has made since it was created. Cumulative: a fan targeted twice counts twice, and the figure never decreases.
  - `first_message_stats` object, required: Figures for the first message of the campaign only. Follow-up steps are reported separately.
    - `sent_messages_count` integer, required: Messages recorded as sent. Includes messages recalled afterwards.
    - `unsent_messages_count` integer, required: Of the sent messages, how many were recalled afterwards. Messages still with the fan are `sent_messages_count` minus this.
    - `replied_messages_count` integer, required: Sent messages a fan replied to. Counted per message, not per fan, and not reduced by a recall.
    - `purchased_messages_count` integer, required: Sent messages a fan paid for.
    - `purchased_amount_gross` number, required: Total the fans paid for these messages, before any platform deduction. 0 when nothing was bought.
    - `reply_rate` number, required: Replied messages over sent messages, between 0 and 1. Null when the figure cannot be computed.
    - `purchase_rate` number, required: Purchased messages over sent messages, between 0 and 1. Null when the figure cannot be computed.
  - `follow_up_message_stats` object[], required: Figures for each follow-up step. The campaign's total is `first_message_stats` plus these.
    - `step` integer, required: Follow-up step these figures belong to, matching `messages[].step`. Starts at 1; the first message is reported in `first_message_stats`.
    - `sent_messages_count` integer, required: Messages recorded as sent. Includes messages recalled afterwards.
    - `unsent_messages_count` integer, required: Of the sent messages, how many were recalled afterwards. Messages still with the fan are `sent_messages_count` minus this.
    - `replied_messages_count` integer, required: Sent messages a fan replied to. Counted per message, not per fan, and not reduced by a recall.
    - `purchased_messages_count` integer, required: Sent messages a fan paid for.
    - `purchased_amount_gross` number, required: Total the fans paid for these messages, before any platform deduction. 0 when nothing was bought.
    - `reply_rate` number, required: Replied messages over sent messages, between 0 and 1. Null when the figure cannot be computed.
    - `purchase_rate` number, required: Purchased messages over sent messages, between 0 and 1. Null when the figure cannot be computed.

## Other responses

- `400`: The request states something this endpoint cannot accept: a value outside its bounds, a schedule member belonging to another trigger, content on a campaign that sends none, or a fan list that does not exist.
- `403`: The API key lacks the permission this endpoint requires, or the request is outside what the organisation or the API key can access.
- `502`: The campaign could not be created or confirmed. Whether the campaign was created is unknown — list the account campaigns before retrying.

## Changes

- **2026-11-05** `0003edb0288a`: 2 warning, 1 info
  - added the new `MIMIC_CAMPAIGN_FILTER_NOT_ALLOWED` enum value to the `code` response property for the response status `400`
  - added the new `verified_account` enum value to the `audience_filters/items/kind` response property for the response status `201`
  - added `subschema #5` to the `audience_filters/items/` request property `anyOf` list
- **2026-11-03** `20f58411c6c5`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/onlymonster/apis/om-api-service/changes/api/v0/accounts/:account_id/auto-message-campaigns/post.md)

---

[API](https://skmtc.dev/onlymonster/apis/om-api-service.md) - [All operations](https://skmtc.dev/onlymonster/apis/om-api-service/llms.txt) - [OpenAPI document](https://skmtc.dev/onlymonster/apis/om-api-service/revisions/0003edb0288a?raw)
