Social Media Sentiment Analysis: A Data Pipeline That Starts With Clean Records
Build sentiment analysis on public social data the reliable way: normalized records in, scores out — with real pagination, freshness control and per-call accounting.
Last reviewed
Quickstart
Every request needs one header: Authorization: Bearer $FETCHPI_API_KEY. Create a free key in the console and you can replay every snippet on this page as-is.
curl -s -H "Authorization: Bearer $FETCHPI_API_KEY" "https://fetchpi.com/v1/x/search/posts?q=your-topic&freshness=default"Sentiment quality is data quality
Sentiment models amplify input noise. Ad entries, deleted authors, unparsable timestamps and layout artifacts all become training/prediction poison. FetchPI filters at the extraction layer — promoted entries are dropped, timestamps are normalized to RFC 3339, authors are typed records — so the frame you hand to a model is already clean.
The pipeline
- Collect: keyword search per platform (
freshness=default,max_ageyou can afford). - Normalize: records already share one schema — dedupe on
id, bucket oncreated_at. - Score: your model (or an LLM pass) labels each text.
- Serve: aggregate by platform/subreddit/author; every number traces to
meta.request_idlineage.
records = []
cursor = None
while True:
params = {"q": "your-brand", "freshness": "default", "max_age": "900"}
if cursor:
params["cursor"] = cursor
r = requests.get(
"https://fetchpi.com/v1/reddit/search/posts",
headers={"Authorization": f"Bearer {os.environ['FETCHPI_API_KEY']}"},
params=params, timeout=30,
)
page = r.json()
records += page["data"]
cursor = page.get("next_cursor")
if not cursor:
break
# records: typed, dedupeable, ready for scoringCost shape
Collection dominates the bill. Cache-mode reads bill at the catalog cache tier (most capabilities half price) and failed upstream calls are never billed — the pipeline's unit economics survive the retry storms that kill scraper-based sentiment projects.