---
title: "Get automation details"
method: GET
path: "/v1/messaging/comment-automations/{automationId}"
tags: ["Comment Automations"]
---

# Get automation details

`GET /v1/messaging/comment-automations/{automationId}`

## Request

- Base URL: `https://apihub.co.il`
- URL: `https://apihub.co.il/v1/messaging/comment-automations/{automationId}`
- Auth: HTTP bearer

Returns an automation with its configuration, stats, and recent trigger logs.

**Billing:** Read (free unless it says otherwise) · **Rate limit:** 120/min

## Path parameters

- `automationId` string, required

## Headers

- `Idempotency-Key` string
- `X-Tag` string

## Response `200`

Completed

- object
  - `id` string: Execution id — stable across internal retries; use it with GET /v1/executions/{id}
  - `status` 'pending' | 'processing' | 'completed' | 'partial' | 'failed' | 'cancelled' | 'timeout'
  - `operation` string
  - `tag` string, nullable: Your X-Tag, if sent
  - `created_at` string, date-time
  - `completed_at` string, date-time, nullable
  - `output` object: Operation result (see each operation). While a Studio render is processing: `stage` (queued · transcribing · downloading · preparing · cleaning_voice · mixing_audio · rendering · finishing), `phase` (the engine's: download · prepare · voice · audio · encode · qa · upload, or null), `progress` (a percent, 0–100) and `progress_fraction` (0–1), `eta_seconds` (seconds left, never below 0) and `estimate_seconds`
    - `logs` object[]: The 20 most recent trigger logs.
      - `id` string
      - `error` string, nullable: DM error message when status is failed, or the reason when it is skipped.
      - `source` 'comment' | 'live_comment' | 'story_reply' | 'story_mention' | 'dm' | 'null', nullable: Which door triggered this send. Null on rows written before this field existed (all of those are comment-triggered).
      - `status` 'pending' | 'sent' | 'failed' | 'skipped' | 'gated': DM outcome. 'pending' = the automation has a dmDelaySeconds and the response is queued but not sent yet. 'gated' = the follow-gate confirmation DM went out and we are waiting for the tap; it flips to 'sent' or 'skipped' when they tap. 'skipped' also covers repeatPolicy, cooldown and dedupeSameTextHours suppressions, with the reason in error.
      - `clickedAt` string, date-time, nullable: This recipient's first click on a tracked link (what uniqueClicks counts).
      - `commentId` string
      - `createdAt` string, date-time
      - `nextDueAt` string, date-time, nullable: When the next queued send fires. Present only while something is still pending.
      - `clickCount` integer: This recipient's total clicks on tracked links.
      - `mediaError` string, nullable: Why the dmMedia follow-up was not delivered. The DM itself still counts as sent.
      - `commentText` string, nullable
      - `commenterId` string
      - `hideSkipped` string, nullable: Why actions.hideComment did not hide the comment. Null when it did or was not configured.
      - `likeSkipped` string, nullable: Why actions.likeComment did not like the comment. Null when it did or was not configured.
      - `commenterName` string, nullable
      - `platformError` object, nullable: Platform error codes of the failed DM (Meta `code` and `error_subcode`), when the platform sent them. Null on successful rows and on rows written before this field existed.
        - `code` integer
        - `subcode` integer
      - `gateResolvedAt` string, date-time, nullable: When the follow-gate tap was claimed.
      - `audienceOutcome` 'passed' | 'blocked' | 'gate_sent' | 'gate_passed' | 'gate_failed' | 'null', nullable: How the audience rule resolved. Null on automations without one.
      - `gateButtonStatus` 'delivered' | 'rejected' | 'omitted' | 'null', nullable: Whether the follow-gate button reached the commenter: 'rejected' = Meta refused the gate DM, 'omitted' = the prompt went out as plain text because it was over 640 characters. Null when no gate DM was sent.
      - `commentReplyError` string, nullable: Public-reply error message if commentReplyStatus is failed
      - `commenterUsername` string, nullable
      - `commentReplyStatus` 'pending' | 'sent' | 'failed' | 'skipped' | 'null', nullable: Outcome of the optional public reply on the triggering comment. With publicReplyPolicy after_dm, 'skipped' if no commentReply was configured or if the DM failed (the public reply is not attempted in that case).
      - `commenterIsFollower` boolean, nullable: Follow relationship at decision time. Null when Instagram would not tell us (the commenter never messaged the account).
      - `publicReplyPostedAt` string, date-time, nullable: When the public reply was posted. Null when it was not.
      - `privateReplyConsumed` boolean, nullable: True when the failed send spent the comment's single private reply (Instagram subcode 1545133 or 2534023, or Meta code 10900 on Instagram and Facebook), the same rule as `details.privateReplyConsumed` on the private-reply endpoint. Null on direct DMs and on rows written before this field existed.
      - `commenterFollowerCount` integer, nullable
    - `success` boolean
    - `automation` object
      - `id` string
      - `name` string
      - `stats` object: Running counters for the automation.
        - `read` integer: DMs confirmed read (IG messaging_seen / Messenger message_reads).
        - `dmsSent` integer
        - `delivered` integer: DMs confirmed delivered (Messenger; IG emits no delivery receipt).
        - `dmsFailed` integer
        - `triggered` integer: Matched triggers that reached the audience or send stage.
        - `linkClicks` integer: Total clicks on tracked links (bots/prefetch excluded).
        - `trackedSends` integer: DMs sent with a trackable (wrapped) link. CTR denominator: divide clicks by this, not dmsSent. Lags dmsSent for campaigns that predate click tracking.
        - `uniqueClicks` integer: Distinct people who clicked a tracked link.
        - `followGateSent` integer
        - `uniqueContacts` integer
        - `audienceSkipped` integer: Triggers the audience rule did not answer with the DM.
        - `followGateFailed` integer
        - `followGatePassed` integer
      - `postId` string
      - `actions` object: Actions taken on the matched comment itself (comment trigger only; ignored on the story-reply and DM doors). They never block or fail the DM: when one cannot run, the log row says why (`likeSkipped`, `hideSkipped`).
        - `hideComment` boolean: Hide the comment once the first DM has been attempted, so the private reply is never sent to an already hidden comment.
        - `likeComment` boolean: Like the comment as the account. Facebook always; Instagram only for accounts connected through Facebook Login and allowlisted for likes while Meta reviews the permission. Otherwise the like is skipped and logged.
      - `buttons` object[]: Inline DM buttons (up to 3). Omitted when none are set.
        - `url` string, uri: Target URL (required when type is url)
        - `type` 'url' | 'postback' | 'phone', required
        - `phone` string: Phone number, e.g. +14155551234 (required when type is phone; Facebook only)
        - `title` string, required: Button label (20 chars max)
        - `payload` string: Postback payload delivered via the messaging_postbacks webhook (required when type is postback)
      - `dmMedia` object: An image, video, audio clip or file sent right after the DM text as a second message (a Meta message carries one body, so text and attachment are two sends). On the comment trigger Meta may refuse the second message until the commenter replies; the DM then still counts as sent and the log row carries `mediaError`.
        - `url` string, uri, required: Publicly reachable http(s) URL Meta downloads the media from.
        - `type` 'image' | 'video' | 'audio' | 'file', required
      - `trigger` 'comment' | 'live_comment' | 'story_reply' | 'story_mention'
      - `audience` object: Who a comment automation answers. Instagram only - Meta exposes the follow relationship on no other platform, and only for people who have MESSAGED the account (a comment grants no consent). `whenUnknown` is therefore the important setting: it decides what happens for a first-time commenter.
        - `tapToUnlock` boolean: Send `followGate.message` with its button to EVERY commenter and deliver the real DM when they tap it, with no follow check at any point. Cannot be combined with a `followerStatus` other than `any` or with `minFollowerCount` (400); `whenUnknown` is ignored. Instagram only. A PATCH that sends `audience` without this field clears it.
        - `whenUnknown` 'send' | 'skip' | 'verify': What to do when Instagram will not reveal the follow relationship. * `send` (default) - deliver the DM anyway (fails open). * `skip` - stay silent. * `verify` - send `followGate.message` with a confirm button. Tapping it is a message, which grants consent, so the re-check on the tap resolves and the real DM (or `followGate.notFollowingMessage`) follows automatically.
        - `followerStatus` 'any' | 'follower' | 'non_follower'
        - `minFollowerCount` integer: Skip commenters with fewer followers than this. Omit for no size rule.
      - `clickTag` string
      - `isActive` boolean
      - `keywords` string[]
      - `platform` 'instagram' | 'facebook' | 'tiktok' | 'threads' | 'linkedin' | 'youtube'
      - `template` object: A Meta generic template (product card) sent as the automation's first DM. It REPLACES the plain `dmMessage` bubble: a Meta message carries one body shape, and a comment gets exactly one private reply, so the card and the text cannot both be delivered. Put your selling copy in `subtitle`. Mutually exclusive with `buttons` (sending both is a 400). Works on every Instagram and Facebook trigger. Up to 10 elements, rendered as a horizontally swipeable carousel. Rendering confirmed on the Instagram and Messenger mobile apps.
        - `type` 'generic', required
        - `elements` object[], required
          - `title` string, required: Card headline (80 chars max). Also used as the Inbox preview for the sent DM.
          - `buttons` object[]: Up to 3 card buttons. A generic template has NO phone button, on either platform. `url` buttons are click-tracked when linkTracking is on.
            - `url` string, uri: Target URL (required when type is url)
            - `type` 'url' | 'postback', required
            - `title` string, required
            - `payload` string: Postback payload delivered via the messaging_postbacks webhook (required when type is postback)
          - `imageUrl` string, uri: Publicly reachable http(s) image rendered large above the card.
          - `subtitle` string: Card description, e.g. the price or a short pitch (80 chars max).
        - `imageAspectRatio` 'horizontal' | 'square': Facebook only. How Messenger renders each element imageUrl: horizontal (1.91:1, the default) or square (1:1). Instagram has no such setting, so an Instagram automation carrying it is a 400.
      - `accountId` string
      - `createdAt` string, date-time
      - `dmMessage` string: Omitted on reply-only platforms (tiktok, threads, linkedin, youtube), together with every other DM-leg field.
      - `matchMode` 'exact' | 'contains' | 'word': How a keyword is compared with the comment. 'contains' (default) matches anywhere, even inside another word (keyword 'app' fires on 'happy'). 'word' matches the keyword only as a standalone word. 'exact' requires the whole comment to be exactly the keyword.
      - `postTitle` string
      - `updatedAt` string, date-time
      - `followGate` object: Copy for the follow gate. Sensible defaults are used for any field left empty.
        - `message` string: Confirmation DM sent when whenUnknown=verify or tapToUnlock=true. The default copy asks for a follow under whenUnknown=verify and only for the tap under tapToUnlock.
        - `buttonLabel` string: Confirm button label. Defaults to "I'm following" (whenUnknown=verify) or "Unlock" (tapToUnlock).
        - `notFollowingMessage` string: Sent to a commenter we know does not follow (followerStatus=follower), and after a confirm tap that does not unlock the DM. When following is what would unlock it, the message carries the confirm button so they can re-check once they follow; above 640 characters it goes out as plain text without the button. Omit to stay silent on a keyword comment; a confirm tap always gets an answer (a default message is used).
      - `commentReply` string
      - `linkTracking` boolean
      - `quickReplies` object[]
        - `title` string, required
        - `payload` string, required: Delivered back via the messaging webhook when tapped.
        - `imageUrl` string, uri
      - `repeatPolicy` object: Whether a commenter can receive this automation's DM more than once. * `once` (default) - one DM per person per door, ever. * `every_comment` - every new matching comment is eligible again. One comment is still answered at most once. `cooldownHours` suppresses a repeat sent to the same person within that many hours.
        - `mode` 'once' | 'every_comment', required
        - `cooldownHours` integer: every_comment only (400 with once). Hours after a DM during which the same person is not DMed again.
      - `typoTolerance` boolean: Only with matchMode=word: also fire on close misspellings of a keyword (one edit for 4-7 character keywords, two from 8 up). Keywords shorter than 4 characters are never fuzzy-matched.
      - `alsoMatchInDms` boolean: Whether these keywords also fire on a plain inbound DM.
      - `dmDelaySeconds` integer: Seconds waited after the trigger before the DM is sent. Absent when the DM goes out immediately.
      - `platformPostId` string
      - `excludeKeywords` string[]: Comments containing one of these never trigger the automation, even when a trigger keyword also matches. Compared using the same matchMode.
      - `publicReplyPolicy` 'after_dm' | 'always'
      - `dedupeSameTextHours` integer: Same-text dedupe window in hours. Omitted when off.
      - `dmMessageVariations` string[]: Alternate DM texts rotated at random with dmMessage. Omitted when none.
      - `commentReplyVariations` string[]: Alternate public replies rotated at random with commentReply. Omitted when none.
      - `commentReplyDelaySeconds` integer: Seconds waited before the public reply is posted. Absent when it follows the DM immediately.
  - `error` string, nullable
  - `usage` object
    - `credits_charged` number, nullable
    - `credits_reserved` number
    - `estimated_credits` number
    - `cost_source` 'provider_reported' | 'calculated' | 'estimated' | 'null', nullable
    - `provider_usage` object, nullable: Normalised consumption, e.g. { VIDEO_SECOND: 22.4 }
  - `balance` object
    - `available` number
    - `reserved` number

## Other responses

- `400`: Invalid input
- `402`: Insufficient credits / project budget
- `404`: Resource not found (or not yours)
- `429`: Rate limited
- `503`: Service temporarily paused

---

[API](https://skmtc.dev/apihub/apis/apihub-one-api-for-chat-image-video-ai.md) · [All operations](https://skmtc.dev/apihub/apis/apihub-one-api-for-chat-image-video-ai/llms.txt) · [OpenAPI document](https://skmtc.dev/apihub/apis/apihub-one-api-for-chat-image-video-ai/revisions/a8caa42835ce?raw)
