General

Social Comments for Sentiment Analysis with an API (2026)

Pull paginated comments from TikTok, YouTube, Instagram, Reddit, and more as normalized JSON — ready for keyword rules, classifiers, or LLM batch jobs.

Social FetchUpdated

Post captions and comment sections often disagree. Pass a public post URL to a platform comments endpoint, paginate with cursor, and feed comment.text into keyword rules or a classifier. Same { data, meta } envelope on every platform.

You'll need an API key. Test in the Playground. Set a per-post page cap before you write the loop.

Why comments

Comments carry objections, churn language, and campaign pushback that captions miss. Manual copy-paste breaks on pagination. Pair comment pulls with search-based listening when you do not have the post URL — search finds candidates; comments endpoints score the ones above your velocity threshold.

Which platforms expose comments

Pattern: GET /v1/{platform}/posts/comments or .../videos/comments, required url, optional cursor.

PlatformRouteNotable query paramsReply depth
TikTok/v1/tiktok/videos/commentstrim for lighter payloadsTop-level per page; replyCount on each row
YouTube/v1/youtube/videos/commentsorder=top or newest/v1/youtube/videos/comments/replies per thread
Instagram/v1/instagram/posts/commentsworks on posts and reelsTop-level; replyCount when reported
Reddit/v1/reddit/posts/commentstrimNested replies on each comment
Facebook/v1/facebook/posts/commentsTop-level pages
Rumble/v1/rumble/videos/commentsTop-level pages

Every response includes data.lookupStatus (found or not_found), data.comments, data.page.nextCursor, data.page.hasMore, and meta.requestId. Field names differ by platform — TikTok uses likes; YouTube uses likeCount; Reddit uses score — but text and id are always present. Each page is one billed lookup; meta.creditsCharged is on every response.

TikTok video comments

Request
curl -sS \
  -H "x-api-key: $SOCIALFETCH_API_KEY" \
  -G "https://api.socialfetch.dev/v1/tiktok/videos/comments" \
  --data-urlencode "url=https://www.tiktok.com/@mrbeast/video/7596844935442189598"

TikTok-specific: replyCount flags debate threads; language routes locale-specific models; trim=true drops ancillary fields. totalComments helps decide whether full pagination is worth it on viral posts.

Reference: TikTok video comments.

YouTube video comments

YouTube exposes sort order at query time — top and newest can disagree on the same video.

Request
const params = new URLSearchParams({"url":"https://www.youtube.com/watch?v=dQw4w9WgXcQ","order":"top"});

const response = await fetch(
  `https://api.socialfetch.dev/v1/youtube/videos/comments?${params.toString()}`,
  {
    headers: {
      "x-api-key": process.env.SOCIALFETCH_API_KEY,
    },
  }
);

const body = await response.json();

console.log(response.status, body);
order valueWhen to use
topBrand monitoring — the visible thread
newestLaunch week, controversy spikes, support triage

YouTube-specific: author.creator marks creator replies (tag separately in aggregates); repliesCursor means a sub-thread exists. Fetch replies when replyCount exceeds your threshold:

Request
bash

Each reply page bills separately. Top-level plus high-reply threads usually captures the argument without walking every leaf.

Reference: YouTube video comments · Comment replies.

Instagram post comments

Pass the full post or reel URL — canonical /p/ or /reel/ is safest.

Request
bash
Request
typescript

Instagram-specific: no separate replies route — replyCount on top-level comments indicates sub-threads; author.verified helps filter brand-account replies.

Reference: Instagram post comments.

Reddit post comments

Long objections and nested arguments. Pull comments only on threads that passed your score filter (see Reddit product research).

Request
bash

Reddit-specific: depth, nested replies, and score. Flatten before scoring if your classifier expects a string list:

Request
typescript

Use trim=true for text, score, and ids only. Keep isSubmitter — OP clarifications change how you read negative replies.

Reference: Reddit post comments. Facebook: /v1/facebook/posts/comments for Page posts or public group discussions.

Paginate the full thread

One page plus data.page.nextCursor per call. Loop until hasMore is false or you hit your cap:

Example
typescript
import { SocialFetchClient } from "@socialfetch/sdk";

const client = new SocialFetchClient({
  apiKey: process.env.SOCIALFETCH_API_KEY!,
});

const videoUrl = "https://www.tiktok.com/@mrbeast/video/7596844935442189598";
const comments = [];
let cursor: string | undefined;

