What changed.

User-visible changes to the REST API, the MCP server, and the data pipeline — newest first. If it affects what your bot receives, it's here.

Scheduled releases on the macro tape

  • alphai_macro now returns releases next to result. It lists the scheduled US releases of the same window, newest first, each with its coverage (the top feed stories about it), followed by the releases due in the next 24 hours. These are the rows alphai_calendar serves, and result is unchanged.
  • An elapsed release with an empty coverage list has come out and its stories are still arriving. Call again in a few minutes before concluding that nothing was published.
  • The jobs report, CPI, PPI and JOLTS also arrive from the Bureau of Labor Statistics' own feeds, with time_published set to the minute the embargo lifts. The September jobs report reached the feed on October 2 stamped 12:30:00 UTC.

Deal cash-outs on Form 4 stop at 6

  • On SEC Form 4 items, a sale back to the issuer (transaction_code D) that leaves the insider with no shares now stops at 6, like an open-market sale. That is how holdings are cashed out when an acquisition closes, and the deal already has its own item. A D that leaves a holding, such as the company buying back a large holder's block, keeps the full value scale.
  • A sale filed without a price now stays at 6 as well. With min_relevance=7, GET /api/news/insider/ and alphai_insider_news return purchases plus those rare buybacks from holders. Items published before today keep their scores. The spec is OpenAPI 1.48.0.

Insider sales top out at 6

  • On SEC Form 4 items, relevance_score for a sale (transaction_code S) now stops at 6, however large the sale. Purchases keep the full value scale up to 10, and a 10b5-1 plan trade still sits one step lower. Insiders sell for taxes, diversification and pre-set plans, while a purchase carries their own view of the company.
  • On GET /api/news/insider/ and alphai_insider_news, min_relevance=7 now returns purchases only, from roughly $1M. min_relevance=6 still includes sales from roughly $1M, and a default alert threshold of 6 keeps receiving them. Items published before today keep their scores. The spec is OpenAPI 1.47.0.

Units on every figure of an earnings read

  • Each row of segments in an earnings read now carries numeric, unit and scale next to the printed revenue, the same companions a key_metrics row has. A segment table usually names its unit in the header and not in the cell, so the companions are what tell you that "$18,002" is $18,002 million. The fields are in GET /api/symbols/{ticker}/earnings/, the earnings block of GET /api/news/{uid}/, alphai_earnings and alphai_article.
  • A read has a new field, table_scale: the unit the filing's table headers name, or null when they name none. The notes and the analysis quote table figures as the filing prints them, so in a read with table_scale: "millions" a bare $36,197 there is $36,197 million. Per-share figures are always as printed.
  • scale is filled for more figures. It now also reads the row's own prior value and the same amount where the filing's prose prints it with a unit. A per-unit metric, such as revenue per customer or a price per ounce, keeps scale: null whatever the tables around it are in.
  • unit follows the currency the figure is reported in when a filing adds a US dollar translation: RMB7.1 billion (US$1.1 billion) is CNY. Every published read was recomputed under these rules, so a stored scale or unit may differ from what you cached. The spec is OpenAPI 1.46.0.

US exchange-traded funds and MCP connection controls

  • About 5,700 funds listed on US exchanges, ETFs and ETNs, are active symbols with asset_type: "ETF". They appear in GET /api/symbols/ and alphai_tickers, and GET /api/news/?symbol=XLE, alphai_ticker_news, news alerts and pages like /stock/GDX work for them. Funds file no Form 4, so supports_insider is false.
  • An article is tagged with a fund only when it names that fund: a cashtag like $XLE, exchange notation like (NYSEARCA: XLE), the fund's full registered name, or the ticker in a sentence about funds. A fund ticker that is also a common acronym, such as IPO, USD or PPI, needs one of the first three. A headline that names a fund gets its tag even when the model did not suggest it.
  • Headlines from the last 180 days that were already in the feed and name a fund now carry that fund's tag, so a fund's history starts before today.
  • In search results a company ranks before a fund at the same match level: search=jpmorgan lists JPM before JEPI. MCP text queries read a fund ticker only when it is written as one, so "PPI report" stays the price index while "qqq" resolves to QQQ.
  • MCP approval shows the callback destination and the permissions available on your plan, including alert changes on Basic or Pro. App names are self-declared and marked unverified. Check registered callbacks in Account → MCP connections, and approve only connections you started.
  • Disconnect blocks the app's existing MCP access and refresh tokens across its sessions. Work already in progress may finish. Reconnect and approve again to restore access. OAuth integrations should refresh one token at a time, save its replacement, and restart authorization on invalid_grant.

Webhooks reach every endpoint, with the feed article shape

  • Every active endpoint on a Pro account receives every event. Each endpoint has its own retries and its own failure count, so an endpoint that is down does not hold back or disable another one. The delivery log for an endpoint in /account/webhooks lists that endpoint's deliveries. A reprint of a story you already received is still skipped once, for all endpoints.
  • data.article has the same shape as an item of GET /api/news/: original is read from the article's current record, and enrichment carries the validated tickers list. Fields outside that schema are not sent, including the undocumented _enrichment_audit block.

Reg FD and Other Events filings: real headlines and the right category

  • Since September 17 the feed carries SEC 8-K filings made under Item 7.01 (Regulation FD) and Item 8.01 (Other Events): about 70 a day, and the source of most FDA decisions, trial readouts, debt closings and binding offers that reach the feed as filings. Their title now reads the release itself ("Cue Biopharma Announces Positive Topline Results from CUE-221 Phase 2 Study") or, for a filing without a press release, the first sentence of the item, instead of the item's name. Rows filed since September 17 were retitled the same way.
  • The category of these rows is the one the analysis assigned (regulation, technology, mergers_acquisitions, earnings or corporate_actions) rather than corporate_actions for all of them, so a category filter in /api/news/ and the MCP tools sees them where they belong. Filings under Item 2.02 and 2.01 keep their fixed earnings and mergers_acquisitions; the change applies to new rows.

Faster coverage of publishers outside the GDELT crawl

  • About a third of our strong stories come from finance sites that GDELT never crawls: TradingView, TipRanks, Simply Wall St, GuruFocus, MarketScreener, Stocktitan, Benzinga and Stocktwits. In the week after September 17 their median delay from publication to the feed dropped from about 5.5 hours to about 1.2 hours, and the 90th percentile from 16 hours to 3. The same stories arrive in /api/news/, the MCP tools and alerts, just earlier.
  • Same-day movement stories ("why is X jumping", premarket and after-hours moves) now land about 25 minutes after publication at the median. Nothing changes in the contract: a sort=ingested poll simply sees these rows sooner, with their publisher's time_published.

Buyer reason in insider cluster buys

  • Every buyer in GET /api/news/insider/clusters/ and in the alphai_insider_clusters tool now carries a reason next to its role. It is set when the Form 4 itself says the shares did not come from the open market: placement for a purchase from the issuer (a PIPE, a subscription or securities purchase agreement, SPAC sponsor units), offering for an allocation in a public offering or IPO, private for a negotiated block from another holder. Such a buyer is plan_like, and the episode gains off_market_buyers in pattern_reasons. Null means the price shape alone decided the role. Spec 1.44.0 at /api/schema/.
  • The default pattern=open_market list therefore drops episodes whose only other buyer bought in a placement or an offering; ask for pattern=plan_or_offering or all to see them with the reason spelled out. Filings from the last 90 days are read this way, and every new Form 4 is read at ingest.

Sentiment rollup on calendar days

  • GET /api/symbols/{ticker}/sentiment-summary/ covers the last seven UTC calendar days, today included. The bullish, neutral, bearish and total counts are the sums of the daily buckets, so the chart of the days and the weekly figure come out of the same response and always agree. Spec 1.43.1 at /api/schema/.
  • A q, query or search parameter sent to a structured feed such as /api/news/ returns a 400 that points to GET /api/news/search/, where free-text search lives.

Source and 8-K item filters in search

  • GET /api/news/search/ now takes source_type and item, with the same values and validation as the feed. q=director&item=5.02 searches only 8-K filings that carry item 5.02, and source_type=gdelt keeps press coverage only. An item next to any source other than sec_form8k returns 400. The MCP tool alphai_news_search already took both. Spec 1.42.0 at /api/schema/.

