> For the complete documentation index, see [llms.txt](https://help.blotato.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.blotato.com/api/dm-automations.md).

# DM Automations

A DM automation sends a direct message when someone comments on your post or sends you a message. Blotato supports DM automations on Instagram and Facebook Pages. Twitter/X, TikTok, LinkedIn, Pinterest, Threads, Bluesky, and YouTube are not supported at this time.

Eight endpoints let you manage automations and inspect their activity:

* [List DM Automations](#list-dm-automations) — `GET /v2/dm-automations`
* [Get DM Automation](#get-dm-automation) — `GET /v2/dm-automations/:id`
* [Create DM Automation](#create-dm-automation) — `POST /v2/dm-automations`
* [Update DM Automation](#update-dm-automation) — `PATCH /v2/dm-automations/:id`
* [Delete DM Automation](#delete-dm-automation) — `DELETE /v2/dm-automations/:id`
* [List Runs](#list-runs) — `GET /v2/dm-automations/:id/runs`
* [List Logs](#list-logs) — `GET /v2/dm-automations/:id/logs`
* [Get Analytics](#get-analytics) — `GET /v2/dm-automations/:id/analytics`

For the web app walkthrough, see [DM Automations](/features/dm-automations.md).

## Before You Start

Blotato needs permission to read comments and read and send messages on your account.

If you connected your account before comments and messaging launched, reconnect it so Blotato has the new permissions.

* For Instagram, see [Connect Instagram](/settings/social-accounts/instagram.md).
* For Facebook, see [Connect Facebook](/settings/social-accounts/facebook.md).

## How an Automation Runs

1. Someone comments on your post or sends your account a message.
2. Blotato matches the event against every live automation on the account.
3. A match starts a **run** and queues the DM for each live automation.
4. The run reaches `completed` once the DM settles, or `failed` with the platform error.

A comment trigger answers with a **private reply to the comment**. A message trigger answers with a standard DM.

Your own comments and the messages your account sends never start a run.

***

## List DM Automations

### Endpoint

**Base URL:** `https://backend.blotato.com/v2`

**URL:** `/dm-automations`

**Method:** `GET`

### Description

Returns your DM automations, ordered by creation time (most recent first). Use cursor-based pagination.

### Query Parameters

| Field    | Type      | Required | Description                                                      |
| -------- | --------- | -------- | ---------------------------------------------------------------- |
| `limit`  | `integer` | No       | Maximum automations to return (1-250). Default 50.               |
| `cursor` | `string`  | No       | Cursor from a previous response. Pass it to fetch the next page. |

### Response

**Status Code:** `200 OK`

```json
{
  "items": [
    {
      "id": "flow_abc123",
      "accountId": "98434",
      "name": "Auto-DM links from comments",
      "platform": "instagram",
      "target": { "targetType": "instagram" },
      "trigger": {
        "type": "comment-received",
        "keywords": ["price", "link"],
        "postId": "post_xyz789",
        "isActive": true
      },
      "dmMessage": "Thanks for the interest! Tap below for the link.",
      "buttons": [
        { "type": "url", "title": "View link", "url": "https://blotato.com" }
      ],
      "isActive": true,
      "publishedVersionId": "ver_001",
      "createdAt": "2026-08-01T12:00:00Z",
      "updatedAt": "2026-08-02T09:30:00Z"
    }
  ],
  "cursor": "eyJz..."
}
```

| Field    | Type     | Description                                                             |
| -------- | -------- | ----------------------------------------------------------------------- |
| `items`  | `array`  | List of automations. See [DM Automation Object](#dm-automation-object). |
| `cursor` | `string` | Cursor for the next page. Absent when there are no more automations.    |

***

## Get DM Automation

### Endpoint

**URL:** `/dm-automations/:id`

**Method:** `GET`

### Description

Fetches a single automation by its Blotato ID, including its trigger and the message it sends.

### Path Parameters

| Field | Type     | Required | Description                   |
| ----- | -------- | -------- | ----------------------------- |
| `id`  | `string` | Yes      | Blotato ID of the automation. |

### Response

**Status Code:** `200 OK`

```json
{ "flow": { "id": "flow_abc123", "...": "..." } }
```

The `flow` object is a [DM Automation Object](#dm-automation-object).

***

## Create DM Automation

### Endpoint

**URL:** `/dm-automations`

**Method:** `POST`

### Description

Creates a DM automation. When its trigger fires, the automation sends one direct message: text plus up to 3 link buttons.

An automation is created as a draft unless you pass `isActive: true`.

### Request Body

```json
{
  "accountId": "98434",
  "platform": "instagram",
  "target": { "targetType": "instagram" },
  "name": "Auto-DM links from comments",
  "trigger": {
    "type": "comment-received",
    "keywords": ["price", "link"],
    "postId": null
  },
  "dmMessage": "Thanks for the interest! Tap below for the link.",
  "buttons": [
    { "type": "url", "title": "View link", "url": "https://blotato.com" }
  ],
  "isActive": true
}
```

| Field       | Type             | Required | Description                                                                                    |
| ----------- | ---------------- | -------- | ---------------------------------------------------------------------------------------------- |
| `accountId` | `string`         | Yes      | Blotato ID of the connected account the automation runs on.                                    |
| `platform`  | `string`         | Yes      | `instagram` or `facebook`.                                                                     |
| `target`    | `object`         | Yes      | Where the automation listens and sends. See [Target](#target).                                 |
| `name`      | `string`         | Yes      | Automation label, 1-60 characters.                                                             |
| `dmMessage` | `string`         | Yes      | Message text, 1-640 characters.                                                                |
| `buttons`   | `array`          | Yes      | Up to 3 link buttons. Pass `[]` for a plain-text message. See [Button Object](#button-object). |
| `trigger`   | `object or null` | No       | The event the automation listens for. See [Trigger Object](#trigger-object).                   |
| `isActive`  | `boolean`        | No       | `true` publishes the automation immediately. Default `false`.                                  |

An automation needs a trigger, a non-empty `dmMessage` of 640 characters or fewer, and a valid `http(s)` URL on every button before it goes live.

### Response

**Status Code:** `201 Created`

```json
{ "flow": { "id": "flow_abc123", "isActive": true, "...": "..." } }
```

***

## Update DM Automation

### Endpoint

**URL:** `/dm-automations/:id`

**Method:** `PATCH`

### Description

Updates an automation. Each field present in the patch replaces that field. Omitted fields stay unchanged.

The connected account, platform, and target are fixed at creation. To run on a different account, create a new automation.

### Request Body

The patch is nested under a `patch` key.

```json
{
  "patch": {
    "dmMessage": "New reply text",
    "buttons": [],
    "isActive": true
  }
}
```

| Field       | Type             | Required | Description                                                                                 |
| ----------- | ---------------- | -------- | ------------------------------------------------------------------------------------------- |
| `name`      | `string`         | No       | New automation label, 1-60 characters.                                                      |
| `trigger`   | `object or null` | No       | Replaces the trigger. See [Trigger Object](#trigger-object).                                |
| `dmMessage` | `string`         | No       | Replaces the message text, 1-640 characters.                                                |
| `buttons`   | `array`          | No       | Replaces the buttons. Pass `[]` to remove every button.                                     |
| `isActive`  | `boolean`        | No       | `true` publishes the automation. `false` moves it to draft. Omit to keep the current state. |

Content changes to a live automation publish as soon as the request succeeds. Content changes to a draft stay saved until you pass `isActive: true`.

A live automation needs a trigger. To clear the trigger, pass `isActive: false` in the same request.

### Response

**Status Code:** `200 OK`

```json
{ "flow": { "id": "flow_abc123", "...": "..." } }
```

***

## Delete DM Automation

### Endpoint

**URL:** `/dm-automations/:id`

**Method:** `DELETE`

### Description

Archives an automation. Its trigger stops listening and the automation stops firing. Runs already in flight finish.

### Response

**Status Code:** `200 OK`

Returns the archived [DM Automation Object](#dm-automation-object).

***

## List Runs

### Endpoint

**URL:** `/dm-automations/:id/runs`

**Method:** `GET`

### Description

Returns the execution runs of one automation, ordered by start time (most recent first). A run is one execution: one comment or message matched the trigger, and Blotato acted on it.

Use this endpoint to check whether an automation fires and why a reply did not go out.

### Query Parameters

| Field    | Type      | Required | Description                                                      |
| -------- | --------- | -------- | ---------------------------------------------------------------- |
| `limit`  | `integer` | No       | Maximum runs to return (1-250). Default 50.                      |
| `cursor` | `string`  | No       | Cursor from a previous response. Pass it to fetch the next page. |

### Response

**Status Code:** `200 OK`

```json
{
  "items": [
    {
      "id": "run_abc123",
      "contactId": "1784000000",
      "platform": "instagram",
      "status": "failed",
      "error": { "code": 20102, "message": "Messaging window has expired" },
      "createdAt": "2026-08-02T09:30:00Z",
      "updatedAt": "2026-08-02T09:30:04Z"
    }
  ],
  "cursor": "eyJz..."
}
```

See [Run Object](#run-object).

***

## List Logs

### Endpoint

**URL:** `/dm-automations/:id/logs`

**Method:** `GET`

### Description

Returns the execution logs written as an automation's runs progress, ordered by creation time (most recent first). Pass `flowRunId` to narrow the logs to a single run.

### Query Parameters

| Field       | Type      | Required | Description                                                                   |
| ----------- | --------- | -------- | ----------------------------------------------------------------------------- |
| `flowRunId` | `string`  | No       | Only return logs belonging to this run. Omit to return logs across every run. |
| `limit`     | `integer` | No       | Maximum logs to return (1-250). Default 50.                                   |
| `cursor`    | `string`  | No       | Cursor from a previous response. Pass it to fetch the next page.              |

### Response

**Status Code:** `200 OK`

```json
{
  "items": [
    {
      "id": "log_abc123",
      "flowRunId": "run_abc123",
      "nodeId": "nd_9fJ2",
      "level": "info",
      "message": "Queued message for send",
      "context": { "messageId": "msg_abc123" },
      "createdAt": "2026-08-02T09:30:01Z"
    }
  ],
  "cursor": "eyJz..."
}
```

See [Log Object](#log-object).

***

## Get Analytics

### Endpoint

**URL:** `/dm-automations/:id/analytics`

**Method:** `GET`

### Description

Returns all-time run totals for one automation.

### Response

**Status Code:** `200 OK`

```json
{
  "analytics": {
    "triggered": 412,
    "completed": 398,
    "failed": 9
  }
}
```

| Field       | Type      | Description                                    |
| ----------- | --------- | ---------------------------------------------- |
| `triggered` | `integer` | Runs started by a matching comment or message. |
| `completed` | `integer` | Runs where the DM settled as sent.             |
| `failed`    | `integer` | Runs where the DM did not send.                |

A run stays open until its message settles, so `completed` plus `failed` is sometimes lower than `triggered`.

***

## DM Automation Object

| Field                | Type             | Description                                                                                                 |
| -------------------- | ---------------- | ----------------------------------------------------------------------------------------------------------- |
| `id`                 | `string`         | Blotato automation ID.                                                                                      |
| `accountId`          | `string`         | ID of the connected account the automation runs on.                                                         |
| `name`               | `string`         | Automation label.                                                                                           |
| `platform`           | `string`         | `instagram` or `facebook`.                                                                                  |
| `target`             | `object`         | See [Target](#target).                                                                                      |
| `trigger`            | `object`         | The event the automation listens for. Absent when no trigger is set. See [Trigger Object](#trigger-object). |
| `dmMessage`          | `string`         | Message text sent when the trigger fires.                                                                   |
| `buttons`            | `array`          | Link buttons attached to the message. See [Button Object](#button-object).                                  |
| `isActive`           | `boolean`        | `true` when the automation is live and listening.                                                           |
| `publishedVersionId` | `string or null` | ID of the published version. `null` for a draft.                                                            |
| `createdAt`          | `string`         | ISO 8601 timestamp when the automation was created.                                                         |
| `updatedAt`          | `string`         | ISO 8601 timestamp of the most recent edit.                                                                 |

### Target

| Field        | Type     | Required     | Description                                                                                                                     |
| ------------ | -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------- |
| `targetType` | `string` | Yes          | `instagram` or `facebook`.                                                                                                      |
| `pageId`     | `string` | For Facebook | ID of the Facebook Page, from [subaccounts](/api/accounts.md#list-subaccounts-pages). Required when `targetType` is `facebook`. |

### Trigger Object

| Field      | Type             | Required | Description                                                                                                |
| ---------- | ---------------- | -------- | ---------------------------------------------------------------------------------------------------------- |
| `type`     | `string`         | Yes      | `comment-received` or `message-received`.                                                                  |
| `keywords` | `array`          | Yes      | Words or phrases the comment or message must contain. Pass `[]` to fire on every comment or message.       |
| `postId`   | `string or null` | No       | Comment triggers only. Blotato ID of the post to watch. `null` watches every post and reel on the account. |
| `isActive` | `boolean`        | No       | `false` stops the trigger listening while the automation stays published. Default `true`.                  |

Keyword matching ignores case, matches whole words, and tolerates line breaks inside a multi-word keyword. A comment or message fires the automation when it contains any one of the keywords.

`postId` is a **Blotato** post ID, so per-post targeting works on posts published through Blotato. Get it from [List Published Posts](/api/publish-post/list-published-posts.md). To act on a post published outside Blotato, leave `postId` as `null` and rely on keywords.

### Button Object

| Field   | Type     | Required       | Description                                                     |
| ------- | -------- | -------------- | --------------------------------------------------------------- |
| `type`  | `string` | Yes            | `url`. Link buttons are the only button type in DM automations. |
| `title` | `string` | Yes            | Button label, up to 20 characters.                              |
| `url`   | `string` | Yes to publish | `http(s)` URL the button opens.                                 |

To send quick-reply chips or postback buttons, use [Send Message](/api/messages.md#buttons-and-quick-replies).

### Run Object

| Field       | Type     | Description                                                        |
| ----------- | -------- | ------------------------------------------------------------------ |
| `id`        | `string` | Blotato run ID. Pass it as `flowRunId` to [List Logs](#list-logs). |
| `contactId` | `string` | Social platform ID of the person who triggered the run.            |
| `platform`  | `string` | `instagram` or `facebook`.                                         |
| `status`    | `string` | See [Run Status Values](#run-status-values).                       |
| `error`     | `object` | Set only when status is `failed`. Holds `code` and `message`.      |
| `createdAt` | `string` | ISO 8601 timestamp when the run started.                           |
| `updatedAt` | `string` | ISO 8601 timestamp of the most recent run update.                  |

#### Run Status Values

| Status      | Meaning                            |
| ----------- | ---------------------------------- |
| `running`   | Executing a step.                  |
| `waiting`   | Waiting for the DM to settle.      |
| `completed` | The DM sent.                       |
| `failed`    | The DM did not send. Read `error`. |

### Log Object

| Field       | Type             | Description                                                     |
| ----------- | ---------------- | --------------------------------------------------------------- |
| `id`        | `string`         | Blotato log ID.                                                 |
| `flowRunId` | `string`         | ID of the run this log belongs to.                              |
| `nodeId`    | `string or null` | ID of the step the log came from. `null` for run-level entries. |
| `level`     | `string`         | `info`, `warning`, or `error`.                                  |
| `message`   | `string`         | Description of the step.                                        |
| `context`   | `object`         | Step-specific details, for example the message ID.              |
| `createdAt` | `string`         | ISO 8601 timestamp when the log was written.                    |

***

## Platform Rules

Instagram and Facebook set these rules, not Blotato. A message outside an allowed window reaches status `failed` on the run.

* **Comment trigger.** Blotato answers with a private reply to the comment. Both platforms allow one private reply per comment, within 7 days of the comment. A comment that already received a private reply, through Blotato or another tool, rejects the second reply.
* **Message trigger.** Blotato replies within 24 hours of the person's last message.
* **No cold outreach.** An automation only answers people who comment or message first.

See [Messaging Windows](/api/messages.md#messaging-windows).

## Active Contacts

Every DM an automation sends counts toward your plan's monthly active-contacts limit, the same as a message sent through [Send Message](/api/messages.md#send-message). Reaching the same person twice in a month counts once.

See [Active Contacts](/settings/billing-and-credits.md#active-contacts).

***

## Errors

| Status | Reason                                                                                                                                    |
| ------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `404`  | The automation was not found. Returned by [Get DM Automation](#get-dm-automation) and [Delete DM Automation](#delete-dm-automation) only. |
| `422`  | The automation is invalid for publishing (error code 20303), or the connected account is missing (error code 5000).                       |
| `500`  | Unexpected server error.                                                                                                                  |

## Rate Limits

| Endpoint                            | Limit    |
| ----------------------------------- | -------- |
| `GET /dm-automations`               | 60 / min |
| `GET /dm-automations/:id`           | 60 / min |
| `POST /dm-automations`              | 30 / min |
| `PATCH /dm-automations/:id`         | 30 / min |
| `DELETE /dm-automations/:id`        | 30 / min |
| `GET /dm-automations/:id/runs`      | 60 / min |
| `GET /dm-automations/:id/logs`      | 60 / min |
| `GET /dm-automations/:id/analytics` | 60 / min |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://help.blotato.com/api/dm-automations.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