do {
  const result = await client.tiktok.getVideoComments({ url: videoUrl, cursor });
  if (!result.ok) break;
  if (result.value.data.lookupStatus !== "found") break;

  comments.push(
    ...result.value.data.comments.map((c) => ({
      text: c.text,
      likes: c.metrics?.likes ?? 0,
    })),
  );
  cursor = result.value.data.page.nextCursor ?? undefined;
} while (cursor);

// Feed comments.text into your sentiment model or keyword rules.
console.log(comments.length, "comments ready for analysis");
  1. Stop when lookupStatus !== "found".
  2. Prefer hasMore over guessing from array length.
  3. Pass cursor verbatim — do not construct tokens.
  4. Log meta.requestId per page.

Re-running the same cursor chain twice bills twice.

Sampling strategies

Full-thread pulls are the exception. Cap pages before you loop.

StrategyHowGood for
Page capStop after N cursor iterationsHourly monitors, credit budgets
Engagement floorSkip comments where likes/score < thresholdNoise reduction on viral posts
Reply thresholdFetch YouTube reply pages when replyCount > 10Debate-heavy threads
Time windowRe-fetch newest page only on repeat runsTrend detection vs archive
Stratified sampleTop page + newest page (YouTube order)When sort order disagrees
Search handoffComments only on search hits above velocityMonitoring workflows

Weight aggregates by engagement: weighted_score = sentiment_score * log1p(likes).

Feed LLM classifiers

Keyword rules — run first. Flag refund, scam, love this, competitor names before spending tokens.

Request
typescript

Classical ML — export text + likes/score to sklearn or Hugging Face. Train on a few hundred hand-labeled comments per vertical.

LLM batch classification — structured input, one batch per 50–100 comments:

Request
json

Ask for per-id labels (positive, negative, neutral, mixed) and optional themes. Require JSON output; store the model version on each row. Strip URLs and bare @mentions if noisy; keep emoji for Gen-Z brands. Pair with transcripts when spoken claims and comments diverge.

Deduplication and warehouse rows

ProblemFix
Same comment on re-fetchUpsert on platform + comment.id
Same text, different ids (rare)Secondary hash on normalize(text) for analytics only
Same post scored twice in one runDedupe URLs before the outer loop
Stale sentiment in dashboardsStore capturedAt; re-pull on schedule
Audit trailPersist meta.requestId and meta.creditsCharged per page
Request
json

Join back to listening snapshots on postUrl or platform-native video id — not title text.

Troubleshooting

not_found but the post opens in a browser

  • Comments may be disabled — lookup can return found with zero rows.
  • Private, age-gated, or region-blocked media returns not_found.
  • Pass canonical URLs (full YouTube watch link, full Reddit /comments/ path).

Empty comments array with lookupStatus: found

  • Legitimate for new posts or comments-off accounts. Still billed.

Pagination stops early or repeats

  • Only pass cursor from the immediately previous response.
  • If hasMore is true but nextCursor is null, stop and log requestId.
  • Cap pages per post.

YouTube top vs newest disagree

  • Two passes with different order values if sort skew matters — two credit lines per page.

Reddit nested replies missing from classifier input

  • Walk replies.items recursively or flatten as shown above.

TikTok id looks like a placeholder

  • Still stable within a pull — use for dedupe keys in that run.

lookup_failed or HTTP 503

  • Not charged. Retry with backoff; include meta.requestId if you contact support.

Classifier drift

  • Re-score a frozen snapshot when you change models — do not compare scores across model versions without calibration.

Billing notes

ActionCredits (typ.)
1 TikTok comment page1
1 YouTube comment page1
1 YouTube reply page1
1 Instagram comment page1
1 Reddit comment page1
10 posts × 3 pages each30

Completed not_found lookups still bill. lookup_failed and 503 do not. See Credits. Planning: (posts) × (pages per post) + (YouTube reply pages) — 20 posts × 3 pages ≈ 60 credits per run.

What you can build

  • Launch monitoring — hourly sentiment after a drop; alert on negative fraction threshold.
  • Creator vetting — flag toxic reply patterns before signing.
  • Support triage — route negative threads to Slack on keyword match.
  • Competitive dashboards — same classifier on your posts and competitor posts from search.
  • Research exports — flat CSV of Reddit thread comments with themes for PM decks.

Next steps: Playground · API reference · Pricing