SEC filings and insider context in Radar

  • Each Radar reading can show recent SEC filings and open-market insider cluster buys alongside news activity. Filings cover seven days; clusters cover 30 days by their latest SEC filing time. Open news headlines and filing evidence to read AlphAI articles. Cluster evidence links to SEC filings with independent buyer counts. 6-K coverage includes selected earnings releases only.
  • GET /api/signals/snapshot/ and alphai_radar add snapshot-level event_context timing and availability, plus each row’s separate context. Check status before using counts: unavailable data is null, while zero means no eligible stored records. Available context does not guarantee complete SEC coverage.
  • Filings include news_title, news_published and has_article alongside news_uid. Use them to link to the AlphAI article when it was available at the snapshot’s context cutoff. Older snapshots have null article metadata and default to false; sec_url remains available.
  • Context follows your plan’s delay and stays fixed when following a cursor. News scores and ranking keep their existing meaning. Field details are in the Radar API reference.

Insider cluster buys

  • GET /api/news/insider/clusters/ answers one question: where did several different insiders of one issuer buy on the open market together? An issuer's Form 4 purchase dates are chained into an episode while they are at most 10 days apart, and every purchase inside it is examined before a buyer counts. An IPO or PIPE allocation at one price, ESPP and DRIP lots, director-plan purchases, units and note exchanges without a price, and the same transaction reported through two owners are labeled per buyer (role: independent, plan_like, unpriced, duplicate_of) and left out of the default list. Ask for pattern=plan_or_offering, holders_only or all to see them, labeled. Each result carries the independent buyer count, the total, every filing with its accession number and EDGAR link, and the news uids for /api/news/{uid}/.
  • days (1 to 90, default 30) is measured on known_at, the moment the episode's latest filing reached EDGAR, so "what became known this month" is one call. A Free key reaches 30 days, Basic and Pro 90; deeper returns the usual archive 403. Narrow with min_buyers, min_usd and symbol (former tickers and share-class siblings match), sort by recent, buyers or value, and follow next_cursor. The rule was checked by hand against 90 episodes and their filings before it shipped; the OpenAPI description says what it can and cannot see.
  • The MCP tool alphai_insider_clusters takes the same arguments and returns the same rows. Connected clients that cache the tool list need a refresh to see it. The insider trading tracker shows the freshest open-market clusters in a new section. Field details in the OpenAPI reference.
  • An article fetched by uid carries the same structured block the feeds serve. GET /api/news/{uid}/ and the MCP tool alphai_article return insider on a Form 4 row, with the shares, average price, 10b5-1 flag and filing time, and filing on an 8-K row. A cluster's news uids open with their trade data in one call.

8-K item filters, a coverage passport and CSV export

  • Filter the feed by source and by 8-K item. GET /api/news/ takes source_type (gdelt, sec_form4, sec_form8k, sec_form6k, repeatable) and item, an 8-K item code such as 5.02 for officer changes or 1.01 for material agreements. item matches any item of the filing and implies source_type=sec_form8k. category still covers the two headline items: 2.02 is earnings, 2.01 is mergers_acquisitions. Every 8-K row now carries a filing block with items, primary_item, accession_number, filed_at, event_date and exhibit_url, so you can cite the filing and open the exhibit without parsing the headline.
  • The MCP tool alphai_news_search takes the same source_type and item arguments, and its items carry the same filing block. alphai_ticker_news carries the block on its 8-K items too. Connected clients that cache the tool list need a refresh to see the new arguments.
  • GET /api/coverage/ tells you what each data source holds and from when: publisher news, SEC Form 4, 8-K, 6-K, earnings reads, earnings dates and the economic calendar, each with its earliest and latest row, the last ingest time, the row count, the collector cadence, a plain note on where the history is thin, the known limits and how far back each plan can page. first_row_at is the earliest row we hold, not the start of dense coverage. The passport is recomputed once a day; as_of says when. Keyed on every plan, Free included, and shown on /developers.
  • Add format=csv to GET /api/news/insider/ to download the insider feed as a file: one row per insider event with the insider block flattened, the same filters as JSON, and one request against your rate limit however long the file is. A file holds up to 500 rows on Free, 2,000 on Basic and 10,000 on Pro, inside your plan's archive window. The response headers X-Alphai-Rows, X-Alphai-Truncated and X-Alphai-Next-Cursor say where the file stopped and how to continue in either format. Field details in the OpenAPI reference.

Brief and Radar in the Python and TypeScript SDKs

  • Upgrade to Python 0.7.0 or TypeScript 0.6.0 for typed news.brief and radar.snapshot methods. Brief groups news and SEC filings for up to 100 explicit tickers in one call, with confirmed earnings dates and flags for omitted stories. It is a ranked overview; use the ingested feed cursor for complete incremental ingestion.
  • Radar includes filters, supporting headlines and freshness metadata. Python radar.iter and TypeScript radar.iterate follow pages of the same snapshot. A ConflictError (HTTP 409) means the cursor expired or its context changed: start a new scan without a cursor. Python supports sync and async clients. See the SDK examples.

Radar for market and watchlist news activity

  • Find unusual news activity in Radar, with story counts, expected activity, news tone and supporting headlines. Choose a 4h or 24h window across the market or your saved watchlist. Scores describe observed news; they are not price forecasts or confirmed alerts.
  • Use GET /api/signals/snapshot/ or the MCP tool alphai_radar for the same readings. Filter exact tickers and news tone, sort by activity or tone change, and follow cursors to keep one complete snapshot. See parameters and examples.
  • All plans include Radar. Free adds 60 minutes, Basic 15 minutes, Pro no added delay. Snapshots refresh every minute; collection and enrichment take additional time. Check as_of and freshness. Normal API/MCP quotas and saved-watchlist allowances apply.

A brief for your watchlist and earnings in connector fetch

  • Your watchlist has a brief of recent news grouped by story, SEC filings and confirmed earnings dates. Choose the past day, three days or week. The MCP tool alphai_watchlist_brief reads the same saved list in one call. For an explicit list, use GET /api/news/brief/?tickers=NVDA,AMD&hours=24. All tiers can use it; truncation flags tell you when more stories are available.
  • Connector fetch includes completed earnings reads in its text, with metrics and comparisons, segment results, guidance and limitations. Clients using only search and fetch can read the analysis through the same article ID. The response shape and citation links stay the same.

Offerings and other 8-K events in the feed; dilutive raises read negative

  • SEC 8-K filings under Item 7.01 (Regulation FD) and Item 8.01 (Other Events) now enter the feed as corporate_actions, next to the earnings, agreement and governance items already covered. This is where debt and convertible offerings, at-the-market programs and press-release-only disclosures are filed, often with no wire release anywhere else. A $3.0B convertible notes announcement reaches /api/news/, ?category=corporate_actions, the per-ticker feeds and the alphai_news_search / alphai_ticker_news tools minutes after EDGAR accepts it, with source_type: sec_form8k and the exhibit as url.
  • Per-ticker sentiment on a dilutive raise (convertible notes, common-stock, at-the-market, registered direct and PIPE offerings) reads negative for the issuer at announcement, unless the article itself reports the stock rising on it. Plain senior-notes refinancings keep the model's own read. The 7-day /api/symbols/{ticker}/sentiment-summary/ rollups follow, and the last 60 days of such rows were re-scored.

alphai-tui 0.23.0: extended sessions and a portfolio

  • Premarket and after-hours candles are on by default, with warm and cool backgrounds across price, volume and RSI in both candle and line charts. Alpaca's IEX mode fills extended sessions from consolidated SIP data delayed by 15 minutes, then Yahoo when SIP cannot supply the session. Yahoo timing varies. The chart names the feed beside EXT and keeps the Shift+E on/off hint visible even when those candles are hidden. Regular-session prices keep their own feed, and a failed supplemental refresh retains the data already loaded.
  • Charts start at 5d / 15m: five days of 15-minute candles, with the same history at startup and after switching presets. The header shows the window and candle size beside the t switch hint; Shift+T cycles backward. Set range and interval in the config to change the defaults. More clock labels, a separate date row and opening and closing markers share a grid across the panels. Short histories fill the available width. US stocks use New York time; timezone under [chart] also accepts local and utc. Session shading and the grid can be disabled there. Holidays, half days and daylight-saving changes shape the session boundaries. A late response from a previous preset cannot replace the current chart, and live prices update only a matching candle, session and feed.
  • The quote rail carries a separate PRE or AH price with its move from the regular close, source and age. A zero-percent move is still shown, and a previous after-hours quote expires when the next premarket begins. The watchlist adds an extended-change column when there is a price to show. Day and 52-week ranges and volume appear when the source reports them; IEX-only share counts are not presented as whole-market volume.
  • Portfolio view 8 tracks quantity and average cost, current value, daily and total P&L, portfolio weights and totals. Press p on a ticker to enter a holding, saved immediately, or use [[positions]] in the config. Fractional quantities and shorts are supported. Held tickers keep receiving prices even outside the watchlist; missing quotes are excluded from totals with a count of the rows covered. Mixed-currency totals are labelled, with no currency conversion. The table and quote rail show holding value and P&L too. Valuations include valid extended prices even with extended candles hidden: premarket Day starts from the latest close, and after-hours Day includes the regular session's move. Theme cycling moves from p/P to } / {; all remain rebindable.
  • Summary view 7 shows the watchlist as a grid of small charts, with arrow-key navigation and paging when it outgrows the terminal. The watchlist can be edited without restarting: a adds a ticker and d removes it. Save in settings keeps those edits for the next launch.
  • News appears on the price chart at the candle containing its publication time: ▲ or ▼ for sentiment, ◆ for neutral, with brightness reflecting relevance and the freshest headline on the bottom border. These marks use news already loaded by Split or News, with no extra API request. A candle with several stories keeps the highest-scoring one; stories outside the visible history or in closed-session gaps are not pinned to an unrelated candle. Press n to toggle them, or set news_markers = false under [chart]. The first feed refresh also keeps older articles in their chronological place; later arrivals still receive the new-row marker.
  • The last good quotes and candles survive a restart, labelled with their age until a fresh poll arrives. The cache matches the selected chart and expires after a week. Transient refusals and gateway errors get brief retries. Yahoo rate limits are reported explicitly, and supplemental requests pause while the limit clears. If every ticker has failed for 45 seconds, the app tries another configured source, retains the visible prices with their original source and age, and announces the switch. It does not switch back automatically. Set source_fallback = false to disable that behavior.
  • --json prints a one-shot quote array for scripts and status bars, including available ranges, volume, extended price and change with timestamp, feed and session. A held ticker includes a position object with valuation and P&L. Missing figures are omitted, failed tickers carry an error, and warnings stay on stderr. This update covers all releases since the previous 0.17.0 entry. Upgrade with brew upgrade alphai-tui, cargo install alphai-tui, apt or AUR. The 0.23.0 release has binaries for macOS, Linux and Windows; alphai.io/tui covers installation. The interface and docs now use the AlphAI brand spelling; the binary name and config keys are unchanged.

