Skip to main content

Documentation Index

Fetch the complete documentation index at: https://www.ayrshare.com/docs/llms.txt

Use this file to discover all available pages before exploring further.

Beta. The Automations API is in beta and we are actively collecting feedback. Endpoints, payloads, and limits may change as we iterate. Please send feedback and bug reports to support so we can prioritize the right improvements.
The Automations endpoints let you define rules that automatically react to incoming Instagram engagement. Each automation pairs one or more triggers (the event that fires the rule) with one or more actions (what happens when it fires). A single rule can listen for multiple triggers and dispatch multiple actions — fire a webhook into your analytics pipeline AND send a DM from the same engagement. The engine runs entirely inside Meta’s policy envelope (no follow-triggered DMs, no first-message-to-strangers, no bulk outbound) and inherits Ayrshare’s per-account rate limits, per-recipient deduplication, and idempotent webhook ingestion.

How it works

1

Create an automation

POST /automations with the triggers and actions you want. The automation activates immediately.
2

An end user engages

Someone comments on your post, replies to your story, sends a DM, or reacts to a DM. Meta delivers the webhook to Ayrshare.
3

Ayrshare matches and dispatches

The engine looks up every rule matching the event, checks per-action deduplication and your daily DM cap, then runs each action. A 20–60 second jitter is applied to DM sends to stay inside Instagram’s anti-spam heuristics.
4

Inspect what fired

GET /automations/:id/activity returns the audit log — every dispatch attempt, the per-action results, and any errors.

Triggers

You can attach up to 50 triggers to one automation. Each trigger is a discriminated union on the type field; type-specific fields live at the same level. All triggers are Instagram-only in v1.
TypeFires whenConfig
comment_keywordA comment matching a keyword lands on a specific postpostId (required); keywords (required, ≥1 entry)
story_replyA user replies to a story via DMstoryId (optional)
dm_reactionA user reacts to one of your DMs with an emojiemoji (optional — omit to fire on any emoji)
dm_keywordA user sends a DM whose text matches a keywordkeywords (required, ≥1 entry)
Keyword matching is case-insensitive and whole-word. An event satisfies a keyword-filtered trigger if it contains any one of the configured keywords. Omit storyId on a story trigger to fire on every story for the connected account.

Actions

You can attach up to 50 actions to one automation. They run sequentially; each result is recorded on the activity row.
TypeEffectConfig
send_dmSends an Instagram DM to the user who triggered the rule, using a templated message.message (required, templated)
fire_webhookPOSTs the automation context to your account-level webhook URL (configure via POST /hook/webhook).(none — payload shape is fixed; see below)
send_emailQueues an email via the platform’s mail pipeline.to (required, email); subject (optional, templated); message (required, templated)

Per-action dedup window

Every action — regardless of type — additionally accepts an optional top-level dedupWindowMinutes field that overrides the default 7-day per-recipient dedup window for that action only.
  • Set to 0 to disable dedup entirely for that action (typical for fire_webhook / send_email where the receiver expects every event).
  • Capped at 525600 (one year).
Action with a 24h dedup override
{
  "type": "send_dm",
  "message": "Thanks {{recipient_username}}!",
  "dedupWindowMinutes": 1440
}

fire_webhook payload

When fire_webhook runs it POSTs a JSON body to your account-level webhook URL:
{
  "automationId":      "auto_9xKp2Lm4nQ",
  "triggerId":         "trg_a1b2c3",
  "trigger":           "comment_keyword",
  "platform":          "instagram",
  "recipientId":       "17841401234567890",
  "recipientUsername": "jane_doe",
  "keyword":           "LINK",
  "timestamp":         "2026-05-12T09:14:22.000Z"
}
recipientUsername and keyword are null when the trigger doesn’t populate them (e.g. dm_keyword doesn’t carry a username on Meta’s payload; story_reply doesn’t have a keyword).

Template variables

