The 300-Headline Problem Every Crypto News API Ignores
Open any generic crypto news API and you get a firehose: every press release, every influencer take reformatted as a headline, every project's own blog post syndicated by six different aggregators. On a normal day, roughly 300 to 500 raw stories hit our ingestion pipeline from free RSS/Atom feeds, venue announcement channels and project feeds. Maybe fifteen to forty of them actually move a market.
Sentiment-tagging that firehose doesn't solve the problem — it just puts a polarity score on noise. If you're building a trading signal, an agent, or a research dashboard, you don't need to know a headline exists. You need to know whether it was a catalyst: something that actually changed how a coin traded afterward.
That's the gap CryptoDataAPI's /api/v1/news suite fills. It doesn't sell you headlines. It sells you a filtered tape of the stories that cleared an impact threshold, plus the tools to check whether the filter is doing its job.
How 500 Raw Stories Become 15-40 Real Catalysts
Every story that comes in passes through a noise gate, an entity resolver (does this actually name a Hyperliquid perp or the broader market?), and an impact scorer that has to clear a minimum threshold. Sub-threshold stories are discarded outright — there is no raw-feed endpoint at any tier to fall back on.
You don't have to take the funnel's word for it. GET /api/v1/news/sources publishes the last 24 hours of funnel counts per stage, so you can see exactly how much got thrown away and why:
| Funnel stage | What it means |
|---|---|
ingested | Raw stories pulled from all feeds this hour |
dropped_noise | Duplicate, syndicated, or clearly non-market content |
dropped_no_catalyst | Real story, but nothing that qualifies as market-moving |
dropped_no_entity | Couldn't be tied to a specific coin or the broader market |
dropped_below_threshold | Matched an entity and a category, but scored too low |
qualified | Cleared every gate — this is what /news/market-moving serves |
That endpoint also reports not_modified per source, which distinguishes "this feed answered 304, nothing new" from "this feed is dead" — two situations that otherwise look identical from the outside.
What's the Difference Between News Coverage and News Pressure?
This is the single most useful distinction in the entire suite, and it lives in one endpoint: GET /api/v1/news/pulse.
Every active Hyperliquid perp gets two related but different numbers:
headlines— raw attention. How many stories in the current window name this coin at high confidence, whether or not any of them qualified as a catalyst.news_pressure(0 to 1) — a recency-weighted, saturating sum of impact scores. This only counts stories that survived the funnel above.
The catalyst funnel discards roughly 95% of what it reads. That means a coin can sit at headlines: 40 and news_pressure: 0 at the same time — it's being talked about constantly, and none of it is actually moving anything. That's a meaningfully different state from a coin with headlines: 2 and news_pressure: 0.8, where one story is doing real work.
Every active perp gets a row in /news/pulse, even at zero — a cross-sectional ranking needs the zeros as much as the spikes, and a silently missing symbol would be indistinguishable from a pipeline failure.
market_response: Checking Whether the Catalyst Actually Moved Price
Most news APIs stop at the headline. Ours keeps watching. Pro Plus rows on /news/market-moving and /news/coin/{symbol} carry a market_response object: the measured price move at +15 minutes, +1 hour and +4 hours after the story broke.
This turns "impact score" from a black-box prediction into a checkable claim. If a story scored high on impact but market_response shows a flat price four hours later, you can see that directly — the scoring model isn't hiding behind vibes.
Combined with bias (signed — negative is risk-off) and corroboration (how many independent sources carried the same symbol and category inside the window, the strongest single signal that a story is real and not syndicated), you get three independent checks on every catalyst: did multiple sources report it, which direction did it point, and did price actually respond.
A Worked Example: Screening /news/pulse for Risk-Off Setups
Here's a minimal screen for coins under active negative news pressure — high news_pressure, negative news_tilt — the kind of setup you'd want to flag before sizing a position:
import httpx
API_KEY = "cdk_live_your_key"
BASE = "https://cryptodataapi.com/api/v1"
resp = httpx.get(
f"{BASE}/news/pulse",
params={"hours": 24},
headers={"X-API-Key": API_KEY},
)
rows = resp.json()["rows"]
risk_off = [
r for r in rows
if r["news_pressure"] > 0.4 and r["news_tilt"] < -0.2
]
risk_off.sort(key=lambda r: r["news_pressure"], reverse=True)
for r in risk_off[:5]:
print(f"{r['symbol']:<6} pressure={r['news_pressure']:.2f} tilt={r['news_tilt']:+.2f} events={r['event_count']}")
Flip the sign on news_tilt and you have the risk-on screen instead. Because every perp gets a row, this works as a true cross-sectional rank — you're scanning the whole Hyperliquid universe in one call, not just checking a watchlist.
The Filtered Catalyst Tape: GET /news/market-moving
When you want the actual story behind a pressure spike, not just the number, /news/market-moving is the tape:
curl -s "https://cryptodataapi.com/api/v1/news/market-moving?symbol=SOL&hours=48" \
-H "X-API-Key: cdk_live_your_key" | python -m json.tool
A qualified event on a Pro Plus key looks like this:
{
"events": [
{
"event_id": "evt_9f2a1c",
"symbol": "SOL",
"title": "Major exchange pauses SOL withdrawals after validator incident",
"url": "https://example-feed.com/sol-withdrawal-pause",
"source": "venue_announcements",
"published": "2026-08-25T14:02:11Z",
"category": "exchange_risk",
"impact_score": 0.81,
"bias": -0.64,
"corroboration": 3,
"severity": 0.78,
"confidence": 0.86,
"match_mode": "cashtag",
"sources": ["venue_announcements", "rss_coindesk", "rss_theblock"],
"market_response": {
"15m": -1.9,
"1h": -3.4,
"4h": -2.1
}
}
],
"count": 1,
"window_hours": 48,
"impact_threshold": 0.35,
"tier_scope": "pro_plus",
"as_of": "2026-08-26T09:15:00Z"
}
Note the shape of the recovery: -1.9% at 15 minutes, -3.4% at the low, then back to -2.1% by four hours. That trajectory — not just the initial score — is what market_response is for.
Free vs Pro vs Pro Plus: What Each Tier Actually Sees
| Tier | Coverage | Window | Extras |
|---|---|---|---|
| Free | BTC, ETH, MARKET only | Last 24h, top 10 rows | — |
| Pro | Every active Hyperliquid perp | 7-day window | Full /news/pulse universe |
| Pro Plus | Every active Hyperliquid perp | Full retained history | Score components (severity, confidence, match_mode, sources) + market_response |
The tier boundary is coin coverage, history depth and score detail — never the noise threshold. A free-tier BTC event and a Pro Plus BTC event cleared the exact same filter.
When to Use This (and When Not To)
Be honest about latency: this is RSS-based, so stories land roughly 30 seconds to 5 minutes after the source publishes. That's fast enough for a context feed, a risk-off screen, or an event study — it is not fast enough to win a listing-sniping race, and it isn't sold as one.
The one exception is exact and immediate: hl_listing and hl_delisting events come from CryptoDataAPI's own Hyperliquid universe diff, not RSS, so there's no feed lag to inherit.
Use this suite for:
- Filtering position sizing or entries around measured risk-off pressure (
/news/pulse) - Explaining a price move after the fact with a corroborated, scored event (
/news/market-moving) - Backtesting whether "news reaction" strategies would actually have worked, using
market_responseas ground truth - Monitoring your own data quality via
/news/sourcesbefore trusting a quiet day
Don't use it as a millisecond-latency trigger for anything except HL listings — that's the one case actually built for it.