Earnings metrics carry a number, a unit and a scale

  • Every row in an earnings read's key_metrics now carries three companions next to the printed value: numeric (the figure as a number, sign applied), unit (an ISO-style currency code, pct or bp, null for a plain count) and scale (ones, thousands, millions, billions). The printed string stays exactly as the filing wrote it, because that is what was verified against the document; the companions are derived from it by code, never by the model. Oracle's "$19,345" therefore comes with scale: "millions" read off the filing's own table header, and Adobe's "$6.76 billion" with scale: "billions", so the two can sit in one column.
  • scale is null when neither the value, the metric name nor the filing's table header says it. That is deliberate: a null you can see beats a multiplier we guessed. Per-share and percentage figures are ones. Served on GET /api/symbols/{ticker}/earnings/, on the earnings object of GET /api/news/{uid}/ and by the MCP tool alphai_earnings; every read published before today was backfilled. Spec 1.34.0; the SDKs type the fields from alphai-sdk 0.6.2 (Python) and 0.5.2 (TypeScript).

Date window on the macro feed

  • GET /api/news/macro/ takes from_date and to_date, the same inclusive window as /api/news/ and the insider feed: ISO dates or datetimes, naive values read as UTC, a bare to_date covers the whole day. The tape after a Fed decision is one request now, from_date=2026-09-16&min_relevance=7, instead of a detour through the main feed's category filter. The window respects your plan's archive depth (403 with reason: archive_horizon on the first page) and is refused together with sort=ingested (400), exactly as on the other feeds. Spec 1.33.0.

Retry-After on a burst 429 is the real wait

  • Retry-After on a per-minute 429 now names the earliest second a retry can succeed. The minute limit is a sliding window: after a burst that fills the current minute nothing frees up until the minute rolls over, and the header used to advertise 2 seconds where the real wait was about 30, so a client that slept exactly as told hit a second 429 and often a third. REST and the MCP server both report the corrected value. A burst block still stays at 60 seconds or less; a day-cap block still carries up to 3600 with the true reset in X-RateLimit-Reset, and a rejected request still costs no quota.
  • Sleep for Retry-After once and retry; the official SDKs do (Python alphai-sdk 0.6.1, TypeScript 0.5.1, which also caps any Retry-After it honours at 60 seconds via maxRetryAfter). Pacing at the limit's own rate from the first request, one call every three seconds on Free, never meets the header at all.

alphai-tui 0.17.0: earnings reads in the terminal

  • alphai-tui has an Earnings view (6) built on GET /api/symbols/{ticker}/earnings/: the verdict and the reason for it, the metric table with prior quarter and prior year, segments, outlook, concerns and the analysis, printed as the filing wrote them. American 8-K item 2.02 filings and foreign private issuers' 6-K releases are both covered, and older quarters continue below the newest read. A ticker with no read yet shows the date of its next confirmed report instead, and the bottom line carries the next US macro releases from GET /api/calendar/. One request per ticker, made only while the view is open.
  • A quote rail now runs under the tabs in every view, with the selected ticker's price and change, where that price sits between the session low and high, and the rest of the watchlist as percentages. It also says what the US market is doing (pre, live, post or closed) and how long until the next bell, so a price that has not moved in hours reads as a closed market rather than as a broken feed. A price source that is delayed says so. [ui] quote_rail = false turns the line off.
  • --bare starts without the header and the footer and hands both rows to the view, which is what a tmux pane with its own status bar wants; z toggles it live. Feeds poll for arrivals instead of refetching the published head of the list, so a Form 4 that reaches the feed days after the trade no longer slips past, and polling keeps running while you are scrolled down the list. The request budget is unchanged at one request per cache lifetime per visible feed, so the free tier still fits.
  • Update with brew upgrade alphai-tui, cargo install alphai-tui, apt or AUR; prebuilt binaries for five platforms are on the releases page, and alphai.io/tui has the screenshots.

Coin tickers answer back

  • Crypto trades under quote-suffixed tickers, so BTC is the Grayscale ETF and BTC-USD is the coin. When GET /api/news/?symbol= names a string a stock or ETF owns while a coin answers to the same base, the response now carries symbol_note: one sentence naming the coin ticker to request. The field is nullable and documented in the OpenAPI spec.
  • The MCP tools say it too. alphai_ticker_news and alphai_insider_news return ticker_note on a collider query, and a guessed form like BTCUSD gets the pointer alongside unknown_ticker.
  • alphai_news_search now resolves a bare coin name in its tickers filter the same way alphai_ticker_news always did, so tickers: ["DOGE"] serves Dogecoin instead of an empty page. A string a stock or ETF owns keeps its equity meaning.
  • Alerts point at the coin as well. Subscribing to an unknown DOGE or BTCUSD names the real ticker in the error message on both REST and MCP, and an MCP subscribe that lands on a collider like BTC succeeds with a note saying the alert bound the ETF.

Alert thresholds, and one switch for all of them

  • A new ticker alert now starts at a relevance floor of 7, the same bar we use for the stories worth indexing. Before this the starting floor depended on where the subscription was created. Pass min_relevance_score to alphai_alerts_subscribe to set your own, anywhere from 0 to 10. Subscriptions you already have keep the threshold they were given.
  • That threshold now applies to email and telegram delivery only. A Pro webhook receives every article the subscription matches, whatever its score, so a bot can run its own filter over the full stream. The per-ticker cooldown and the hourly email limit already worked this way.
  • Your watchlist has a Turn all alerts off control. It switches off every active alert in one step and keeps each subscription's settings, so turning one back on restores the categories and threshold you had set.

Earnings reads per ticker, and the next report date

  • GET /api/symbols/{ticker}/earnings/ is now in the contract. It returns every published AlphAI earnings read for a ticker, newest first, with the full analysis inline rather than a pointer. A read is produced from the company's own SEC filing, an 8-K item 2.02 for US filers or a 6-K earnings release for foreign private issuers, and every number in it is checked against the filing text before it publishes. Share classes bridge, and each row names the class the filing was actually made under. The existing /earnings/latest/ pointer is unchanged.
  • Both that response and GET /api/symbols/{ticker}/ now carry next_report_date: the date of a company's next earnings report, in America/New_York. It is only ever a date the company itself has confirmed. We do not project one from the reporting cadence, so null means we hold no confirmed date rather than that the company is not reporting. Confirmed dates usually appear about five weeks ahead.
  • On MCP the same field rides on alphai_tickers, and the new alphai_earnings tool returns AlphAI's read of a company's reports once they land, so an agent can go from "when do they report" to the filing's own numbers in two calls. Feed items now also carry source_type, which is how you tell the filing itself from the coverage written about it. alphai_calendar stays US macro only. The symbol response also documents supports_insider and tv_symbol, which it was already returning. Spec is at /api/schema/, now 1.31.0.
  • Foreign private issuers reach the feed itself, not only the reads. A Form 6-K earnings release from an issuer like Nebius, PDD or Royal Bank of Canada arrives as a news row whose source is SEC EDGAR 6-K and whose category is earnings, so it shows up in GET /api/news/, in the per-ticker feeds, in your alerts and in alphai_ticker_news alongside an 8-K item 2.02. A 6-K carries no item codes, so the release is identified from the filing text, and the period it reports is often a half year rather than a quarter.

