Overview
Changelog
Customer-visible changes to the Wealthnow REST API, MCP server and dashboard, newest first. Dates are UTC; changes before 2026-09-19 are listed by month. Within each date or month, breaking changes and deprecations come first.
Follow this page in a feed reader at https://app.wealthnow.io/docs/changelog.xml (Atom). Live health for each service is on the status page.
2026-10-18
Devin Desktop (formerly Windsurf) MCP config uses url
The Devin Desktop example in MCP and SDKs now sets the server with url, the field current Devin Desktop reads, instead of the older serverUrl. Nothing changed on the server.
Link previews show the Wealthnow logo
Links to the dashboard shared in chat apps and social posts now preview with the square Wealthnow logo.
2026-10-17
Clearer sign-up, trial checkout and account pages
Signing up from a plan now names it ("Start your 7-day free Pro trial"), and the Plans page says when it is taking you to secure checkout, with a way to stay on Free. Checkout fills in your account email and says the trial starts with no charge today. The Plans page states each trial's credits, the yearly amount after an annual trial, and "Skip trial, subscribe now" for paying today. New keys show their created date and "Never" until first used, and Usage reads "1,000 of 1,000 credits left". No prices, limits or credit costs changed.
Billing and trial wording matches what happens
A failed payment reads "Payment needed" everywhere, and your API key keeps working on the Free plan until you update your card; the trial checkout states the first charge as 7 days after you start, a refused repeat trial says so with no charge, and usage figures during a trial follow the trial's credit limit.
2026-10-16
7-day free trial on Starter, Pro and Expert
Starter, Pro and Expert can start with a 7-day free trial at checkout: same plans, same prices, and the card is charged when the trial ends unless you cancel first in Billing. During the trial, usage stops at the plan's trial credits. If a payment fails, your API key keeps working on the Free plan, with the monthly Free credits, until you update your card.
The dashboard's credit balance is the one the API reports
"Credits remaining" on the dashboard now shows the same wallet balance as X-Credits-Remaining and MCP account_status, including overage headroom on paid plans; the included credits left before overage are shown beside it.
2026-10-14
Congressional trades and every FIRM analytic are back on the API; only the Copilot and the Brain agent are not sold
The 2026-10-13 change also took congressional trades, and the analytics that size or propose a position, off the plans and out of these docs. They are back, on the plans and at the prices they had before:
- Congressional and politician trades (
/api/v3/intel/congress,/politicians,/corporate_donors): Starter and up, 2 credits. See Congressional Trades. - Decisions and trade setups (
/api/v3/decision/*), the signal and decision streams and Kelly sizing: Quant Signals, Starter and up. - Index hedge proposals: Risk Analytics, Pro and up.
- Trading plans and portfolio-aware scores: Execution & Research, Pro and up.
- The rest of what the 2026-10-13 entry lists: the congressional feature panel and
/api/v2/congressional, portfolio allocations (HRP, risk parity, the RL allocator), pairs signals, briefings, agent outputs and account VaR, each on the plan it had before.
Starter has Congressional again and keeps Crypto Market Data. The endpoint reference lists 353 endpoints. Only the Copilot and the Brain agent API are not sold: a key that calls a Copilot route gets 403 not_offered, whatever its plan, and is not charged.
The seller line no longer says the data is not personalized to anyone's portfolio, because some sold routes, such as the portfolio-aware score and the historical VaR scenarios, compute on holdings you send.
2026-10-13
Breaking: the API sells data only
Market data and analytics for software developers. Not investment advice, and not personalized to anyone's portfolio.
These are no longer offered on the API. A call to one answers 403 not_offered, whatever your plan or add-ons, and is not charged:
- Copilot (
/api/v1/copilot/*,/api/v3/copilot/*) and the Copilot add-on. - The Brain agent API (
brain.wealthnow.io/v1). - Congressional and politician trades (
/api/v3/intel/congress,/politicians,/corporate_donors,/api/v2/congressional) and the feature panel built from them. - Decisions and trade setups (
/api/v3/decision/*), trading plans, Kelly sizing, portfolio allocations (HRP, risk parity, the RL allocator), hedge proposals, pairs signals, the signal and decision streams, briefings, agent outputs and account VaR.
Starter adds Crypto Market Data in place of Congressional. Expert is now data at scale: every data product, 10,000,000 credits plus Private Markets Pro's 1,200,000-credit pack (11,200,000 in all), overage to a 50,000,000-credit ceiling, and 1,500 requests a minute.
Breaking: the tengu.co hosts are retired
Wealthnow no longer owns the tengu.co domain. Anything still pointed at firm.tengu.co, keys.tengu.co, app.tengu.co or a connector added as firm.tengu.co/mcp must move to the wealthnow.io hosts now: a request sent to a tengu.co host, and the key it carries, goes to whoever runs that domain.
- REST API:
https://firm.wealthnow.io. The published 0.1 SDKs default tofirm.tengu.co, so set the host explicitly (see MCP and SDKs). - MCP server:
https://mcp.wealthnow.io/mcp. Remove a connector added under the old host and add it again. - Dashboard:
https://app.wealthnow.io.
Your keys, plan and credits are unchanged. If you think a key was sent to a tengu.co host after 2026-10-12, rotate it under Developers → API Keys (see Manage your keys).
2026-10-02
Breaking: a news filter a route does not take is refused, not dropped
A news route used to drop a filter it did not take and serve its unfiltered answer, so a filtered request could read news about something else. news/aggregated?ticker=AAPL returned the market-wide feed, and news/ returned XOM's news unfiltered.
- Every
/api/v3/news/*,/api/v3/intel/news_*,/api/v3/news_crypto/*and/api/v3/news_forex/*route now answers422witherror: "unsupported_, not billed, when it is sent a non-blankfilter" ticker,tickers,symbol,symbols,sector,sectors,industry,topicortopicsit does not declare. Onnews_forex,pair,pairs,currencyandcurrenciesare also refused.detailnames the parameter or route to use,unsupportedlists the refused names andacceptedthe route's own parameters. news/ticker_newsno longer takessector. The news source ignores it besidetickers. Filter by sector onnews/category.- Any other unknown parameter is still ignored, and a blank value is not a filter.
See News & Sentiment.
News: news/aggregated takes one ticker, and news/alerts takes tickers alone
news/aggregated?ticker=AAPLreads the same trailing window from the source's ticker feed and keeps only the headlines tagged with that symbol. The answer echoesticker(nullmarket-wide), andsourceisnews_ticker. An empty window is an empty list with anoteandsymbol_check. A symbol no listing knows is404 unknown_ticker, not billed.news/alerts?tickers=AAPLnow meanscategory=tickerand returns those symbols' alerts. It used to be a503 upstream_.unavailable tickerswithcategory=generalis422 unsupported_filter.- The docs now describe
hoursas it has worked since 2026-09-29. Onnews/aggregatedandnews/events,hoursis a trailing window read newest first, at most 150 items per call.coveragesays whether the read reached the window's start. The guide still described calendar buckets and one page of 50.
Unverified symbols: a current listing is never unverified
An empty answer about a symbol in the security master's current listings, such as AAPL over a quiet minute of news/latest, could carry ticker_ and be refunded when the live symbol check did not finish in time. A current listing now counts as verified: such an answer is an ordinary empty answer, billed, without the field. An unknown symbol is unchanged. See Unverified symbols.
Tape: a day with more prints than limit says so, and pages exactly
GET / and GET / used to return limit prints of a busy day with nothing to say the day held more.
- Every answer with rows carries
rows_total,truncated,windowandnext_cursor.rows_totalis the day's exact print count for the request,truncatedistruewhen the day holds more than was returned, andwindownames the prints a first page holds:most_recenton futures,largest_premiumon options. - Pass
next_cursorback ascursorto read the next page, until it isnull. Pages never repeat or skip a print, identical prints included, so a finished day pages to exactlyrows_totalprints. tape/futuresalso takesbefore=<ISO-8601 instant>as a coarse place to start.- A bad position is a
422, not billed:invalid_cursor,invalid_before, orcursor_and_beforewhen both are sent. tape/futures_curveaddsrows_totalandtruncated.
Existing fields are unchanged. See Page a day that holds more prints than limit.
Fundamentals: a fiscal fourth quarter carries its own EPS and share count
A fiscal-Q4 row on quarterly income_statements was the year less the first three quarters, which is right for revenue and net income and wrong per share: it carried the year's weighted share count and an EPS that could be a cent or two from the company's release.
eps_basic,eps_dilutedandshares_outstandingon a fiscal-Q4 row are now the quarter's own, from the filer's SEC filings: served as filed where the filer reports the quarter, otherwise derived from the year and the first three quarters, day-weighted. Apple's fiscal Q4 2025 reads 1.85 and 1.85 on 14,815,308,000 shares, where it read 1.86 and 1.84 on 14,948,500,000.fiscal_q4_per_sharesays what was done:status(reported,derived, or a withheld state with its reason), the period, andcent_ambiguousfor an EPS whose cent the filer's rounded share counts cannot decide.- The previous figures stay in
vendor_eps_basic,vendor_eps_dilutedandvendor_.shares_ outstanding - TTM figures use the corrected quarter, including
eps_ttm,pe_ttmandforward_peonprice_snapshot: Apple'seps_ttmis 8.72, was 8.71.
See Fundamentals.
Prices and quotes: the last trade, whole-share volumes, exact changes
priceis the last eligible trade in any session, never an exchange's official-close message. After 20:00 ET, NYSE Arca ETFs such as SPY, IWM and GLD were served at their regular close, because the feed's last print was the exchange's closing message and not a trade.price_session,extended_hoursandday_changenow follow the real last trade. This applies toprice_snapshotand to/api/market/quote/{ticker}.- Volumes are whole shares.
day_volumeandregular_session.volumeonprice_snapshotandvolumeon equity bars fromfundamentals/pricesare integers (40711869, not40711869.0). - A finished session's
regular_session.volumeis the consolidated daily total, the same figurefundamentals/pricesserves for that day. While the session forms it is the live running tally. - On
/api/market/quote/{ticker},changeis the exact price difference (it could read4.850000000000023) andchange_pcthas 6 significant figures. - On
/api/market/quote/{ticker},bid,askand their sizes arenulloutside a session. They are served only in pre-market, regular or after-hours trading, and only when the quote was set during that session, as onprice_snapshot. The route used to serve a stale bid and ask with the market closed.
See Read the latest price and its freshness.
Errors: route fields in the body, and an unverifiable symbol is not billed
- An error body carries the fields its route names, after the envelope keys:
availableon an unknown dataset or index,known_rootson an unknown futures root,symbolandhinton the crypto404s,reasonandtickeronexcluded_. The guides documented these fields, but several never reached the body. The envelope keys andfrom_ equity_ ranking X-Error-Codeare unchanged. See Detail fields. - A symbol that cannot be verified is a
200that is not billed. When a metered call's answer is empty and its symbol could not be checked in time, the answer carriesticker_and a note, withverification: "unverified" X-Credits-Cost: 0andX-Credits-Settlement: refunded. It used to be a billed empty answer. A symbol known not to exist is still404 unknown_ticker, not billed. See Unverified symbols.
MCP: account_status reads the balance live
account_status could return a cached balance, 30 seconds old or more, so it disagreed with the X-Credits-Remaining of the call just made. It now reads the key service on every call and returns as_of (when the balance was read) and stale_seconds (0 for a live reading). It still costs no credits.
The five newswire tools are in the spec and the MCP catalogue
intel_news_pro, intel_news_why_moving, intel_news_movers, intel_ and intel_news_crypto (/api/v3/intel/news_*, News & Sentiment, Starter and up, 2 credits) are now listed in GET /api/openapi.json, which has 370 operations, and in the MCP catalogue. The routes already answered over REST. See Newswire stories.
2026-10-01
New API keys start with wn_; the variable is WEALTHNOW_API_KEY
- Keys created from today start with
wn_. Keys created before start withtengu_and keep working on every surface. Nothing to change. - The guides, snippets and MCP configs name the environment variable
WEALTHNOW_API_KEY. The SDKs still readTENGU_API_KEYwhen that is the one set. - A first key needs no plan first. On a workspace with no plan, Create key under Developers → API Keys starts the Free plan (1,000 credits a month) and shows the new key to copy. Signing up from the API pages starts it for you.
2026-09-30
The MCP tool list shows every tool a Free key can call; search_tools finds the rest
- Without a
catalogoption,tools/listshowsaccount_status,search_toolsand the tools your key can call. A key that can call 40 tools or fewer, as on Free, sees all of them; it used to see the first 12. A larger plan sees about 100, never more than 120: every Free tool, a curated set of headline tools and your add-on tools, then your own plan's tools. See What the default list shows. - New:
search_toolsfinds tools anywhere in the public catalogue by topic and gives each match's cheapest plan and credits per call. It runs no data tool and costs no credits. See Find a tool.
2026-09-29
Breaking: the dividend yield is the trailing 12 months, split-adjusted
/api/ (MCP manifest 2.154) served dividend_yield as the last fiscal year's dividends paid over that year's shares, divided by the live price. That lagged a raise by up to a year and ignored later splits. NVDA's dividend yield was the prior fiscal year's (0.017%); it is now the trailing 12 months (0.23%). BKNG read 23.8% because its pre-split dividend was divided by the post-split price; it now reads about 1.0%.
dividend_yieldis regular cash dividends with an ex-date in the last 365 days, split-adjusted, over the live price, as a fraction. Specials are excluded. It isnull, never0, for a non-payer, when the dividend record cannot be read, or when the figure fails a plausibility check.- New:
dividend_(the latest declared regular dividend times payments per year, over the price), theyield_ indicated dividendblock with its status (ok,non_payer,overdue,irregular,unavailable,currency_mismatch,split_,adjustment_ unresolved implausible), andunitsfor every valuation field. - Trailing EPS is on today's share basis. Quarters filed before a split are restated, so KLAC's
pe_ttmis about 53, not 7.16, and BKNG's about 17, not 1.22.eps_ttm_basissays how, andeps_ttmisnullwhen the basis cannot be established. forward_peis unchanged in kind (trailing P/E over one plus the latest fiscal year's growth, not an analyst consensus), but the growth is read as a percent, and it switches to net income growth when a split sits between the two years.forward_pe_basisandforward_pe_growthsay so.- Every new dividend field is
nullwhenvaluation_statusis notok.
See Dividend status.
Breaking: the day change runs from the previous close in every session
price_snapshot served NVDA at -0.39% before the open on a day it was up 1.68%: before the open, on weekends and on holidays, day_change was the previous session's move from its open to its close. It is now price - prev_close in every session, the exact difference, with the percent to 6 significant figures.
sessionnow comes from the exchange clock:pre,regular,postorclosed.off_hoursis gone, andregularno longer appears at 22:00 ET.market_sessioncarries the same value.bidandaskare served only while the exchange is in a session, and only a quote set during that session (quote_as_of). The 20:00 quote is no longer served overnight.- New:
price_session(the session of the last trade; the closing auction readsregular),prev_close_date,day_bar_date,regular_session(the latest regular session, dated, with its own change),extended_hours(the move since that close) andsession_detail_status.
See Read the latest price and its freshness.
Breaking: research-grade price history is on one basis, with total returns
/api/:
prcis the price as traded on every row. Live rows fetched after a later split carried that split's basis, and were then divided bycfacpragain: BKNG's 2025-01-02 close read 197.01. It now reads 4,925.29, andprc / cfacpris 197.01.price_basisnames the rows restored and how each row's basis was established.retis the total return on live rows, the price return plus the cash dividend on its ex-date over the prior close (KLAC 2026-08-17: 1.00% became 1.11%). It used to be the price return under a note that said it included dividends.retxis now served on live rows as the price return.returns_basisstates both per segment; liveretisnullwhen the dividend record could not be read.- Refusals, not billed:
503 price_(a price step no recorded split explains;series_ discontinuous retryable: false),503 split_events_unread(the split record could not be read and the series steps;Retry-After: 30) and503 price_basis_unknown(a live row's basis cannot be placed). A step across a missing session is served and listed inprice_.basis.flagged_ steps - Also: archive rows carry
source: "archive_daily"; a window with no rows warnsno_rows:archiveorno_rows:live; a live-tail answer that skipped the security lookup givesidentity.reason: "security_. The documented defaultid_ lookup_ skipped" startwas wrong: with nostartthe window is the last 365 days, asstart_defaultedandwindow_notesay.
See Research-grade daily history.
Breaking: screener filters state their unit, and a fraction under a percent name is refused
/api/v3/fundamentals/screener read its filters in percent but said so nowhere. A screen for ROE above 0.2 and revenue growth above 0.2, meant as 20%, returned 137 rows; 91 of the first 100 failed the intended screen.
- New percent parameters:
roe_min_pct,roe_max_pct,roa_min_pct,net_margin_min_pct,revenue_growth_min_pct,eps_growth_min_pctandpayout_ratio_max_pct(20is 20%,0.5is 0.5%). The older names still work, in the same percent unit. - Refused, not billed (
422):ambiguous_(an older name with a value strictly between -1 and 1, other than 0),percent_ threshold conflicting_(an older and afilter_ values _pctname that disagree),debt_(outside 0 to 20) andto_ equity_ max_ out_ of_ range non_finite_threshold. - Negative equity never passes a debt-to-equity ceiling. ABBV (-20.49) and HCA (-7.71) passed "D/E below 0.5". Such rows now carry
equity_negative: trueand leave the screen. - Revenue growth beyond ±100% is checked against the SEC 10-K on one revenue concept. TRV's +1,123% compared net investment income with premiums; it is now +5.18%, and the growth floor is applied again to the checked figure.
growth_status,revenue_growth_basisandvendor_say what was checked.revenue_ growth_ yoy - New:
filters_applied(each filter with its unit and basis: the row's latest fiscal year, not TTM) andunits. - Over MCP, an argument the screener does not declare is refused with the accepted list, instead of being ignored. Every tool's parameter descriptions, with units, now reach MCP
inputSchema.
See Screener units and refusals.
Breaking: company snapshots state every block's period and unit
/api/, company_full/{ticker} and full/{ticker} put a quarter's ratios as fractions (NVDA roe 0.2812), trailing ratios in percent (roe_ttm 84.23) and a percent payout_ratio (0.81 meaning 0.81%) side by side, unlabelled.
- Every block carries
period(quarter,fiscal_year,ttm,partial_ttm,point_in_time) andunits, and the ratio blocks carrydefinitions.balance_sheet_mrqwas labelledTTM; it now names its quarter. - A TTM is four consecutive quarters, or
nullwithttm_status. TRV's "TTM" skipped a quarter. A field some quarters leave empty is summed over the rest and named inttm_underfilled_fields. debt_to_assetsis total debt over total assets. The old figure was total liabilities over assets and is nowliabilities_to_assets(NVDA 0.285 against 0.1042). Debt to equity isnullwithdebt_components_missingwhen the balance sheet lacks a debt component.- The cash flow reconciles.
change_was only the receivables change, so the served parts summed to 85.2B against NVDA's 24.1B of operating cash flow. It is nowin_ working_ capital nullwith a status, andchange_in_receivables,other_operating_itemsandoperating_sum to operating cash flow, withcash_ flow_ components cash_conversion_pct. - Dividends:
dividends_paid_ttmwas the fiscal year's total (NVDA 0.97B); it is now the trailing four quarters (6.73B), and the fiscal year's total isdividends_.paid_ fiscal_ year dividend_historyrows addper_, so a split no longer reads as a cut;share_ split_ adjusted dividend_andper_ share_ growth_ yoy_ pct years_measure per share. The same applies onconsecutive_ per_ share_ growth /api/.v3/ fundamentals/ dividends fullserves top institutional holders again, from 13F filings with their report period and freshness. They were always an empty list. Insider trades and holders now need a plan with thefundsproduct (Starter and up), as the standalone routes do; on Free they arenullwith statusplan_required.period_pairspairs statements of the same period.- Growth beyond ±100% is checked in the
growthblock too; see below.
See Periods and units in company snapshots and Dividends.
Breaking: SEC filing extracts serve the narrative sections
/api/ returned null text sections under a _status note. It now serves risk factors, MD&A, market risk, business and subsequent events, verbatim from the filing, for the sections named in the new sections parameter, paged with max_chars and offset. Each section is an object with a status, and text_sections._status is extracted, partial, not_extracted or available_on_request.
- New:
accession_index_url(the filing's own document index) andcash_(a 10-Q's cash flows are year to date).flow_ summary.period diluted_trend_4qholds one value per quarter end. NVDA's 2026-07-26 appeared twice, as the quarter's and the year-to-date diluted shares.
See Narrative sections.
Breaking: a stock or unlisted ticker on the crypto derivatives routes is a 4xx, not an outage
/api/, open_interest, basis and vol_surface used to answer 503 whenever no row could be served, so an agent read "NVDA" or a typo as "the exchanges are down" and retried.
- A ticker the venues list as a security, not a coin (for example
NVDA, which OKX, Gate and Coinbase International list as a stock perp):422witherror: "not_.a_ crypto_ asset" rows[].reasonnames each venue's declaration. - A symbol no venue lists (every first-party venue answered):
404witherror: "symbol_. Onnot_ listed" vol_surface, a currency Deribit lists no options on. - Both are standing answers: not billed,
retryable: false, noRetry-After. They keeprows,coverageandsources. - A real venue failure is still a
503witherror_(orcode: "crypto_ derivatives_ unavailable" crypto_). It now carriesvol_ surface_ unavailable error: "upstream_,unavailable" Retry-After,is_andempty_ result_ set: false Cache-Control: no-store, like every other refusal.sourcesnames the venue that failed. - A request that mixes a coin with a stock (
symbols=BTC,NVDA) is unchanged: a200whose NVDA row is markedrefused.
XBRL facts are read from SEC, dated
/api/ and xbrl/{ticker}/{concept} read a bulk copy that stopped refreshing in the spring of 2026. They now read SEC's live companyfacts document: source is sec_ (it was warehouse:edgar/companyfacts), or archive when SEC cannot be read. New fields: as_of (companyfacts) or data_as_of (xbrl), last_filed, financial_, is_stale, freshness and, on xbrl, concept_last_filed, field_notes and each row's own period_fy, period_fp and period_months (fy and fp stay the filing's). is_stale is true when the financial facts lag the filings (TSM). SEC unreachable with no archived copy is 503 sec_, not billed. See XBRL freshness.
Growth, bars, peers and history say what they are
/api/v3/fundamentals/growthchecks revenue growth beyond ±100% against the SEC annual report. Onvendor_concept_mismatchthe SEC figure and recomputed CAGRs are served (TRV: 3-year 157.83% became 9.8%), the margins computed on the wrong revenue are withheld intovendor_margins, and the source's figures stay invendor_,revenue_ growth_ yoy vendor_andrevenue_ growth_ 3y_ cagr vendor_.revenue_ growth_ 5y_ cagr sec_check_pendingandunverified_outlierservenull. See The revenue growth check./api/v3/fundamentals/pricesaddsadjusted,adjustment_basis(splits,unverifiedornone) andadjustment_note: equity bars are split-adjusted, not dividend-adjusted, so KLAC's 2,108.06 close before its split reads 210.806. See Adjusted bars./api/runs to next calendar year whenv3/ fundamentals/ historical/ {ticker} end_yearis omitted, so NVDA's fiscal 2027 quarters are included, and says so inend_year_default./api/addsv3/ fundamentals/ peers/ {ticker} peers_status(ok,none_after_size_filter,none_,after_ data_ error_ filter vendor_no_peers,vendor_unavailable) and documentsmin_relative_size. NVDA's peers were all dropped by the size floor with no reason given.- Crypto derivatives funding, open interest and basis add
coverage.not_covered(the venues in no value, with areason_code),coverage.headline_scope(verified_venues) andheadline_scope_note, so no total reads as market-wide. The aggregator'sreasonisnot_enabled, and the Binance and Bybit reason is reworded.
Served text says what the data is
Notes, hints and messages on about 40 routes described our own vendors, plans, scripts and jobs. They now say what the data is and what you can do; every code, status and flag beside them is unchanged. A few fields that only described our vendor arrangements are gone or empty: used, cap, limit, priority and scope on news budget refusals; vendor, monthly_limit, daily_limit, per_minute_limit and safe_threshold on monitoring/api_quotas; data_source_options and checked_alternatives on borrow_cost (now [], removed next release). intel/ml_drivers source is model_shap_attributions, and a 504 says "request exceeded the N s time limit; retry, or narrow the request".
Voter attribution: options flow is attributed; failures are refusals
GET / (MCP manifest 2.151):
voter=options_flownow attributes the voter from the ticker's options-flow alerts. Every call used to fail and answer a billed200witherror: "uw_read_failed". Each alert takes its direction from option type and side of the book (a call bought or a put sold is bullish), and mixed alerts are skipped. Alerts are weighted by premium. The new fieldsalerts_readandwindow_truncatedsay how much was read.score_reconstructionis a reconstruction from those alerts, not the voter's own score.- When the options-flow feed cannot be read:
503,error_,code: options_ flow_ unavailable Retry-After: 30. It is not billed and never cached. On a server without the feed configured,Retry-Afteris3600andretryableisfalse. voter=insider_flow:- A Form 4 read that fails answers
503witharchive_read_failedorarchive_read_timeout. - An empty filings archive answers
503 dataset_unavailable. - A ticker with no filings answers
200withn_events: 0andscore_. It used to be a neutralreconstruction: null 0.0.
- A Form 4 read that fails answers
- Input checks:
days_backoutside 1-90 and an unknownvoteranswer422.
Status routes and vendor errors carry codes, never text
/api/v3/stream/*status routes and the universe status report a daemon's last error as a code (flush_failed,subscribe_timed_out, ...). Any stored value that is not one of our codes is served asunclassified_error.vendor_error,upstream_errorandvendor_errorsblocks carry the kind, status, codes and path of a failed vendor call, never the vendor's response body or the exception's text.
Every response refuses to be framed; sign-in pages are never cached
- Every response carries
Content-Security-Policy: frame-ancestors 'none', so no page can be embedded in another site's frame. It restricts framing only. - Every
/oauth/response carriesCache-Control: no-storeunless the route sets its own policy. The consent page used to carry none.
The point-estimate disclosure is measured on the served book
The point_estimate block that describes predicted_return_pct now reports what the served book's column actually holds: blended_score * 100, model return estimate, mixed or none. It adds definition_basis (measured_on, at, n_rows). It says unmeasured until a book has been served since the server started. is_calibrated_forecast stays false, and the value stays withheld.
2026-09-28
Breaking: predicted returns are withheld on every route
predicted_return_pct is blended_score × 100, a rescaling of the ranking score, not a calibrated return forecast. Six routes already withheld it; every other route that serves the prediction book now withholds it too, with its band (interval_lo, interval_hi, interval_half_width), as null with withheld: "uncalibrated_.
- The routes:
/api/,v3/ decision/ universe_ scan /api/v3/signals/fusion,/api/, and the v1 routesv3/ learning/ prediction_ tracker /api/predict/{ticker},/api/predictions,/api/top-picks,/api/signals,/api/scan,/api/snapshot/{ticker},/api/risk/{ticker}and/api/dashboard. /api/risk/{ticker}:kelly_fractionisnullwithkelly_withheld. It used to be a fabricated0.0.- Averages:
/api/predictions/accuracyand/api/v2/models/calibrationwithhold the mean point estimate and the band's mean width. Hit rate, IC and coverage are still served. /api/results: withholds its predicted column and says why intrack_record_note.
Rank, decile, direction, conviction and the order of rows are unchanged, so rank on those. See Withheld magnitudes.
Breaking: the /api/users routes are removed
The undocumented /api/users routes (user records with a broker account, and pause or resume controls) now answer 404. They were never offered as a product, and they held no users.
New: private company news
GET / (MCP tool private_markets_news, Pro, 5 credits) serves news about private companies: funding rounds, M&A, IPO filings, partnerships, launches, leadership, legal and layoffs. It gives one story per event, with its other outlets listed, each tagged with its companies. It filters by category, sector, company_id and q, sorts by latest or top, and pages with a cursor. A feed that cannot be read answers a 503 refusal, not billed, never an empty list. The MCP manifest is 2.150. See Private company news.
The crypto vol surface ends at the last completed hour
The venue stamps the hour in progress with its end time, so /api/ served a partial hour, stamped in the future, as realized_vol, and built vol_risk_premium on it. realized_vol now ends at the last completed hour. vol_risk_premium adds iv_as_of and rv_as_of, the time of each leg.
Error bodies name a code, never an internal error
- No internal error detail in any body. No response carries an internal exception's class or text, which could name storage paths or queries.
- An unexpected failure answers
500witherror: "internal_error"anddetail: "request_. Quote the request id when you contact support.id=..." /api/health/private_reportsmarkets detail: "probe_failed"or"probe_timed_out".- Security master unavailable: when the service that maps a symbol to its security cannot be reached, the routes that need it answer
503 identity_instead of a billedunavailable 200. sentiment_is served again during a security-master outage, stampedhistory?entity= identity_.verified: false
Sign-in: a client metadata document must be served directly
For developers of MCP clients that sign in with a client ID metadata document. The document at your client_id URL must answer 200 directly. A redirect is refused, as the draft specification requires, and client_id must equal the URL exactly. Every client we know of already does this: Claude, Claude Code, Codex, Goose, Grok, VS Code, Zed and Copilot CLI.
2026-09-27
Breaking: company events return each key development once
/api/v3/events/{ticker} returned the vendor's version history as separate events: every version of a key development, and a row for each type and role. For Apple since 2025 that was 309 rows for 244 developments, and repeats pushed real events past the limit.
- It now returns each development once, from the vendor's current version. New
typesandrolesfields list every type it is filed under and every role the company plays. limitandncount events.- With a
typefilter, the top-level type is one you asked for. - Developments the vendor has closed are left out. The new
include_closed=trueadds them, flaggedvendor_status: "closed"withclosed_at. untilnow includes the whole day.
The MCP manifest is 2.149. See One event per key development.
Breaking: price refusals carry error: "upstream_ unavailable"
When every price source fails, /api/v3/fundamentals/prices and /api/ still answer 503 with error_, but error is now "upstream_unavailable" (it was "price_), as for every other refusal where the data behind a route could not be read. The code is also sent on the X-Error-Code header, and the body adds is_ and data_available: false. The prices refusal no longer carries items: [], which read as a symbol with no bars. A crypto snapshot older than 15 minutes is refused the same way, with error_. Read the cause from error_code. See When no price can be retrieved.
The price snapshot refuses when its live quote fails
/api/ answered 200 with price: null when the live quote failed, because the failure was lost before the response was built. It now answers the 503 price_ refusal above. When a snapshot is rebuilt within 5 seconds of a good quote for the same ticker, it reuses that quote instead of fetching a new one; a failed quote is never reused.
Five MCP tools say they cannot answer today
The MCP manifest is 2.148. The descriptions of five tools now open with UNAVAILABLE, so an agent does not reach for them. The routes behave as before.
intel_ml_drivers:503 upstream_.dead_ drivers_ unbound market_events_catchup: no producer publishes market events.intel_voter_ic_drift: its table has not been produced, so it answers with no voter rows.tape_optionsandtape_futures: capture stopped after 2026-07-29 and 2026-07-30; earlier days are still served.
2026-09-26
Breaking: crypto funding is weighted by open interest, from first-party venues only
/api/, /open_interest and /basis read first-party venues only: OKX, Deribit, Kraken, dYdX, Bitget, Gate and Coinbase International, each marked tier: "verified" in sources. One former source was retired and is no longer read. funding_rate_8h keeps its name and unit but now means the open-interest-weighted rate across verified venues, or their median when a verified venue has no open interest; it was the plain mean of the served venues, which is still served as mean_rate_8h_verified. A new funding_rate_basis field names the method ("oi_weighted_verified"). Binance and Bybit, which answered ok through a relayed feed, now report status: "geo_blocked": their APIs are blocked from the API's region and are not reached another way. Deribit reports not_applicable instead of missing when a request names neither BTC nor ETH. The three routes take a new optional detail (auto, full or summary, default auto) that keeps responses under about 15,000 characters; existing calls are unchanged. The MCP manifest is 2.147. See Derivatives, events and on-chain.
Breaking: earnings press releases are retired
/api/ answers 410 with error_, not billed, and its MCP tool is gone (the full catalogue is 276 tools). The upstream source of the release text no longer exists and nothing else holds it; the route had been answering with an earnings calendar instead. For report dates and estimates use /api/; the filed release is usually exhibit 99.1 of the Item 2.02 8-K (/api/).
Breaking: corporate actions come from the current archive, as known on a date
/api/ read a distributions archive frozen at 2024-12-31. It now reads the current archive, which records every version of each event, and serves each event in its newest version known on the new optional as_of. The response adds as_of, current_through with current_through_basis, clock, coverage and a versions block; rows add the version fields and distype, and distcd is now null. An unreadable archive is a 503 warehouse_, not billed, never the old archive.
Breaking: news topics are the news source's own categories
topic on /api/v3/news/by_topic and /api/v3/news/category, and topic, topic_or and topic_exclude on /api/v3/news/ticker_, now accept only the news source's categories: earnings, dividend, layoffs, lawsuit, mergers (M&A, also acquisition or m&a, sent as manda), pricemovement, tanalysis, product, ceo, pressrelease, podcast, oil and futures, and the access tags paywall and paylimitwall. Anything else returns 422 with error: "invalid_topic", naming the supported topics, and is not billed. ipo, fda, analysts, pricetarget, guidance, stock_buyback, stocksplit, partnership, spinoff, bankruptcy, insider, esg and crypto were documented, but the source has no such category and always answered an empty list, which read as "no news"; the 422 now says there is no such category. mergers and acquisition, which answered empty too, now reach the M&A category. by_topic adds source_topic, the category it sent. See News topics.
Breaking: the analyst ratings calendar answers from a live feed
/api/ served an archive whose newest action was 2026-06-26, because its own feed was retired. It now answers from the live analyst-ratings feed behind /api/v3/news/ratings, with source: "vendor:news-ratings-feed", and falls back to the archive only when that feed fails, in which case a 503 advises a retry. Live rows carry analyst_name, company and url as null and add time_zone. action_company is Upgrades, Downgrades, Initiates, Reiterates or Resumes. action_pt is derived from the prior and current targets (Raises, Lowers, Maintains, Announces), and the Maintains filter also matches a reiterated rating. The response adds scan (rows_read, pages, complete, filtered_after_read): an action matched over only the newest rows read says result: "not_ or "partial_scan" instead of reading as an empty answer. See The analyst ratings calendar.
Breaking: funds and ADRs leave the equity rankings
The prediction book carries an equity-model score for several thousand funds and ADRs, which the equity model cannot rank: in the 2026-09-14 book SPY ranked 98th and AGG sat in decile 10. A fund or ADR (by security class in the security master) whose row carries an equity-model score is now removed before any ranking or per-ticker prediction, and so is a row the pipeline's quarantine list says to refuse. rank and decile keep the book's own values; nothing is re-ranked. Ranking routes add a book_guard block that counts what was removed, with non_ for funds and ADRs in excluded_by_reason: /api/ml/top-picks, /api/v3/decision/trade_, /api/, /api/v3/decision/ultimate, /api/v3/signals/fusion, /api/ when it answers from the book, and /api/v2/predict/multi_. For a fund or ADR asked for by name:
/api/ml/predict/{ticker}answers404witherror: "excluded_.from_ equity_ ranking" /api/,v2/ predict/ {ticker}/ intervals /api/andv3/ decision/ ultimate? ticker= /api/answerv3/ validation/ {ticker}/ kelly_ uncertainty 200with the valuenulland anexcludedblock./api/answersv3/ intel/ ml_ prediction/ {ticker} available: falsewithexcluded, which reaches you as503 paid_, not billed.data_ unavailable /api/v2/predict/multi_lists it inhorizon missing_tickersand in the newexcluded_tickers./api/snapshot/{ticker}servesprediction: nullwithprediction_excluded.
When the guard cannot load its sources, these routes answer 503 with error: "upstream_, error_ and Retry-After: 60, not billed, and the batch route answers 503 snapshot_cold or snapshot_unusable. See Funds and ADRs.
Breaking: the prediction book is dated, and a stale answer says so
The prediction book has not been regenerated since 2026-09-14, and the routes that serve it answered as if it were current. They now carry data_freshness, graded on the served rows when you call: data_as_of, data_age_hours, data_age_days, sessions_behind, max_sessions_behind (2), is_stale and stale_reason. It is on /api/v3/intel/ml_, /api/ml/predict, /api/ml/top-picks, /api/, /api/v3/decision/ultimate, trade_setups and universe_scan, /api/v3/signals/fusion, /api/ when it answers from the book, and /api/v1/copilot/score, /top-picks, /universe and /macro-regime. While the book stays frozen, every one of them answers is_stale: true. snapshot_stale on /api/v1/copilot/top-picks, /api/v1/copilot/universe and /api/ is now also true when the book is more than 2 sessions old; it used to mean only that the server's copy had failed to refresh for 4 hours, so the ten-day-old book read false. A stale Copilot answer's narrative starts with STALE BOOK:, and the top picks say "picks from the 2026-09-14 book" instead of "picks today". as_of_ts on the Copilot top picks, universe and macro regime is the book's newest time, null when it is unknown. data_staleness_days on a served prediction row is computed from the row's as_of_ts when you call; it was a stored 0.0 on every row. See How old the prediction book is.
Breaking: ml/top-picks and prediction intervals withhold the return estimate
/api/ml/top-picks served each pick's predicted_return_pct (the blended score × 100) and the band around it. They are now null, with withheld: "uncalibrated_ on each pick and one magnitudes_withheld block on the response. /api/ withholds interval.lo, interval.hi and interval.half_width the same way, with interval.withheld and magnitudes_withheld, because the band is built around that number. Rank, decile, blended score and conviction are unchanged. /api/ml/top-picks also adds data_freshness and book_guard, and its as_of_ts is the newest time among the served rows. See Quant Signals.
Breaking: tape bars take one row per minute, and websocket minutes have no trade count
/api/v3/tape/bars/{ticker} kept the last-written row for each minute, which was the REST fallback's on every minute the websocket also wrote. It now serves one row per minute: the websocket's final bar, and the fallback's only for a minute the websocket never wrote. n_transactions is null on websocket minutes, whose stored number was an average trade size, not a count, and a 5m, 15m or 1h bar's count is null unless every minute in it has one. /api/v3/tape/index_bars keeps summing n_ticks. See One bar per minute.
The price snapshot answers without waiting on fundamentals
/api/ fetched its valuation inputs (trailing EPS, diluted shares, book value per share, growth and dividends per share) again with every price, which made a ticker's call take 1.5 to 8 seconds, longest when several tickers were asked for at once. The inputs are now kept for 6 hours and applied to the live price, so pe_ttm, forward_pe, price_to_book, dividend_yield and market_cap still move with the price; the price itself is at most 30 seconds old, as before. The snapshot adds valuation_as_of, when the inputs were fetched. A ticker's first call in 6 hours still waits for them.
The price snapshot says whether its valuation fields could be computed
/api/ adds valuation_status to every equity snapshot: ok when the valuation inputs were fetched, unavailable when the fetch failed or the provider has no inputs for the security (a fund, for example). With unavailable, every valuation field and valuation_as_of is null, which says nothing about the company's earnings; before, the same nulls were indistinguishable from a company with no positive earnings. The valuation keys are always present, as null when there is no value.
Crypto news is unavailable until 2026-09-30 00:51 UTC
The crypto news provider's monthly call quota ran out on 2026-09-25 at about 15:00 UTC, and it resets on 2026-09-30 at 00:51 UTC. Until then every /api/v3/news_crypto/* route answers 503 with error_ and the reset time, not billed. Wealthnow's own daily limit on these calls restarted from zero on each deploy, so it did not hold the monthly quota; it now holds across deploys.
Book routes answer a ticker's first call without the wait
/api/v3/intel/ml_, /intel/voter_coverage, /signals/mtf, both kelly_uncertainty routes, /api/, /api/v3/decision/ultimate, /api/predict, /api/snapshot and /api/risk read one shared, pre-loaded copy of the prediction book instead of reading it per ticker, so a ticker's first call no longer takes 9 to 22 seconds. Every one of them now answers from the same snapshot: when the newest snapshot is degraded they fall back to the last healthy one (up to 4 days back), and a ticker missing from the newest snapshot is reported as missing rather than answered from an older one (ml_prediction, voter_coverage and signals/mtf used to differ). While the shared copy loads after a restart, these routes answer 503 with error_ and Retry-After: 5, not billed.
Corporate actions the archive holds are served
/api/ counts a version as known from the earlier of its vendor date and first_held_at, the new row field for when Wealthnow first stored it. A recent action the archive already holds (for example a dividend whose vendor date is weeks away) is no longer withheld.
Credit-default-swap history keeps its latest quotes and wide windows
/api/ and the CDS block of /api/v3/credit/{ticker} read less of the archive and answer faster. Explicit start/end windows of any width are served, and a name that stopped quoting still returns its newest quotes (window.widened_).
Price history names missing adjustment factors
/api/ rows before 2000 carry null cfacpr and cfacshr. The response now says so in an adjustment block, and its note no longer suggests adjusting with them.
Latest news serves the window you ask for
/api/v3/news/latest accepted minutes up to 1440 but read only the last hour above 60, so a day's window could answer empty in the evening. It now reads the requested window, and an empty one carries a note.
Crypto bars mark the bar still forming
With asset_class=crypto, /api/v3/fundamentals/prices now marks today's UTC day bar and the open week's bar partial: true, and adds as_of, as_of_basis, last_bar_partial, data_through and session_complete, as equity bars do. It used to serve those bars as if final. See Bars still forming.
FX news takes EURUSD
The pair and pairs parameters of the /api/v3/news_forex/* routes now also accept EURUSD and C:EURUSD, beside EUR-USD, EUR/USD and eur_usd, and send each as EUR-USD. EURUSD used to reach the feed unchanged: latest answered 503, and sentiment_stats and summary came back empty. See FX news, sentiment and prices.
The last report date follows the options-flow calendar
On /api/, most_ came from dates found in web search, so an old date could stand as the latest report: NVDA read 2025-05-28. When the options-flow earnings calendar, which also dates earnings_history, holds a newer reported quarter, its date now wins, with most_, and the superseded date and its source are kept in most_. NVDA now reads 2026-08-26. See Macro, Rates & FX.
Quota refusals say when the quota resets
When a news feed refuses for quota on the /api/v3/news/*, /api/v3/news_forex/* or /api/v3/news_crypto/* routes and states when its quota resets, upstream_error adds quota_resets_at (UTC) and quota_resets_at_basis, and the body adds retry_. Retry-After is when Wealthnow next checks the feed, within the hour, not when the quota returns: on 2026-09-25 the crypto news refusal said to retry in 40 minutes for a quota that resets at 2026-09-30T00:51:46Z. See News & Sentiment.
On-chain flows answer
/api/v3/crypto/onchain/flows answered 503 with error_ on every call, because the server could not compute the event hashes it filters the chain logs by. It now computes them itself and serves the stablecoin flows and Aave liquidations. See Crypto.
Empty answers say why
/api/adds av3/ intel/ corporate_ donors/ {ticker} notewhen the source answered and holds no records for the company: many companies have no corporate PAC./api/answers with every field,v3/ intel/ short_ interest/ {ticker} null, when it has no record. It used to omitavg_anddaily_ volume_ at_ settlement prior_settlement_dateexactly then.
Outside the public API, /api/status and /api/ready report a stale book. While the served book is more than 2 sessions old, /api/status answers status: "red" with model_ready: false, model_ and pipeline_, and /api/ready answers ready: false with reason: "predictions_. Both add prediction_freshness and still answer HTTP 200. /api/ answers 404 excluded_ for a fund or ADR candidate, and for a book whose holdings are all funds or ADRs; a book with no covered holding keeps its sentence, "none of the held tickers are in the prediction universe", now naming any excluded holdings. /api/v1/copilot/portfolio and /api/ leave funds and ADRs out of holdings and candidates and add data_freshness, book_guard and the STALE BOOK lead. /api/signals/history, /api/research/screen and /api/briefing in the firm shape withhold predicted_return_pct and its band, with magnitudes_withheld. /api/v3/signals/veto_ applies the same guard, so its vetoes exclude funds and ADRs and it can answer 503 book_, and it adds data_freshness and book_guard. /api/ and /api/v3/signals/mtf/{ticker} answer a fund or ADR with an excluded block, and /api/ and /api/v2/briefing/overnight name predicted_return_pct in point_estimate.field.
2026-09-25
Breaking: the screener floors, types and sorts on Wealthnow's own data
/api/v3/fundamentals/screener used to pass the fundamentals source's screen through: it served nano caps and shells first, ignored sort_by=market_cap, and ranked revenue in yen and won as if it were dollars. It now sizes every matched row from exchange prices and shares outstanding and applies the floors itself. With no new parameters it returns only common stock with at least a $300M market cap and $1M a day of dollar volume, sorted by market_cap_usd, so the same query returns different rows. New parameters: min_market_cap_usd (default 300000000, 0 turns it off), min_adv_usd (default 1000000) and security_class (comma list of common, adr, preferred, fund, unit, warrant, other; default common). sort_by is validated: an unknown key returns 400 invalid_sort_by and an unknown class 400 invalid_, each listing the allowed values. Rows add listing_ticker, security_class, exchange, price_usd, adv_21d_usd, market_cap_usd, reporting_currency, currency_status, revenue_usd, net_income_usd, fx and fundamentals_stale; the response adds floors, total_matched, total_pages, universe, field_sources and as_of. market_cap_usd is null when the close has moved more than 3x from the close on the share count's date, and liquid listings the floor dropped for lack of a verifiable size are named in universe.liquid_. While its size data loads the route answers 503 build_timeout (Retry-After: 10); when its data cannot be read, 503 upstream_ with screener_ or screener_. None is billed. See How the screener sizes and sorts.
Breaking: a news or alternative-data feed that failed returns 503, not an empty list
When the feed behind a route fails and returns nothing, the route now answers 503 with error: "upstream_, not billed and with no result field, where it used to answer a billed 200 with an empty list and a vendor_error. A feed that answered with nothing is still a 200, and a partial failure keeps its rows. This applies to the /api/v3/news/* newswire routes, every /api/v3/news_forex/* route and the /api/v3/news_crypto/* routes, with error_code upstream_<kind> (for example upstream_, or upstream_not_configured when no feed is configured, which used to be a 503 with ok: true); and to intel/congress, intel/politicians, intel/corporate_donors, intel/insiders, intel/lobbying, intel/gov_contracts, intel/gov_, intel/patents, intel/exec_compensation, intel/wsb, intel/off_exchange and intel/etf_holdings, with upstream_, archive_read_timeout, archive_read_failed or build_busy. intel/twitter, whose upstream dataset returns no rows for any ticker, answers 503 upstream_ (Retry-After: 86400) instead of an empty list with a note. On news_forex/by_category, a section other than general or alltickers returns 422. See News & Sentiment, Macro, Rates & FX and Alt-Data.
Breaking: per-ticker alternative data comes from a dated warehouse copy
intel/lobbying, intel/gov_contracts, intel/patents, intel/off_exchange and intel/congress with provider=alternative_ and a ticker now read a warehouse copy of the feed first, and the live feed only for a ticker the copy does not hold. The copy's history starts where it began: lobbying filings from 2025-01-19, congressional trades from 2025-05-20 (earlier for some tickers), off-exchange sessions from 2026-05-08, contract quarters from fiscal 2020, and a recent window per ticker for patents. Answers say so in data_from, history_floor, coverage_note, as_of, archive_ingested_at and data_through, with source: "warehouse:<product>-archive". Lobbying rows add registrant; contract rows are quarterly totals on the US federal fiscal year, with fiscal_basis, period_start and period_end; off-exchange rows from the copy have total_volume: null. See Alt-Data, Congressional and Options Flow.
Breaking: /api/ml/predict withholds the return estimate
/api/ml/predict/{ticker} served the stored prediction row as it was, with predicted_return_pct (the blended score × 100) and the interval built around it. predicted_return_pct, interval_lo, interval_hi and interval_half_width are now null, with withheld: "uncalibrated_, point_estimate and point_, as on ml_prediction. The score, conviction, decile, rank and voter sub-scores are unchanged. See Quant Signals.
Breaking: price bars run through today, and the forming bar is marked
With no end_date, /api/v3/fundamentals/prices used to end an equity window on the previous UTC day. It now ends with today's session, so the newest bar can still be forming; such a bar carries partial: true. The response adds as_of, data_through, as_of_basis, last_bar_partial and session_complete. C: forex and X: crypto tickers on this path are graded on the UTC day. A window with no bars yet is a 200 with items: []; end_date before start_date returns 422 invalid_date_range, and a date that does not exist 422 invalid_date. See Bars still forming.
Breaking: earnings history is dated by the announcement and measures the reaction
On /api/, report_date is now the day results were announced, and null when no date is known. It used to be the end of the calendar quarter, sometimes a day that had not happened yet, which is now calendar_quarter_end. day_move_pct and day_range_pct are measured on the session that traded on the release (the next session after an after-close report), named in day_move_date with day_move_basis; they used to be measured on the quarter-end date. New fields: reaction_move_pct, avg_, max_, fiscal_year, fiscal_quarter, fiscal_quarter_end, report_time, report_date_source and eps_basis (adjusted) with eps_basis_note, and warning: "report_ when the date source failed. See Earnings reaction moves.
Breaking: the analyst price-target mean is the source's own
On /api/, when the band comes from a source's summary, price_target_avg was the mean of that source's mean, high and low, and price_target_count (3) read like a number of analysts. price_target_avg is now the source's own mean. price_target_count keeps its value and price_ says what it counts (rating_actions, news_rating_actions or summary_fields); price_target_analysts is the number of analysts behind the targets when the source says. See News & Sentiment.
Breaking: skill counts from a failed feed are null
In ta_master and apex_equity, a count or total from a feed that was not fetched or whose call failed is now null, not 0, with the reason in vendor_errors: the components counts, and apex_equity's intel fields such as congress_30d and ttm_lobbying_usd. A cached ta_master or trading_plan answer is no longer shared between keys with and without the Congressional product, so congressional rows reach only plans that include it. See Execution & Research.
Breaking: warehouse reads that fail return 503
The private-markets relations routes answered a relation read that failed or timed out as a billed 200 with no rows. They now answer 503 with error: "upstream_ and error_, not billed and never cached, with a Retry-After of 30 to 60 seconds; a genuinely empty relation is still a 200. /api/ refuses a failed read the same way. The board relation now leads with the current board, then the current team, then former members, each row with role_kind, and investor and service-provider deals and fund returns come newest first. See Private Markets.
Breaking: the market-event catch-up refuses instead of answering empty
/api/v3/events answered 200 with no events when the event store could not be read. It now answers 503 with error_ (Retry-After: 5), and a read from the start of a stream that holds no events at all answers 503 with error_; neither is billed. A malformed since returns 422; since takes <ms>, <ms>-<seq> or -. The response adds feed.last_event_age_s. See Catch-up refusals.
Breaking: Kelly sizes are in decimals, and withheld without a calibrated forecast
/api/ divided a percent return by a percent variance, so every fraction it served was 100 times too small. It now computes in decimals, (predicted_, capped at ±0.25. The size is withheld, with kelly_fraction and inputs both null, when the expected return is not a calibrated forecast (magnitude_unsupported, explained in magnitudes_withheld) or when the book is more than two US equity sessions old (book_stale); withheld_reasons lists each. The expected return is the blended score × 100 for every ticker today, so no size is served: on 2026-09-25 AAPL answered withheld_ with book_age_sessions: 9 and is_stale: true. A missing interval or conviction is no longer replaced by 0.02 or 0.5; the answer is null with warning no_interval_half_width or no_conviction. New fields: as_of_ts, book_age_sessions, is_stale, stale_after_sessions, withheld_reasons and magnitudes_withheld, and on a served size kelly_uncapped, cap_binding and the inputs keys mu_pct, sigma_pct, mu_decimal, sigma_decimal, interval_half_width_pct and units. The alias /api/, outside the public API, computes and withholds the same way. See Kelly sizing.
Breaking: SHAP drivers are served only for the model serving now
/api/ serves drivers only when every row of the drivers file names the model bundle serving now. Otherwise it answers 503 with error: "upstream_ and error_, not billed, with binding.status (unbound, mixed_bundles, foreign_bundle or active_bundle_unknown) and Retry-After: 3600 (300 for active_bundle_unknown). The published file records no model bundle, so on 2026-09-25 every ticker is refused with unbound; the route used to serve drivers from that file. A failed read of the file is refused with archive_read_timeout, archive_read_failed or upstream_. None of these refusals means the ticker is outside the model's universe. A served answer adds model_bundle_sha256, as_of, stale and report_freshness. In ticker_transparency and ticker_full, the ml_drivers layer is now missing with the reason http_503. See Example 2.
Breaking: report snapshots are aged by their own timestamp
Routes that serve a model-health or research report snapshot now grade it by the timestamp inside it, never by when the file was written or copied. /api/v2/models/drift and /api/v2/features/decay, when served from the voter-drift snapshot, add stale and report_freshness (80-hour limit), and each voter row's stale in drift is now also true when the snapshot is stale, with the producer's own flag in stale_at_build. /api/v2/features/importance and /api/, when served from the factor-loading and voter-weight reports, add stale, report_freshness and a note that the rows are factor betas and voter weights, not feature importances. In /api/v1/copilot/track-record, each report_freshness entry adds as_of, as_of_field, provenance and max_age_hours; a report with no generation time of its own is stale: true with provenance: "unknown_ and report_age_hours: null. It used to be aged by the time the file was uploaded, or answer stale: null when that was unknown too. Outside the public API, /api/ adds stale and report_freshness on an 80-hour limit and re-grades voters[].stale the same way; on 2026-09-25 its snapshot was dated 2026-08-28, 659 hours old. See Example 5.
Breaking: the DSR trial registry is loaded, and an empty one refuses
Outside the public API, /api/v3/validation/trials, /api/, /api/v3/validation/deflate, /api/research/strategies, /api/swarm/strategies, /api/ and /api/ serve the research loop's registered trials, its published trial corpus merged with an archive of its earlier cycles and each trial counted once, with a registry block (count_): 189 trials on 2026-09-25, 80 of them in oos_backtest_top_decile. An empty or unreadable registry answers 503 with error_, not billed: reason is source_unreadable, or table_empty when the corpus loaded and holds no trials, with Retry-After: 300. trials and trial_count used to answer a billed count of 0. deflate adds n_trials_is_lower_bound, answers 409 insufficient_trials for a family with no registered trials instead of deflating against a single trial, and needs n_trials_override to be at least 1.
Breaking: trade setups count only LONG and SHORT toward the skew
/api/v3/decision/trade_ no longer counts a NEUTRAL setup (blended_score between -0.15 and 0.15) as long or short by the sign of its score. universe_skew is computed over LONG and SHORT setups only, so a screen of neutral setups is mixed, with no regime_. The response adds the book's age: as_of_ts, book_age_sessions, is_stale (more than two sessions old) and stale_after_sessions. See Quant Signals.
Breaking: the credit snapshot rates the issuer's outstanding issues
rating on /api/v3/credit/{ticker} was the newest rating action on any of the issuer's instruments, often the withdrawal (NR) of a note that had just matured. It is now the latest long-term rating on the issuer's outstanding issues, leaving out withdrawn and matured ones, and the most common one when they differ. rating_basis says how it was derived (grain: "issue", status, n_live_issues, issue_ratings, dispersed, complete), as_of and outlook follow the rating served, and newest_action_date keeps the date of the newest action of any kind. rating is null when no outstanding issue has a long-term rating. See Example 1.
Breaking: cross-asset signals withhold values the source cannot have meant
/api/v3/signals/cross_ serves null for a futures level that is missing, holds the source's 0.0 marker for a missing input, or falls outside a wide plausibility range, and for every field derived from it, regime_score included. Each bucket's invalid_fields names the withheld fields and why. dx_front held EUR per USD from the euro future, not the Dollar Index: it is now always null, the value is served as usd_proxy_eur_per_usd, and dxy_momentum_basis says what dxy_momentum measures. dx_curve_slope is always null. See Withheld values in cross_asset.
Breaking: multi-timeframe signals withhold the return estimate
Outside the public API, /api/v3/signals/mtf/{ticker} now serves predicted_return_pct, interval_lo, interval_hi and interval_half_width as null, with withheld: "uncalibrated_, as ml_prediction does. blended_score, conviction, decile and rank are still served: on 2026-09-25 AAPL showed blended_score 0.0272 and decile 9.
Batch predictions for up to 200 tickers
GET / (MCP multi_horizon_batch, Quant Signals, Starter and up) is now in the public API. tickers is required (1 to 200 symbols) and horizons defaults to 1m,3m,1y. Only the 1m training horizon carries a leg, with direction and percentile; other horizons are null, and predicted_return_pct is withheld while point_ is false. Every ticker is in rows or missing_tickers. A server that has not loaded the prediction book answers 503 snapshot_cold with retry_after_s: 5. The public API now has 286 operations, and the full MCP catalogue lists 277 tools: the 276 operations that are not streams, plus account_status. See Batch predictions.
The regime forecast says which day its regime describes
/api/v2/regime/forecast adds current_regime_as_of, current_regime_source, as_of, book_age_sessions, stale_after_sessions and stale: the forecast starts from the regime in the prediction book, and stale is true when that book is more than 2 sessions old. A cold call used to time out with a 504; a server still loading the book now answers 503 dataset_unavailable with Retry-After: 5, not billed. See Example 6.
Price history answers cold tickers
/api/ no longer times out on a ticker that is not cached. When its 2025-to-date bars cannot be read in time, the archive rows are served with live_ and a warning, or, when nothing else covers the window, it answers 503 dataset_unavailable, not billed. A split the source lists twice is applied once, which corrects cfacpr and cfacshr for such tickers. See Research-grade daily history.
One next-report date, and EPS labelled by basis
/api/ and /api/ both add next_report_resolved, one next-report date resolved from the same inputs, with status, confirmed_by, source, alternatives and inputs. street_estimates labels its actual EPS eps_basis: "unknown" with eps_basis_note, and returns 400 invalid_ticker for a ticker that is not a plain symbol. street_ and street_ return the newest limit rows in the window, oldest first, add data_through, is_stale, max_lag_days and window_after_coverage, and report a failed read as error: "warehouse_. On income_statements, an EPS whose sign contradicts its row's net income is replaced from a second source or withheld, and the row carries eps_repair. See One next-report date and Fundamentals.
Smaller fixes
/api/refuses a symbol that cannot exist withv3/ fundamentals/ company_ facts 422 invalid_tickerbefore calling any source./api/v3/credit/loans/{ticker}and the snapshot'sloansblock addn_active_facilities,active_andfacility_ amt_ by_ currency total_facility_amt_note:total_facility_amtcounts every facility ever, at face, not outstanding debt./api/servesv3/ intel/ iv_ analytics/ {ticker} expiryon skew rows, compares the term structure's expiries nearest 30 and 90 days (0-DTE excluded) and names them inshape_tenors, and addsn_expiries.options_flow_historyanddarkpool_historysummaries addscope,n_rows,completeandscope_note;peak_issnapshot_ premium_ usd null, not0, when no snapshot carried a premium./api/labels its daily volumes as FINRA-reported off-exchange volume (v3/ origin/ short_ activity/ {ticker} volume_scope,volume_note), not the stock's total volume./api/v3/origin/ipo_addspipeline expected_price_dateandshare_price(the filed range on an upcoming deal).accounting_flagsaddsfirst_event_date,last_event_dateandn_events_last_5yto the restatement and auditor flags./api/insider/clustersaddsn_purchases,n_purchases_pricedandtotal_shares, counts a re-carried or restated purchase once, and servestotal_value_usdonly when every purchase is priced.- The
readyframe of every SSE stream addsproducersandproducer_live, which say whether anything is publishing;ready: truedescribes the transport only./api/v3/stream/eventsreads only the calling key's namespace and refuses a request with no key with403.
Outside the public API, on the deprecated /api/, date_range is validated (422 invalid_date_range), and nextNdays (1 to 366) is sent as an explicit window from today, returned as resolved_date_range.
Regime history says how far its labels reach
When /api/v2/regime/history refuses a days window with no label in it, the refusal adds window_days and min_days_with_labels, the smallest days that reaches coverage_end: 105 on 2026-09-25. A served history adds window_days, as_of, stale and report_freshness, grading its newest label on a daily report's 72-hour limit, so while the sequence ends on 2026-06-12 it is always stale. See Example 6.
The quote's exchange calendar runs through 2028
The exchange calendar behind market_status on /api/market/quote/{ticker} now lists NYSE holidays and early closes through 2028-12-25; it used to end at 2026-12-25. Past its last listed holiday, holidays are unknown to it, and a holiday is recognised only from the data vendor's empty day bar during core hours.
2026-09-24
Breaking: a route with no data behind it returns 503, not an empty list
A route whose dataset was never built, or whose read came back with nothing, used to answer a billed 200 with an empty list or a null. It now answers 503 with error: "upstream_ and error_, not billed. The body has no result field and carries reason (table_missing, table_empty or source_unreadable) and retryable, with a Retry-After header: 3600 seconds for a dataset that was never built, which a retry will not fix, and 60 otherwise. Among the documented routes, this applies to /api/insider/clusters when the insider feed cannot be read or has no rows, to /api/v2/regime/history when no label falls inside days, and to /api/, /api/v2/features/importance, /api/v2/models/drift and /api/v2/features/decay when no measurement is published. Routes outside the public API that read a dataset that was never built refuse the same way. See When a dataset is unavailable.
The reference clients no longer retry a 503 that says "retryable": false or asks for a wait longer than 120 seconds.
Breaking: regime history counts days on the calendar
days on /api/v2/regime/history now means calendar days back from today, not the last N recorded labels, so fewer rows can come back. From the recorded sequence the response adds coverage_end, the last date the sequence covers. That sequence currently ends on 2026-06-12, so on 2026-09-24 a days below 104 is refused as above. See Example 6.
Breaking: 13F routes refuse a failed read instead of answering empty
/api/v3/intel/sec13f, /api/v3/intel/sec13f/changes and /api/ answer 503 with error: "upstream_, not billed, when neither the 13F archive nor the alternative-data feed can answer. They used to return a billed 200 with an empty list, or a 504 at the time limit. error_code is archive_read_timeout (Retry-After: 60), archive_read_failed (120) or upstream_ (120). /api/ and /api/ refuse a failed archive read the same way, with archive_read_failed. In the Copilot ticker aggregations, the sec13f_changes and institutional_ownership layers are then missing with the reason http_503. See When the 13F archive cannot answer.
Breaking: 13F changes no longer report a missing filing as a trade
On /api/, a manager with no filing at all for one of the two quarters compared is left out, instead of being shown as having closed or opened the position. unreported_prev_holders, unreported_cur_holders and unreported_note count them. is_closed and is_new now always describe a manager that filed for both quarters and held the stock in only one of them.
Breaking: whale holdings are dated per manager and valued in dollars
/api/v3/origin/whale_ serves each tracked manager's newest filing only when it is for the quarter now due or the one before; older filings are named in managers_ instead. The answer can be available: false when no manager has filed recently enough, and a ticker= answer can name older_. Filings that state value in thousands of dollars are scaled to dollars, and positions are ranked by that value. New fields: period_ending, manager_periods, lagging_note and the 13F freshness fields. See Example 4.
Breaking: 13F history sums each holder's lots
/api/ now sums each holder's equity lots per quarter and leaves out option lots, so a manager that files a stock in several lots appears once, with its total, and values change. Its quarters window reaches one quarter further back, so an archive a quarter behind EDGAR still returns the number of quarters asked for.
Breaking: SEC filings come from EDGAR first
/api/ reads SEC EDGAR first and falls back to a third-party filings index only when EDGAR cannot answer, so filings that index had not yet listed now appear. On EDGAR rows, url and report_url point to the filing in the EDGAR archive under the company's CIK. New fields: source, newest_item_date, is_stale, is_partial, accepted_date_timezone, and where they apply searched_back_to, partial_note, fallback_reason and staleness_note. Answers are cached for up to 5 minutes, or 1 minute from the fallback, instead of 30 minutes. See Where the index comes from.
Breaking: forward returns are no longer served as characteristics
/api/ withholds the panel's realized forward returns (the fwd_* columns and excess_ret_1m): they are the return after as_of, not a characteristic known then. outcome_labels_withheld names them. /api/ refuses them with 422 unknown_. See Example 9.
Breaking: feature panels are dated by observation and graded on their data
/api/v3/features/{dataset} keys observation_date, since, until and the latest cross-section on the date a row describes. On equity_ that is now the month, where it used to be the ratios' publication date, which moves to its own column, ratio_vintage. beta_features adds returns_data_through. Rows dated after today, and monthly rows for a month still in progress, are no longer served. A dataset is current only when its data is also on its own rhythm; a live producer over old data is archival with not_, and daily panels count that clock in weekdays. A servable dataset measured into withheld now returns 404 dataset_withheld, not billed. Where they apply, the catalogue and reads add vintage_column, vintage_clock, data_clock_counted_in, data_lag_business_days, typical_, coverage.rows_ and coverage.rows_. See Feature store.
Breaking: quote volume is today's only, and market status follows the exchange calendar
market_status on /api/market/quote/{ticker} now comes from the exchange calendar and the New York clock, not from the data vendor's session flag. It no longer says open before the session starts, reports exchange holidays as closed all day, ends the session at 13:00 ET on early-close days, and says open during the session even for a stock that has not traded yet that day. day_volume on the quote, and quote.volume on /api/snapshot/{ticker}, are the current session's only: null before 04:00 ET, on weekends and holidays, and when the daily bar is empty or from an earlier day, where they used to carry the previous session's volume. /api/snapshot/{ticker} also fills quote.as_of_ts, quote.change and quote.change_pct, which were always null.
13F answers say how current they are
sec13f, sec13f/changes, sec13f_history, top_shareholders and institutional_ownership add newest_report_period, expected_report_period, is_stale, quarters_behind, vendor_ceiling and staleness_note, so an answer a quarter behind EDGAR says so. A stale ?ticker= answer on sec13f and sec13f/changes adds current_quarter: the tracked managers' newer filings from EDGAR. See How current a 13F answer is.
Insider clusters are dated by their latest purchase
On /api/insider/clusters, each cluster's as_of_ts is the date of its latest purchase instead of the time of the request. Clusters count open-market purchases (Form 4 code P) only, and the 30-day window is read in full up to a row cap. The response adds rows_scanned and complete, which is false if the cap was reached, and source is now warehouse:insider-archive.
Docs follow the public API route by route
The docs now describe the routes in the OpenAPI spec and name the MCP tool beside each one in the API reference. New pages cover Crypto and Reference Data. Execution & Research, Private Markets and LLM Research document their remaining routes, among them the trading plan and equity brief, the private-company page, valuation and syndicate, and page reading with research_fetch_url.
Routes that are outside the public API are no longer listed as endpoints: portfolio VaR and stress, pairs signals, execution cost estimates, smart routing, the scenario simulator, and the quote-stream subscribe call (connecting to /api/v3/stream/quotes subscribes coverage by itself). Cost estimates and smart routing still answer 503 capability_ and consume no credits. /api/market/quote/{ticker} stays documented as a supported route outside the spec.
The pages also document the billing cases that are not one charge per call. A 200 from a paid route is billed even when it holds no data: many routes answer an empty list, a null value or a warning instead of an error, and the trading plan, the technical read and page reading report some problems in an error field. Withheld results, such as a private-company valuation without enough priced rounds, arrive as 503 paid_ and are not billed.
2026-09-23
Breaking: malformed JSON returns 400
A request body that is not valid JSON now returns 400 invalid_json ("request body is not valid JSON"). It used to return 422.
Breaking: OpenAPI operation ids use the new tool names
The OpenAPI spec now uses the new tool names as operationId, so an SDK regenerated from it gets new method names: for example fundamentals_full instead of tengu_. Calling an unknown MCP tool now returns JSON-RPC error -32602, as the MCP specification expects, instead of -32601.
Breaking: internal and unavailable tools removed from MCP
39 internal operations tools and tools with no data behind them are no longer listed in tools/list or the OpenAPI spec, and can no longer be called over MCP. The 12 server-sent-event stream tools stay on REST only, because MCP cannot relay a stream. The public API has 282 operations; the MCP server lists the 270 that are not streams, plus account_status: 271 tools. Later the same day, stream_realtime_guide and market_events_catchup joined MCP, because they answer JSON rather than a stream. Since then the MCP server has listed 273 tools, and 10 stream operations are REST only.
Breaking: ops routes need an admin key
GET /api/logs and GET /api/cache/stats now require the platform's admin key and are gone from tools/list, the OpenAPI spec and /api/capabilities.
MCP tool names drop the brand prefix
Tools have plain names: tengu_ is now fundamentals_full, tengu_v2_short_interest is short_interest and tengu_ml_predict is ml_predict. The old names, and the names of tools retired earlier, still work in tools/call, so agents built against them keep working. Every tool now carries an MCP title and the annotations readOnlyHint, destructiveHint, idempotentHint and openWorldHint.
The MCP starter list matches your plan
Without a catalog option, tools/list returns account_status plus the first 12 tools your plan and add-ons can call, so no first call answers 402. tools/call accepts any public tool, listed or not. Use ?catalog=full to list every tool. Each OpenAPI operation names its lowest plan in x-wealthnow-min-plan.
Listed in the MCP Registry as io.wealthnow/mcp
The server is in the official MCP Registry as io.wealthnow/mcp: Streamable HTTP at https://mcp.wealthnow.io/mcp, with OAuth sign-in or an X-API-Key header. The old io.github.Hlobo-dev/ entry is deprecated and points to it. The server card at https://mcp.wealthnow.io/.well-known/ now lists every MCP tool with its full description and input schema: 271 when it was published, and 273 once the two JSON routes above joined MCP.
Rate-limit headers
Authenticated responses carry X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (Unix time in seconds), read from your key's budget. A 429 now carries the real Retry-After in seconds, at least 1, instead of a fixed 60. X-RateLimit-Remaining and X-RateLimit-Reset are left out when the count came from a cache. See response headers.
Deprecation headers (RFC 9745)
Deprecated routes now answer with a Deprecation header in RFC 9745 form (Deprecation: @1790121600, the date the signal was first sent). When a route has a replacement, they also send Link: </. Look for the header in your client to find the calls to move. No route has a Sunset date. See response headers.
Error bodies link the docs and name the bad parameter
Every error body carries doc_url, a link to the error table. A 422 validation error names the offending parameter in param (for example "limit") and says what is wrong: invalid 'limit': Input should be greater than or equal to 1. The 401 body links the quickstart.
Settlement headers on every metered call
Failed calls are never charged: every non-2xx response is refunded and says so in X-Credits-Settlement. The same applies to a paid response that could not be delivered and to a stream that aborts. Metered responses carry X-Credits-Receipt, and JSON responses also carry X-Credits-Settlement (consumed or refunded). A stream settles after its last byte. See response headers and how credits work.
Usage alerts at 80% and 100% of included credits
A workspace gets one email when it has used 80% of the credits included in its billing cycle (the plan's grant plus credits bought this cycle), and one at 100%. The 100% email says what happens next: on Free, calls return 402 usage_exceeded until the cycle resets; on paid plans, calls keep working and overage is billed at the plan's per-credit price. Each alert is sent at most once per cycle.
Team members and roles
Invite people from Settings, Team as Admin or Member. Every plan has 20 Basic Seats for members; Full Seats for admins are 1 on Free and Starter and 10 on plans that include a team. A pending invitation holds a seat and expires after 7 days. Members open the workspace from the workspace switcher, and can see and create named keys. Only admins can buy plans, add-ons and top-ups, open the billing portal, rotate, revoke or reveal keys, and disconnect agents. Only the owner can delete the workspace.
Docs at /docs, readable by agents
The docs live at https://app.wealthnow.io/docs, and old /tengu-docs links redirect there. Agents can read them as plain text: /llms.txt, /docs/llms-full.txt, and every page as markdown at /docs/<page>.md.
2026-09-22
Tengu is now Wealthnow
The API has a new name and new hosts:
| Service | Host |
|---|---|
| Dashboard | https://app.wealthnow.io |
| REST API | https://firm.wealthnow.io |
| MCP server | https://mcp.wealthnow.io/mcp |
| Key service | https://keys.wealthnow.io |
The tengu.co hosts still answer, so existing integrations and connectors added as firm.tengu.co/mcp keep working. Keys keep the tengu_ prefix. The OpenAPI spec is titled "Wealthnow API" and lists https://firm.wealthnow.io first. The Claude Desktop extension is now wealthnow.mcpb, and the old tengu.mcpb link redirects to it.
Connect an agent by signing in
Claude (web, Desktop and mobile), Claude Code, Cursor and ChatGPT connect to https://mcp.wealthnow.io/mcp with Sign in to Wealthnow (OAuth 2.1 with PKCE), with no key to paste. In Claude Code, run claude mcp add --transport http wealthnow https://, then /mcp. A connection holds a one-hour access token (tengu_at_…) with a rotating refresh token, never your API key. Clients revoke a token with POST https:// (RFC 7009), and GET https:// returns the connection's plan and credits_remaining. The dashboard lists connected agents on the Overview page and can disconnect them. See MCP and SDKs.
Fixed intermittent 502 errors on key verification
Metered calls verify your key and reserve credits reliably. A 502 unkey_unreachable is a transient key-service error: it carries Retry-After, is never charged, and is safe to retry. See error responses.
September 2026
Breaking: private-markets search is a paid call
/api/ needs Pro or the Private Markets add-on and costs 5 credits. On other plans it returns 402 plan_required. MCP tools accept companyid as an alias for company_id.
Breaking: price history is daily
/api/v3/prices/history serves daily bars and interval defaults to 1d. An intraday interval returns 422 interval_not_daily, pointing to /api/. /api/v3/prices/* needs Starter or above.
Data fixes
The dataset freshness report /api/data/freshness added as_of_period, the fiscal period a dataset covers, next to pipeline freshness; it is not part of the public OpenAPI spec. The legacy quote route /api/market/quote fills prev_close and change_pct when it falls back to a second vendor, and reports the pre-market, after-hours or closed session outside market hours; its OpenAPI equivalent is /api/.
August 2026
Breaking: plan changes for older routes
Some older routes were reachable on plans that did not include their data. /api/snapshot/{ticker} now needs Quant Signals (Starter). /api/v3/prices/history, /api/, /api/v3/fundamentals/segments and the street-estimates routes need Starter. Check each route's plan in the API reference.
Breaking: rate-limited calls return 429
A billable call over your rate limit is refused with 429 rate_limited instead of being served. When the credit check cannot complete, the answer is 429 billing_unavailable with Retry-After.
Crypto derivatives, events and on-chain flows
New on every plan: /api/, /api/, /api/ and /api/; /api/ (listings, delistings and trading-caution flags from the exchanges' own announcements) and /api/ (breaking crypto-native headlines, mapped to coins); and /api/v3/crypto/onchain/flows (stablecoin issuance and lending liquidations, read from the chain).
Refuse stale data with freshness
/api/v3/intel/macro_ and the options-flow and dark-pool routes accept freshness=off|live|strict. The default, off, serves the data with its age. live returns 503 data_stale when a live-market field is stale, and strict when any field is past its own update cadence.
Price fixes
When every price source fails, price routes return 503 price_ instead of a 200 with no items. A limit without dates returns the most recent bars, not the oldest. asset_class=crypto returns real crypto prices and bars.
Failed calls are not charged
A call that fails (any status of 400 or above) is refunded and reports X-Credits-Cost: 0.
New research routes
New: /api/v3/origin/* (short activity, whale holdings, insider flow, macro pulse and the IPO pipeline), /api/v3/workforce/* (hiring momentum and WARN-Act layoffs), /api/v3/supply_chain/* (customers, suppliers and revenue exposure) and /api/v3/fundamentals/pit/* (point-in-time fundamentals, as known on a date). /api/v3/credit/indices serves credit-index composites (Pro), and /api/v3/intel/macro_ adds a credit block with CDX IG and HY spreads.
Live 1-minute bars stream
/api/v3/stream/bars streams live 1-minute bars as server-sent events, on Starter and above. See Streaming.