# Comments

Read comments on your posts across platforms, reply, like, hide, pin and moderate them, and send a private DM to a commenter.

Comments are the public replies under your posts. Pozy lists them for every connected account that supports them, lets you answer from any of your accounts, and fires `comment.received` the moment a new one arrives. The same endpoints work whether the post was published through Pozy or directly on the platform.

## Find posts with comments

`GET /v1/inbox/comments` returns posts that have comments, newest first, with their `commentCount`, `likeCount` and `permalink`. Filter with `profileId`, `accountId`, `platform`, `since` and `minComments`, and sort by `date` or `comments`.

> **Do not poll this list:**
> 
> It is cached for up to 10 minutes. For new comments in real time, subscribe to `comment.received` instead and use this list for backfill.

Boosted and ad posts from connected Meta ad accounts show up too, flagged `isAd: true` with `adId` and a `placement` of `facebook` or `instagram`. Filter them with `platform=metaads`.

## Read a post's comments

```bash cURL
curl "https://api.pozy.ai/v1/inbox/comments/17912345678901234?accountId=6650c1e2a3b4c5d6e7f80a22&limit=25" \
  -H "Authorization: Bearer $POZY_API_KEY"
```
```ts Node
const res = await fetch("https://api.pozy.ai/v1/inbox/comments/17912345678901234?accountId=6650c1e2a3b4c5d6e7f80a22&limit=25", {
  headers: { Authorization: `Bearer ${process.env.POZY_API_KEY}` },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error);

for (const c of data.comments) {
  console.log(c.from.username, c.message, { canHide: c.canHide, canLike: c.canLike });
}
```
```python Python
import os
import requests

resp = requests.get(
    "https://api.pozy.ai/v1/inbox/comments/17912345678901234",
    headers={"Authorization": f"Bearer {os.environ['POZY_API_KEY']}"},
    params={"accountId": "6650c1e2a3b4c5d6e7f80a22", "limit": 25},
    timeout=30,
)
for c in resp.json()["comments"]:
    print(c["from"]["username"], c["message"])
```

`postId` is the platform's post id (a YouTube video id on YouTube). Each comment comes with capability flags (`canReply`, `canDelete`, `canHide`, `canLike`) and state (`isHidden`, `isLiked`), so your UI can show only the actions that will work. `from.isOwner` marks comments written by the connected account itself.

To page through the replies under one comment, pass `commentId` (Facebook, Instagram, Reddit and TikTok). Bluesky comments carry a `cid` you need for likes and replies.

## Reply

`POST /v1/inbox/comments/{postId}` posts a comment. Add `commentId` to reply under a specific comment, leave it out to comment on the post itself.

```bash cURL
curl -X POST https://api.pozy.ai/v1/inbox/comments/17912345678901234 \
  -H "Authorization: Bearer $POZY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 3f1d2c7a-5a8e-4c43-8f0e-2b6d1a9e7c10" \
  -d '{
    "accountId": "6650c1e2a3b4c5d6e7f80a22",
    "commentId": "18034567890123456",
    "message": "Thanks! The link is in our bio."
  }'
```
```ts Node
import { randomUUID } from "node:crypto";

const res = await fetch("https://api.pozy.ai/v1/inbox/comments/17912345678901234", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.POZY_API_KEY}`,
    "Idempotency-Key": randomUUID(),
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    accountId: "6650c1e2a3b4c5d6e7f80a22",
    commentId: "18034567890123456",
    message: "Thanks! The link is in our bio.",
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error);
console.log(data.data.commentId);
```
```python Python
import uuid

