SocialCrawl

Sentiment analysis

Build a social sentiment pipeline. Universal search finds the conversation, comment endpoints pull what real people said, and your LLM labels it. 23-35 credits per run.

You will build a "how do people actually feel about X" pipeline: find the conversation across the social web, harvest the comments where the real sentiment lives, and hand an LLM a clean batch to classify.

Cost per run: 23-35 credits, plus your LLM tokens. Twenty of those are the flat universal-search charge. The rest is the three deep comment fetches, and their price depends on which platforms the top results land on.

How do you analyze social media sentiment with an API?

Two stages: data, then judgment. GET /v1/search/everywhere returns posts from 14 platforms with each post's top comments already attached. Per-platform comment endpoints deepen the sample on the hottest threads. Then a single LLM call labels every comment positive, negative, or neutral.

Sentiment lives in comments, not posts. The post says "we launched a new pricing page"; the comments say what people think about it. Keyword-based scoring ("bad" means negative) falls over on sarcasm immediately, which is why the labelling step is a model, not a dictionary.

What you need

EndpointWhat it doesCost
GET /v1/search/everywhereFinds posts about the topic across 14 platforms, with top_comments pre-attached20cr
GET /v1/tiktok/post/commentsDeeper TikTok comment pages. Param: url1cr
GET /v1/youtube/video/commentsDeeper YouTube comment pages. Param: url1cr
GET /v1/reddit/post/commentsThe full Reddit comment tree in one call, nested replies auto-expanded. Param: url5cr

The Reddit leg is the expensive one for a reason: it is not a page of top-level comments but the whole tree with nested replies already expanded, so it replaces a pagination loop you would otherwise write yourself. A run that samples three Reddit threads costs 15 credits in comment fetches alone.

Want an aggregate without running an LLM at all? GET /v1/content_analysis/sentiment (param: keyword, 20 credits) returns a positive/negative/neutral split plus a 6-axis emotional breakdown (anger, happiness, love, sadness, share, fun) over the keyword's web mentions in one call. It does not undercut the pipeline below on price. Pick it when you want one number and no LLM plumbing, not when you want to save credits.

The code

TypeScript
// recipe-sentiment.ts
// Harvests comments about a topic, builds an LLM-ready classification batch.
// Run with: SOCIALCRAWL_KEY=sc_... npx tsx recipe-sentiment.ts

const KEY = process.env.SOCIALCRAWL_KEY;
if (!KEY) throw new Error("Set SOCIALCRAWL_KEY");

const BASE = "https://www.socialcrawl.dev/v1";
const topic = "github copilot pricing";

async function get(path: string, params: Record<string, string>) {
  const url = new URL(`${BASE}/${path}`);
  for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);
  const res = await fetch(url, {
    headers: { "x-api-key": KEY!, accept: "application/json" },
  });
  return (await res.json()) as {
    success: boolean;
    data?: Record<string, any>;
  };
}

// ── Step 1: Find the conversation (comments come pre-attached) ────────────
const search = await get("search/everywhere", {
  query: topic,
  lookback_days: "14",
});
if (!search.success) throw new Error("search failed");

type Sample = { platform: string; post_url: string; text: string };
const samples: Sample[] = [];

for (const item of search.data!.items as Array<{
  source: string;
  url: string;
  source_items: Array<{
    metadata?: { top_comments?: Array<{ text: string }> };
  }>;
}>) {
  for (const c of item.source_items[0]?.metadata?.top_comments ?? []) {
    samples.push({ platform: item.source, post_url: item.url, text: c.text });
  }
}

// ── Step 2: Deepen the sample on the 3 hottest posts ──────────────────────
const COMMENTS_PATH: Record<string, string> = {
  tiktok: "tiktok/post/comments",
  youtube: "youtube/video/comments",
  reddit: "reddit/post/comments",
};

const hot = (search.data!.items as Array<{ source: string; url: string }>)
  .filter((i) => COMMENTS_PATH[i.source])
  .slice(0, 3);

for (const post of hot) {
  const res = await get(COMMENTS_PATH[post.source]!, { url: post.url });
  for (const item of (res.data?.items ?? []) as Array<{
    comment?: { text?: string | null };
  }>) {
    if (item.comment?.text)
      samples.push({
        platform: post.source,
        post_url: post.url,
        text: item.comment.text,
      });
  }
}

console.log(`${samples.length} comments harvested about "${topic}"`);

// ── Step 3: Hand the batch to your LLM of choice ──────────────────────────
const prompt = `Classify the sentiment of each social media comment about
"${topic}" as "positive", "negative", or "neutral". Judge sentiment toward
the topic itself, not general mood. Account for sarcasm. Return a JSON array
of { index, sentiment, confidence } objects.

Comments:
${samples.map((s, i) => `${i}. [${s.platform}] ${s.text.slice(0, 280)}`).join("\n")}`;

// Send `prompt` to any LLM, OpenAI, Anthropic, Gemini, a local model.
// Then aggregate: share positive vs negative per platform, over time, etc.
console.log(prompt.slice(0, 600), "…");

What you get back

JSON
// `samples` after Step 2, the LLM input batch:
[
  { "platform": "reddit", "post_url": "https://reddit.com/r/programming/...", "text": "Honestly worth every cent, it writes half my tests." },
  { "platform": "youtube", "post_url": "https://www.youtube.com/watch?v=...", "text": "$39/mo for autocomplete, lol no thanks" },
  { "platform": "tiktok", "post_url": "https://www.tiktok.com/@.../video/...", "text": "the new pricing killed it for students fr" },
  // ... 80-200 more, depending on how active the topic is
]

// And the LLM's output after Step 3:
[
  { "index": 0, "sentiment": "positive", "confidence": 0.95 },
  { "index": 1, "sentiment": "negative", "confidence": 0.9 },
  { "index": 2, "sentiment": "negative", "confidence": 0.85 },
]

What to change

  • topic: any brand, product, feature, or announcement.
  • How deep to go: .slice(0, 3) in Step 2 sets the number of threads you expand, and therefore most of the price. Three TikTok or YouTube posts is 23 credits, a mixed TikTok + YouTube + Reddit sample is 27, three Reddit threads is 35. A topic with fewer than three comment-capable results costs less.
  • The classifier: prompt is plain text, so any model works. Swap in structured outputs if your provider supports them.
  • Go further back: raise lookback_days, or use from_date / to_date for a fixed window such as a launch week.
  • Skip the LLM: use GET /v1/content_analysis/sentiment for a 20-credit aggregate distribution without per-comment labels.

On this page