Cookbook

Analyse crypto podcasts programmatically

118 podcast feeds, tagged by project, each episode carrying a written description. Enough to track what the circuit is saying without transcribing a single minute of audio.

~25 min Python, stdlib onlyNo API key, no signup
/items/podcasts//items/news/
01

Be clear about what the API gives you

News items carry a computed sentiment and sentiment_score. Podcast episodes do not. What they carry is short_description — a real paragraph, not a truncated title — which is enough to classify against without audio. Anything calling itself podcast sentiment is doing a model pass on that text, and this recipe shows the seam rather than hiding it.

import json, urllib.request, statistics from urllib.parse import urlencode BASE = "https://api.alphaday.com" def get(path, **p): with urllib.request.urlopen(f"{BASE}{path}?{urlencode(p)}") as r: return json.load(r) TAG = "ethereum" pods = get("/items/podcasts/", tags=TAG, period=1, limit=8) # 1 = LAST_WEEK news = get("/items/news/", tags=TAG, period=1, limit=50)["results"] # The news half needs no model — the scores are already on the rows. scores = [float(n["sentiment_score"]) for n in news if n.get("sentiment_score") is not None] print(f"news sentiment over {len(scores)} articles this week: " f"mean {statistics.mean(scores):+.2f}, median {statistics.median(scores):+.2f}") print(f"podcast episodes mentioning {TAG} this week: {pods['total']}\n") print("Episodes to feed an LLM (title + description, no transcript needed):") for p in pods["results"][:5]: desc = (p.get("short_description") or "").strip().replace("\n", " ") print(f"- {p['source']['name']}: {p['title'][:58]}") print(f" {desc[:96]}...")
02

Classify the descriptions

Pass the titles and descriptions to a model in one batched call and ask for a label per episode. Batching matters: five separate calls cost five times as much and give the model no way to calibrate one episode against another.

Classify each episode's stance on Ethereum as bullish, bearish or neutral. Return one JSON object per episode with the title and a one-line reason.

What it prints

Produced by running the code above against the live API, not written by hand.

news sentiment over 50 articles this week: mean +0.32, median +0.43 podcast episodes mentioning ethereum this week: 20 Episodes to feed an LLM (title + description, no transcript needed): - Thinking Crypto News & Interviews: THE CLARITY ACT IS IN TROUBLE! DEMOCRATS REJECT NEW CRYPTO Crypto News: Democrats reject the Republicans new Clarity Act draft bil but are sending over a c... - ETH Daily - Ethereum News: Ethereum And Base Split On Account Abstaction Ethereum core developers and Base to ship different account abstraction standard. Balancer gover... - Milk Road Radio: Dan Tapiero: Crypto Is Entering a Much Bigger Bull Market Dan Tapiero, founder and CEO of 50T Funds, joins the show to explain why he believes the crypto ... - Bankless Podcast: Crypto is Ready for Onchain Options | Nick Forster, CEO of Getting the direction of ETH right doesnt guarantee you survive the trade. Derive co-founder Nic... - Thinking Crypto News & Interviews: HUGE CLARITY ACT NEWS! DEMOCRATS MEET TO DISCUSS CRYPTO BI Crypto News: Democrats reject the Republicans new Clarity Act draft bil but are sending over a c...

Actual output, 15 Sep 2026. The mean of +0.32 is the number to be careful with: the single largest Ethereum story that week scored -2, and averaging it against 49 quieter items produces a reading of mild optimism that no human following the story would recognise. Weight by recency or by outlet, or report the distribution rather than the mean.

Variations

The same shape, pointed somewhere else. Every figure below came back from the live API.

Follow one show

sources scopes to a single feed — Bankless alone has 1,393 indexed episodes, which is enough to track one show's stance over time rather than the circuit's.

get("/items/podcasts/", sources="bankless_podcast", period=1, limit=20)

Report the distribution, not the mean

The mean hides the story. Counting the buckets keeps the -2 visible instead of averaging it into mild optimism.

from collections import Counter print(Counter(n["sentiment"] for n in news))

Cross-check against video

121 YouTube channels are indexed the same way and take the same filters, so the same script runs over a second medium by changing one path.

get("/items/videos/", tags=TAG, period=1, limit=8)

Before you build on this

Some tags return zero for a project that clearly has coverage

tags=lido returns 0 governance items. A tag only matches content through its keywords, and a tag filed with none never matches anything. Check a tag returns results before building a scheduled job on it.

Sentiment is per article, not per project

Each news item carries sentiment (-2 to +2) and sentiment_score. There is no project-level mood field — averaging is your call, and a mean over 50 articles can read positive in a week whose single biggest story scored -2.