resp = requests.post(
    "https://api.pozy.ai/v1/inbox/comments/17912345678901234",
    headers={"Authorization": f"Bearer {os.environ['POZY_API_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={"accountId": "6650c1e2a3b4c5d6e7f80a22", "commentId": "18034567890123456", "message": "Thanks! The link is in our bio."},
    timeout=30,
)
print(resp.json())
```

With an `Idempotency-Key`, a retry of the same body within 24 hours replays the first response instead of posting twice. The same key with a different body answers `422`, and a key whose first request is still running answers `409`. Reddit replies need the `subreddit`; Bluesky replies need `parentCid`, `rootUri` and `rootCid` from the thread.

## Moderate and engage

| Action | Call | Platforms |
| --- | --- | --- |
| Hide or unhide | `POST` or `DELETE /v1/inbox/comments/{postId}/{commentId}/hide` | Facebook, Instagram, Threads, X, TikTok |
| Delete | `DELETE /v1/inbox/comments/{postId}?accountId=&commentId=` | Facebook, Instagram, Threads, LinkedIn, Bluesky, X, YouTube, TikTok (your own comments), Reddit |
| Like or unlike | `POST` or `DELETE .../{commentId}/like` | Facebook, X, Bluesky (needs `cid`), LinkedIn (reactions), Reddit. Instagram is in limited release |
| Pin or unpin | `POST` or `DELETE .../{commentId}/pin` | TikTok |
| Edit | `PATCH .../{commentId}` with `content` | Reddit |
| Moderate | `POST .../{commentId}/moderation` with `published`, `rejected` or `heldForReview`, plus optional `banAuthor` | YouTube, on channels you own |
| Like the post | `POST` or `DELETE /v1/inbox/posts/{postId}/like` | LinkedIn, X, Facebook, YouTube, Bluesky |

Hidden comments stay visible to the commenter and to page admins, which makes hiding a gentler tool than deleting. On X, you can only hide replies in conversations your account started.

LinkedIn reactions take an optional `reactionType` (`LIKE`, `PRAISE`, `EMPATHY`, `INTEREST`, `APPRECIATION`, `ENTERTAINMENT`). Because any connected account can like any post, a brand can have its executives' accounts react to the company post.

> **Limited and closed features:**
> 
> - **Instagram likes** need a Meta permission that is still in review. Until it is granted, the call answers `403` with code `PLATFORM_BETA_RESTRICTED` for most accounts. It only ever works for accounts connected through Facebook Login.
> - **LinkedIn** accounts connected before the social feed permissions existed answer `403` `linkedin_reconnect_required`. Reconnect them.
> - **YouTube** likes on comments do not exist in YouTube's API, and every like on a video spends part of a small daily quota.
> - **Reddit** is paused while Reddit blocks third-party apps.

## DM a commenter

On Instagram and Facebook you can answer a comment privately: `POST /v1/inbox/comments/{postId}/{commentId}/private-reply` sends a DM to the comment's author.

- One private reply per comment, within 7 days of the comment.
- Add up to 13 `quickReplies` or 1 to 3 `buttons` (not both).
- Instagram can refuse buttons, cards and attachments to people who do not follow the account. That refusal spends the comment's one private reply, so open with plain text when you are not sure. See [Comment to DM](https://pozy.ai/docs/automations/comment-to-dm).

To do this automatically on keywords, use a [comment-to-DM automation](https://pozy.ai/docs/automations/comment-to-dm) instead of calling this yourself.

## The `comment.received` event

`comment.received` fires for new comments on Instagram, Facebook, Threads, YouTube, LinkedIn, Bluesky, Reddit and TikTok. It carries the comment (`id`, `text`, `author`, `isReply`, `parentCommentId`, `createdAt`) and the post it belongs to. A few fields are worth branching on:

- `comment.postId` is the Pozy post id, or `null` when the post was published outside Pozy. `platformPostId` is always set.
- `comment.author.isOwnAccount` is `true` for comments the connected account wrote, so your bot does not answer itself.
- `comment.ad` is present only for comments on paid content, so `if (comment.ad)` separates ad comments from organic ones.
- `comment.isLive` marks Instagram comments made during a live broadcast.
- `comment.author.instagramProfile` (follower status and count) appears only for people who have messaged the account before. Missing means unknown.

## Endpoints

| Endpoint | What it does |
| --- | --- |
| [`GET /v1/inbox/comments`](https://pozy.ai/docs/api/listInboxComments) | List commented posts |
| [`GET /v1/inbox/comments/{postId}`](https://pozy.ai/docs/api/getInboxPostComments) | Get post comments |
| [`POST /v1/inbox/comments/{postId}`](https://pozy.ai/docs/api/replyToInboxPost) | Reply to comment |
| [`DELETE /v1/inbox/comments/{postId}`](https://pozy.ai/docs/api/deleteInboxComment) | Delete comment |
| [`PATCH /v1/inbox/comments/{postId}/{commentId}`](https://pozy.ai/docs/api/editInboxComment) | Edit comment |
| [`POST /v1/inbox/comments/{postId}/{commentId}/moderation`](https://pozy.ai/docs/api/setCommentModeration) | Set comment moderation status |
| [`POST /v1/inbox/comments/{postId}/{commentId}/hide`](https://pozy.ai/docs/api/hideInboxComment) | Hide comment |
| [`DELETE /v1/inbox/comments/{postId}/{commentId}/hide`](https://pozy.ai/docs/api/unhideInboxComment) | Unhide comment |
| [`POST /v1/inbox/comments/{postId}/{commentId}/pin`](https://pozy.ai/docs/api/pinInboxComment) | Pin comment |
| [`DELETE /v1/inbox/comments/{postId}/{commentId}/pin`](https://pozy.ai/docs/api/unpinInboxComment) | Unpin comment |
| [`POST /v1/inbox/comments/{postId}/{commentId}/like`](https://pozy.ai/docs/api/likeInboxComment) | Like comment |
| [`DELETE /v1/inbox/comments/{postId}/{commentId}/like`](https://pozy.ai/docs/api/unlikeInboxComment) | Unlike comment |
| [`POST /v1/inbox/posts/{postId}/like`](https://pozy.ai/docs/api/likePost) | Like post |
| [`DELETE /v1/inbox/posts/{postId}/like`](https://pozy.ai/docs/api/unlikePost) | Unlike post |
| [`POST /v1/inbox/comments/{postId}/{commentId}/private-reply`](https://pozy.ai/docs/api/sendPrivateReplyToComment) | Send private reply |

## Webhook events

| Event | When it fires |
| --- | --- |
| [`comment.received`](https://pozy.ai/docs/webhooks/events#comment-received) | Comment received. |
