Endpoints
Configuring Automations is free. Only the actions they carry out can cost credits.
Your first Automation
This Automation sends a private reply with a link to anyone who comments “link” on any post of an Instagram account. A private reply is free.active when the request returns. A comment such as “Can I get the LINK?” now gets one of the two texts, picked at random, and once_per_person makes sure each commenter gets it only once.
To stop it, pause it. Send active to resume:
How an Automation runs
When a comment or DM arrives on the account, every active Automation with a matching trigger is checked on its own:- Comments and messages from the account itself are skipped.
- For a comment trigger with
post_ids, the comment must be on one of those posts. - The
startstep’s filters must all pass. If they do not, nothing happens and no run is recorded. - Unless
once_per_personor the hourly cap on dm Automations stops it, the run is recorded as a Firing and thestartstep’s actions are carried out.
Triggers
Fields that shape the trigger:
A
dm trigger fires on every dm.received, which can include story replies and story mentions on Instagram. Add a keyword filter to the start step when you only want to answer certain messages.
Facebook sends an edited comment again as a new event. Automations answer new comments only, so an edit never triggers one.
Steps
An Automation is a list of 1 to 10 steps. Every Automation has one step keyedstart, which runs when the trigger fires. Other steps run only when the person taps a button, or when a step’s filters fail and it falls through to another step.
Filters
keyword
Matches the comment or message text against a list of keywords.
How matching works:
- Case, accents, and spacing are ignored. “LINK”, “Link” and “link” all match
link, and “cafe” matches “Café”. Runs of spaces count as one space. containsmatches whole words.linkmatches “send me the link!” but not “linked”. A keyword of 2 or more words matches that phrase. An apostrophe separates words, soinfomatches “l’info”.exactcompares the whole text.linkmatches “Link” but not “link please” or “link!”.- Symbols and emoji need no boundary. On a side where a keyword starts or ends with a symbol or emoji, it matches with no space there:
#promomatches “join#promo”, and 🔥 matches wherever it appears. - Unspaced scripts match anywhere. Chinese, Japanese, Korean, Thai, Lao, Khmer and Burmese are written without spaces between words, so a keyword in those scripts matches wherever it appears in the text.
- Accents are ignored only where they are optional to a reader: in Latin, Greek, Cyrillic, Arabic and Hebrew text. Elsewhere a mark changes the word (Japanese voicing marks, Thai tone marks), so it must match.
follows_account
Passes when the person follows the account. Instagram only.- It cannot be used on
start. Instagram shares whether someone follows the account only after they tap a button or message it, and a comment does not count. Put it on a step reached by a button. - It is checked live when the step runs. A person whose follow status is unknown is treated as following. Only a definite “does not follow” fails the filter, because denying a real follower costs you more than letting one non-follower through, and Instagram can be slow to report a fresh follow.
- On a Facebook account it is refused with
400 validation.filter_unsupported: Facebook does not tell apps whether a person follows a Page.
Actions
Actions run in a fixed order, whatever order you write them in:hide_comment, reply_comment, private_reply, send_dm. A failed action does not stop the next one, and a failed action is not retried.
Each cost is the cost of the same API call. See what counts as an interaction.
Set the field named by
type with the texts to send. hide_comment takes no field:
texts holds 1 to 10 variants, each 1 to 1,000 characters, and one is picked at random each time the action runs. On Instagram, a private reply or DM text above 1,000 bytes of UTF-8 is refused by Instagram, and the failure is recorded on the Firing. When the step has buttons, each private_reply and send_dm text is at most 640 characters.
Steps after start run after a button tap, which opens the messaging window but has no comment to act on, so they can use only send_dm.
Buttons and multi-step flows
Buttons appear under the step’sprivate_reply or send_dm message. A step with buttons must have one of those two actions. On Facebook, the buttons of a send_dm action are not delivered, because a Facebook DM send delivers only the text. The buttons on the first private_reply are delivered.
This comment Automation answers “menu” with a private reply carrying three buttons. Two of them lead to steps that send a DM:
prices step and sends 1 DM (1 interaction credit). The Opening hours answer offers Prices again, since buttons can loop: each loop needs a person to tap.
Rules for the graph:
- Every
next_stepandfallthrough_stepmust name a step that exists. - On a comment Automation, a button cannot lead back to
start. - A step reached by a tap checks its own filters when the tap arrives. A tap carries no text, so a keyword filter on a step after
startnever passes. Usefollows_accountthere, andfallthrough_stepfor what to do when it fails.
once_per_person and from the hourly cap on dm Automations: they continue the run the trigger started.
The Follow gate
The Follow gate sends a link only to people who follow the account. It is a shortcut for Instagram comment Automations: sendfollow_gate instead of steps, and SocialAPI builds the steps for you.
The gate is stored as three ordinary steps:
GET returns these steps, with no trace of follow_gate, so you edit a gate like any other Automation. Sending follow_gate together with steps, or with the dm trigger, returns 400 validation.follow_gate_invalid. On a Facebook account it returns 400 validation.filter_unsupported, since the gate relies on follows_account.
Limits and safety
What keeps an Automation from misbehaving:
- Your own activity never triggers it. Comments and messages sent by the account itself are skipped, so an Automation’s replies cannot trigger it again. On Facebook the account is the Page: a Page admin commenting from their personal profile does trigger it.
- A dm Automation answers one person at most 5 times an hour. This stops two auto-responders from replying to each other forever. Button taps are not counted.
- Each event runs at most once per Automation, even when the platform delivers it twice.
- The account needs the permissions the Automation uses. Creating an Automation, changing its
steps, or setting it toactivereturns400 validation.permission_missingwhen its trigger or an action needs a permission outside the account’seffective_permissions.error.meta.permissionnames it. An Automation is not paused when the account later loses a permission: its actions fail on the Firing withaccount.permission_missing. - A past-due account gets no actions. While your subscription is past due, Automations do nothing and record no Firings, the same way the API returns
402. - Platform rules still apply. An action the platform or SocialAPI refuses (a private reply on a comment older than 7 days, a DM outside the messaging window, an exhausted interaction allowance) fails with the same error code the API call returns, and the failure is recorded on the Firing.
Firings
A Firing is one run of an Automation against one event: a comment, a DM, or a button tap. It records the step that ran and the outcome of each action. Firings are kept for 30 days. Aonce_per_person Automation keeps its record of who it reached after the Firings expire, so it never answers the same person twice.
Firings are listed newest first.
limit is 1 to 100 (default 20); pass next_cursor as cursor to fetch the next page, and stop when it is empty.
The Automation itself carries running totals: fired_count (runs, taps included), sent_count (actions that succeeded) and failed_count (actions that failed).
Debug a failed action
GET /v1/automations/{id}and checkfailed_count.- List the Firings and find an outcome with
"status": "failed". - Look up its
error_codein Errors. It is the code the same API call would have returned, so it means the same thing. For example,platform.instagram.private_reply_ineligiblemeans the comment is older than 7 days or already had a private reply, perhaps from another Automation or from your own API call.platform.instagram.window_closedmeans asend_dmwent outside the messaging window. - Fix the cause, for example by removing an overlapping Automation. The failed action is not retried.
When nothing fired
A comment or DM that records no Firing at all was skipped before any action ran. Check, in order:- The Automation is
active. - The account has the permission for the trigger:
comments.readfor a comment Automation,messages.readfor a dm Automation. Without it, the platform’s events are dropped before they reach the Automation. - For a comment trigger with
post_ids, the comment is on one of those posts. - The text passes the
startstep’s filters. A non-matching event records nothing. - With
once_per_person, the person has not been reached already. - For a dm Automation, it has not already run 5 times for that person in the last hour.
- The comment or message is not from the account itself (on Facebook, the Page).
- The event is not an edited Facebook comment.
- Your subscription is not past due.
comment.received and dm.received webhooks. If those stop arriving for an account, for example because it needs reconnecting, its Automations stop too.
Scopes
Two scopes cover Automations themselves:
An Automation sends on your behalf, so a scoped key also needs the scope each of its actions’ own API call needs. Without it, the request returns
403 auth.insufficient_scope naming the missing scope.
On
PATCH, renaming or pausing needs only automations:write, so a key can always stop an Automation it can see. Resuming, or changing steps, post_ids or once_per_person, also needs each action’s scope. Deleting needs only automations:write.
A brand-restricted key sees only the Automations on its brands’ accounts. Creating one on another brand’s account returns 404 account.not_found.
Automations and your webhooks
Automations do not change what your webhooks receive. Every event goes to your webhook endpoints and to your Automations alike:- Triggers are still delivered. A comment or DM an Automation answers still arrives as
comment.receivedordm.received. If your own handler also replies to those events, the person gets both replies, so let one or the other answer each kind of event. - Button taps arrive as
dm.postback. A tap on an Automation’s postback button reaches your endpoint like any other tap, with an opaquemetadata.payloadthat starts withsa1.. The Automation handles the tap, so ignore those payloads, and do not start your own payloads withsa1.. - Sent DMs echo as
dm.sent. DMs an Automation sends are messages the account sent through SocialAPI, so on Instagram and Facebook they produce the samedm.sentecho as a DM you send through the API. Nothing in the event tells the two apart. - There are no Automation events. To see what an Automation did, read its Firings.
Use from an AI agent
An agent connected to the SocialAPI MCP server can create and manage Automations: see the MCP tools reference. The tool descriptions carry the main rules on this page, so an agent can build a valid definition from a plain request such as “When someone comments ‘menu’ on my Instagram posts, send them a private reply with a link to our menu.”Related
- Comments for replying, private replies, and hiding through the API
- Direct messages for the messaging window and sending DMs through the API
- Webhook events for the events your own code receives
- Account permissions for the permissions an account needs
- Scoped API keys for least-privilege keys
- Errors for every error code an action can record
- Unified inbox for the inbox areas an Automation answers