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

# Get a comment automation

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

## Request

- Base URL: `https://api.postzen.dev`
- URL: `https://api.postzen.dev/v1/comment-automations/{automationId}`
- Auth: HTTP bearer

Returns the automation and 20 newest logs. Out-of-scope ids return 404 automationNotFound. Instagram only. A comment permits one private reply ever, within 7 days. Story replies use normal DMs inside the 24-hour messaging window. Buttons and image cards (template) fall back to text with title and URL lines if Meta rejects the template. Reconnect the account on 403 platformCapabilityMissing to grant instagram_business_manage_comments and instagram_business_manage_messages.

## Path parameters

- `automationId` string, required

## Response `200`

Get a comment automation.

- CommentAutomationDetailResponse
  - `automation` CommentAutomation, required
    - `accountId` string, required: Connected Instagram account id. Immutable after creation.
    - `profileId` string, required: If supplied, must equal the account profile.
    - `name` string, required: Trimmed name.
    - `trigger` 'comment' | 'story_reply', required
    - `platformPostId` string: Instagram media or story id. Mutually exclusive with postId; omit both for account-wide matching.
    - `postId` string: Owned PostZen post with an Instagram target on this account. Resolves providerPostId at match time, including posts not yet published. Mutually exclusive with platformPostId.
    - `postTitle` string
    - `keywords` string[], required: Trimmed and deduplicated case-insensitively. Empty matches every comment.
    - `matchMode` 'exact' | 'contains' | 'word', required
    - `excludeKeywords` string[], required: Vetoes matching using the same matchMode; trimmed and deduplicated case-insensitively.
    - `typoTolerance` boolean, required: word mode only: Damerau-Levenshtein per word, 1 edit for 4–7 characters, 2 edits for 8+, none for fewer than 4.
    - `dmMessage` string, required: Plain text: at most 1000 UTF-8 bytes. With buttons: at most 640 characters.
    - `dmMessageVariations` string[], required: Same limits as dmMessage. Uniform random choice from the base message and variations.
    - `buttons` CommentAutomationButton[], required
      - `type` 'url', required
      - `title` string, required
      - `url` string, uri, required: Public HTTP(S) URL; private hosts and embedded credentials are rejected.
    - `template` CommentAutomationTemplate: Meta generic template: an image card sent instead of dmMessage and buttons. If Meta rejects it for a send, PostZen resends the card's title, subtitle, image URL, and button links as plain text and marks the log buttonsDropped.
      - `type` 'generic', required
      - `imageAspectRatio` 'horizontal' | 'square'
      - `elements` CommentAutomationTemplateElement[], required: One card per element. Instagram renders several as a swipeable carousel.
        - `title` string, required: Card title. Trimmed.
        - `subtitle` string: Optional line under the title.
        - `imageUrl` string, uri, required: Public HTTPS image URL that Meta fetches. A `publicUrl` from `POST /v1/media/presign` qualifies and is kept for as long as an automation uses it; upload the bytes before saving the automation.
        - `buttons` CommentAutomationButton[]: Up to three link buttons under the card.
          - `type` 'url', required
          - `title` string, required
          - `url` string, uri, required: Public HTTP(S) URL; private hosts and embedded credentials are rejected.
    - `commentReply` string: Optional public reply, sent only after successful comment DM. Ignored for story_reply.
    - `commentReplyVariations` string[], required: Uniform random choice independent of the DM.
    - `dmDelaySeconds` integer, required
    - `commentReplyDelaySeconds` integer, required: Effective delay is max(dmDelaySeconds, commentReplyDelaySeconds).
    - `isActive` boolean, required
    - `linkTracking` false, required
    - `id` string, required
    - `platform` 'instagram', required
    - `alsoMatchInDms` false, required
    - `stats` object, required
      - `totalTriggered` integer, required
      - `totalSent` integer, required
      - `totalFailed` integer, required
    - `createdAt` string, date-time, required
    - `updatedAt` string, date-time, required
    - `audience` CommentAutomationAudience, required: 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). So any rule here sends the Opening DM first (`openingDm`, defaults when unset) and checks the person when they tap its button. Story replies are already messages and are checked right away.
      - `followerStatus` 'any' | 'follower' | 'non_follower'
      - `minFollowerCount` integer: Omit for no size rule. Zero is stored as absent.
      - `whenUnknown` 'send' | 'skip' | 'verify': Applies after the Opening DM tap, when Instagram still will not reveal the follow relationship. `send` (default) - deliver the DM anyway (fails open). `skip` - stay silent. `verify` - treat them as not following, so followerStatus=follower sends the follow request (`followGate.message`); tapping its button re-checks.
    - `openingDm` CommentAutomationOpeningDm, required: A first DM with a button, sent as the private reply to the comment. Tapping the button counts as the person messaging you, which opens the 24-hour messaging window and lets Instagram reveal whether they follow you. Required for any `audience` rule: when `audience` filters by followers and no `openingDm` is set, the defaults are used. Ignored for story replies, which already count as a message.
      - `message` string: Trimmed. Empty or omitted uses the default.
      - `buttonLabel` string: Trimmed. Empty or omitted uses the default.
    - `followGate` CommentAutomationFollowGate: Copy for the follow request (audience.followerStatus=follower). Sensible defaults are used for any field left empty.
      - `message` string: The follow request sent after the Opening DM tap to people who do not follow yet.
      - `buttonLabel` string: Label of the button on the follow request. Tapping it re-checks the follow.
      - `notFollowingMessage` string: Sent when they tap the follow request button but still do not follow. The button stays, so they can follow and tap again.
  - `logs` CommentAutomationLog[], required
    - `id` string, required
    - `commentId` string, required
    - `platformPostId` string
    - `commenterId` string, required
    - `commenterName` string
    - `commentText` string
    - `skipReason` 'already_sent_to_contact' | 'automation_inactive' | 'not_follower' | 'is_follower' | 'below_min_followers' | 'follow_status_unknown' | 'contact_blocked' | 'contact_unsubscribed'
    - `error` string
    - `sentMessageId` string
    - `commentReplyError` string
    - `source` 'comment' | 'story_reply', required
    - `status` 'pending' | 'sent' | 'failed' | 'skipped' | 'gated', required: gated: a button DM (Opening DM or follow request) went out and we are waiting for the tap; it flips to sent or skipped when they tap. A tap from someone who still does not follow keeps it gated for another tap.
    - `buttonsDropped` boolean
    - `commentReplyStatus` 'pending' | 'sent' | 'failed' | 'skipped'
    - `nextDueAt` string, date-time
    - `createdAt` string, date-time, required
    - `updatedAt` string, date-time, required
    - `gateStage` 'opening' | 'follow': Which button DM a gated log is waiting on: `opening` (the Opening DM) or `follow` (the follow request).
    - `gateMessageId` string
    - `commenterIgsid` string
    - `gateSentAt` number: Unix timestamp in milliseconds.
    - `gateTappedAt` number: Unix timestamp in milliseconds.
    - `gateAttempts` integer: Follow requests and not-following replies sent after taps.
    - `followerCount` integer
    - `followStatus` 'follower' | 'non_follower' | 'unknown'
    - `gateDropped` boolean: Meta rejected the Opening DM template and delivery failed open: the DM was sent without the audience check.

## Other responses

- `400`: Invalid request.
- `401`: Missing or invalid API key.
- `403`: The API key does not have sufficient permission or profile access.
- `404`: Resource not found.
- `429`: Rate limit exceeded. Retry after the interval indicated by the `Retry-After` header.
- `500`: Unexpected server error.

---

[API](https://skmtc.dev/postzen/apis/postzen-public-api.md) · [All operations](https://skmtc.dev/postzen/apis/postzen-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/postzen/apis/postzen-public-api/revisions/40863e3710ec?raw)
