DM Automations API
Configure Instagram or Facebook trigger-based DMs, activation, gates, runs, logs, and automation analytics.
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.
Nine endpoints let you manage automations and inspect their activity:
List DM Automations —
GET /v2/dm-automationsGet DM Automation —
GET /v2/dm-automations/:idCreate DM Automation —
POST /v2/dm-automationsUpdate DM Automation —
PATCH /v2/dm-automations/:idUpdate DM Automation Trigger —
PATCH /v2/dm-automations/:flowId/triggers/:triggerIdDelete DM Automation —
DELETE /v2/dm-automations/:idList Runs —
GET /v2/dm-automations/:id/runsList Logs —
GET /v2/dm-automations/:id/logsGet Analytics —
GET /v2/dm-automations/:id/analytics
For the web app walkthrough, see DM Automations.
Before You Start
Blotato needs permission to read comments and read and send messages on your account.
If you connected your account before comments, messaging, or (for Instagram) follow gating launched, reconnect it so Blotato has the new permissions.
For Instagram, see Connect Instagram.
For Facebook, see Connect Facebook.
For Instagram comment triggers, the connected Instagram account must own the post. DM automations do not run on posts where your account appears only as a collaborator. If you co-authored a post, create the automation under the Instagram account that originally published the post.
How an Automation Runs
Someone comments on your post or sends your account a message.
Blotato matches the event against every active trigger on every live automation on the account.
A match starts one run per matching automation. An automation with a comment trigger and a message trigger starts a single run per event.
If the automation has a follow gate or email gate, Blotato waits for the contact to complete it. On automations published after September 14, 2026, a contact with an email already on file skips the email gate.
Blotato sends the DM, then calls the webhook if one is configured.
The run reaches
completed,failed,expired, orsuperseded.
Every live automation whose trigger matches starts its own run. Two automations matching the same comment both try to answer it, one reply reaches the contact, and the other run fails. Two automations matching the same message both send. Each matching comment also starts a new run, so a contact who comments the keyword twice gets two replies.
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.
Comments on Instagram collaborator posts do not start a run for the collaborator account. Use the owner account for the automation.
Testing a Comment Trigger
Test from a different Instagram or Facebook account. A comment posted by the same account connected to the automation is skipped, even when its text matches a trigger keyword.
Optional Steps
Set followGate, emailGate, or webhook to extend the run. Blotato runs the steps in a fixed order:
Follow gate (
followGate, Instagram only). Sends the gate message with a confirm button, waits up to 30 days for a reply, then checks whether the contact follows the account. A contact who does not follow gets the gate message again.Email gate (
emailGate). Sends the gate message, waits up to 72 hours for a reply, and reads the first email address out of it. A reply holding no email address returns the gate message. A match saves to the contact. On automations published after September 14, 2026, a contact with an email already on file skips the gate. See Email Gate Object.Your message (
dmMessageplusbuttons).Webhook (
webhook). Calls your endpoint after the message sends.
A run waiting on a gate reaches expired when the contact never answers inside the window, and superseded when a newer run starts waiting on the same contact.
While a run waits on a contact's reply, their next DM resumes the waiting run instead of starting a new run. A button tap never starts 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. Archived automations do not appear. Every item includes run counts from the last 24 hours and the time it last ran.
Query Parameters
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
items[].stats
object
Run counts from the last 24 hours: triggered, completed, and failed, plus lastRunAt.
items[].stats.lastRunAt
string or null
ISO 8601 time the automation last ran. Null when it has never run.
cursor
string
Cursor for the next page. Absent when there are no more automations.
For all-time totals and failures from the last 7 days, use Get Analytics.
Get DM Automation
Endpoint
URL: /dm-automations/:id
Method: GET
Description
Fetches a single automation by its Blotato ID, including its triggers and message. An archived automation still returns here with isActive: false.
Path Parameters
id
string
Yes
Blotato ID of the automation.
Response
Status Code: 200 OK
The flow object is a DM Automation Object.
Create DM Automation
Endpoint
URL: /dm-automations
Method: POST
Description
Creates a DM automation. When any of its triggers fires, the automation sends one direct message: text plus up to 3 link buttons. Pass up to 2 triggers in triggers: one comment-received trigger and one message-received trigger. One matching comment or message starts a single run. Optional fields gate the message behind an Instagram follow check, ask for an email address first, or call a webhook after the message sends.
Set
followGate(Instagram only) to gate the message behind a follow check.Set
emailGateto gate it behind the contact replying with an email address.Set
webhookto call an external endpoint once the message sends.
An automation is created as a draft unless you pass isActive: true. Inspect existing flows before creating another. Keep the example inactive until the user requests activation and approves the account, trigger scope, message, and link. Include only the requested triggers and optional steps.
Request Body
Response
Status Code: 201 Created
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. triggers replaces the whole trigger set, and [] clears it. Pass null for followGate, emailGate, or webhook to remove it.
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.
name
string
No
New automation label, 1-60 characters.
triggers
array
No
Replaces every trigger. Up to 2 triggers, at most one per type. Pass [] to remove every trigger. See Trigger Object.
dmMessage
string
No
Replaces the message text, 1-640 characters.
buttons
array
No
Replaces the buttons. Pass [] to remove every button.
followGate
object or null
No
Replaces the follow gate. Pass null to remove it. Instagram only. See Follow Gate Object.
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 run already in progress keeps the version it started with.
A live automation needs at least one active trigger. To clear every trigger, pass an empty triggers array and set isActive: false in the same request. To remove one trigger, pass triggers holding the trigger you keep. To update a single trigger without other changes, for example to turn it off, use Update DM Automation Trigger.
Updating an automation's content or triggers reissues its trigger IDs. Read triggers from the response before you call Update DM Automation Trigger.
Response
Status Code: 200 OK
Update DM Automation Trigger
Endpoint
URL: /dm-automations/:flowId/triggers/:triggerId
Method: PATCH
Description
Updates a single trigger on an automation, for example to turn it on or off. The change applies immediately on a live automation, with no republish. The other triggers, the message, and the optional steps stay as they are.
Read the trigger ID from the triggers array of the automation. Updating an automation's content or triggers reissues its trigger IDs, so fetch the automation again before you update a trigger.
Path Parameters
flowId
string
Yes
Blotato ID of the automation.
triggerId
string
Yes
ID of the trigger, from the automation's triggers array.
Request Body
The patch is nested under a patch key.
isActive
boolean
Yes
true turns the trigger on. false turns it off.
A live automation needs at least one active trigger. Turning off its last active trigger returns 422 with error code 20303. To stop every trigger, move the automation to draft with Update DM Automation.
A draft accepts any update. Blotato checks the active-trigger rule when you publish.
Response
Status Code: 200 OK
The trigger object is a Trigger Object. A 404 means the automation or the trigger ID was not found.
Delete DM Automation
Endpoint
URL: /dm-automations/:id
Method: DELETE
Description
Archives an automation and stops new runs. Existing runs, including waiting gates, remain able to continue. Archiving does not cancel messages already queued. Archive only when the user requests it.
The archived automation leaves List DM Automations, but Get DM Automation still returns it. Publishing it again with Update DM Automation and isActive: true restores it.
Response
Status Code: 200 OK
Returns the archived DM Automation Object.
List Runs
Endpoint
URL: /dm-automations/:id/runs
Method: GET
Description
Returns the execution runs of one automation, ordered by activity time (most recent first). Use this endpoint to confirm an automation fired and inspect failed runs.
Query Parameters
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.
status
string[]
No
Include runs matching any supplied status: running, waiting, completed, expired, superseded, or failed. Omit to include every status.
since
string
No
Include runs with activity at or after this ISO 8601 timestamp.
Response
Status Code: 200 OK
See Run Object.
List Logs
Endpoint
URL: /dm-automations/:id/logs
Method: GET
Description
Returns logs written as an automation's runs progress, ordered by creation time (most recent first). Pass flowRunId to narrow the response to one run.
Query Parameters
flowRunId
string
No
Include logs belonging to this run. Omit to include 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
See Log Object.
Get Analytics
Endpoint
URL: /dm-automations/:id/analytics
Method: GET
Description
Returns all-time run totals and the number of recent failures for one automation.
Response
Status Code: 200 OK
triggered
integer
Runs started by a matching comment or message.
completed
integer
Runs where every step finished.
failed
integer
All-time runs ending on an error.
issues
integer
Runs that failed during the last 7 days. This is a subset of failed.
Runs still in progress and runs ending as expired or superseded count toward triggered, but not completed or failed. The sum of completed and failed is sometimes lower than triggered.
DM Automation Object
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.
triggers
array
Triggers the automation listens for, up to 2. Empty on a draft with no triggers. See Trigger Object.
dmMessage
string
Message text sent when a trigger fires.
followGate
object
Follow gate on the automation. Absent when no follow gate is set. See Follow Gate Object.
emailGate
object
Email gate on the automation. Absent when no email gate is set. See Email Gate 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
targetType
string
Yes
instagram or facebook.
pageId
string
For Facebook
ID of the Facebook Page, from subaccounts. Required when targetType is facebook.
Trigger Object
An automation holds up to 2 triggers: one comment-received trigger and one message-received trigger. Each trigger carries its own keywords, and a comment trigger carries its own postId. One matching comment or message starts a single run.
id
string
Read-only
Blotato trigger ID. Present on every trigger Blotato returns. Omit it when you create or update an automation. Pass it to Update DM Automation Trigger.
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 text message. A message without text, such as a photo or sticker, never fires.
postId
string or null
No
Comment triggers only. Blotato ID of the tracked post to match. Do not use the platform's native post ID. null watches every post and reel on the account.
isActive
boolean
No
false turns this trigger off while the automation stays live. Default true.
Blotato enforces these rules when an automation goes live and while it stays live:
At least one active trigger.
At most one trigger per type.
A draft holds any trigger set, including an empty one. Blotato rejects a request with more than 2 triggers.
Updating an automation's content or triggers reissues its trigger IDs. Read triggers from the response before you update a trigger.
Keyword matching ignores case, matches anywhere in the text, and tolerates line breaks inside a multi-word keyword. For example, price matches both price and pricey. A comment or message fires the automation when it contains any one of the keywords.
The trigger matches a Blotato post ID, not publication origin. List Published Posts and the web post picker list Blotato-published posts only. For an Instagram post published outside Blotato, an incoming comment creates a tracked post record. Retrieve the comment through List Comments, verify its account and native platformPostId, and use its non-null postId for the trigger. The request still needs the connected account and platform containing this post.
If the required Blotato post ID is unavailable, stop and explain the missing ID. Do not replace it with a native ID or widen a single-post request to all posts. Use postId: null with a keyword only when the user approves matching across the account's posts and reels.
Button Object
type
string
Yes
url. Link buttons are the only type buttons accepts.
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.
Instagram renders buttons in the Instagram mobile app only. A recipient reading the DM on instagram.com in a desktop browser sees the message text with no buttons. To work around this issue, you can add the URL directly to the message text, and Instagram will render it as a clickable link. Set buttons or put a URL inside dmMessage, not both, since a message carrying both leaves the URL unclickable on desktop. For a desktop audience, pass buttons: [] and put the URL in dmMessage. See Instagram Limitations.
Follow Gate Object
Instagram only. Holds dmMessage back until the contact follows the account.
message
string
Yes
Gate message text, 1-640 characters. Blotato sends it with a confirm button under it.
buttonTitle
string
No
Label on the confirm button, up to 20 characters. Default I'm following.
Blotato sends the gate message, waits up to 30 days for a reply, then reads the contact's follower status. A contact who follows receives dmMessage. A contact who does not receives the gate message again.
The gate message always goes first. Instagram grants access to follower status once the contact opens a DM thread with the account, so the gate message precedes the check.
An unknown follower status sends
dmMessage. Instagram withholds follower status for a contact who never granted profile access, and Blotato proceeds rather than blocking them.A confirmed follow lasts 30 days. The gate message still goes out on every run. Blotato reuses a confirmed follow for 30 days, so a repeat contact's reply passes without a new check. A negative result is never reused.
The confirm button is a postback button Blotato manages. You set its label only. See Instagram Limitations.
Any text reply advances the gate. Blotato runs the follower check on the contact's next text DM, whatever it says. A photo, sticker, or voice note does not count. The tap is a shortcut, not a requirement.
The account needs a button-tap subscription. Blotato subscribes the account at connect time. An account connected before DM automations and follow gating landed does not reliably receive a tap, and runs reach
expired. Reconnect the account to fix it.Instagram renders the confirm button in the mobile app only. A contact reading on instagram.com in a desktop browser sees the gate message with nothing to tap. Write
messageto ask for a typed reply, for example "Reply FOLLOWING once you have", so a desktop audience still advances.
Email Gate Object
Holds dmMessage back until the contact replies with an email address.
message
string
Yes
Gate message text, 1-640 characters.
Blotato sends the gate message, waits up to 72 hours for a reply, and reads the first email address out of it. A reply holding no email address returns the gate message and Blotato waits again. A match saves to the contact and dmMessage sends.
A contact with an email already on file skips the gate. Blotato sends dmMessage without the gate message. An email lands on file when the contact replies with an address to any email gate on the same connected account.
This applies to automations published after September 14, 2026. An automation published earlier sends the gate message every time until you save it again. Pass its current triggers to Update DM Automation, or click Save and Publish in the web app.
Blotato checks the shape of the address, not whether the mailbox exists. Read a captured address through the Webhook Object.
Webhook Object
Endpoint Blotato calls after dmMessage sends.
method
string
Yes
GET, POST, PUT, PATCH, or DELETE.
url
string
Yes
Public http(s) endpoint, 1-2048 characters.
headers
object
No
String keys and string values sent with the request, for example an API key.
Every method except GET carries a JSON body with Content-Type: application/json. GET carries no body.
email
string or null
Email address on file for the contact, captured by an email gate. null when Blotato holds none.
isFollower
boolean or null
Follower status a follow gate last recorded for the contact. null when Blotato never checked.
Both keys are present on every request except GET, with or without a gate on the automation.
Address
The host must resolve to a public address. Private, loopback, link-local, and cloud metadata ranges return error code 20304.
Protocol
http and https only.
Redirects
Blotato does not follow them. Point the automation at the final URL.
Timeout
15 seconds. A timeout logs a warning with error code 20305, the run still completes, and Blotato does not retry the request.
Response body
Blotato reads the first 16 KB.
Error response
A non-2xx status gets logged with its status, and the run still completes.
Failure
A blocked address, a DNS failure, or a connection error fails the run with error code 20304.
Headers
Redacted from run logs. The URL and body appear in the logs, so send keys in a header, not in the URL.
This webhook is separate from the webhook publish target, which sends post content to your endpoint at publish time.
Run Object
contactId
string
Social platform ID of the person who triggered the run.
platform
string
instagram or facebook.
error
object
Set only when status is failed. Holds code, message, and, when available, action and details with recovery context.
createdAt
string
ISO 8601 timestamp when the run started.
updatedAt
string
ISO 8601 timestamp of the most recent run update.
Run Status Values
running
Executing a step.
waiting
Waiting for the DM to settle, or waiting on the contact to answer a gate.
completed
Every step finished, including the DM.
expired
The contact never answered a gate inside its window: 30 days for a follow gate, 72 hours for an email gate. A run also expires when its message never settles within 30 minutes. Nothing further sent.
superseded
A newer run started waiting on the same contact, so this one stopped.
failed
The run stopped on an error, either before or after the DM went out. Read error.
Log Object
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.
A reply during a gate continues the run. While a run waits on a contact's answer, their next DM resumes the waiting run instead of starting a new one. A button tap never starts a run.
See Messaging Windows.
Active Contacts
Every DM an automation sends counts toward your monthly active-contacts limit, the same as a message sent through Send Message. Reaching the same person twice in a month counts once.
See Active Contacts.
Errors
404
The automation was not found. Returned by Get DM Automation, Update DM Automation, Update DM Automation Trigger, and Delete DM Automation. Update DM Automation Trigger also returns it for an unknown trigger ID. An archived automation still returns 200 from Get, Update, and Delete.
422
The automation is invalid for publishing (error code 20303), or the connected account is missing (error code 5000). Setting followGate on a facebook automation returns 20303. So does a live automation with no trigger, two triggers of one type, or no active trigger.
500
Unexpected server error.
A webhook failure surfaces on the run, not on the request. A blocked address, a DNS failure, or a connection error fails the run with error code 20304. A timeout logs a warning with error code 20305, and the run still completes. See Error Reference.
Rate Limits
GET /dm-automations
60 / min
GET /dm-automations/:id
60 / min
POST /dm-automations
30 / min
PATCH /dm-automations/:id
30 / min
PATCH /dm-automations/:flowId/triggers/:triggerId
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
Last updated