Token Narrative Pulse is a small Python script for crypto sentiment analysis. For a token watchlist it pulls the last 24 hours of X posts and Reddit threads and writes a daily report: mentions per token, unique authors, top posts and a bullish, bearish or neutral breakdown with cited links.
The problem
Crypto narratives move fast on X and Reddit. Analysts want a daily read on which tokens people talk about, how many different people, and in what tone, without bot spam inflating the numbers.
What the app does
- Takes a watchlist of tokens and terms.
- Pulls Top and Latest X posts per term from the last 24 hours.
- Runs AI Search on Reddit and on X plus Reddit for a sentiment breakdown with links.
- Counts mentions and unique authors per token.
- Flags duplicates and template bot posts.
- Writes a report, a CSV of posts and a mentions chart.
How it works
- X search.
GET /twitterthrough thedesearch-pySDK,sort=Topandsort=Latest, start date yesterday. - AI Search.
POST /desearch/ai/searchwithtools=["reddit"]andtools=["twitter","reddit"]. - Clean. Drop posts older than 24 hours, duplicates and template bots.
- Write the report and a cost log.
The code
async def collect(count, outdir, raw_dir):
now = dt.datetime.now(dt.timezone.utc)
since = now - dt.timedelta(hours=24)
start_date = since.strftime("%Y-%m-%d") # GET /twitter takes a UTC day, not a timestamp
costs, x_raw, ai_raw = [], {}, {}
async with Desearch(api_key=os.environ["DESEARCH_API_KEY"]) as ds:
print("X search (GET /twitter via desearch-py x_search):")
for label, (query, _) in WATCHLIST.items():
for sort in ("Top", "Latest"):
data = await timed(costs, f"x_search {query!r} sort={sort}",
ds.x_search(query=query, sort=sort, count=count,
start_date=start_date, include_metadata=True))
x_raw[f"{label}|{sort}"] = dump(data) or []
print("AI Search (POST /desearch/ai/search via desearch-py ai_search):")
terms = " OR ".join(q for q, _ in WATCHLIST.values())
for tools in (["reddit"], ["twitter", "reddit"]):
data = await timed(costs, f"ai_search tools={tools}",
ds.ai_search(prompt=f"What are people saying in the last 24 hours about {terms}?",
tools=tools,
result_type="LINKS_WITH_FINAL_SUMMARY",
system_message=SYSTEM_MESSAGE, count=10,
include_metadata=True))
ai_raw["+".join(tools)] = dump(data) or {}
json.dump({"generated_utc": now.isoformat(), "x": x_raw, "ai": ai_raw, "costs": costs},
open(os.path.join(raw_dir, f"raw-{now:%Y-%m-%d}.json"), "w"), indent=1, default=str)
return now, since, x_raw, ai_raw, costs
The folder has one script, pulse.py, a sample report in sample-output.md and the chart from that run.
Endpoints
GET /twitterPOST /desearch/ai/search
Example output
From a run on 2026-10-03 for a Bittensor watchlist, 24-hour window:
| Token | Mentions | Unique authors |
|---|---|---|
| TAO | 45 | 42 |
| Bittensor | 31 | 29 |
| Chutes (SN64) | 3 | 2 |
| Desearch (SN22) | 1 | 1 |
94 posts returned, 85 unique, 63 inside the window. These are counts inside a sample, not total X volume.
Run it yourself
The public examples folder linked above includes the script and a README. Install its requirements, set DESEARCH_API_KEY from console.desearch.ai, and use the run command in that README.
Useful flags: --count (posts per X query, default 20), --from-raw FILE (re-run with no API calls). Edit WATCHLIST in pulse.py to change tokens.
What it costs
One run with the default watchlist made 10 calls, took about 75 seconds and cost $0.026 on 2026-10-03, from the X-Desearch-Cost-Usd headers. See pricing.
Ideas to extend it
- Run it every morning and chart mentions over time.
- Alert when unique authors for a token jump.
- Add on-chain data next to the social view.