Only tool calls count against your MCP quota

  • On mcp.alphai.io your per-minute and per-day quotas now meter tool calls and nothing else. The connect handshake, the tool catalog, keepalives and the event stream are protocol traffic and are free. A client that opens a fresh session per task, or holds one open and pings it, no longer spends its allowance on staying connected. Free is 20 calls a minute and 100 a day, and those 100 are now 100 tool calls.
  • Protocol traffic has its own ceiling, set high enough that a normal client never reaches it. If yours does, the 429 body reports "window": "transport" alongside the existing "minute" and "day". It means the client is reconnecting too often, not that the account is out of quota, so handle it by reusing a session rather than by upgrading.
  • On both REST and MCP, a request rejected with 429 no longer consumes quota. Retrying after Retry-After costs nothing extra, and a burst block never asks you to wait longer than the minute window it belongs to. X-RateLimit-Remaining counts real usage. Spec is at /api/schema/, now 1.30.0.

Structured earnings reads on major-ticker filings

  • Earnings articles now carry AlphAI's own structured read of the company's SEC Form 8-K (Item 2.02). GET /api/news/{uid}/ returns a new top-level earnings object with every reported metric and its year-over-year and sequential change, segment revenue, forward guidance, a verdict and several paragraphs of analysis. Every figure was checked against the filing text before it was stored, and consensus estimates and price targets are left out because they are not in the filing. The field is present only on a major ticker's earnings whose numbers passed that check, and is null everywhere else. The same block renders on the article page, and alphai_article returns it inline over MCP.
  • New GET /api/symbols/{ticker}/earnings/latest/ returns a pointer to a ticker's most recent earnings read, 204 when there is none, and 404 for a ticker we don't list (the same ticker forms and error as the other symbol endpoints). It powers the "Latest earnings report" button on a stock's page, and it bridges share classes, so a request for one class returns the read filed under the issuer's primary class.

Story fields on actionable-now and macro, one id per story

  • alphai_actionable_now and alphai_macro now carry the story fields. When syndicated reprints are collapsed, which is the default, each item reports story_id, sources_count (distinct outlets covering the story) and sources (their domains), the same fields alphai_trending and the search tools already return. With dedupe=false nothing is collapsed and the three fields stay null. Most stories run at a single outlet, so expect 1 and treat anything higher as the signal.
  • story_id now names the story root everywhere. GET /api/news/?collapse=story, GET /api/news/trending/ and the MCP news tools all report the uid of the story's root article, so one story keeps one id across tools and across calls. The item shown on trending is the strongest article of its story, not always the root, so its story_id can differ from the item's own original.uid there. Both resolve via GET /api/news/{uid}/.
  • The spec is at /api/schema/, version 1.28.0.

limit and ticker accepted as parameter aliases

  • The news feeds now accept limit as an alias of page_size and ticker as an alias of symbol, on GET /api/news/, GET /api/news/insider/ and GET /api/news/macro/. GET /api/symbols/{ticker}/insider-trades/ takes limit too. These are the names the MCP tools already use, so a query written for one surface now runs on both. The canonical names are unchanged and remain what the docs and SDKs use.
  • An alias is the same parameter under another spelling: identical bounds, identical defaults, and the same Pro requirement for page sizes above 20. Sending both spellings of one parameter in a single request returns a 400 rather than a silent pick. Full details are in the OpenAPI spec (1.27.0).

Date windows on the news feeds

  • GET /api/news/ and GET /api/news/insider/ take from_date and to_date, the same window the MCP tools alphai_news_search and alphai_insider_news accept: identical names and identical reading, so a window written on either surface selects the same rows on both. Bounds are ISO dates or datetimes, naive values read as UTC, inclusive on both ends. A bare to_date=2026-07-01 covers that whole day, so a one-day window returns the day instead of an empty page, and symbol=NVDA&from_date=2026-07-01&to_date=2026-07-31 is one month of one ticker. The official Python and TypeScript SDKs pass the window from 0.5.0: from_date=date(2026, 7, 1) in Python (a date object keeps the whole-day form), fromDate: "2026-07-01" in TypeScript.
  • The window respects your plan's archive depth. Asking past the horizon returns 403 with reason: archive_horizon and your tier's numbers in the body, on the first page rather than after paging down to it. Free reaches back 30 days, Basic 90, Pro 180.
  • Windows apply in the default sort=published mode. Combining one with sort=ingested returns a 400, since delta polling reads forward from your cursor and never walks history. An inverted window, a from_date after the to_date, is a 400 on REST and a tool error on MCP rather than an empty list. On the insider feed the window bounds when a filing reached the feed, not the trade date reported inside the insider block.
  • Spellings this API does not use, such as published_after, start or since, get a 400 that names the real parameter. Full semantics are in the OpenAPI spec (1.26.0).

Relevance floor on the per-ticker feed

  • alphai_ticker_news takes min_relevance, the same 1 to 10 floor as alphai_news_search, with the same default of 4. Ask for a ticker at min_relevance=7 and the tool returns the material stories for that name instead of the whole tape, so an agent working through a watchlist does not have to score and drop rows itself.
  • It composes with the rest of the tool: include_insider, collapse_stories, and sort=ingested delta polling. SEC Form 4 rows ride the same feed and obey the floor like everything else, so raising it narrows insider events too.
  • On REST the same query is GET /api/news/?symbol=NVDA&min_relevance=7, documented in the OpenAPI spec.

Insider feed: 10b5-1 filter, joint-filing names

  • GET /api/news/insider/?is_10b5_1=false returns the discretionary trades and drops the sales that ran on a Rule 10b5-1 plan set up months earlier. Pass true for the plan events alone, or omit the parameter for the feed as before. The same filter is on alphai_insider_news in MCP, and it composes with symbol=, min_relevance= and sort=ingested delta polling.
  • It filters on the same field each item already reports, at the same level. An event is the whole transaction group of a filing, so a filing that mixes a plan tranche with a discretionary one counts as a plan event on both the filter and the insider.is_10b5_1 field. The two values split the feed with nothing left over: every event the unfiltered feed returns comes back under exactly one of them.
  • Joint Form 4 filings now name every reporting owner. When a holding vehicle files together with the person behind it, the headline carries both (“BERKSHIRE HATHAWAY INC (BUFFETT WARREN E) sold $36.5M of DVA”), the summary lists each co-filer with their role, and the authors array holds all owners, primary first. About one in five of the largest filings is a joint one, so the names most worth watching were exactly the ones the feed used to drop. Applies to filings ingested from today onward.
  • Full parameter reference is in the OpenAPI 1.25.0 spec.

alphai-tui 0.13.0: the insider trades chart, in the terminal

  • The Insider view of alphai-tui now draws the same chart as our insider trades pages: every Form 4 event as a triangle on a log dollar scale, buys and sells apart, hollow marks for sales to the issuer, 10b5-1 plan trades dimmed, with weekly dollar bars underneath. The g key cycles the window between 3 months, 12 months and off.
  • The chart reads the /api/symbols/{ticker}/insider-trades/ endpoint documented today, riding the same request the view already made, so the free tier budget is untouched. Selecting a filing in the list highlights its mark on the chart, and the detail pane picks up the stake share the event moved and its tranche count.
  • Update with brew upgrade alphai-tui, cargo install alphai-tui, apt or AUR; prebuilt binaries are on the releases page.

Per-ticker insider trades endpoint

  • GET /api/symbols/{ticker}/insider-trades/ serves the complete Form 4 event history for one ticker, built for charts. The first page carries 3-month, 12-month and all-time rollups, the most active insiders, weekly and monthly dollar buckets, and chart_events: every event of the trailing 12 months in one array. Deeper history pages with cursor=. This is the payload behind our own insider trades pages, now part of the documented contract in the OpenAPI 1.24.0 spec.
  • Each event extends the feed's insider block with stake_change_pct (the share of the position the event moved, sells negative), tranche_count, security_title and a news_uid link to the enriched article. One semantic difference: side follows the value flow here, so a code D sale to the issuer counts as sell, and transaction_code tells the two apart.
  • page_size= accepts up to 200 on every tier, so one request loads a chart's whole working set. The aggregates always cover both sides regardless of the side= filter.

