Sentiment analysis
Find the conversation about a topic on YouTube and Reddit, pull the comments, and read the sentiment label every comment already carries for free. From 400 credits per run.
This recipe measures public mood around a topic in three steps: locate the posts where it is discussed, collect the comments on the most active ones, and tally the sentiment of those comments. Every comment list on the API comes back with a free sentiment label on each comment, so there is no model to run.
Cost per run
400 to 1,900 credits. Two searches (YouTube 20–380, Reddit 20–680), three YouTube comment pages (20–100 each) and three Reddit comment trees (100–180 each). The labels add nothing. The Reddit leg costs the most because each call returns a whole discussion with nested replies expanded, not one page.
How do you analyze social media sentiment with an API?
Two stages. Search finds the posts where the topic is being discussed. The comment endpoints then return what people said under them, and each comment carries computed.labels.sentiment: a level from 0 (very negative) to 4 (very positive), the same value as score_0_1 on a 0 to 1 scale, and a confidence. Count the levels and you have a sentiment split.
Sentiment lives in comments, not in posts. The post says "we changed our pricing". The comments say what people think of it.
What you need
| Endpoint | Role | Credits |
|---|---|---|
GET /v1/youtube/search | Find videos about the topic | 20–380 |
GET /v1/reddit/search | Find Reddit threads about the topic | 20–680 |
GET /v1/youtube/video/comments | Top-level comments on a video, labelled | 20–100 |
GET /v1/reddit/post/comments | A thread's full comment tree, labelled | 100–180 |
Every comment list carries four labels by default, at no extra cost: sentiment, question, purchase_intent and complaint. Labels are judged under a short time budget. A comment not finished in time arrives without them and is filled on your next call for the same page. To have every comment judged inside this response, name the labels you want, for example label=sentiment. Asking for a default label by name is still free. See Labels.
The code
# sentiment.py
# Harvests labelled comments about a topic and counts the sentiment split.
# Run with: INSIGHTSOCIAL_API_KEY=isk_live_... python sentiment.py
import os
from collections import Counter
from concurrent.futures import ThreadPoolExecutor
import requests
KEY = os.environ["INSIGHTSOCIAL_API_KEY"]
BASE = "https://api.insightsocial.app/v1"
TOPIC = "github copilot pricing"
THREADS_PER_PLATFORM = 3
def get(path, **params):
res = requests.get(f"{BASE}/{path}", params=params,
headers={"x-api-key": KEY}, timeout=120)
return res.json()
def band(level):
if level is None:
return "not_yet"
return "negative" if level <= 1 else "positive" if level >= 3 else "neutral"
# Step 1: find the conversation on both platforms.
yt = get("youtube/search", query=TOPIC, relevance="filter")
rd = get("reddit/search", query=TOPIC, relevance="filter", timeframe="month")
videos = [i["post"]["url"] for i in yt.get("data", {}).get("items", [])
if "watch?v=" in (i.get("post") or {}).get("url", "")][:THREADS_PER_PLATFORM]
threads = [i["post"]["url"] for i in rd.get("data", {}).get("items", [])
if (i.get("post") or {}).get("url")][:THREADS_PER_PLATFORM]
# Step 2: pull labelled comments under the top results.
jobs = [("youtube/video/comments", u) for u in videos] + \
[("reddit/post/comments", u) for u in threads]
with ThreadPoolExecutor(max_workers=6) as pool:
pages = list(pool.map(lambda j: (j, get(j[0], url=j[1], label="sentiment")), jobs))
# Step 3: count the split per platform.
split = {"youtube": Counter(), "reddit": Counter()}
spent = yt.get("credits_used", 0) + rd.get("credits_used", 0)
for (path, url), body in pages:
spent += body.get("credits_used", 0)
if not body["success"]:
continue
platform = path.split("/")[0]
for item in body["data"].get("items", []):
sentiment = ((item.get("computed") or {}).get("labels") or {}).get("sentiment")
split[platform][band(sentiment["level"] if sentiment else None)] += 1
for platform, counts in split.items():
print(platform, dict(counts))
print(f"credits used: {spent}")What you get back
youtube {'negative': 212, 'neutral': 96, 'positive': 71}
reddit {'negative': 88, 'neutral': 54, 'positive': 40, 'not_yet': 3}
credits used: 520The figures are illustrative. data.labels on each comment page reports how many comments were judged, how many are still pending and what the labels cost (extra_credits: 0 for these).
Where the free labels stop
The sentiment label judges how a comment feels, not how it feels about your topic in particular. A comment that is angry about a bug in a competing product still reads as negative. When you need sentiment toward one named thing, either:
- Hand the harvested comment text to your own model with a prompt that names the topic, or
- On post lists and post searches, use
label=mention&brand=..., which judges whether each post is about the brand and how it feels toward it. This label is metered and adds credits, so check the price first withdry_run=1, which is never charged.
The same comments also carry question, purchase_intent and complaint probabilities, which are often more useful than the split itself: "how many people are asking how to cancel" is a sharper signal than "38% negative".
What to change
TOPIC. Any brand, product, feature or announcement.- How deep to go.
THREADS_PER_PLATFORMsets most of the price. At 3 per platform the floor is 400 credits. At 1 per platform it is 160. - Other platforms. Swap in
tiktok/searchwithtiktok/post/comments(20–140),twitter/search/tweetswithtwitter/tweet/replies(20–100), orinstagram/search/reelswithinstagram/post/comments(100–380). Every comment list carries the same labels. - A fixed window. Use
timeframeon Reddit andmax_age_dayson the searches to cover a launch week.
Related
Brand mention monitoring
Run a daily brand-mention sweep across the search endpoints of six platforms in parallel, drop off-topic rows for free, dedupe against earlier runs and alert on what is new. From 120 credits per sweep.
Competitor tracking
Snapshot a competitor's followers, engagement and latest posts on TikTok, Instagram, YouTube and X in one parallel sweep, then diff it against the last run. 160 to 660 credits per competitor.