send_dm.message, send_email.subject, and send_email.message support {{placeholder}} substitution. Unknown placeholders are rejected at create/update time (error 467) so a typo never silently leaks the literal {{foo}} into a customer-facing message.
PlaceholderResolves to
{{recipient_username}}The engaging user’s Instagram handle (when the webhook carries it)
{{recipient_id}}The engaging user’s Instagram participant ID (IGSID)
{{recipient_name}}Reserved; resolves to empty until a future enrichment source populates it
{{sender_username}}Your linked Instagram username
{{sender_name}}Your linked Instagram display name
{{comment_text}}The text of the comment / DM / story reply that fired the trigger
{{comment_id}}The platform id of the comment / message that fired
{{comment_sent_at}}ISO 8601 timestamp of the event (when available)
{{matched_keyword}}The keyword that matched (or the emoji string for dm_reaction)
{{platform}}Platform identifier (e.g. instagram)
{{trigger_type}}Trigger type (e.g. comment_keyword)
No sender_email / recipient_email. These are deliberately not exposed — your billing email has no legitimate place in a DM to a stranger, and Meta does not provide the recipient’s email on any IG webhook. Avoiding the placeholders prevents accidental disclosure.
Example template:
Hey {{recipient_username}}, thanks for the comment "{{comment_text}}" — here is the link you wanted: https://example.com

Rate limits and caps

PlanActive automationsDaily DM cap
Business101,000
Enterprise505,000
Caps apply per parent Ayrshare account. When a DM cap is hit the activity row records status rate_limited and no DM is sent. The active-automation cap is enforced on both POST (create) and on PUT when re-activating (active: false → true) — both surface error code 470. Structural caps on a single automation: 1–50 triggers, 1–50 actions. Instagram itself caps DMs at roughly 200/hour per account. The engine paces dispatch with a 20–60 second jitter to stay safely under this.

Activity statuses

A row in GET /automations/:id/activity carries a top-level status plus a per-action status inside actionResults[]:
StatusMeaning
pendingJust written; the worker hasn’t picked it up yet
in_flightWorker is currently dispatching
sentEvery action succeeded
failedAt least one action failed (and none hit an auth error)
auth_errorThe Instagram access token was invalid; the DM was not retried
rate_limitedThe daily DM cap (tier or per-profile) was hit; no DM was sent
deduplicatedThis action already fired to this recipient inside its dedup window
skippedThe automation became inactive or was deleted between fan-out and dispatch
pending and in_flight are transient; everything else is terminal.

Error codes

CodeHTTPMeaning
462400Missing required field: trigger
463400Invalid trigger type
464400Missing postId (required for comment_keyword)
465400Missing keywords (required for comment_keyword)
466400Missing message (required for send_dm / send_email)
467400Unknown template variable in message / subject
468403Business or Enterprise plan required
469404Automation not found (also returned when the caller doesn’t own it)
470429Active automation cap reached for your plan tier
471404No social account linked on the requested platform for this profile
472403Feature not yet available on your account — contact us for early access

What Meta does NOT allow

A few commonly-requested capabilities are not supported because Meta doesn’t permit them on the public Instagram API:
  • Auto-DM on new followers. Instagram does not publish a follow webhook.
  • First-message DMs to strangers. Meta requires the recipient to initiate contact (comment, reply, DM, reaction) before a business account can message them — which is exactly what every supported trigger here represents.
  • Bulk outbound campaigns. Hourly DM caps and anti-abuse heuristics apply at the platform level.

Multi-profile usage

The endpoints respect the profileKey header. Pass a child profile’s key and the automation is created/managed under that profile. Rate limits split across profiles via a per-profile sub-cap so one chatty profile doesn’t drain the parent account’s quota.

FAQ

No. Instagram does not publish a follow webhook, and Meta does not allow third-party apps to send a DM to a user who has not initiated a conversation. Every supported trigger (comment_keyword, story_reply, dm_reaction, dm_keyword) satisfies the “user contacted you first” requirement.
The activity row records status auth_error and the DM is not retried. Relink the account, then the next matching engagement will fire normally.
Each send_dm dispatch is scheduled 20–60 seconds after the engagement to look organic to Instagram’s anti-spam systems. fire_webhook and send_email actions do NOT have jitter. The activity row’s created timestamp is when the trigger matched; completedAt is when dispatch finished.
Activity rows are retained indefinitely for trace and analytics. The GET /automations/:id/activity endpoint returns rows from the last 30 days for performance. (The dedup guard uses its own per-action window — defaulting to 7 days — which is unrelated to the activity lookback.)
No. Delete is a soft-delete: the master row is flagged deleted, no new dispatches occur, but historical activity rows remain readable via the activity endpoint.

Endpoints