Form 4 coverage gap: fixed and backfilled

  • Between early June and August 5 our SEC Form 4 collector missed a share of filings, so insider items were incomplete in /api/news/, /api/news/insider/, the alphai_insider_news MCP tool, per-ticker insider summaries and alerts. The collector was fixed on August 6.
  • Every recoverable filing was backfilled the same day from SEC's daily indexes (1,489 filings). Historical insider queries now return the full set. If you poll with sort=ingested, the restored rows arrived on August 6 carrying their original time_published.
  • The weekly Insider Radar issues on /research for the affected weeks were restated with the corrected figures. Each restated issue says so in its methodology note.
  • Coverage is now verified daily against SEC's own filing index, independent of our pipeline.

Company lookups match brand names

  • A free-text query on alphai_news_search now resolves the name a company is known by, not only the name it is registered under. query="spacex" returns SPCX news, though the symbol is registered as SPACE EXPLORATION TECHNOLOGIES CORP. The search tool that deep-research clients call reads the same way.
  • alphai_tickers and GET /api/symbols/?search= match brand names too, so you can go from a name a user typed to a canonical ticker in one call. Brand hits rank with exact ticker and exact name matches, above prefix and substring ones. See the updated OpenAPI spec (1.22.0).
  • A company name in query now resolves to the issuer rather than to one of its listings, so query="google" returns the Alphabet stories tagged GOOG as well as those tagged GOOGL. That matches how the per-ticker tools have always treated a symbol. An explicit tickers filter is unchanged and still means exactly the symbols you list.
  • A word that fits more than one active company still resolves to no ticker instead of a guess, and an unresolved query returns the general feed. When you already know the symbol, pass tickers rather than free text, and you get an exact filter every time.

Economic calendar: scheduled US macro releases

  • GET /api/calendar/ lists the official schedule of US macro releases: FOMC decisions and minutes, CPI, PPI, the jobs report, GDP estimates, PCE, retail sales, weekly jobless claims and JOLTS, taken from official agency schedules. The default window is the next 7 days. from_date and to_date take a date or an ISO datetime, event_key narrows to specific series, importance filters by tier. Spec: OpenAPI 1.21.0.
  • Each occurrence has a stable uid like US-CPI-2026-07 that survives reschedules: a moved release keeps its identity and updates scheduled_at and schedule_status. The computed phase field says whether the scheduled moment has passed (upcoming or elapsed); it deliberately does not claim the agency has published, so a postponed release reads as postponed, not missing. schedule_basis tells you where each date came from: official means it is printed on the agency schedule, inferred means it follows the documented release cadence (weekly jobless claims, FOMC minutes the Fed has not dated yet). FOMC rows carry press_conference_at and has_sep for the projection meetings.
  • The alphai_calendar MCP tool serves the same calendar with one addition: elapsed occurrences include coverage, the top feed stories about that release with their uids and relevance scores, ready to expand via alphai_article. Coverage applies only to releases that actually happened: a cancelled or postponed occurrence returns coverage: null. Ask it what is coming this week, then read alphai_macro for what a release meant once it is out.

Macro coverage: Fed decisions, CPI and jobs prints, commodities, geopolitics

  • Market-wide macro news is now in the feed. Rows in the macro_economy, commodities and geopolitics categories carry an empty tickers list, because an FOMC statement is not news about one company. They appear in /api/news/, in alphai_news_search, in trending and in the actionable feed. Filter them by category rather than by symbol.
  • A dedicated GET /api/news/macro/ endpoint and an alphai_macro MCP tool serve the macro tape in one call: central-bank decisions, inflation and jobs prints, oil and gold, geopolitical risk. The REST endpoint returns newest first, with sort=ingested for delta polling; the MCP tool ranks by information novelty, so on a release day the release itself leads and the reaction pieces follow. Free-text queries with words like “fed”, “fomc” or “cpi” now resolve to the macro category. Spec: OpenAPI 1.20.0.
  • Scoring: a scheduled market-wide release scores 7-9 on its release day (8-9 when it surprises consensus or carries a policy shift), so min_relevance=7 keeps the events and drops most of the commentary. Previews and post-release reaction pieces keep their lower scores.

Event-level story grouping

  • Story grouping now matches articles by meaning, not only by headline overlap. Two outlets writing up the same event in their own words (“J&J reaches $5.5bn talc deal” and “Johnson & Johnson offers $5.5 billion to settle”) land in one story with both sources attached.
  • Every story surface benefits: ?collapse=story on /api/news/, collapse_stories=true on the MCP news tools, and the trending feeds, which collapse by default. Expect fewer duplicate rows per event and sources_count above 1 more often. Most stories still run at a single outlet.
  • No contract changes: same parameters, same fields, and the default uncollapsed feed still returns every article. Grouping is deliberately conservative, so two genuinely different takes on a ticker stay separate rows.

Validated insider transaction values

  • Dollar values on SEC Form 4 insider items are now validated against the instrument's own recent filing history before they reach the feed. A filing that carries the lot total, or a decimal-shifted number, in its price-per-share field is corrected back to the true per-share price. When nothing corroborates a correction, the dollar value is omitted rather than guessed and the item keeps its share count. This covers avg_price_usd and total_value_usd in the insider block, the amounts in titles and summaries, and the value-driven relevance_score on insider items.
  • 28 historical insider items published between May 28 and July 28, 2026 now serve corrected figures and scores. Their uids are unchanged. If you store insider events, re-fetch that window on GET /api/news/insider/ or alphai_insider_news to pick up the corrections.

Pro archive depth is now 180 days

  • The Pro news archive on the REST API and MCP is now 180 days deep instead of unlimited. Free stays at 30 days and Basic at 90. Paging past your horizon on GET /api/news/ or GET /api/news/insider/ returns 403 with extra.reason: archive_horizon and your plan's archive_days, exactly as before. MCP news tools apply the same window as a search cutoff.
  • An honest note on what the archive holds: our collectors expanded in June 2026, so months before that carry fewer articles per day than the current feed. The paging depth is the same for every plan surface, the per-day density before June 2026 is not. The OpenAPI spec now says the same.
  • If your use case needs history deeper than 180 days, tell us through the contact form. A dedicated deep-history plan is in the works, and early requests shape what it guarantees.

One event, one alert

  • When several outlets carry the same story, alerts no longer fire once per outlet. Each ticker subscription now receives a single delivery per story per channel within a 24-hour window, on email, Telegram and Pro webhooks. The daily digest follows the same rule, so one event takes one line instead of five.
  • For webhook consumers this changes what arrives on news.matched.v1. If you collapse near-duplicate articles yourself before acting on them, that layer is now mostly redundant. Articles still carry their own uid and you can still fetch any of them from GET /api/news/<uid>/; what changed is how many of them we push at you for one event.
  • Telegram alerts also picked up the per-ticker cooldown that email alerts have always had. A ticker in the middle of a heavy news cycle paces its messages now rather than sending one per article.
  • Nothing to configure and no change to how alerts are created. Manage them in your account or through the alphai_alerts_* MCP tools as before.

A public status page

  • Availability is now public at status.alphai.io. Four endpoints are watched around the clock: the website, the REST API, the authentication gate on api.alphai.io, and the MCP server. The page keeps response times and uptime for each of them, and every incident is filed publicly as it happens.
  • The REST API check is a readiness check, not a ping. It passes only when the database and the cache both answer, so a green REST API on that page means your requests can actually be served.
  • The monitor runs outside our own infrastructure and the page is hosted away from it, so when our stack has a bad day the status page stays reachable and reports it. The 30-day numbers also sit on the API page and the MCP page.

Delta polling on the insider feed, story sources on trending, symbol locale

  • The insider feed polls like the main feed. GET /api/news/insider/?sort=ingested and alphai_insider_news with sort="ingested" return Form 4 events in the order they became available, under the same cursor contract as the main feed: next_cursor is always present, and an empty page means you are caught up. Reach for this mode when you are watching insider activity. A Form 4 is filed days after the trade it reports, so a new event often enters the feed below the newest page, where a poller that only re-reads the first page never sees it.
  • Trending items now carry the story fields. GET /api/news/trending/ and alphai_trending collapse syndicated reprints to one representative, and each item reports the story it stands for: story_id, sources_count (distinct outlets covering it) and sources (their domains). Two pieces from the same outlet count once, so the number counts outlets and not articles. Most stories run at a single outlet, so expect 1 on the majority of items and treat anything higher as the signal. On MCP the fields appear when dedupe is on, which is the default; with dedupe=false nothing is collapsed and they stay null.
  • country and currency are populated across the symbol universe. US listings report US and USD, foreign listings their venue and local currency, crypto pairs USD with an empty country since a coin has no domicile. Visible on GET /api/symbols/, GET /api/symbols/{ticker}/ and alphai_tickers.
  • Free-text search resolves an asset by name, not just by symbol. Asking search or alphai_news_search for "bitcoin" returns BTC-USD coverage instead of the whole crypto category, and the same holds for other names that collide with a family of tickers. Topic words like "crypto", "earnings" and "insider" still resolve to their category.
  • Insider events report when the filing landed. The insider block on GET /api/news/insider/ and alphai_insider_news adds filed_at, the moment EDGAR accepted the Form 4, and late_filing, true when the filing missed the SEC's two business day deadline. Roughly 3% of events carry the flag, and the tail is catch-up filings covering trades from years earlier. Dates are compared in Eastern time with one weekday of slack, so a trade in a holiday week is not flagged.
  • The spec is at /api/schema/, version 1.17.0.

