Comments
Read the comments on a public Instagram post or reel, or a TikTok video, straight from the post URL, one page at a time.
Each call reads one page of comments live from the platform; nothing is stored. Pass the returned nextCursor back as cursor until there is no next page.
Read a page of comments
curl -G {API_BASE_URL}/v1/comments \
-H "Authorization: Bearer <API_TOKEN>" \
--data-urlencode "url=https://www.instagram.com/p/ABC123/"| Query | Required | Notes |
|---|---|---|
url | Yes | An Instagram post (/p/…) or reel (/reel/…), or a TikTok video (tiktok.com/@{user}/video/{id}). Share tags and other query parameters are ignored. Short links such as vm.tiktok.com return 422 VALIDATION_ERROR |
cursor | No | The nextCursor of the previous page. Leave it out, or empty, for the first page |
There are no other parameters. Any other query parameter is ignored.
{
"platform": "instagram",
"postUrl": "https://www.instagram.com/p/ABC123/",
"comments": [
{
"id": "17890012345678",
"username": "creator_jane",
"text": "Love this!",
"createdAt": "2026-09-23T10:00:00.000Z",
"likeCount": 4,
"replyCount": 1
}
],
"nextCursor": "cursor-value",
"hasMore": true
}| Field | Notes |
|---|---|
platform | instagram or tiktok |
postUrl | The cleaned-up post URL, without share tags or other query parameters |
comments[].id | The platform's comment id. The id is different on each platform, so key on platform and id together |
comments[].username | The commenter's handle |
comments[].text | The comment text |
comments[].createdAt | When the comment was posted, as an ISO 8601 UTC timestamp |
comments[].likeCount, comments[].replyCount | null when the platform does not expose them |
nextCursor | Send as cursor to get the next page; null when there is no next page |
hasMore | false when the platform reports no more pages |
Only top-level comments are returned. replyCount counts the replies to a comment; the replies themselves are comment replies.
A 200 with an empty first page means the post has no comments. A post that is gone returns 404 POST_NOT_FOUND instead. On TikTok, an empty first page is checked against the video itself, so a missing video returns an error, typically 404, and does not look like a video with no comments.
Order and page size
No sort parameter
The API does not sort comments and takes no sort, order or page size parameter. Comments come back in the order the platform returns them, and the platform decides how many are on a page. That order is not specified, so do not assume newest first or most liked first. To get a specific order, collect the pages and sort on createdAt or likeCount yourself.
Read every page
Every page is a separate data lookup, so a post with many comments costs one lookup per page. A page that fails is not counted.
async function allComments(postUrl: string) {
const comments = [];
let cursor: string | null = null;
do {
const params = new URLSearchParams({ url: postUrl });
if (cursor) params.set("cursor", cursor);
const res = await fetch(`${API_BASE_URL}/v1/comments?${params}`, {
headers: { Authorization: `Bearer ${API_TOKEN}` },
});
if (!res.ok) throw new Error((await res.json()).error);
const page = await res.json();
comments.push(...page.comments);
cursor = page.hasMore ? page.nextCursor : null;
} while (cursor);
return comments;
}The cursor is opaque: send back only what nextCursor returned, unchanged. Stop when nextCursor is null, even if hasMore is true. The two differ by platform:
| TikTok | ||
|---|---|---|
nextCursor | The platform's cursor string | The platform's numeric cursor, as a string |
hasMore | true when there is a cursor | true when the platform reports more pages. It can be true with nextCursor null, and then there is no next page to request |
A cursor you made up | Passed to the platform as it is | Not validated: a value that is not a number is not rejected, it is sent on as NaN and the result is up to the platform |
The route allows 60 requests per minute from one client IP, so pace a long walk or handle 429 RATE_LIMITED by waiting for the Retry-After header.
Errors
Every error has the standard error and message envelope, and you branch on error.
error | HTTP | Retry? | When |
|---|---|---|---|
UNAUTHORIZED | 401 | No | The Bearer token is missing, invalid or expired |
VALIDATION_ERROR | 422 | No | url is missing or is not an Instagram post or reel, or a TikTok video, URL. Nothing was read |
POST_AGE_RESTRICTED | 422 | No | The platform withholds the post because of its age restriction |
POST_NOT_ACCESSIBLE | 422 | No | The platform refuses access to the post, for example because it is private |
POST_NOT_FOUND | 404 | No | The post no longer exists at that URL |
RATE_LIMITED | 429 | Yes | More than 60 requests in a minute from your client IP. Wait for Retry-After |
SCRAPING_RATE_LIMITED | 429 | Yes | The platform is throttling reads. Wait for Retry-After |
SCRAPING_ERROR | 502 | Yes | The read failed for an unclassified reason |
SCRAPING_UNAVAILABLE | 503 | Later | Reading the platform is temporarily unavailable |
UPSTREAM_TIMEOUT | 504 | Yes | The platform did not answer in time |
Comments on an Instagram post with an age restriction can fail as 502 or 504 rather than POST_AGE_RESTRICTED, because the read stalls instead of being refused. Retrying will not help while the post stays age-restricted.
Any other failure returns 500 INTERNAL_ERROR. See data lookup errors for the codes every data lookup shares. 404 and 422 are permanent for that post; 429, 502, 503 and 504 are worth retrying.
Comment replies
This feature is available on demand (opens in a new tab).
Replies read the replies to one comment on an Instagram post or reel, a TikTok video or a YouTube video, one page at a time. On YouTube, a reply lookup takes the continuation token that a comment returns, not a comment id.
| Parameter | Notes |
|---|---|
url | The post URL, as for comments |
comment_id | The parent comment. Use the id that Read a page of comments returns |
cursor | Pages through the replies |
| Reply data | TikTok | |
|---|---|---|
| Reply | Id, text, time posted | Id, text, time posted |
| Parent comment | Parent comment id | Parent id |
| Likes and replies | Reply count | Like count |
| Author | Username, verified flag | Username, nickname |
| Paging | Cursor and whether there are more replies | Numeric cursor, whether there are more replies, and a total |
YouTube comments
This feature is available on demand (opens in a new tab).
- YouTube. Input: video, and
topornewestorder. Returns the video's comments. A cap applies to how many comments one video returns.
Replies to an X post
This feature is available on demand (opens in a new tab).
- X. Input: the post id, not the post URL. Returns the replies to the post.
Last updated on