---
title: "List commented posts"
method: GET
path: "/v1/inbox/comments"
tags: ["Comments"]
---

# List commented posts

`GET /v1/inbox/comments`

Returns posts with comment counts from all connected accounts. Aggregates data across multiple accounts.

Responses are cached for up to 10 minutes, so the feed may lag new comments by that
window. Do not poll this endpoint for real-time updates: subscribe to the
`comment.received` webhook, which fires for every new comment across your posts and
carries the post reference needed to keep this list current.

For users with the Ads add-on (Metronome plans always qualify), the user's Meta ads
(boosted/dark posts) are included too. There's one row per (ad, placement-with-comments):
an ad that runs on both Facebook feed and Instagram feed produces up to two rows (the
Page dark post and the IG media have separate comment threads), each flagged
`isAd: true` with `adId` and `placement` (`id` is `{adId}:{placement}`). Use
`?platform=metaads` to return *only* ad rows; passing `facebook`/`instagram` returns
*organic* posts only (no ads); omitting `platform` returns both. Fetch a row's thread
from GET /v1/ads/{adId}/comments?placement={placement}. Ad comment counts are read with
the Marketing API token (Facebook side) or the connected Instagram account's token
(Instagram side); a row whose count can't be read is omitted.

Pagination walks each account's platform listing. Following `nextCursor` reaches past
the first page on Facebook, Instagram, Threads, LinkedIn and YouTube, since they are
the platforms that support a server-side date window; on the others the listing stops
at its first page. Cursor pagination is only coherent for the default sort
(`sortBy=date`, `sortOrder=desc`): with `sortOrder=asc`, or with `sortBy=comments`,
the cursor filter does not match the sort order and the second page is unreliable.

`nextCursor` is opaque: pass it back verbatim, never construct or parse it, its
composition may change without notice. Because each page re-queries a live window,
results can still shift between requests, so dedupe by `id` on the client.

`commentCount` semantics differ by platform: YouTube's includes replies, Facebook's counts
top-level comments only.

## Query parameters

- `profileId` string
- `platform` 'facebook' | 'instagram' | 'twitter' | 'bluesky' | 'threads' | 'youtube' | 'linkedin' | 'reddit' | 'metaads'
- `minComments` integer
- `since` string, date-time
- `sortBy` 'date' | 'comments'
- `sortOrder` 'asc' | 'desc'
- `limit` integer
- `cursor` string
- `accountId` string

## Response `200`

Aggregated posts with comments

- object
  - `data` object[]
    - `id` string
    - `platform` string
    - `accountId` string
    - `accountUsername` string
    - `content` string — The post text/caption. On ad rows (isAd: true) this is the AD NAME, not the underlying post's caption — the creative text isn't exposed here.
    - `picture` string, nullable — Post media thumbnail. On ad rows this is the ad creative thumbnail.
    - `permalink` string, nullable — Public URL of the post. On ad rows: the Facebook dark-post URL (facebook placement) or the IG media permalink (instagram placement); may be null when unknown.
    - `createdTime` string, date-time
    - `commentCount` integer
    - `likeCount` integer — Not fetched for ad rows (always 0 there).
    - `cid` string, nullable — Bluesky content identifier
    - `subreddit` string, nullable — Reddit subreddit name
    - `isAd` boolean — True when this row is an ad (boosted/dark post). `platform` is then the placement (facebook = the Page dark post / instagram = the IG media), `id` is `{adId}:{placement}`, and the thread is at GET /v1/ads/{adId}/comments?placement={placement}.
    - `adId` string — Internal Zernio ad id — only on ad rows.
    - `placement` 'facebook' | 'instagram' — Which side of the ad this row's comments are on — only on ad rows.
  - `pagination` object
    - `hasMore` boolean
    - `nextCursor` string, nullable
  - `meta` object
    - `accountsQueried` integer
    - `accountsFailed` integer
    - `failedAccounts` object[]
      - `accountId` string
      - `accountUsername` string, nullable
      - `platform` string
      - `error` string
      - `code` string, nullable — Error code if available
      - `retryAfter` integer, nullable — Seconds to wait before retry (rate limits)
    - `lastUpdated` string, date-time

## Other responses

- `401` — Unauthorized
- `403` — Inbox addon required

---

[API](https://skmtc.net/zernio/apis/zernio-api.md) · [All operations](https://skmtc.net/zernio/apis/zernio-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/zernio/zernio-api/revisions/ac5fffe58a63/schema)
