vlayervlayer docs
Data lookups

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 hasMore is false.

Read a page of comments

GET/v1/comments?url={postUrl}&cursor={nextCursor}Data lookup
curl -G {API_BASE_URL}/v1/comments \
  -H "Authorization: Bearer <API_TOKEN>" \
  --data-urlencode "url=https://www.instagram.com/p/ABC123/"
{
  "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
}
FieldNotes
postUrlThe cleaned-up post URL, without share tags or other query parameters
comments[].idThe platform's comment id. Use it to de-duplicate across pages and across calls
comments[].usernameThe commenter's handle
comments[].createdAtWhen the comment was posted
comments[].likeCount, comments[].replyCountnull when the platform does not expose them
nextCursorSend as cursor to get the next page; null on the last page
hasMorefalse when there are no more pages

A 200 with an empty comments array means the post has no comments. A post that is gone returns 404 POST_NOT_FOUND instead.

Read every page

Every page is a separate data lookup, so a post with many comments costs one lookup per page.

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 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

When the post cannot be read, the route returns one of the data lookup errors. 404 and 422 are permanent for that post; 429, 502 and 503 are worth retrying.

Last updated on