Delta polling with sort=ingested

  • The feed has a polling mode. GET /api/news/?sort=ingested returns rows in the order they became available, so a bot can ask "what is new since my last call" instead of re-reading the first page. Call it once without a cursor, store the next_cursor, and pass it back on each later call. In this mode next_cursor is always present, and an empty results list means you are caught up. Every filter works unchanged: symbol, category, min_relevance, collapse=story.
  • Why a separate mode: articles reach the feed after their publish time. General news lands a median of about 33 minutes after publication and SEC filings in 5 to 9 minutes, so a poller that tracks time_published silently skips late arrivals. The ingest-order cursor cannot lose a row.
  • The same mode is on MCP: alphai_news_search and alphai_ticker_news accept a sort argument. MCP news items also carry a new created_at field, the moment AlphAI received the article, matching the REST feed's original.created_at.
  • A cursor belongs to the mode that issued it, so pass the same sort value on every call of a run. A cursor replayed into the other mode is rejected, and so is one that was truncated or edited in storage: 400 on REST, invalid_cursor on MCP. It is an error rather than a fresh first page on purpose. In polling mode a quiet restart at the head would skip everything in between, and nothing in the response would tell you it happened.
  • Your plan's news-archive depth applies to where a poll resumes, not just to what it returns. On Free and Basic a cursor that resumes further back than your window is rejected: 403 with reason: archive_horizon on REST, an archive_horizon error on MCP. Poll on your plan's cadence and you will never see it. Pro has no window, so a Pro poller can resume from any position.
  • A ready-to-run poller and the recommended cadence per plan are on /developers; the formal contract is in the OpenAPI spec (1.15.0).

Share classes, 8-K categories, fresher trending

  • Ticker queries now cover the whole issuer. The feed's symbol= filter, alphai_ticker_news, alphai_insider_news, the per-ticker summaries and news alerts match every listed share class of a company: a query for GOOGL returns SEC filings tagged GOOG, and an alert on either class fires for filings tagged the other. Article tags stay as published.
  • SEC 8-K filings categorize by their primary item: an earnings release (Item 2.02) is earnings, a completed acquisition or disposition (Item 2.01) is mergers_acquisitions, and the remaining events keep corporate_actions. Historical rows are reclassified the same way, so category filters return them consistently.
  • 8-K relevance scores now read the attached press release. An earnings or acquisition 8-K from a widely followed issuer scores on the disclosure itself, up to 10, so a major print can clear a min_relevance=8 filter and reach trending. Other 8-K items keep their fixed scores.
  • Trending (GET /api/news/trending/, alphai_trending) ranks by relevance score decayed with article age and returns at most two stories per ticker, so the list follows the current tape instead of the strongest story of the past two days.

Any page size from 1 to 20

  • GET /api/news/ and GET /api/news/insider/ accept any page_size from 1 to 20 on every tier, including keyless traffic. Ask for page_size=3 to sample the feed cheaply while you build, or page_size=20 to walk it in half the round-trips. Leaving the parameter off still gives you 10.
  • Pro keys reach 50. A page above 20 without a Pro key returns 400, as does any value outside 1 to 50. A page is never quietly shrunk to a size you did not ask for. Cursor pagination is unchanged: pass each response's next_cursor back as cursor regardless of page size.
  • The MCP tools carry the same axis. page_size and limit reach 20 on Free and Basic, and 50 on Pro. MCP still caps an oversized request at your ceiling and returns the page, rather than failing the call.
  • The OpenAPI spec is at version 1.13.0 with the new bounds on both feed endpoints: OpenAPI spec.

Summary endpoints validate tickers and resolve crypto

  • /api/symbols/{ticker}/sentiment-summary/ and /insider-summary/ now return 404 for a ticker no symbol owns, with a pointer at /api/symbols/?search= to look up the right one. Zeros in a 200 response always mean a quiet window for a real listing, never a misspelled symbol. Response codes are documented in the OpenAPI spec.
  • Both endpoints accept the same ticker forms as the rest of the API. A bare crypto name resolves to its <SYM>-USD listing, so /api/symbols/DOGE/sentiment-summary/ returns Dogecoin's rollup and echoes DOGE-USD as the ticker. Delisted and renamed symbols stay addressable, and a symbol a stock or ETF already owns keeps its meaning: BTC is still the Grayscale ETF, BTC-USD the coin.

Crypto and foreign tickers, plus symbol search

  • News queries accept every market's ticker form. US equities are the bare symbol (AAPL). Cryptocurrencies use the <SYM>-USD form (BTC-USD), and foreign listings use the Yahoo suffix (VOD.L). The symbol parameter on /api/news/ and the /api/symbols/{ticker}/ path document this in the OpenAPI spec.
  • A bare crypto name now resolves to its suffixed ticker. ?symbol=DOGE on /api/news/ returns Dogecoin instead of an empty page, browsing to /stock/DOGE opens the coin, and the MCP alphai_ticker_news tool does the same. A symbol a stock or ETF already owns is left as is: ?symbol=BTC still returns the Grayscale ETF, so pass BTC-USD for the coin.
  • New search on /api/symbols/. Pass ?search= to resolve a company name or ticker prefix to matching symbols, with ticker-prefix matches first. search=bitcoin returns BTC-USD and search=nvda returns NVDA. It matches the alphai_tickers lookup on MCP.

