---
title: "Comment received event"
method: POST
path: "comment.received"
tags: ["Webhook Events"]
---

# Comment received event

`POST comment.received` (webhook)

Fired when a new comment is received on a tracked post. Delivered for
Instagram, Facebook, Threads, YouTube, LinkedIn, Bluesky, Reddit and
TikTok. X/Twitter does NOT fire this event. Instagram, Facebook and
TikTok arrive in real time from the platform's own webhook; the rest are
poll-driven, so delivery is not instant. TikTok needs an account
connected through the TikTok for Business app.

## Payload

- WebhookPayloadComment — Webhook payload for comment received events (Instagram, Facebook, Threads, YouTube, LinkedIn, Bluesky, Reddit, TikTok). X/Twitter does NOT fire this event. TikTok events carry only the author id: the comment.update webhook has no username, picture or owner flag.
  - `id` string, required — Stable webhook event ID
  - `event` 'comment.received', required
  - `comment` object, required
    - `id` string, required — Platform comment ID
    - `postId` string, nullable, required — Internal post ID (null for posts not published through Zernio)
    - `platformPostId` string, required — Platform's post ID
    - `platform` 'instagram' | 'facebook' | 'threads' | 'youtube' | 'linkedin' | 'bluesky' | 'reddit' | 'tiktok', required
    - `text` string, required — Comment text content
    - `author` object, required
      - `id` string, required — Author's platform ID
      - `username` string
      - `name` string
      - `picture` string, nullable
      - `isOwnAccount` boolean — True when this comment was authored by the connected account itself. Populated on the Instagram and Facebook realtime webhooks (Meta re-delivers the account's own replies as comments events) and on TikTok, where it is inferred: comments created through this API are always flagged, and once the account's own author identifier is known (from one of those or from a comments listing) every author is compared against it. Absent means not evaluated, never "not the account".
      - `instagramProfile` object — Instagram only, best-effort. Present ONLY for commenters who have messaged the account before: Meta gates the follow relationship behind messaging consent, and commenting does not grant it. Absent otherwise - treat a missing object as "unknown", never as "not a follower". To check on demand, call GET /v1/accounts/{accountId}/follow-status/{userId}.
        - `isFollower` boolean, nullable — The commenter follows this account.
        - `isFollowing` boolean, nullable — This account follows the commenter.
        - `followerCount` integer, nullable
        - `isVerified` boolean, nullable
    - `createdAt` string, date-time, required
    - `isReply` boolean, required — Whether this is a reply to another comment
    - `parentCommentId` string, nullable, required — Parent comment ID if this is a reply
    - `ad` object — Ad context. Present only when the comment was made on paid content. Instagram: populated from the webhook payload's value.media.ad_id and value.media.ad_title. Facebook: populated via a Graph API lookup of the parent post's promotion_status. Absent for comments on organic posts that are not currently promoted.
      - `id` string — Meta ad ID (Instagram only).
      - `title` string — Ad creative title (Instagram only).
      - `promotionStatus` string — Facebook promotion status returned by Graph API. Common values: "active" (organic post currently boosted), "ineligible" (dark post or ad creative, not promotable because it already is an ad).
    - `attachment` object — Facebook only. Present on graphic-only comments (sticker, GIF, photo) that carry no text. URLs are ephemeral and may expire for Meta platforms (oe= expiry), so fetch promptly. Instagram comments do not support attachments.
      - `type` string, required — Attachment type: sticker, animated_image_share, or photo.
      - `imageUrl` string — Rendered image/preview URL (from attachment.media.image.src).
      - `url` string — Source URL (from attachment.url). For GIFs this is an l.facebook.com redirect.
  - `post` object, required
    - `id` string, nullable, required — Internal post ID (null for posts not published through Zernio)
    - `platformPostId` string, required — Platform's post ID
    - `content` string, nullable, required — Post text, from our synced copy. No platform call is made on the comment path, so null when the post was never synced.
    - `imageUrl` string, nullable, required — Post thumbnail or first media item URL. Platform CDN URLs expire, fetch promptly.
    - `permalink` string, nullable, required — Public URL of the post. Null when no URL was ever stored for it, for example a platform draft or a post recovered without one.
  - `account` object, required
    - `id` string, required — Account ID
    - `accountId` string — Account ID (same as id); canonical field for account filtering.
    - `platform` string, required
    - `username` string, required
  - `timestamp` string, date-time, required — UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.

## Acknowledgement `200`

Webhook received successfully

---

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