A stock news API for trading bots.
By the request.
The same feed that powers AlphAI, served as plain JSON. Every article arrives scored for relevance and linked to tickers, so a trading bot or an agent backend can filter the wire at request time. Auth is one Bearer header.
curl https://api.alphai.io/api/news/ \
-H "Authorization: Bearer $ALPHAI_API_KEY" \
-G -d "symbol=NVDA" -d "min_relevance=7"Financial news over REST and MCP, scored before you read it.
- Endpoint
- Plain JSON over HTTPS, cursor-paginated. Full OpenAPI 3.1 spec at api.alphai.io/api/schema/.GET https://api.alphai.io/api/news/
- Auth
- One header, sent from your server (the API is server-side only, no CORS). Create a key in your account, no credit card.Authorization: Bearer ak_live_…
- Filter server-side
- Symbol, category, minimum relevance and delta polling are query params, so the wire is cut before it costs you a token.?symbol=NVDA&min_relevance=7&sort=ingested
- Every row carries
- A relevance score from 1 to 10, the tickers the story affects, per-ticker sentiment with written reasoning, the publisher URL and domain, and both publication and ingest timestamps.
- For agents
- An MCP server serving the same feed as tools: news search, ticker feed, trending, insider, calendar, macro and alerts.https://mcp.alphai.io/mcp
- Free tier
- One key at 20 requests a minute and 100 a day. Enough to evaluate the feed and build a prototype.
Rows that cleared the relevance floor with a verified ticker or a market-wide macro tag. This is the set a request to /api/news/ pages through.
Scored, tagged, and already live on the API.
Mention counts across those articles. Query any of them with ?symbol=, or open one to see the rows behind the count.
Fresh
New articles land within the hour of publication; SEC filings become feed rows in minutes (median ~6). Poll the feed on your own schedule.
Ticker-linked
Articles carry machine-extracted tickers, and every ticker gets its own analysis.
Relevance-scored
Every article carries an LLM-assigned relevance score (1–10). Filter at request time.
SDK optional
Plain JSON over HTTPS. Bring any HTTP client, or install the official typed Python / TypeScript SDK if you prefer one. No lock-in either way.
Where the data comes from.
Most financial-news APIs hand you a firehose and wish you luck. We filter before a story ever costs you a request, so what reaches the API is the part worth a model's context window.
Collect
A GDELT-driven monitor watches the global financial press around the clock, while a second worker tails SEC EDGAR for Form 4, 8-K and 6-K filings. Hand-curated publisher RSS feeds fill the gaps neither catches. Everything lands in one feed.
Enrich
An LLM pass scores each article 1–10 for relevance, assigns it a topic category, and writes per-ticker sentiment with a confidence level and reasoning.
Validate
Extracted tickers are checked against the active-symbol list and the article text itself. Hallucinated symbols get dropped, PR-wire spam domains are blocked outright, and near-duplicates collapse into one row.
Serve
Only articles that clear the relevance floor and carry at least one verified ticker reach the API. Fewer than 1 in 5 makes the cut, from 6,900+ monitored sources, so the noise never reaches your parser.
A real row, from the feed, right now.
An excerpt from the newest article scoring 8 or higher at render time. It shows selected fields from /api/news/, with the first ticker analysis and shortened reasoning.
Published 00:00 UTC, Oct 26
{
"original": {
"uid": "b7e1a2e7d0ce0edd",
"title": "Is Bloom Energy Corp (BE) Significantly Overvalued Despite Q3 Ea",
"time_published": "2026-10-26T00:00:51Z",
"source_domain": "gurufocus.com",
"url": "https://www.gurufocus.com/news/9141490/is-bloom-energy-corp-be-significantly-overvalued-despite-q3-earnings-beat-gf-score-69100-eps-at-094-revenue-12358m"
},
"enrichment": {
"relevance_score": 8,
"category": "earnings",
"ai_trading_insights": {
"ticker_analysis": [
{
"ticker": "BE",
"impact_analysis": {
"sentiment": "positive",
"confidence": "high",
"reasoning": "Revenue jumped 138% YoY and operating income surged, beating estimates; analysts may upgrade the stock."
}
}
]
}
}
}Typed clients, two languages.
Prefer a typed client to hand-rolled requests? The official Python and TypeScript SDKs include text search, Brief and Radar alongside news and symbols. They handle cursor pagination, retries on 429/5xx, typed errors, and rate-limit inspection for you. They take the same key and return the same data, so you can adopt one later or never.
Both read ALPHAI_API_KEY from the environment and target api.alphai.io by default. Python 0.8.0 and TypeScript 0.7.0 add typed news search, including query interpretation, match context, date windows and cursor pagination. The Python client offers sync and async; the TypeScript client ships zero runtime dependencies.
$ pip install --upgrade alphai-sdkfrom alphai import Client
with Client() as c:
search = c.news.search(query="Jane Street", page_size=5)
print(search.query.mode, search.query.note)
brief = c.news.brief(tickers=["NVDA", "AMD"])
print(brief.events_truncated, brief.filings_truncated)
page = c.radar.snapshot(limit=3)
for reading in page.results:
print(reading.ticker, reading.news_z)$ npm install alphai-sdk@latestimport { AlphaAI } from "alphai-sdk";
const c = new AlphaAI();
const search = await c.news.search({ query: "Jane Street", pageSize: 5 });
console.log(search.query.mode, search.query.note);
const brief = await c.news.brief({ tickers: ["NVDA", "AMD"] });
console.log(brief.events_truncated, brief.filings_truncated);
const page = await c.radar.snapshot({ limit: 3 });
for (const reading of page.results)
console.log(reading.ticker, reading.news_z);Built with the SDK: alphai-news-to-email — a deployable news-to-email digest in Python · alphai-sdk-ts-examples — runnable TypeScript scripts covering the whole API surface. All examples →
Endpoints
stableNews & search
Read the latest financial news. Filter by ticker, category or relevance, and group coverage of the same story.
Usage notes for /api/news/
- Newest first, with cursor pagination. page_size is 1–20 on Free and Basic, up to 50 on Pro (default 10). Pass next_cursor as cursor. limit and ticker are aliases for page_size and symbol.
- Filters: symbol, category, exclude_categories and min_relevance. Categories accept comma-separated or repeated values. from_date and to_date accept ISO dates or datetimes; both are inclusive, and a bare to_date includes the whole day. A window beyond your archive horizon returns 403 on the first page.
- Every row has a permanent story_id, shared with search, trending, MCP and /api/stories/. A lone article uses its own UID. Resolve it with /api/stories/{story_id}/. collapse=story groups reprints and independent coverage of one event, adding sources_count and sources. collapse_stories=true is an equivalent boolean alias; false leaves articles ungrouped. Send only one spelling.
- sort=ingested polls articles in arrival order and always returns next_cursor. Date windows are not allowed in this mode. The first sample may be partial or empty; subsequent successful empty pages mean caught up. See Polling for new articles below.
- source_type accepts gdelt (press), sec_form4, sec_form8k or sec_form6k, comma-separated or repeated. item=5.02 finds officer changes and implies sec_form8k; it matches any item in a filing. Full 8-K results include items, primary_item, accession_number, filed_at, event_date and exhibit_url in a filing block.
Search article titles, summaries and named entities. Combine a text query with the feed’s filters.
Usage notes for /api/news/search/
- q requires words together; use "a phrase", -word or OR (nvidia OR amd) to refine it. One typo is tolerated in words of five or more letters. Results are ranked, newest first among equal matches, up to the best 200, with cursor pagination.
- symbol, category, source_type, item, min_relevance, from_date, to_date and collapse=story remain hard filters. collapse_stories=true also enables grouping; false disables it. Send either collapse or collapse_stories, not both. For example, q=director&item=5.02 searches officer-change filings. Search covers your plan’s archive (30, 90 or 180 days) unless dates narrow it.
- The query block reports strict, broadened or no_match. Broadened results match at least two query words; check search_match for terms_matched and matching text before treating them as matches. A search outage returns 503 with reason search_unavailable; the feed stays available.
Top news from the past 48 hours, ranked by relevance and freshness.
Usage notes for /api/news/trending/
- Includes articles scoring at least 8, with at most two stories per ticker. Repeated coverage is grouped, with story_id, sources_count and sources on each item.
- story_id is shared across the news tools and can differ from the article’s UID. /api/stories/top/ ranks whole stories with their summaries.
Read market-wide news on central banks, inflation, commodities and geopolitics.
Usage notes for /api/news/macro/
- Combines macro_economy, commodities and geopolitics. Most rows have no tickers; analysis is still included. category narrows the selection, and min_relevance=7 focuses roughly on release-day events.
- Uses the main feed’s shape and cursors. from_date and to_date set an inclusive publication window. For polling, use sort=ingested without a date window.
See upcoming US economic releases from official agency schedules.
Usage notes for /api/calendar/
- Covers FOMC decisions and minutes, CPI, PPI, jobs, GDP, PCE, retail sales, weekly jobless claims and JOLTS. FOMC rows include press_conference_at and has_sep for projection meetings.
- Defaults to the next 7 days. from_date and to_date accept dates or ISO datetimes (from inclusive, to exclusive). event_key selects series; importance filters by tier.
- A release keeps its uid if rescheduled. phase is upcoming or elapsed; elapsed means the scheduled time passed. Check schedule_status for postponements or cancellations. Use /api/news/macro/ for the surrounding news.
Catch up on several tickers in one call, with grouped news, SEC filings and confirmed earnings dates.
Usage notes for /api/news/brief/
- Pass tickers=NVDA,AMD, up to 100 explicit tickers on every plan. hours is 1–168 (default 24); limit is 1–20 per section (default 20). The website and MCP alphai_watchlist_brief use the same brief with your saved watchlist.
- Each section groups the newest 500 matching articles and ranks them by relevance, novelty and recency. events_truncated and filings_truncated flag omitted coverage; unknown_tickers lists unknown symbols. This is a publication-window snapshot, not a changes cursor.
Open an article by UID to get its full AlphAI summary and analysis.
Usage notes for /api/news/{uid}/
- SEC results keep their structured Form 4 insider or 8-K filing blocks. Earnings filings add a completed earnings read when available. MCP alphai_article returns the same data; connector fetch also includes earnings metrics, comparisons, segments, guidance and limitations in citation-ready text.
Find up to six related articles, prioritizing recent news about the same tickers.
Usage notes for /api/news/{uid}/related/
- Uses same-category articles to fill remaining slots.
Stories
The leading stories from the past 48 hours, each covered by at least two publishers.
Usage notes for /api/stories/top/
- Ranks events with independent coverage. The score is importance (7 or above on the 1–10 scale), plus min(3, log2(publishers)), minus one point per 12 hours since key facts last changed. One slot per ticker, two per no-ticker macro category; up to 50 cards, no pagination. ranking_version identifies the formula.
- Cards include story_id, summary title and lead, importance, category, tickers, publishers, materials, first_published_at, last_material_at, updated_at and summary_state. The state is published, stale if articles joined after the summary, or preparing (lead-article text until a summary is ready). /api/news/trending/ ranks articles rather than whole stories.
Browse stories by their newest article, with a summary of each story when ready.
Usage notes for /api/stories/
- Uses the same cards as the top list, with cursor pagination. page_size is 1–50 on every plan (default 20); limit is an alias. Pass next_cursor as cursor. Paging beyond your archive horizon returns 403.
- A story moves up as articles join it and its summary is rewritten. Reading the same story_id later can return different text; updated_at records when the facts last changed.
Read a story summary with sourced facts, per-ticker analysis and open questions.
Usage notes for /api/stories/{story_id}/
- Includes title, lead, why_it_matters, up to six key_facts with publisher and source_uid, ticker_takes and uncertainties. based_on and materials_at_build show source coverage; new_materials, revision_generated_at and model describe the summary revision.
- status=found returns the story; merged supplies redirect_to; not_a_story identifies a single-publisher event in article for /api/news/{uid}/. Unknown IDs return 404. An article’s story_id is not always a current story.
- Every figure comes from a source article, with no passage copied beyond a dozen words. Article bodies are never returned. Stories beyond your archive horizon return 403.
Get the articles behind a story, oldest first, with links to their publishers.
Usage notes for /api/stories/{story_id}/materials/
- Cursor-paginated: page_size is 1–50, default 50. Each entry has uid, title, publisher, time_published, publisher URL, relevance_score and seo_eligible. Open a UID with /api/news/{uid}/; key_facts cite these entries by source_uid.
- Only current stories have materials. Resolve merged or single-publisher IDs through /api/stories/{story_id}/ first.
Filings & earnings
Find SEC Form 4 trades by company insiders. Download matching events as JSON or CSV.
Usage notes for /api/news/insider/
- Each insider block includes side, shares, average price, total value, 10b5-1 status, owner and filed_at. late_filing flags filings beyond the two-business-day deadline. Uses the feed’s cursors and page sizes: default 10, up to 20 on Free/Basic or 50 on Pro. limit and ticker aliases work here too.
- Filter by symbol and min_relevance. Sales score at most 6; a floor of 7 selects purchases of about $1M or more, plus rare large issuer buybacks from holders who retain a stake. is_10b5_1=false excludes prearranged-plan trades; true selects them.
- This endpoint always selects category=insider. category, exclude_categories and story-grouping parameters belong to /api/news/; they are not accepted here.
- from_date and to_date bound publication time (when the filing reached the feed), not the trade date. For new arrivals, use sort=ingested without a date window: a trade reported days later can enter below the newest page.
- format=csv flattens the insider fields into one row per event, with the same filters. A file holds up to 500 rows on Free, 2,000 on Basic or 10,000 on Pro, within your archive window, and counts as one request. X-Alphai-Truncated explains planned limits.
- Before continuing, check the stream completed and the parsed data-row count matches X-Alphai-Rows. Discard a partial file and retry the original request. X-Alphai-Next-Cursor continues the export and also works with JSON; other endpoints remain JSON-only.
Find companies where several insiders bought shares on the open market, with links to the SEC filings.
Usage notes for /api/news/insider/clusters/
- Purchases form a cluster when consecutive trade dates are at most 10 days apart, up to a 30-day episode. Every purchase is checked before a buyer counts.
- The default list excludes IPO/PIPE allocations, ESPP/DRIP and director-plan purchases, unpriced units or note exchanges, and duplicate ownership reports. Price patterns and filing footnotes help identify offerings. Buyer roles are independent, plan_like, unpriced or duplicate_of. Use pattern=plan_or_offering, holders_only or all to inspect the others.
- buyers counts independent buyers; buyers_total counts everyone. days uses known_at, when the latest filing reached EDGAR: default 30, maximum 30 on Free and 90 on Basic/Pro.
- Filter with min_buyers, min_usd and symbol (including former symbols and share-class siblings). Sort by recent, buyers or value and page with next_cursor. Each result includes accession numbers, EDGAR links and news UIDs for /api/news/{uid}/.
Summarize a ticker’s insider activity over the past 30 days.
Usage notes for /api/symbols/{ticker}/insider-summary/
- Includes buy/sell counts, dollar volumes, the share under 10b5-1 plans and the most active insiders.
Get a ticker’s Form 4 trade history with aggregates ready for charts.
Usage notes for /api/symbols/{ticker}/insider-trades/
- The first page includes 3-month, 12-month and all-time rollups, active insiders, zero-filled weekly/monthly dollar buckets, and chart_events for the trailing 12 months. Events include stake_change_pct (negative for sells), tranche_count and news_uid for the article.
- A code D sale to the issuer counts as sell here; the feed’s insider block calls it other. Check transaction_code. page_size goes up to 200 on every plan; side filters the paginated list and cursor continues older history.
Find a ticker’s latest AlphAI earnings read.
Usage notes for /api/symbols/{ticker}/earnings/latest/
- Returns a pointer to an 8-K item 2.02 or a foreign issuer’s 6-K earnings read. Open it through /api/news/{uid}/. Returns 204 when no read exists, or 404 for an unsupported ticker.
Read a company’s earnings reports from SEC filings and find its next confirmed report date.
Usage notes for /api/symbols/{ticker}/earnings/
- Newest first, capped at 20 reads without pagination. Coverage starts in late July 2026, so a ticker may have only one or two reports. An empty list means no read is available. Share classes share coverage; each row’s ticker names the filing’s class.
- Reads are produced from the filing with figures checked against its text. next_report_date is company-confirmed, never an estimate; null means no confirmed date on file. Confirmed dates usually appear about five weeks ahead.
- key_metrics and segments preserve printed values and add numeric, unit and scale. scale is null if the filing gives no unit. table_scale is the filing tables’ unit, also used for figures quoted without a unit in the notes and analysis.
Tickers
Look up supported tickers by symbol, company name or brand.
Usage notes for /api/symbols/
- Returns name, sector, exchange, country and currency, alphabetically. The full list is returned by default (about 10k); use limit and offset to slice it.
- search resolves names, brands and ticker prefixes: search=bitcoin returns BTC-USD; search=spacex returns SPCX.
Discover recently covered tickers and browse sectors.
Usage notes for /api/symbols/directory/
- Sector cards include the total number of index-eligible tickers and the most-covered names.
Browse a sector’s tickers, ordered by news coverage and then symbol.
Usage notes for /api/symbols/sectors/{slug}/
- Pass page=1, 2, … for up to 500 tickers per page; continue while has_next is true. count describes the page, total_count the sector. Pages beyond the end return an empty symbols array. Rankings refresh periodically.
Get company details for one ticker, including renamed or delisted symbols.
Usage notes for /api/symbols/{ticker}/
- Check status and renamed_to for a successor symbol. News queries include former ticker tags and other listed share classes of the issuer (GOOGL includes GOOG).
See seven days of bullish, neutral and bearish news counts for one ticker.
Usage notes for /api/symbols/{ticker}/sentiment-summary/
- Covers the last seven UTC calendar days, including today; totals sum the daily buckets.
Find related companies in the same industry with recent news coverage.
Usage notes for /api/symbols/{ticker}/peers/
- Returns up to ten tickers, most recently covered first. Widens to the sector if the industry has too few matches. An unknown but well-formed ticker, or one with no covered peers, returns an empty list.
Radar & coverage
Find tickers getting more news coverage than usual, across the market or your saved watchlist.
Usage notes for /api/signals/snapshot/
- Choose a 4h or 24h window and filter exact tickers, market and sentiment. Free: 60 min delay; Basic: 15 min delay; Pro: no added delay. Snapshots refresh every minute; processing time is additional. Cursors keep one complete snapshot, including supporting headlines.
- Scores describe news activity, not price forecasts or confirmed alerts. event_context adds recent SEC filings and insider clusters with their own cutoff and availability. Filings include news_uid, news_title, news_published and has_article for article links; older snapshots use false with null title/publication metadata. sec_url keeps the original SEC link. See the Radar section below for full usage notes.
Check what each news source covers, how far its history goes and when it last updated.
Usage notes for /api/coverage/
- Returns the coverage passport shown below. If an uncached report is already being computed, the endpoint returns 503 with reason coverage_unavailable and Retry-After: 30.
Send Authorization: Bearer ak_live_… from your server. Per-minute and per-day quotas apply to your account, across all its keys. Free is for evaluation and non-commercial use; production requires a paid plan.
The same key works with MCP. See MCP setup and tools for OAuth connections, permissions and compact news responses.
Polling for new articles
Use sort=ingested to follow new arrivals, including articles published earlier that reached AlphAI late. It works on the main feed and the insider feed. Keep your cursor between runs.
- Call once without a cursor, then save next_cursor. The first response is a recent sample and may be partial or empty. Use published order to read older history.
- Keep sort and filters unchanged when continuing. Date windows (from_date and to_date) are not supported with sort=ingested. Using a cursor from the other sort mode returns 400.
- After the first request, keep reading until a successful empty results page. A short nonempty page can still have more results. Responses are cached for 60 seconds.
- A 409 with reason delta_scan_incomplete supplies extra.next_cursor: continue from it. A 503 with reason delta_candidates_changed means retry the original request. Neither error means you are caught up. SDK iterators raise the 409, so callers must resume explicitly.
# pip install --upgrade alphai-sdk
import time
from alphai import APIStatusError, Client
cursor = None # restore your saved cursor when restarting
with Client() as client: # reads $ALPHAI_API_KEY
while True:
while True:
try:
page = client.news.list(sort="ingested", cursor=cursor, page_size=20)
except APIStatusError as error:
reason = error.extra.get("reason")
if error.status == 409 and reason == "delta_scan_incomplete":
cursor = error.extra["next_cursor"]
# Persist this cursor too: repeating the old one cannot help.
continue
if error.status == 503 and reason == "delta_candidates_changed":
time.sleep(5)
continue # same cursor and filters
raise
for article in page.results:
print(f"[{article.relevance_score}/10] {article.title}")
cursor = page.next_cursor # persist after processing the page
if not page.results:
break
time.sleep(900)This example uses the Python SDK. The TypeScript SDK supports the same sort option, or you can call the REST endpoint directly.
Timing and quota sizing
Measured July 25, 2026: general news arrived a median of about 33 minutes after publication; SEC filings took 5–9 minutes. Form 4 trade dates can be days earlier still. Tracking only time_published will miss late arrivals.
Budget enough calls to drain every page. As a sizing example, roughly 2,700 rows a day at the default score floor of 4 need about 135 calls with page_size=20, plus one empty confirming call per wake-up (96 at the 15-minute interval above). A min_relevance=7 stream of roughly 1,000 rows needs fewer calls. Basic and Pro have the budget for the full-feed example. On Free’s 100 calls a day, narrow the stream with min_relevance, symbol or category, or poll less often. If calls per day × page_size falls below new arrivals, the cursor falls behind.
Radar
Find the names that need a closer read.
Rank unusual news activity across the market or your saved watchlist. Each ticker brings story counts, expected activity, news tone and the headlines behind the reading. Follow the evidence before acting.
Every plan sees the same eligible markets and can use its saved watchlist. Plans change the added delay, with no separate Radar ticker allowance. Collection and enrichment take additional time; always read as_of.
- free
- 60 min delay
- basic
- 15 min delay
- pro
- No added delay
curl -G https://api.alphai.io/api/signals/snapshot/ \
-d tickers=AAPL,MSFT -d window=24h \
-H 'Authorization: Bearer YOUR_API_KEY'scope=market is the default. Use scope=watchlist for the authenticated account’s saved symbols. tickers is an exact, comma-separated filter within that scope; ticker selects one symbol instead. There is no alias expansion.
window=4h|24h ends at the selected data cutoff. Filter market by all, us_equity, crypto or international. Use sentiment=negative or sort=sentiment_change&order=asc to find deteriorating news tone. Other sorts: score (default), stories, model_stories and sentiment. Missing metrics always sort last.
limit accepts 1–100 on every tier (REST default 50, MCP default 20). Pass next_cursor as cursor with identical filters and limit. It pins the full snapshot, including supporting titles. On 409, restart without the cursor. Snapshots refresh every minute and stay available for three hours. API/MCP quotas still apply.
as_of is the actual cutoff; access.delay_seconds is the applied plan delay. freshness records generation time, the last source check and the latest enrichment observed. A stopped producer or missing eligible history returns 503, with no substitution of newer data.
stories includes broad coverage. model_stories excludes it and is compared with stories_expected, adjusted for activity across the same market. news_z is descriptive, not a price forecast or confirmed alert. Collection coverage is unverified. Null metrics include a reason; missing news tone is not neutral. Historical corrections can affect the baseline, so this is not a point-in-time backtest.
MCP: call alphai_radar with the same filters and your existing OAuth connection or API key. Open an evidence UID with alphai_article. For a quiet or uncovered saved symbol, inspect watchlist_coverage instead of treating an absent row as a zero score.
event_context reports the SEC/insider cutoff, generation time, availability and age_seconds at the news snapshot’s cutoff. Context older than max_age_seconds=300 is unavailable. Read its status before using results[].event_context; a missing row context is null, never zero.
Each row’s context includes up to three recent 8-K/6-K filings over seven days by filed_at, and up to three open-market insider clusters over 30 days by known_at (the latest SEC filing time). Counts cover all eligible records; the arrays contain the newest. Clusters include independent buyer and officer/director counts, trade dates and up to five sec_url evidence links, with filings_count and evidence_truncated.
Context is shared by instruments with the same SEC CIK. 6-K coverage is selected earnings releases only; available context does not certify complete collection. Unsupported or unidentified issuers carry a status/reason and null counts. Supported issuers with no eligible records have zero counts. SEC observations follow the same delay and cursor as news, without changing scores, ranking or which tickers appear. No USD total is reported.
What the fields mean.
Every news item ships an enrichment block produced by an LLM pass over the article. These are the four fields you'll use most.
Scores rate the article, not the company it mentions: a recap of a mega-cap's week-old earnings scores low, while a small-cap's fresh FDA approval scores high. Scoring is deterministic: the same article always gets the same score, and SEC Form 4 filings are scored from the transaction itself (size, buy vs. sell, 10b5-1 plan or not) rather than by the model.
Need the formal contract? The interactive API reference lives at /api/schema/swagger-ui/ (Swagger UI, with the raw OpenAPI spec linked at the top).
How much trading value the article itself carries.
- 1–2 · no trading relevance — lifestyle, solicitations, short-interest scrapes.
- 3–4 · derivative content about already-known events — opinion pieces, recaps, 13F stake writeups, market wraps.
- 5–6 · macro/sector datapoints with read-across; minor-but-real company news.
- 7–8 · real company news — analyst actions with a thesis, settlements, clinical data, same-day moves with a fresh catalyst.
- 9–10 · primary, material, newly disclosed — M&A, prints with numbers, approvals, major contracts.
The /api/news/ feed defaults to ≥ 4; pass ?min_relevance=N to relax or tighten the filter.
Per-ticker price impact direction. Not earnings-positive vs earnings-negative — this is "where will the chart move on this story."
- positive — bullish
- neutral — sideways
- negative — bearish
Each ticker block also carries impact_analysis.confidence (high / medium / low) and a free-text reasoning field, which helps when you filter an automation pipeline down to confident bullish or bearish signals.
One topic bucket per article. Use ?category=earnings (CSV or repeated for OR-matching) on /api/news/ to filter the feed, or ?exclude_categories= to drop buckets you never trade on.
The numbers are article counts from the last 7 days of the live feed, refreshed every 15 minutes.
Tickers extracted from the article. We only retain symbols that exist in our /api/symbols/ list of active symbols (US equities, cryptocurrencies, and foreign listings), so articles that don't mention any active ticker are filtered out before they reach the API. US equities use the bare symbol, cryptocurrencies use a -USD suffix like BTC-USD, and foreign listings use a Yahoo suffix like VOD.L. Each ticker also gets a dedicated ticker_analysis entry with sentiment and reasoning, so multi-ticker stories don't collapse to a single read.
One real event reported by N outlets is N rows by default. Add ?collapse=story on /api/news/ to get one row per story instead — the representative article carries story_id (the story root's UID, which here equals the row's own UID and resolves via /api/news/{uid}/), sources_count (how many distinct outlets ran it, usually 1 because most stories are carried by a single outlet), and sources (the distinct domains). These fields are null in the default feed. Filters like symbol and category apply to the representative row, so a story whose representative doesn't match is omitted.
Form 4 filings, as news.
A dedicated worker tails SEC EDGAR and turns every Form 4 filing (officer and director buys and sells) into a feed row shortly after it's filed. One row covers one economic event: all of a filing's non-derivative trades of the same type and holding form, aggregated into a single article. The JSON shape matches every other article, so your parser doesn't need a special case.
Form 4 summaries are deterministic templates built from the filing itself: insider name, role, transaction code, total shares, price (volume-weighted average and executed range when a sale runs across tranches), and total value. There is no LLM paraphrase between you and the disclosure. The relevance score is computed from the event itself — its total size, buy vs. sell, 10b5-1 plan or not — so it's reproducible.
GET /api/news/insider/— the Form 4 insider feed, cursor-paginated,?symbol=to scope.GET /api/news/insider/clusters/— cluster buys: several different insiders of one issuer buying on the open market in one run, with plan lots, offering allocations and duplicate filings labeled per buyer.GET /api/news/?category=insider— the same rows through the main feed's category filter.GET /api/symbols/{ticker}/insider-summary/— 30-day rollup: buys vs. sells, dollar volumes, % under 10b5-1 plans, most active insiders.GET /api/symbols/{ticker}/insider-trades/— the chart payload: complete event history with 12-month rollups, weekly dollar buckets and per-event stake impact, loadable in one request.GET /api/symbols/{ticker}/sentiment-summary/— its sibling: 7-day bullish / neutral / bearish counts from the news flow.
The SEC Form 4 API, in detail →
Coming from yfinance? What it covers, and what it does not →
{
"ticker": "NVDA",
"days": 30,
"total_transactions": 14,
"buy_count": 2,
"sell_count": 12,
"buy_value_usd": "1240000.00",
"sell_value_usd": "224580213.05",
"pct_10b5_1": 64,
"top_insiders": [
{
"name": "STEVENS MARK A",
"title": "Director",
"transaction_count": 3,
"net_value": "-221102600.00"
},
{
"name": "Dabiri John",
"title": "Director",
"transaction_count": 1,
"net_value": "-133750.00"
}
]
}Value fields are decimal strings in USD; buy_value_usd / sell_value_usd are null when the window has no buys or sells. net_value is buys minus sells per insider; title can be empty when the filer reports as a director without an officer role.
What an API-connected bot can do.
From watchlist alerts to Telegram bots, it's the same JSON in whatever stack you run. The API stays out of your way.
"Claude, what moved NVDA today?"
alphai_news_search → MCP
Try it"Send only high-relevance earnings news for my watchlist."
/api/news/?category=earnings · min_relevance=7
Try it"Build a Telegram bot for market-moving news in 10 minutes."
/api/news/trending/ + your bot framework
Try it"Any insider buying in my watchlist this week?"
alphai_insider_news → MCP · /api/news/insider/
Try it"Feed my agent relevance-scored financial news via MCP."
OAuth 2.1 · News & watchlist tools · Streamable HTTP
Try itTry the API right here.
Live responses from the real API, proxied through this site so you don't need a login or a key to explore. Direct calls to api.alphai.io always require an API key — sign up for one and metered headroom.
// click Send to fetch a live responsePriced for scale.
Quotas are per account: a per-minute burst cap plus a per-day volume cap. Every keyed response carries X-RateLimit-Limit, -Remaining and -Reset headers, and a 429 adds Retry-After plus your tier's caps and an upgrade pointer in the JSON body. Feed depth is gated per plan: a cursor walked past your archive horizon returns 403 with the same hint, and a from_date window reaching past it gets that answer on the first page; Pro keys page back 180 days. One honest note on the archive: our collectors expanded in June 2026, so months before that hold fewer articles per day than the current feed. Both api.alphai.io and the public /api/news and /api/symbols routes on alphai.io require a key: keyless requests get a 401. To try the API without signing up, use the playground above, which proxies the read-only public endpoints through this site. Send a key for predictable headroom.
| Plan | Rate limit | Archive | Active keys | Radar delay |
|---|---|---|---|---|
| Free | 20 / min · 100 / day | 30 days | 1 | 60 min delay |
| Basic | 60 / min · 10,000 / day | 90 days | 1 | 15 min delay |
| Pro | 150 / min · 100,000 / day | 180 days | 5 | No added delay |
What we hold, from when.
One row per data source: the earliest and latest row we hold, when the newest one arrived, and how many there are. The first row is the earliest we have, not the start of dense coverage, so read the note under each source before you backtest across it. The same passport, with each source's cadence, limits and archive horizon per plan, is the JSON at GET /api/coverage/, recomputed once a day.
| Source | Rows | First row | Last row | Last ingest |
|---|---|---|---|---|
Publisher news The collectors expanded in June 2026, when the GKG bulk collector and the RSS feeds landed together: months before that hold far fewer articles per day, and November 2024 to March 2025 holds fragments only. first_row_at is the earliest article, not the start of dense coverage. | 1,770,633 | Oct 15, 2001 | Oct 25, 2026 | Oct 25, 2026 03:49 UTC |
SEC Form 4 Live collection since May 2026. Filings from August 2025 to May 2026 were replayed from SEC daily indexes in August 2026 without enrichment: they count here and on /api/symbols/{ticker}/insider-trades/, but have no scored article in the news feed. first_row_at is the earliest replayed filing. | 59,363 | Aug 11, 2025 | Oct 24, 2026 | Oct 24, 2026 02:00 UTC |
SEC 8-K Collected since June 2026; there is no 8-K history before that. Until 2026-09-17 filings carrying only items 7.01 or 8.01 (Regulation FD, Other Events — the way debt and convertible offerings are usually filed) were not collected. | 14,981 | Jun 5, 2026 | Oct 23, 2026 | Oct 23, 2026 21:35 UTC |
SEC 6-K Live since 2026-08-28; filings from 2026-07-28 to 2026-08-28 were backfilled. Nothing before 2026-07-28. | 658 | Jul 28, 2026 | Oct 23, 2026 | Oct 23, 2026 20:32 UTC |
Earnings reads Reads exist for filings from 2026-07-28 onward. The analyzer only reads filings younger than its age window, so earlier filings will never get one. | 2,370 | Jun 24, 2026 | Oct 23, 2026 | Oct 24, 2026 04:40 UTC |
Earnings dates One row per ticker holding only the next confirmed report date; there is no history of past dates here — past prints are the 8-K 2.02 and 6-K filings themselves. first_row_at and last_row_at are the earliest and latest scheduled dates currently held. | 1,236 | Oct 21, 2026 | Jan 21, 2027 | Oct 24, 2026 05:30 UTC |
Economic calendar Occurrences from July 2026 onward: the first seed covers the second half of 2026 (releases 2026-07-01 to 2026-12-31). There is no earlier history; later years appear as their seed files are committed. | 77 | Jul 2, 2026 | Dec 31, 2026 | Jul 31, 2026 12:51 UTClast change, synced daily |
Counted Oct 25, 2026 03:50 UTC. Dates are UTC. “stale” means the newest ingest is older than the source's own horizon (six poll cycles for the collectors, three days for SEC filings), or, for the calendar, that nothing is scheduled ahead.
Publisher news — cadence and limits
The GDELT GKG stream and RSS feeds are polled every 5 to 10 minutes, and each article is fetched and parsed directly from the publisher's page. A per-ticker rotation revisits the 300 most active tickers about every 2.5 hours and the rest about every 25 hours.
- English-language articles only; since 2026-08-26 pages whose title or body is mostly non-Latin script are dropped before enrichment.
- Only enriched articles are served: the feed applies a relevance floor (default 4) and requires a verified ticker or a market-wide macro category.
- Summaries and per-ticker analysis only; the full article text is never served.
- Some publishers are reached only through the per-ticker rotation, so their articles can arrive hours after publication.
- created_at is when the article arrived; time_published is GDELT's first-seen time for GKG rows and the publisher's own time for RSS rows.
Feed archive per plan: Free 30 days, Basic 90, Pro 180.
SEC Form 4 — cadence and limits
The SEC EDGAR Form 4 feed is polled every 5 minutes during US hours and every 30 minutes off-hours.
- Open-market transactions only: non-derivative purchases (code P), sales (S) and dispositions to the issuer (D). Grants, option exercises, tax withholding and derivative-table rows are not collected, so counts run below EDGAR's raw Form 4 total.
- The issuer must map to an active symbol in our universe; filings by issuers we do not track are skipped.
- One feed row per filing and (transaction code, ownership form) group: a laddered 10b5-1 sale is one event. Per-tranche detail is on /api/symbols/{ticker}/insider-trades/.
Feed archive per plan: Free 30 days, Basic 90, Pro 180.
SEC 8-K — cadence and limits
The SEC EDGAR 8-K feed is polled every 5 minutes during US hours and every 30 minutes off-hours.
- The issuer must be an active symbol in our universe.
- Only filings carrying at least one surfaced item: 1.01, 1.02, 2.01, 2.02, 2.03, 3.02, 5.02, 5.07, and since 2026-09-17 also 7.01 and 8.01.
- The summary is built from the press-release exhibit (EX-99.1) or the cover document; a filing whose manifest lists no readable document is still recorded, header-only.
- Tickers on 8-K rows are assigned by the enricher (the liquid issuer a reader follows), not copied from the security that filed.
Feed archive per plan: Free 30 days, Basic 90, Pro 180.
SEC 6-K — cadence and limits
Polled by the same EDGAR worker as the 8-K feed, as a second pass each cycle: every 5 minutes during US hours, every 30 minutes off-hours.
- Only 6-K filings a deterministic text classifier reads as an earnings release (results for a period, at least two metric families). Interim and annual reports, dividend and buyback notices, AGM materials, transcripts and KPI updates are logged but not ingested.
- The issuer must be an active symbol in our universe.
- Every row carries category earnings.
Feed archive per plan: Free 30 days, Basic 90, Pro 180.
Earnings reads — cadence and limits
A standing worker claims new 8-K item 2.02 filings and classified 6-K earnings releases as they arrive; each read is attached to the filing's feed row.
- 8-K item 2.02 and classified 6-K earnings releases only, and only for tickers in the major-ticker set.
- A read is published only when its numbers verify against the filing text; a filing whose numbers cannot be verified is skipped, so not every earnings filing has a read.
Earnings dates — cadence and limits
Polled daily from Yahoo Finance (05:30 UTC) for major tickers whose last earnings filing is at least 55 days old.
- Only dates the source marks as confirmed are served; its estimates are held internally and never served, and no date is ever computed on our side.
- Major tickers only.
- Dates only: the source does not encode before-open or after-close timing.
Economic calendar — cadence and limits
The committed seed is synced into the database daily at 04:50 UTC; the seed itself is regenerated from the agencies' schedule pages and checked against them before it is committed.
- US releases only, ten series: FOMC decisions and minutes, CPI, PPI, nonfarm payrolls, GDP, PCE, advance retail sales, weekly jobless claims and JOLTS. ISM and Conference Board releases are deliberately absent.
- Dates come from the agencies' own schedule pages; jobless-claims Thursdays and FOMC minutes are inferred from cadence until the agency publishes them (schedule_basis says which).
- phase says whether the scheduled moment has passed, not that the agency actually published; released_at is not populated.
Push, not poll.
Register HTTPS endpoints in /account/webhooks and receive a signed POST when a high-relevance news article hits one of your ticker subscriptions. The article has the same shape as an item of GET /api/news/.
- One delivery per story. When several outlets carry the same event, you get one POST for it, not one per outlet.
- HMAC-SHA256 signature header (Stripe-style, identical scheme).
- Up to 5 attempts: retries after 1m, 5m, 30m and 2h.
- SSRF guard refuses private and loopback targets.
- Up to 5 endpoints per Pro account; each one receives every event.
- Auto-disable after 10 failed attempts in a row (any error, including timeouts and 4xx), with an email to the owner.
POST https://your-service.example.com/alphai-webhook
Content-Type: application/json
User-Agent: alphai-webhook/1.0
X-Alphai-Event: news.matched
X-Alphai-Delivery: 42
X-Alphai-Signature: t=1715932000,v1=<hex-HMAC-SHA256>
{
"id": "evt_42",
"type": "news.matched.v1",
"created_at": "2026-05-17T07:08:00Z",
"delivery_attempt": 1,
"data": {
"alert": { "ticker": "NVDA" },
"article": { ...same as an item of GET /api/news/ }
}
}import hashlib
import hmac
def verify(secret: str, signature_header: str, body: bytes) -> bool:
"""Return True iff X-Alphai-Signature header matches the body."""
parts = dict(p.split("=", 1) for p in signature_header.split(",") if "=" in p)
ts, sig = parts.get("t"), parts.get("v1")
if not ts or not sig:
return False # malformed header is a failed check, not an exception
expected = hmac.new(
secret.encode(),
ts.encode() + b"." + body,
hashlib.sha256,
).hexdigest()
return hmac.compare_digest(expected, sig)
# In your handler:
# verify(os.environ["ALPHAI_WEBHOOK_SECRET"], request.headers["X-Alphai-Signature"], request.body)Still shipping.
The probes run from GitHub Actions, outside our own infrastructure, so the status page stays reachable when our services are not. The API probe is a deep one and passes only when the database and the cache both answer. Response times, history and past incidents are public.
Questions, answered.
The short version of what the stock news API is, what the free tier gives you, and how it fits next to a market-data API.
What is the AlphAI stock news API?
AlphAI serves financial news as JSON over HTTPS. Articles include a relevance score (1–10) and source links, with sentiment and reasoning for affected tickers. Use a Bearer key to filter the feed and page through results with a cursor. The same API powers alphai.io.
Why not send raw articles to my own agent instead?
You can. AlphAI saves you the step of scoring news and grouping repeated coverage. Filter by relevance before sending articles to your model. Use collapse=story for one result per event; sources_count tells you how many outlets covered it.
Is there a free financial news API?
Yes. Free includes one API key, 20 requests a minute and 100 a day, with no credit card. Use it to evaluate the feed or build a prototype. Production and commercial use require Basic or Pro, which also provide a deeper archive.
How is this different from a market-data or financial-data API?
AlphAI covers news: what happened, which tickers it affects and why it matters. It does not serve prices, fundamentals or OHLC bars. You can pair it with a market-data API.
Does the API cover SEC filings and insider trading?
Yes. Form 4 insider trades appear in the news feed and at /api/news/insider/. You can also fetch per-ticker trade history and find clusters of insider purchases. The feed includes 8-K filings and earnings releases from foreign issuers’ 6-K filings. See Filings & earnings above for filters and structured fields.
Does the API cover macro news like Fed decisions and CPI prints?
Yes. /api/news/macro/ covers central banks, inflation, jobs, commodities and geopolitics. Macro stories often have no ticker, so filter by category. min_relevance=7 focuses on release-day events. /api/calendar/ lists the scheduled US releases, including Fed decisions and CPI.
Can I call the API from the browser?
No. Call the API from your server and keep the key in an environment variable. The API has no CORS support; browser preflight requests receive 403. Expose your own backend route for a web app to call.
Can I trace a story back to the original source?
Yes. Results include the publisher’s URL and domain, publication time and available bylines. Use those links to cite the original. Full article text stays internal and is never returned by the API.
Can I download the insider feed as CSV?
Yes. Add format=csv to /api/news/insider/. Each file counts as one request and holds up to 500 rows on Free, 2,000 on Basic or 10,000 on Pro, within your archive window. Check that the stream completed and the data-row count matches X-Alphai-Rows before continuing with X-Alphai-Next-Cursor. See the endpoint’s usage notes for export limits and retries.
Build on the beat.
Sign up for any plan, generate a key in your account, and start shipping.
Get a free API key