Delisted tickers keep their history, renames stay connected

  • /api/symbols/{ticker}/ now resolves delisted symbols and reports their lifecycle: status, delisted_at, and renamed_to with the ticker the company continues under after a rename (EchoStar's SATS points to ECHO). Field details are in the OpenAPI spec.
  • News queries follow renames. ?symbol= on /api/news/ and /api/news/insider/ returns a delisted symbol's history instead of an empty page, and querying a renamed company's current ticker also matches articles tagged with its former ticker. Tags on past articles stay exactly as published.
  • On MCP, alphai_ticker_news and alphai_insider_news now serve any known symbol and set delisted and renamed_to on the result. unknown_ticker is reserved for symbol strings we do not recognize at all.
  • Creating a news alert requires an active symbol on both REST and MCP. Updating or removing an existing alert on a delisted ticker keeps working.

alphai-tui, an official terminal client

  • alphai-tui is an official open-source terminal dashboard, written in Rust and MIT licensed. Live quotes and candlestick charts sit next to the scored news feed with per-ticker sentiment, and a separate view streams SEC Form 4 insider activity. Everything comes from the public REST API with a regular ak_live_ key, and a free key is enough: the app fetches only what the visible view needs and caches each response for five minutes.
  • Install with brew install makeev/tap/alphai-tui or cargo install alphai-tui; prebuilt binaries for macOS, Linux and Windows, with checksums, are on the releases page.
  • The new alphai.io/tui page covers installation and the first run, and shows how to pair the dashboard with an AI agent over MCP in a terminal multiplexer.

Structured trade data on the insider feed

  • Items on /api/news/insider/ now carry a structured insider block, so you can read the trade instead of parsing the headline: side (buy, sell, or other, with the raw SEC transaction_code), shares, avg_price_usd, total_value_usd, a 10b5-1 plan flag, the reporting owner and their role, and the transaction date. A multi-tranche filing arrives as one event: shares and value are summed, the price is value-weighted, and money fields are decimal strings.
  • The same endpoint now accepts min_relevance (1 to 10), matching the main feed. Insider rows are scored from the event's total dollar value, so this works as a size filter: min_relevance=7 keeps roughly the $10M+ trades.
  • The MCP tool alphai_insider_news returns the same block on every item. Full schema in the OpenAPI spec and on the developers page. The Python and TypeScript SDKs pick it up in 0.3.0 with typed models and the new parameter.

A new n8n briefing template you can import in one click

  • Our flagship n8n workflow is now published in the official n8n template library, so you can add it to your instance in one click instead of loading JSON by hand.
  • The template pulls news, sentiment, and SEC Form 4 insider activity for your watchlist, flags the movers with rule-based red flags, writes a short briefing with GPT, and sends it by email with an urgent Discord ping. A small watchlist runs inside the free tier.
  • It joins the three starter workflows in the n8n integration guide. Your key stays in an n8n credential, and the same flow runs on n8n Cloud or self-hosted.

SDK 0.2.0 and did-you-mean validation errors

  • SDK 0.2.0 (PyPI and npm) adds a page-size control to the news feeds: page_size=50 in Python, pageSize: 50 in TypeScript, available on news.list, news.insider, and both auto-paginating iterators. The API accepts 10 (the default) or 50 with a Pro key, so deep pagination through the SDKs now takes a fifth of the requests. Upgrade with pip install -U alphai-sdk or npm i alphai-sdk@latest.
  • Validation errors now point at the parameter an endpoint actually takes. Sending limit or per_page to /api/news/ still returns 400, but the error message adds Did you mean 'page_size'?, and offset or page suggest cursor. Nothing changes on /api/symbols/, where limit and offset are real parameters for slicing the ticker list.
  • The full parameter tables live in the OpenAPI spec (now 1.10.1), with per-language details in the SDK changelogs on PyPI and npm.

OAuth at connect and API keys on the MCP server

  • API keys now authenticate the MCP server. The same ak_live_ keys that call the REST API are accepted on mcp.alphai.io/mcp as a static Authorization: Bearer header, so headless clients (n8n, cron bots, CI) can skip the browser OAuth flow entirely. A key session sees the full toolset and shares the per-account MCP rate budget with OAuth sessions on the same plan.
  • Create a key under Account → API keys and see the “API key (headless)” tab on alphai.io/mcp for ready-made n8n, Claude Code, Cursor, and curl snippets. Keys travel in the header only; query-string keys are not accepted. Revoking a key cuts MCP access immediately.
  • The full mcp.alphai.io/mcp surface now authenticates at connect: initialize and tools/list require a Bearer token, and an unauthenticated request answers 401 with a WWW-Authenticate pointer to the protected-resource metadata. In practice: your client shows the AlphAI login as soon as the server is added — not at the first tool call. Anonymous catalog introspection is no longer served; the tool list is documented on alphai.io/mcp.
  • OAuth discovery documents are also served at the path-suffixed well-known URLs — /.well-known/oauth-protected-resource/mcp and /.well-known/oauth-authorization-server/mcp — matching how MCP clients derive them from the resource URL.
  • Loopback redirect URIs match port-agnostically at /oauth/authorize: a desktop client registered with http://localhost:<port>/… can come back on a different ephemeral port without re-registering.

Free-text search and forgiving page sizes on the MCP tools

  • alphai_news_search now takes a free-text query (alias q) alongside its structured filters: company names, ticker symbols, and topic words in the query resolve to ticker and category filters. Explicit tickers or category still take precedence when you pass both.
  • Paginated tools now accept limit as an alias for page_size, and a page request above your plan's ceiling is capped to it (10 on Free and Basic, 50 on Pro) — you get a full page plus a next_cursor instead of an error.
  • MCP responses now carry a standing note that AlphAI output is AI-generated financial information for research, not investment advice.

Official Postman collection

  • The whole REST surface is now packaged as an official Postman collection — the /api/news/* feed, trending, insider transactions, single-article and related lookups, plus the /api/symbols/* directory, details, sentiment and insider summaries, and peers. Import the collection and environment, set bearerToken to your API key, and call every endpoint without writing a line of code.
  • Requests target api.alphai.io and authenticate with Authorization: Bearer out of the box. Linked from the developer docs.

Insider feeds are now SEC Form 4 only

  • category=insider, the /api/news/insider/ feed, and the MCP alphai_insider_news tool now return SEC Form 4 insider transactions only — company officers, directors, and 10%+ owners buying or selling their own stock. 13F / institutional-stake and executive-change stories no longer appear on these surfaces.
  • Those stories haven't gone away — they stay in the general feed under their own category (most as other), reachable via /api/news/ and alphai_news_search. Only the dedicated insider surfaces were narrowed.
  • The result is a clean, deterministic Form 4 signal: one row per filing event, aggregated (total shares, volume-weighted price, total value) with a relevance score derived from the event size and its buy / sell / 10b5-1 shape. Full contract in the OpenAPI spec.

ChatGPT deep research support — search and fetch join the MCP toolset

  • The MCP server now implements ChatGPT's connector contract: two new tools, search and fetch, alongside the eleven alphai_* tools (thirteen total). Add mcp.alphai.io as a source in ChatGPT deep research and it can search the enriched news feed and pull per-article digests on its own.
  • search takes a natural-language query — ticker symbols (NVDA, BTC-USD), company names, and topic words (insider, earnings, ipo, crypto…) all resolve to the right filters. fetch returns the enriched digest for one result id: summary, per-ticker analysis, category, relevance score, and a canonical article link. Agents with precise filters should keep using alphai_news_search.
  • Same OAuth flow, tiers, and rate limits as every other tool — nothing to reconfigure. Connected clients that cache the tool list need a refresh to see the new tools (in ChatGPT: Settings → Apps → AlphAI → Refresh). Setup per client on the MCP page.

The full archive goes Pro — tiered depth, richer limit errors, alert delivery modes

  • News-archive depth is now part of the plan matrix. Free keys page the feeds (/api/news/, /api/news/insider/) back 30 days and Basic 90; Pro walks the full enriched archive — every article with its relevance score, per-ticker analysis and category, deep enough to backtest against. MCP search follows the same axis (Pro was previously capped at 365 days; the cap is gone). Requesting a cursor past your horizon returns 403 with extra.reason: archive_horizon — first pages and everything inside the window are unaffected.
  • alphai_news_search (MCP) is filter-first: query by tickers, category, from_date / to_date and min_relevance. The free-text q parameter has been removed — resolve companies to tickers with alphai_tickers and filter, or match text client-side on the returned titles and summaries.
  • Capped responses now tell you what to do about them. A REST 429 (and the archive 403) carries your tier, its limit_per_minute / limit_per_day, retry_after_seconds and an upgrade block naming the higher tiers' caps; the MCP 429 adds the same tier + upgrade fields. Full shapes in the OpenAPI spec (v1.10.0). One number moved with this release: Pro's per-minute burst is now 150/min (was 300); the 100,000/day volume is unchanged.
  • Alert delivery is now a plan capability: instant per-article delivery (email and webhooks) is Pro; Basic alerts arrive as the 06:00 UTC daily digest. Alerts that existed before today keep the delivery mode they were created with. Pro accounts choose per alert via delivery_mode (instant | digest) on PATCH /api/news/alerts/{ticker}/ or in account settings.
  • The plan license is now explicit: Free is for personal, non-commercial use; Basic covers commercial use inside your own organization; Pro additionally covers redistributing the enriched feed as an integrated part of your own product, with attribution to alphai. Offering the data as a standalone feed, dataset, or API stays an Enterprise conversation. Stated on pricing and in the terms.

AlphAI in n8n — ready-made workflow templates

  • You can now wire the feed into n8n with no code. A new n8n integration guide covers setup, and three ready-to-import templates live at github.com/makeev/alphai-n8n-templates.
  • The three templates: trending news to Discord (rich cards with AI sentiment, relevance score and likely price impact), a daily watchlist digest by email, and SEC Form 4 insider alerts to Discord — each alert linking back to the full analysis.
  • Each is built on n8n's HTTP Request node against api.alphai.io with Bearer Auth, so your key stays in an n8n credential — never in the workflow — and the same flow runs on n8n Cloud or self-hosted.

Interactive API reference, and bulk page size on the feed

  • The REST API now has an interactive reference at api.alphai.io/api/schema/swagger-ui/ — browse every endpoint, query parameter and response shape, and fire authorized test calls straight from the page with your Bearer ak_live_… key. Browsing needs no key; the raw OpenAPI spec is linked at the top.
  • GET /api/news/ and GET /api/news/insider/ now take a page_size query parameter. Pro keys can request page_size=50 to receive 50 articles per page instead of the default 10 — fewer round-trips to walk the feed. Free and Basic keys stay at 10.
  • Only 10 and 50 are accepted; any other value returns 400, and page_size=50 without a Pro key returns 400. Cursor pagination is otherwise unchanged — pass each response's next_cursor back as cursor regardless of page size.
  • This brings the REST feed in line with the MCP server, which already served Pro callers 50 results per page. Full parameter reference in the OpenAPI spec (now 1.9.0).

Crypto and global equities join the symbol universe

  • Cryptocurrencies are now first-class symbols. The top ~200 coins by market cap are returned by GET /api/symbols and the MCP alphai_tickers tool, with asset_type: "Crypto". Crypto tickers carry a -USD quote suffix — BTC-USD, ETH-USD, SOL-USD — so they never collide with the US spot-crypto ETF tickers.
  • The symbol shape gained two fields, country and currency, and ticker path parameters now accept the suffixed form (e.g. /api/symbols/BTC-USD/). Full reference in the OpenAPI spec (now 1.8.0).
  • Crypto news is now classified and tagged: an article about a coin lands under the crypto category with the coin's -USD ticker, so it flows into /api/news, alphai_ticker_news, and the other feed and ticker surfaces.
  • Foreign (non-US) equities are now in the universe too. Listings from global exchanges — London (LSE), Frankfurt (XETR), EURONEXT, Tokyo (TSE), Hong Kong (HKEX), Korea (KRX), … — are returned by GET /api/symbols and the MCP alphai_tickers tool. They carry the Yahoo-style ticker suffix — VOD.L, 7203.T, 0700.HK, 005930.KS, MC.PA — with exchange set to the venue prefix and country / currency populated.
  • News about a foreign-only company is tagged with its suffixed ticker, so it flows into /api/news, alphai_ticker_news, and the other ticker surfaces. For companies that also trade in the US, news prefers the US listing — e.g. Toyota coverage lands on TM, not 7203.T.

Two-layer rate limits: per-minute burst + per-day volume

  • REST and MCP rate limits are now two layers per tier — a per-minute burst cap and a per-day volume cap; a request passes only when both are under budget. Current limits, applied independently to REST and MCP: Free 20/min · 100/day, Basic 60/min · 10,000/day, Pro 300/min · 100,000/day.
  • The X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset headers now report your daily volume budget, with Reset at the next 00:00 UTC. A per-minute burst surfaces only as a 429 with a short Retry-After (a daily-cap block caps Retry-After at 3600s).
  • On MCP, a 429 body now includes a window field — "minute" or "day" — so you can tell a burst from a daily cap.
  • The Free tier is now for evaluation / non-commercial use; production or commercial workloads require a paid plan. See pricing.
  • Ticker discovery on MCP (alphai_tickers) now ranks ticker-prefix matches ahead of company-name matches for the q filter — so q=NV returns NVDA, NVAX, … first, then names that merely contain "nv".
  • The default relevance floor dropped from 6 to 4. /api/news/, the MCP query tools (alphai_news_search, alphai_ticker_news, alphai_insider_news, alphai_pair_analysis) and the site feeds now return articles scoring 4+ by default instead of 6+ — more depth per ticker. Pass a higher min_relevance to restore the stricter view. Trending (alphai_trending) keeps its 8+ bar.

Insider transactions: direct vs. indirect

  • Insider (SEC Form 4) news now carries an ownership_form field — "direct" or "indirect", and null on non-insider news. It sits at original.ownership_form on the REST feed and at the top level of every MCP news item.
  • One Form 4 can report a sale from an insider's direct holdings and from indirect holdings (e.g. a trust or fund) as two items that share the same filing URL and date. They are distinct economic events — sum them, don't dedupe by URL or accession number. Indirect items are now also flagged in the headline with (indirect holdings).
  • Full field reference in the OpenAPI spec.

Official Python and TypeScript SDKs

  • Typed clients now wrap all nine REST endpoints, so you can skip hand-rolling requests: pip install alphai-sdk (import AlphAI) or npm install alphai-sdk (import AlphaAI).
  • Both ship cursor auto-pagination, automatic retries on 429/5xx with Retry-After backoff, typed errors, and rate-limit inspection. They read ALPHAI_API_KEY from the environment and target api.alphai.io by default. The Python client offers sync and async; the TypeScript client runs on Node, browsers, edge, Deno, and Bun with zero runtime dependencies.
  • Get them on PyPI and npm, with quickstarts on the developers page. The REST contract is unchanged — the SDKs are entirely optional.

Story clustering — one row per story, not per reprint

  • When one event is reported by many outlets, you can now collapse the reprints into a single row. Pass ?collapse=story on /api/news/, or collapse_stories=true on the MCP alphai_news_search and alphai_ticker_news tools, to get one representative article per story instead of every syndicated copy.
  • Collapsed items carry three new fields: story_id (the representative's UID, resolvable via /api/news/{uid}/), sources_count (how many outlets ran the story — a corroboration signal), and sources (the distinct source domains). They are null in the default, uncollapsed feed.
  • Trending surfaces now collapse reprints by default: /api/news/trending/ and the MCP alphai_trending / alphai_actionable_now tools return one entry per story, keeping the highest-ranked copy.
  • Full field reference in the OpenAPI spec and on the developers page.

SEC 8-K corporate events in the feed

  • A new category, corporate_actions, surfaces issuer 8-K events straight from SEC EDGAR — earnings, material agreements, new debt, executive changes, and annual-meeting vote results — enriched with per-ticker analysis like the rest of the feed. On these rows source reads SEC EDGAR 8-K.
  • Filter them with ?category=corporate_actions on /api/news/ (CSV or repeated to combine with other buckets), or the category argument on the MCP alphai_news_search tool.
  • Relevance tracks event materiality: earnings and completed acquisitions score 7; material agreements, new debt, executive changes, and annual-meeting results score 6 — at the default min_relevance feed floor, so they appear without any filter.

Insider data, tickers, and quota headers in the contract

  • Form 4 insider news arrives one article per filing event: all of a filing's trades of one type (and holding form) collapse into a single item. The title carries the event's total dollar value; the summary carries total shares, the volume-weighted average price with the executed range, and the trade count — a 10b5-1 ladder sale is one article, not one per price tranche.
  • Relevance scores for Form 4 articles are computed from the whole event — tranches sum before the size bands apply — so a plan sale executed across dozens of small steps scores by its total, and min_relevance filters see it accordingly.
  • Every news response now carries enrichment.tickers — the validated symbols the article mentions (only tickers present in /api/symbols/), the same top-level list the MCP server returns. Per-ticker detail stays in ticker_analysis.
  • Every keyed response now carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset, so you can watch your remaining budget without provoking a 429 — which still adds Retry-After.
  • Errors on the API surface are JSON end to end: unknown paths now answer {"message": "Not found."} with the same shape as every other API error.
  • /api/symbols/ takes optional limit and offset params — slice the ~10k-ticker list instead of downloading it whole. Without them the full bare array comes back unchanged; the list is alphabetical by ticker either way.
  • OpenAPI 1.3.0 at /api/schema/ now covers the per-ticker rollups: /api/symbols/{ticker}/sentiment-summary/ (7-day bullish / neutral / bearish counts) and /insider-summary/ (30-day Form 4 stats: buy/sell counts, dollar volumes, 10b5-1 share, top insiders) — with full response schemas.
  • Also added to the spec: the market_movers category (13 total), Symbol.exchange, and the exclude_categories filter on /api/news/.
  • alphai_actionable_now takes a new min_actionability parameter. The feed is gated to articles the enricher scored actionability="high" — a concrete decision to act on today — so an empty list outside US market hours means a quiet tape, not an error. Pass min_actionability="medium" to also include stories that shape a position over days or weeks; the default stays "high".
  • /developers gained a dedicated insider-data guide with live playground presets; /mcp now carries the full 11-tool reference — including alphai_actionable_now (breaking, high-actionability news) and alphai_pair_analysis (cross-ticker read-across) — plus a per-plan limits table.

Relevance scoring recalibrated

  • Scores now rate the article, not the company it mentions: a recap of a mega-cap's week-old earnings scores low; a small-cap's fresh FDA approval scores high.
  • Scoring is deterministic — the same article always gets the same score — and SEC Form 4 rows are scored from the transaction itself (size, buy vs. sell, 10b5-1 plan or not) rather than by the model.
  • If you filter on min_relevance, expect cleaner separation: derivative coverage drops out of the mid band, and the ≥8 band in /api/news/trending/ tightens to primary, market-moving disclosures.

api.alphai.io — a dedicated API host

  • New key-only base URL that bypasses the website CDN: no shared edge cache between your bot and the data, predictable latency. The same routes on alphai.io keep answering as before.
  • The OpenAPI spec at api.alphai.io/api/schema/ is downloadable without a key.

Public launch: REST API, MCP server, insider feed, alerts

  • REST API with API-key auth and hourly tiers — Free 100, Basic 1,000, Pro 10,000 — plus an OpenAPI 3.1 contract at /api/schema/.
  • MCP server at mcp.alphai.io: OAuth 2.1 with dynamic client registration and PKCE, Streamable HTTP, flat deterministic response shapes keyed by article uid.
  • SEC Form 4 insider transactions surfaced as first-class news rows (category=insider) shortly after EDGAR publication.
  • Ticker news alerts over email, with Pro webhooks: HMAC-SHA256-signed deliveries (Stripe-style X-Alphai-Signature) and exponential-backoff retries.

Earlier history predates the public API. Questions about a change? Get in touch.