API Reference
API Reference
Authentication, per-plan access, pagination, errors, and every FIRM endpoint. One key and one credit wallet work on the REST API and on the MCP server.
| Surface | Base URL | Auth | What it is |
|---|---|---|---|
| FIRM data API | https://firm.wealthnow.io | Authorization: Bearer wn_ (or X-API-Key) | REST over 21 metered data products, per-call |
Every endpoint also has its own page in the endpoint reference: its parameters, plan, price, MCP tool name and a request you can run in Shell, Python or TypeScript.
Authentication
Send the same wn_ key to both surfaces in an HTTP header. Authorization
takes precedence when both headers are present:
Authorization: Bearer wn_: recommended (works with the OpenAI/Anthropic SDKs and most HTTP clients).... X-API-Key: wn_...
Keys created before October 2026 start with tengu_ and keep working; TENGU_API_KEY is still read by the SDKs.
Query authentication using the api_key parameter remains available for
compatibility. URLs may be recorded in access logs, browser history, and monitoring
tools, so use a header to keep the credential out of the URL.
Most FIRM responses are a JSON envelope: { "ok": true, "timestamp": "<ISO-8601>", ...data }. The data keys
differ per endpoint (e.g. items for feeds, results for search, quote for a quote). The product guides note
the exceptions: Crypto Market Data puts its payload under data, beside freshness fields
(Crypto), and the ML weights routes answer without the envelope
(Quant Signals).
Discover every live endpoint (method, path, params) at any time, with no key required:
curl https://firm.wealthnow.io/api/capabilities | jq '{manifest_version, tool_count, groups}'Products, costs & per-plan access
Which products your key can call depends on your plan. Calling a product outside your plan returns
402 plan_required and is non-billable. Read detail for the product and required
plan; don't assume an unlocked_by[] field exists in every error envelope.
The table describes access permissions, not guaranteed output availability. When a
paid route marks its own result unavailable (ok: false or available: false in
the body), the caller gets a 503 that consumes no credits (for example, VWAP
without a fully observed session). A 200 from a paid route is billed even when it
holds no data. Many routes answer a 200 with an empty list, a null value,
found: false, or a warning or note when there is nothing to return: for
example kelly_uncertainty for a ticker with no stored prediction or with its size withheld, a
private-markets relation with no rows, or an unknown private-markets id. Some report
a problem in an error field instead: trading_plan and technical_analysis
(ta_master) when price history is too short, and research_fetch_url when a page
is blocked or cannot be fetched. Check these fields before using a result. Quant
intervals and Kelly sizes can be withheld when supporting evidence is missing.
| Product | Credits/call | Free | Starter $99 | Pro $499 | Expert $999 | Enterprise |
|---|---|---|---|---|---|---|
| Market Data (crypto quotes, perpetuals, on-chain flows, charts, ETFs) | 1 | Yes | Yes | Yes | Yes | Yes |
| Fundamentals (price snapshots, OHLCV, statements, ratios, screener) | 1 | Yes | Yes | Yes | Yes | Yes |
| Public Filings (SEC/EDGAR index + extract) | 1 | Yes | Yes | Yes | Yes | Yes |
| Congressional / Politician Trades | 2 | - | Yes | Yes | Yes | Yes |
| News & Sentiment (equity and crypto news, analyst consensus) | 2 | - | Yes | Yes | Yes | Yes |
| Macro, Rates, FX & Commodities | 2 | - | Yes | Yes | Yes | Yes |
| Quant Signals (stored predictions, nullable intervals, voter evidence, live streams) | 3 | - | Yes | Yes | Yes | Yes |
| Funds & Institutional (13F + Form-4 insiders) | 4 | - | Yes | Yes | Yes | Yes |
| Alt-Data (lobbying, contracts, patents, workforce, supply chain, identifiers, 13F holders, macro and estimates history) | 3 | - | - | Yes | Yes | Yes |
| Options Flow & Dealer Positioning (flow, GEX, dark pool, options tide, securities lending and borrow) | 4 | - | - | Yes | Yes | Yes |
| Execution & Research (TWAP/VWAP scenarios, TA, equity briefs, trading plans) | 4 | - | - | Yes | Yes | Yes |
| Risk Analytics (index hedge proposals, historical VaR for a portfolio you supply) | 5 | - | - | Yes | Yes | Yes |
| Private Markets (10.6M companies, deals, funds) | 5 | - | - | Yes | Yes | Yes |
| Tape & Intraday (minute bars, options/futures prints) | 3 | - | - | Yes | Yes | Yes |
| Credit & Fixed-Income (TRACE bonds, CDS, ratings, loans) | 4 | - | - | Yes | Yes | Yes |
| Transcripts & Events (earnings calls, Key Developments, the earnings-call calendar) | 3 | - | - | Yes | Yes | Yes |
| Crypto Market Data (coin profiles, daily history, global market, categories, exchanges) | 2 | - | Yes | Yes | Yes | Yes |
| Crypto History (recorded funding, open interest, basis, vol surface, events, on-chain flows) | 3 | - | - | Yes | Yes | Yes |
| Volatility & Positioning (volatility-index history, VIX futures curve, full Commitments of Traders) | 4 | - | - | Yes | Yes | Yes |
| LLM Research (web search, page reading, cited synthesis, AI company analysis) | 6 | - | - | Yes | Yes | Yes |
| Social Sentiment (X/social sentiment read for a ticker or a question) | 2,500 | - | - | Yes | Yes | Yes |
No-auth routes (no key needed): /api/capabilities, /api/health, /api/openapi.json.
They are unmetered, and so are the MCP account_status and search_tools tools. Private Markets search and
suggestions cost 5 credits and require Pro+ or the Private Markets add-on.
À-la-carte add-ons: buy on top of any paid plan (each is its own subscription that unlocks one product + tops your wallet): Private Markets $299/mo (or Private Markets Pro $799/mo) and Options Flow $79/mo.
Included credits/month: Free 1,000 · Starter 250,000 · Pro 2,000,000 · Expert 11,200,000 (10,000,000 plus Private Markets Pro's 1,200,000 pack) · Enterprise 20,000,000. Rate limits: Free 30 · Starter 120 · Pro 600 · Expert 1,500 · Enterprise 6,000 req/min. See Pricing & credits.
Pagination
Many list endpoints accept ?limit (results per call). Most return one window and take no page parameter:
narrow it with the endpoint's filters or a date range instead. A few routes page:
?page=(1-based):/api/v3/fundamentals/screener,/api/v3/fundamentals/tickers, and 14 news routes under/api/v3/news/and/api/v3/news_crypto/(for exampleticker_news,alerts,ratings).?offset=(0-based):/api/crypto/universeand/api/.v3/ private_ markets/ companies
Defaults and maxima vary by endpoint. The authoritative params are in GET /api/openapi.json and
GET /api/capabilities. Example:
curl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \ "https://firm.wealthnow.io/api/v3/fundamentals/sec_filings?ticker=AAPL&limit=10"FIRM data endpoints
Paths are relative to https://firm.wealthnow.io. {ticker} is a symbol like AAPL. This lists the most-used
routes per product; the full versioned catalog is in GET /api/capabilities (filter by tool_count/groups),
and the curated public spec is GET /api/openapi.json. The MCP tool column is the route's operationId and
its tool name on the MCP server. Server-sent-event streams are
REST only: MCP cannot relay a stream, so they have no tool.
Market Data: Free+ · 1 credit
| Method | Path | MCP tool | Description |
|---|---|---|---|
GET | /api/market/quote/{ticker} | none (REST only) | Live equity quote. A supported route outside the OpenAPI spec and MCP; the spec equivalent is fundamentals_ below. An unknown ticker is 404 ticker_not_found on this route; the v3 routes answer unknown_ticker. |
GET | /api/crypto/{ticker} | crypto_quote | Live crypto quote (vs quote currency, default USD) |
GET | /api/crypto/universe | crypto_universe | Liquid crypto universe ranked by 24h dollar volume (limit 1–1000, offset, min_dollar_volume default 1,000,000) |
GET | /api/ | crypto_ | Cross-venue perpetual funding, normalised to 8h-equivalent, for up to 20 base assets |
GET | /api/ | crypto_ | Perpetual open interest in USD per base asset across venues |
GET | /api/v3/crypto/onchain/flows | crypto_onchain_flows | Net stablecoin supply and lending liquidations read from the chain (hours 1–72, default 24) |
GET | /api/ | crypto_ | Exchange listings, delistings and trading-caution flags with origin timestamps |
GET | /api/v3/intel/chart/{ticker} | intel_chart | Candlestick chart PNG with RSI/MACD/Bollinger overlays (bars 20–500, default 120) |
See Crypto for the derivatives, on-chain and exchange-event routes.
Fundamentals: Free+ · 1 credit
| Method | Path | MCP tool | Description |
|---|---|---|---|
GET | /api/ | fundamentals_ | Last trade in any session, the exchange session, the latest regular session and the extended-hours move with their dates, and valuation context against the live price, under snapshot; check is_stale (asset_class=crypto for a crypto asset) |
GET | /api/ | fundamentals_ | Full financials in one call; every block states its period and units (ratios are fractions of one quarter, ttm.ttm_ratios and growth are percent). See Periods and units |
GET | /api/ | fundamentals_ | Income statement |
GET | /api/ | fundamentals_ | Balance sheet |
GET | /api/ | fundamentals_ | Cash flow |
GET | /api/ | fundamentals_metrics | Key metrics & ratios |
GET | /api/v3/fundamentals/tickers | fundamentals_tickers | Paged covered-ticker universe (is_sp500, sector, limit 1–500, page) |
GET | /api/v3/fundamentals/screener | fundamentals_screener | Multi-filter screen, floored by default to common stock with at least a $300M market cap and $1M a day of dollar volume (min_market_cap_usd, min_adv_usd, security_class), sorted on market_cap_usd unless sort_by says otherwise. Percent filters are the *_pct parameters (roe_min_pct=20 is 20%); revenue growth beyond ±100% is checked against the SEC annual report. See Screener units and refusals and How the screener sizes and sorts |
GET | /api/ | fundamentals_prices | OHLCV bars through today's session; a bar still forming is partial: true. Equity bars are split-adjusted, not dividend-adjusted (adjustment_basis). See Bars still forming and Adjusted bars |
Public Filings (SEC / EDGAR): Free+ · 1 credit
| Method | Path | MCP tool | Description |
|---|---|---|---|
GET | /api/ | fundamentals_ | Filing index from SEC EDGAR, with a labelled fallback → {ticker, form_. See Public Filings |
GET | /api/ | sec_filing_extract | XBRL extract of the latest 10-K, 10-Q or 8-K, and its narrative sections verbatim (sections, paged with max_chars and offset). See Narrative sections |
Insider / Form-4 data is in the Funds & Institutional product (4 credits), not Public Filings. See below.
Identifier crosswalks (CUSIP, ISIN, SEDOL, CIK) are in Alt-Data; see Reference Data.
Congressional / Politician Trades: Starter+ · 2 credits
| Method | Path | MCP tool | Description |
|---|---|---|---|
GET | /api/v3/intel/congress | intel_congress | Congressional trades → {items, count} |
GET | /api/v3/intel/politicians | intel_politicians | US Congress roster (House and Senate) with disclosed trade counts per member (limit 1–1000, default 100) |
GET | /api/ | intel_corporate_donors | Corporate donors |
News & Sentiment: Starter+ · 2 credits
| Method | Path | MCP tool | Description |
|---|---|---|---|
GET | /api/v3/news/summary/{ticker} | news_summary | Equity news summary for one ticker |
GET | /api/ | intel_analyst_consensus | Analyst consensus |
GET | /api/v3/intel/news_ | intel_news_headlines | Market-wide newswire headlines (limit 1–100); for one ticker's news use news_summary |
GET | /api/v3/intel/news_pro | intel_news_pro | Newswire stories by ticker or channel, with history back to 2018 (date_from, date_to) |
GET | /api/v3/intel/news_ | intel_news_why_moving | "Why It's Moving" explainers, each with a catalyst_type |
GET | /api/v3/intel/news_ | intel_news_movers | The movers channel: gainers, losers, halts and breakouts |
GET | /api/ | intel_ | Company press releases carried on the newswire (sparse coverage) |
GET | /api/v3/intel/news_ | intel_news_crypto | The newswire's cryptocurrency channel |
GET | /api/v3/news/by_ | news_by_topic | Headlines for one of the news source's own categories, echoed with source_topic; any other topic is 422 invalid_topic. See News topics |
GET | /api/ | news_crypto_summary | One coin's last 24h of news, 7-day sentiment and trending headlines |
GET | /api/ | news_ | Large on-chain and exchange crypto transactions (min_amount in USD) |
Macro, Rates, FX & Commodities: Starter+ · 2 credits
| Method | Path | MCP tool | Description |
|---|---|---|---|
GET | /api/v3/macro/treasury_ | macro_treasury_curve | US Treasury curve (T+1): 1m–30y tenors, 1-day changes, 2s10s and 3m10y spreads with inversion flags |
GET | /api/v3/intel/yield_ | intel_yield_curve | Treasury yields, recession-watch spreads, breakeven inflation |
GET | /api/v3/intel/commodities | intel_commodities | Commodities |
GET | /api/v3/news_ | news_forex_latest | FX news (pairs as EUR-USD, EURUSD, EUR/USD or C:EURUSD) |
GET | /api/ | intel_calendar_ratings | Live analyst rating actions with price-target moves, and a scan block. See The analyst ratings calendar |
GET | /api/v3/news_ | news_forex_prices | FX mid prices (15-minute upstream refresh) by pairs or base |
GET | /api/ | news_ | Macro releases with actual, forecast and previous values |
GET | /api/ | none (REST only) | SSE: a ticker's next earnings date, as a partial event then a verified result |
Quant Signals: Starter+ · 3 credits
Check interval availability and calibration separately. Recent realized coverage is withheld; a stored interval does not establish measured coverage or a 90% band. See Quant Signals for nullable fields and authorization gates.
| Method | Path | MCP tool | Description |
|---|---|---|---|
GET | /api/ | intel_ml_prediction | Stored prediction, nullable return estimate and interval, voter evidence, and the book's age in data_freshness |
GET | /api/ml/predict/{ticker} | ml_predict | The stored prediction row, magnitude withheld; a fund or ADR is 404 excluded_. See Funds and ADRs |
GET | /api/ | prediction_intervals | Stored interval for one ticker, bounds withheld (null) with magnitudes_withheld |
GET | /api/ | intel_ml_drivers | SHAP drivers of the model serving now; 503 upstream_, not billed, when the drivers file cannot be tied to it (every ticker on 2026-09-25) |
GET | /api/ | intel_voter_attribution | Attribution of one voter's score on a ticker (voter, days_back) |
GET | /api/v3/decision/trade_ | trade_setups | Ranked trade setups, with the book's age (book_age_sessions, is_stale, data_freshness); funds and ADRs left out and counted in book_guard |
GET | /api/ | multi_horizon_batch | Up to 200 tickers per call: direction and percentile per ticker on the 1m training horizon, other horizons null, magnitude withheld; a fund or ADR is in missing_tickers and excluded_tickers. See Batch predictions |
GET | /api/v2/regime/forecast | regime_forecast | Regime probabilities N days ahead, dated by current_regime_as_of and graded stale on the prediction book's age |
GET | /api/ | none (REST only) | SSE: live per-venue bid/ask quotes (symbols required); connecting subscribes coverage within about 5 seconds |
GET | /api/v3/stream/bars | none (REST only) | SSE: live 1-minute candles, every US ticker (no subscribe step) |
GET | /api/v3/stream/ticks?symbols= | none (REST only) | SSE: live US-equity trade prints |
GET | /api/v3/stream/signals | none (REST only) | SSE: fused signals (symbols optional) |
GET | /api/v3/stream/news | none (REST only) | SSE: structured-news items (symbols optional) |
GET | /api/v3/stream/market_ | none (REST only) | SSE: market events, each carrying its source as-of time, feed lag and staleness |
Streams are long-lived SSE connections billed once per connection, not per frame. After a reconnect,
GET /api/v3/events (Transcripts & Events, below) returns the retained market events you missed. See
Real-Time Streaming.
Funds & Institutional (13F + Form-4): Starter+ · 4 credits
| Method | Path | MCP tool | Description |
|---|---|---|---|
GET | /api/ | intel_sec13f | Institutional holdings → {items, count, source} plus newest_report_period, expected_report_period, is_stale, quarters_behind, vendor_ceiling and, when stale, staleness_note |
GET | /api/ | intel_top_shareholders | Top shareholders, with the same freshness fields |
GET | /api/ | fundamentals_ | Institutional ownership, with the same freshness fields |
GET | /api/ | intel_insiders | Insider (Form-4) activity |
GET | /api/insider/clusters | insider_clusters | Cross-insider buy clusters |
When the 13F archive and its fallback cannot answer, the 13F routes return 503 upstream_ with error_code archive_read_timeout, archive_read_failed or upstream_, not billed, instead of an empty list. See When the 13F archive cannot answer.
Alt-Data: Pro+ · 3 credits
| Method | Path | MCP tool | Description |
|---|---|---|---|
GET | /api/ | intel_lobbying | Lobbying activity |
GET | /api/ | intel_gov_contracts | Government contracts |
GET | /api/ | intel_patents | Patents |
GET | /api/ | intel_exec_compensation | Executive compensation |
GET | /api/v3/intel/wsb/{ticker} | intel_wsb | WallStreetBets mentions |
GET | /api/ | workforce_momentum | Monthly headcount, hiring, attrition and salary level (months 2–120, default 24) |
GET | /api/ | workforce_layoffs | WARN-Act layoff filings with window totals |
GET | /api/ | supply_ | Customers, suppliers, competitors and partners (rel_type, status, as_of) |
GET | /api/ | supply_ | Revenue dependence in both directions: customer concentration and dependents |
GET | /api/ | fundamentals_pit | Point-in-time quarterly financials as first reported, as known on as_of |
GET | /api/ | reference_crosswalk | Every identifier a security and its issuer carry (CUSIP, ISIN, SEDOL, gvkey, CIK) |
GET | /api/v3/reference/lookup | reference_lookup | Reverse lookup from exactly one identifier to the security |
See Alt-Data, Fundamentals for point-in-time data, and Reference Data for the identifier crosswalk.
Options Flow & Dealer Positioning: Pro+ · 4 credits
| Method | Path | MCP tool | Description |
|---|---|---|---|
GET | /api/v3/intel/options_ | intel_options_flow | Unusual options flow |
GET | /api/v3/intel/gex/{ticker} | intel_gex | Gamma exposure |
GET | /api/ | intel_max_pain | Max pain |
GET | /api/ | intel_darkpool_ticker | Dark-pool prints |
GET | /api/ | intel_options_chain | Live options chain with greeks, IV and open interest |
GET | /api/ | intel_options_contract | One contract's live quotes and trades |
Execution & Research: Pro+ · 4 credits
TWAP is an arithmetic schedule and VWAP a historical allocation; neither predicts fills or
trading costs. VWAP without a complete observed session returns a route-level 503 without
consuming credits. See Execution & Research for availability limits.
| Method | Path | MCP tool | Description |
|---|---|---|---|
GET | /api/ | twap_plan | Arithmetic TWAP schedule from quantity and duration |
GET | /api/ | vwap_plan | Allocation from a complete named historical volume session |
GET | /api/ | research_ | What moves with a ticker: 36-month return correlations of magnitude 0.6 or more (seed required, depth 1–3) |
GET | /api/ | technical_analysis | One-call technical read: signals, bull/bear stance and a chart (interval, bars 40–400) |
GET | /api/ | equity_brief | Single-call equity brief: fundamentals and alternative-data digests, flags, charts |
GET | /api/ | trading_plan | Long/short plan: entry, stop, 1R/2R/3R targets and sizing for a risk_pct |
Risk Analytics: Pro+ · 5 credits
| Method | Path | MCP tool | Description |
|---|---|---|---|
GET | /api/v3/institutional/hedging | index_hedge_proposals | SPY/QQQ/IWM hedge proposals (protective puts, collars) from dealer gamma, IV rank and the 25-delta risk reversal |
POST | /api/ | none (REST only) | Historical VaR and expected shortfall for an explicit portfolio you send; see Historical VaR |
kelly_uncertainty is billed as Quant Signals, and its size is withheld today; see
Kelly sizing.
Private Markets: Pro+ or add-on · 5 credits, including search
| Method | Path | MCP tool | Description | Credits |
|---|---|---|---|---|
GET | /api/ | private_markets_search | Search companies/investors/funds → {results} | 5 |
GET | /api/ | private_markets_company | Full company profile | 5 |
GET | /api/ | private_ | Render-ready company page: identity, key facts, valuation/revenue/headcount series, team | 5 |
GET | /api/ | private_ | Everything on a company in one call | 5 |
GET | /api/ | private_ | Wealthnow's modeled valuation mark with a confidence band and driver bridge | 5 |
GET | /api/ | private_ | Funding rounds / M&A history | 5 |
GET | /api/ | private_ | Screen by sector/geo (sort, status, limit 1–500, offset 0–50000) | 5 |
Tape & Intraday History: Pro+ · 3 credits
FIRM's own self-collected tick tape: minute bars, per-print options/futures trades, and a historical options chain with greeks/IV/OI. Full catalogue in Tape & Intraday History.
| Method | Path | MCP tool | Description |
|---|---|---|---|
GET | /api/v3/tape/bars/{ticker} | tape_bars | Intraday minute bars (FIRM's own capture), one row per minute; n_transactions is null where the capture recorded no count. See One bar per minute |
GET | /api/ | tape_options_chain | Historical options chain w/ greeks, IV, OI |
GET | /api/v3/tape/options/{ticker} | tape_options | Raw options trade prints for one day |
GET | /api/v3/tape/futures/{root} | tape_futures | CME futures trade prints |
GET | /api/ | tape_futures_curve | Futures term structure |
GET | /api/ | tape_futures_contracts | Live tradeable futures contracts for a root |
GET | /api/ | tape_futures_live | Live futures snapshot, trades, quotes and daily bars |
Credit & Fixed-Income: Pro+ · 4 credits
Institutional corporate-credit stack from licensed institutional archives (served at the latest available lag). Full catalogue in Credit & Fixed-Income.
| Method | Path | MCP tool | Description |
|---|---|---|---|
GET | /api/v3/credit/{ticker} | credit_snapshot | One-call credit snapshot (call this first) |
GET | /api/v3/credit/bonds/{ticker} | credit_bonds | FINRA TRACE corporate-bond trade prints |
GET | /api/ | credit_cds_history | Single-name CDS spread history |
GET | /api/ | credit_ratings | S&P credit rating-action history |
GET | /api/v3/credit/loans/{ticker} | credit_loans | Syndicated bank-loan book |
GET | /api/v3/credit/indices | credit_indices | CDX + iTraxx index composites by series/tenor (index-keyed, T-2) |
Research Datasets: cost varies by product group
Row-level access to the licensed research archives. Full catalogue in Research Datasets.
| Method | Path | MCP tool | Description |
|---|---|---|---|
GET | /api/v2/datasets | research_datasets | List every dataset slug (4 credits, funds, Starter+) |
GET | /api/v2/datasets/{dataset} | research_read | Read rows; each dataset bills at its product group's rate |
Transcripts & Corporate Events: Pro+ · 3 credits
Full-text earnings-call transcripts + the Key Developments corporate-event ledger back to 1990. Full catalogue in Transcripts & Corporate Events.
| Method | Path | MCP tool | Description |
|---|---|---|---|
GET | /api/v3/transcripts/{ticker} | transcripts_list | List a company's earnings calls / investor events |
GET | /api/ | transcript_text | Full transcript as ordered speaker turns |
GET | /api/v3/transcripts/search | transcripts_search | Search transcripts (headlines or full text) |
GET | /api/v3/events | market_events_catchup | Catch-up page of retained market events after a stream id (since), for use after an SSE reconnect |
LLM Research: Pro+ · 6 credits
Source publication dates can be missing. A response timestamp records retrieval, not the age of the cited information. Inspect source dates before making a freshness claim; see LLM Research.
| Method | Path | MCP tool | Description |
|---|---|---|---|
GET | /api/v3/research/web_ | research_web_search | Grounded web search (freshness pd/pw/pm, count 1–20) |
GET | /api/v3/research/fetch_ | research_fetch_url | Read one page you already have the URL for, as clean markdown with a domain trust tier |
GET | /api/v3/research/synthesis | research_synthesis | Cited research synthesis (prose + source URLs) |
GET | /api/ | fundamentals_ai_analyze | AI-generated company analysis; 3 new analyses a day per customer |
Social Sentiment: Pro+ · 2,500 credits
Each answer runs a live grounded search. A repeat of the same ticker or query within 5 minutes is served from that answer and billed the same. See LLM Research.
| Method | Path | MCP tool | Description |
|---|---|---|---|
GET | /api/v3/research/x_ | research_x_sentiment | X/social sentiment narrative for a ticker or a free-form query, with the sources it searched |
Volatility & Positioning: Pro+ · 4 credits
| Method | Path | MCP tool | Description |
|---|---|---|---|
GET | /api/ | volatility_vix_indices | Daily OHLC of VIX (from 1990), VXO, VXN and VXD |
GET | /api/v3/volatility/vx_ | volatility_vx_curve | VIX futures settlements for one session, with contango or backwardation stated |
GET | /api/v3/positioning/cot | positioning_cot | The full disaggregated Commitments of Traders, every trader category per commodity market |
See Macro, Rates & FX.
Crypto History: Pro+ · 3 credits
| Method | Path | MCP tool | Description |
|---|---|---|---|
GET | /api/ | crypto_ | Recorded cross-venue funding, open interest and basis per 15-minute cycle (date or start, up to 31 days) |
GET | /api/v3/crypto/history/events | crypto_history_events | The recorded exchange-announcement and crypto-headline archive |
See Crypto for all five routes.
Not offered on the API
The Copilot and the Brain agent are not sold on the API. A key that calls a Copilot route gets
403 not_offered, whatever its plan, and is not charged. Every other route on this page is sold on the plans above.
Error responses
FIRM uses a flat error envelope: {"ok": false, "error": "<code>", "detail": "<message>", "request_ (?shape=firm adds a message field; detail is still there). When one
parameter caused the error, param names it. doc_url links to this section. A route's own fields
follow the envelope keys; see Detail fields below. The code is usually
also on the X-Error-Code header and the id on X-Request-ID.
Example 422 validation body:
{ "ok": false, "error": "validation", "detail": "invalid 'limit': Input should be a valid integer, unable to parse string as an integer (query.limit)", "request_id": "example-request-id", "doc_url": "https://app.wealthnow.io/docs/api-reference#error-responses", "param": "limit"}detail is a string, not an object. body["detail"]["error_ raises. Parse body["error"]
for the code and body["detail"] for the human-readable message. See the _parse_error helper in
Quickstart: Production client.
Some 503 responses come from the route itself: they carry status (such as
unavailable_), reason, available: false, billable: false, and retryable,
with no error field and no X-Error-Code header. Read status as the code.
Every non-2xx response is non-billable. A request refused before its credit reservation is never
debited; one that fails after it is refunded and reports X-Credits-Settlement: refunded with
X-Credits-Cost: 0. See Pricing & credits for the credit headers.
A 404 names what was not found, and the code depends on the route: unknown_ticker on the v3
routes, ticker_not_found on the legacy quote, and a typed code on the routes listed below. The
code is also on X-Error-Code. The crypto market and derivatives, COT, transcript and
ai_analyze routes, and crypto_, repeat it as error_code. A 404 is a standing answer: the same request gets the same one.
| Status | error | Meaning |
|---|---|---|
400 | invalid_json | The request body isn't valid JSON. |
400 | invalid_security_class, invalid_sort_by | The screener got a security_class or sort_by it does not know; detail lists the allowed values. |
400 | invalid_tickers, too_many_tickers, no_valid_tickers, invalid_horizons | Batch predictions: a malformed symbol (named in invalid_tickers), more than 200 distinct symbols, no usable symbol, or a horizon outside 1d, 1w, 1m, 3m, 1y. |
400 | invalid_ticker | street_estimates got a ticker that is not a plain symbol. |
401 | unauthorized | Key missing, malformed, or not sent. An unset env var produces this too. See Troubleshoot a 401. |
402 | plan_required | Product not in your plan; detail names the product and the plan that unlocks it. |
402 | usage_exceeded | Wallet empty / overage cap reached. |
403 | account_suspended | The account behind this key is not active. A failed payment does not cause this by itself: it moves the key to the Free plan, which keeps working with the Free credits until you update your card. |
404 | not_found | An unknown path. Also a private-markets id (company, deal, fund, investor, person, limited partner, service provider) that does not exist; a symbol outside the prediction book on ml_predict, which answers before the symbol check and so never sends unknown_ticker; framework/lookup; and some crypto/market list routes. |
404 | unknown_ticker | A symbol that neither the market-data listing nor the security master knows, current or delisted, on a single-ticker route (fundamentals, intel, news, credit, tape, earnings, transcripts, ownership and more). param names the parameter (symbol on the reference crosswalk and history routes) and ticker echoes the value. Not billed. A symbol that could not be checked in time is a 200 instead; see Unverified symbols. |
404 | ticker_not_found | /api/market/quote/{ticker}. An unknown ticker is 404 ticker_not_found on this route; the v3 routes answer unknown_ticker. |
404 | unknown_crypto_symbol | /api/crypto/{ticker}: not a pair the market-data feed lists. hint gives the accepted forms, and /api/crypto/universe lists the pairs. |
404 | crypto_ | asset_class=crypto on a route that has no crypto model. Never a cue to fall back to the equity with the same symbol. |
404 | no_analysis_available | fundamentals/ai_analyze: the analysis source has nothing for this symbol. retryable: false, and it does not use one of the day's analyses. |
404 | underlying_not_listed, underlying_not_covered, unknown_option_contract | Options routes (options_chain, options_flow, gex, max_pain, options_volume, net_premium, gex_strikes, their history routes, iv_analytics, tape/options_chain): the underlying has no listed options or is outside coverage. unknown_option_contract is intel/options_contract's. |
404 | contract_not_in_report, unknown_contract, market_not_in_report, unknown_market | Commitments of Traders: the first two on intel/cftc_cot, the last two on positioning/cot. |
404 | ticker_not_resolved, transcript_not_found, event_not_for_ticker, transcript_ | transcripts/. See Events & transcripts. |
404 | symbol_not_listed | Crypto derivatives (funding, open_interest, basis, vol_surface): no venue lists the symbol. |
404 | coin_not_found, contract_not_found, category_not_found, exchange_not_found, platform_not_found, network_not_found, address_not_found, token_not_found, pool_not_found | crypto/market/*: the id is malformed or unknown. See Crypto. |
404 | no_curve_for_date, seed_not_in_universe, unknown_index, unknown_futures_root, unknown_, pair_not_quoted, unknown_filer | One route each: volatility/vx_curve, research/correlation_, tape/index_bars, tape/futures_contracts and futures_live (root, then contract), news_forex/prices, ownership/filer/{id}. |
404 | wrds_dataset_not_found, dataset_not_found, dataset_withheld, dataset_excluded | Research datasets: /api/v2/datasets/{dataset}, then /api/v3/features/{dataset}. |
404 | excluded_ | The ticker is in the prediction book but is a fund or ADR, which the equity model does not rank (ml_predict). detail says so; this is the answer for that ticker, and another ticker is not a substitute. See Funds and ADRs. |
422 | validation | A parameter failed validation; detail names it. Some routes send a more specific code. |
422 | invalid_date_range | The window ends before it starts, for example end_date before start_date on fundamentals/prices. |
422 | invalid_date | A date that does not exist, such as 2026-09-31. |
422 | invalid_ticker | A symbol that cannot exist, refused before any data source is called (for example on company_facts). |
422 | ambiguous_, conflicting_, debt_, non_finite_threshold | The screener cannot read a filter: an older percent name with a value between -1 and 1, an older and a _pct name with different values, a debt-to-equity ceiling outside 0 to 20, or a value that is not a finite number. Nothing is screened; billed: false. |
422 | invalid_topic | A news topic, topic_or or topic_exclude that is not one of the news source's categories; detail lists the supported ones. See News topics. |
422 | unsupported_filter | A news route (news/*, intel/news_*, news_crypto/*, news_forex/*) was sent a subject filter it does not take, such as ticker where it takes tickers, or sector on news/ticker_news. Nothing was read. detail names the parameter or route to use, unsupported lists the refused names and accepted the route's parameters. See News & Sentiment. |
429 | rate_limited | Plan rate limit exceeded. Wait Retry-After seconds. |
429 | billing_unavailable | The metering call didn't confirm a debit, so the request was refused. Header Retry-After: 5. |
500 | internal_error | Unexpected server error. Retry a few times with backoff. |
502 | unkey_unreachable | Transient key-service blip. Retry. Header Retry-After: 5. |
502 | billing_unavailable | Credit reservation unavailable. Retry. Header Retry-After: 5. |
502 | invalid_paid_response | The result wasn't complete JSON within the response size limit. Narrow the request if it repeats. |
503 | paid_data_unavailable | The route couldn't produce a complete, usable result. Don't retry in a loop. |
503 | capability_ | The route is tagged data_pending_v1 and serves no data; status is unavailable_, retryable: false. |
503 | capability_ | Serving policy temporarily unavailable; retryable: true. |
503 | billing_ | Billing policy temporarily unavailable. Header Retry-After: 5. |
503 | status field, no error | A route-level unavailable body. Retry only when retryable is true. |
503 | upstream_unavailable | The data behind the route could not be read. This is not an empty result: the body has no result field and is_empty_result_set is false. error_code (also X-Error-Code) names the case: dataset_unavailable (see below); price_feed_unavailable or data_stale (prices; price_snapshot keeps a snapshot whose price is null); a feed and archive code such as archive_read_timeout, archive_read_failed, upstream_ or build_busy; warehouse_read_failed (a warehouse read failed, for example a private-markets relation or sentiment_history); redis_unavailable (the market-event store); upstream_<kind> for a news feed that failed, such as upstream_ or upstream_not_configured; upstream_dataset_empty (an upstream dataset that returns nothing for any ticker); screener_ or screener_ (the screener); price_, split_events_unread or price_basis_unknown (research-grade history); sec_edgar_unavailable (XBRL facts, Retry-After: 60); book_guard_unavailable (the check that keeps funds and ADRs out of the equity rankings could not load its sources, Retry-After: 60); or upstream_ (SHAP drivers that cannot be tied to the model serving now). Header Retry-After. Do not retry when retryable is false or Retry-After is longer than 120 seconds. |
503 | build_timeout | The screener's size data is still loading on that server. A warm-up, not an outage: retry once after Retry-After (10 seconds). |
503 | snapshot_cold | Batch predictions: the prediction book, or the check that keeps funds and ADRs out of it, is not loaded on that server yet. Retry after Retry-After (5 seconds). |
503 | snapshot_unusable | Batch predictions: the loaded book lacks the columns the route needs (Retry-After: 5), or no row of it can be verified (Retry-After: 60, with a book_guard block). |
504 | request_timeout | The request exceeded the server's time budget. Narrow it (add limit, or a start and end date) before retrying. |
Example 402 plan_required body:
{ "ok": false, "error": "plan_required", "detail": "your plan 'free' does not include 'congressional' ...", "request_id": "example-request-id"}Retry 429 and 502, and a 503 only when it carries Retry-After or
"retryable": true, honoring Retry-After with exponential backoff capped at 120
seconds. Do not retry a 503 that says "retryable": false or whose Retry-After is
longer than 120 seconds: the answer will not change soon. Before retrying 401, 402,
403, 404, or 422, check credential delivery, permissions, the wallet or plan
restriction, and the requested path.
A 401 alone does not justify rotating a key. See the
Quickstart for the Free-plan quote
check and the reference clients.
Detail fields
An error body carries the fields its route names, after the envelope keys (ok, error, detail,
request_id, doc_url), so a client can act on the refusal without parsing the sentence in detail:
| Field | On |
|---|---|
param, ticker | unknown_ticker: the parameter and the symbol sent. |
available | An unknown or withheld dataset (wrds_dataset_not_found, dataset_not_found, dataset_withheld, dataset_excluded), unknown_index: the names the route does serve. |
known_roots | unknown_futures_root: the futures roots the tape covers. |
symbol, hint, asset_class | The crypto 404s, such as unknown_crypto_symbol. |
reason, ticker | excluded_. |
tool_group, current_plan, required_plan, unlocked_by, upgrade_url | 402 plan_required. |
A route's field never replaces an envelope key, and X-Error-Code is unchanged. Example, a
404 from /api/crypto/ZZZZQ:
{ "ok": false, "error": "unknown_crypto_symbol", "detail": "'ZZZZQ' is not a crypto pair the market-data feed lists. ...", "request_id": "example-request-id", "doc_url": "https://app.wealthnow.io/docs/api-reference#error-responses", "param": "ticker", "symbol": "ZZZZQ", "hint": "Pass a crypto symbol as BTC, BTCUSD or X:BTCUSD (non-USD quote currencies via ?vs=, e.g. ?vs=EUR). ...", "timestamp": "2026-10-02T16:12:40.634451+00:00", "normalized_pair": "X:ZZZZQUSD"}Unverified symbols
A symbol known not to exist is a 404 unknown_ticker, not billed. A symbol is checked against the
market-data listing and the security master, and sometimes that check cannot finish in time. When a
metered call's answer is empty and its symbol could not be verified, the call answers 200 with the
route's usual empty body plus two fields, and is not billed. Abridged, from
/api/:
{ "ok": true, "ticker": "ZZQXV", "snapshot": {}, "company_facts": {}, "insider_trades_recent": [], "ticker_verification": "unverified", "ticker_verification_note": "The symbol could not be verified against the market-data listing and the security master in time, so this empty answer was not billed."}The headers say the same: X-Credits-Cost: 0, X-Credits-Settlement: refunded, and
Cache-Control: no-store. Read ticker_ as "this symbol may not exist",
not as "this company has no data": check the spelling, or look the company up with
fundamentals_search. An answer that carries data is served and billed as usual and never carries
the field. It applies to single-symbol equity calls on metered routes, not to a tickers list, a
crypto symbol or an asset_class call.
A symbol that is a current listing in the security master counts as verified even when the live
check cannot finish, so an empty answer about it (for example news/latest?ticker=AAPL over a
quiet minute) is an ordinary empty answer: billed, without ticker_verification.
When a dataset is unavailable
A route whose dataset was never built, or whose read came back with nothing, answers 503 with
error: "upstream_ and error_ (also on X-Error-Code)
instead of a billed empty list. The body has no result field, names the public dataset, and says
why in reason:
reason | Meaning | retryable | Retry-After |
|---|---|---|---|
table_missing | The dataset was never built. A retry will not change the answer. | false | 3600 |
table_empty | The dataset exists but the read returned no usable rows. This can also be a read that failed without saying so. | true | 60 |
source_unreadable | The read failed, or nothing came back and the catalog could not say whether the dataset exists. | true | 60 |
The call is not billed. Do not poll a table_missing refusal: report that the data is not
available. Retry the other two after Retry-After. Among the documented routes, this refusal can
come from insider clusters,
regime history, the importance,
drift and decay routes on Quant Signals, the
regime forecast while its book is
loading (Retry-After: 5), price history when
its 2025-to-date bars cannot be read, and the market-event catch-up
when the stream holds no events.
Response headers
Every authenticated response carries these headers, so a client can pace itself and reconcile credits without extra calls.
| Header | Meaning |
|---|---|
X-Request-ID | The request's id. Quote it when you contact support. |
X-RateLimit-Limit | Requests allowed per minute on your plan. |
X-RateLimit-Remaining | Requests left in the current window. |
X-RateLimit-Reset | When the window resets, as a Unix time in seconds. |
Retry-After | On a 429, and on many 503s, the seconds to wait before retrying. |
X-Credits-Cost | Credits this request cost (0 when it was refunded). |
X-Credits-Remaining | Credits left in your allowance after this request. |
X-Credits-Receipt | The receipt id for the credits this request reserved. |
X-Credits-Settlement | consumed for a billed success, refunded when a failed request was not charged. |
Deprecation | Present on a deprecated route (RFC 9745). A Link header with rel="successor-version" names the route to move to. |