Tool Reference
Every Stocklake tool - parameters, response fields, and examples. Organized by what you're paying for: data is free, intelligence is Pro. ← Getting Started
get_stock free
Returns price, fundamentals, technical indicators, and company profile for a ticker - everything you need about a stock in one call.
Parameters
| Name | Type | Description |
|---|---|---|
| symbol | string | Ticker symbol, e.g. AAPL. Case-insensitive. |
Response fields
| Field | Type | Description |
|---|---|---|
| symbol | string | Ticker |
| name | string | Company full name |
| sector / industry | string | Sector and industry classification |
| country / currency / exchange | string | Country, reporting currency, exchange code |
| price | number | Current market price (multi-source, authoritative) |
| change_pct | number | Day change % |
| volume / avg_volume | number | Day volume and average volume |
| prev_close | number | Previous close |
| week52_high / week52_low | number | 52-week range |
| market_cap / enterprise_value | number | Market cap and enterprise value, in the listing's own currency (see currency) |
| market_cap_usd | number | null | Market cap converted to US dollars; null when no FX rate is available for the listing currency |
| beta | number | Beta vs market |
| pe_trailing / pe_forward | number | Trailing and forward P/E ratios |
| price_to_book | number | Price-to-book ratio |
| dividend_yield / dividend_rate / ex_dividend_date | number / string | Dividend info |
| debt_to_equity | number | D/E ratio |
| profit_margins / operating_margins / gross_margins | number | Net, operating and gross profit margins (ratios, e.g. 0.25 = 25%) |
| revenue_growth / earnings_growth | number | YoY growth rates |
| earnings_date / earnings_is_estimate / last_earnings_date | string / bool / string | Next scheduled earnings report (UTC ISO; null when no date has been announced) and whether that date is an estimate; last_earnings_date is the most recent report |
| revenue_ttm / gross_profit_ttm | number | Trailing twelve-month revenue and gross profit |
| free_cashflow | number | Free cash flow (TTM), in the listing currency. Converted from the filing currency when they differ; null with a financials_note when no rate is available |
| financial_currency | string | Currency the company files its statements in (e.g. CNY for BABA) |
| return_on_equity | number | ROE |
| analyst_rating | string | Analyst consensus label: strong_buy · buy · hold · sell · strong_sell |
| analyst_rating_score | number | Mean analyst recommendation score: 1.0 = strong buy, 5.0 = strong sell (lower is better) |
| analyst_target / analyst_count | number | Mean price target and number of analyst opinions |
| indicators | object | RSI, MACD {macd_line, signal_line, histogram}, Bollinger Bands {upper_band, middle_band, lower_band}, SMA20/SMA200, EMA20/EMA200, ATR (all tiers). pro also unlocks every other field inside this same object: williams_r, ultimate_osc, vix_fix {value, percentile, spike}, williams_ad {trend, divergence}, td_sequential {setup_count, setup_direction (the setup currently counting: downtrend_exhaustion = counting falling closes, a decline that may be running out; uptrend_exhaustion = counting rising closes), countdown_count, countdown_complete, countdown_direction (same two values, for the countdown; can differ from setup_direction), signal (the most recent completed setup or countdown: DOWNTREND_EXHAUSTION_SETUP / UPTREND_EXHAUSTION_SETUP / DOWNTREND_EXHAUSTION_COUNTDOWN / UPTREND_EXHAUSTION_COUNTDOWN. It can be weeks old. For the count running now, read setup_direction with setup_count, or countdown_direction with countdown_count), phase}, elliott_wave {signal, trade_signal}, adx {adx, plus_di, minus_di}, ichimoku {tenkan, kijun, cloud_top, cloud_bot, above_cloud, below_cloud}, squeeze {squeeze_on, hist}, rs_rank (relative-strength rank 1-99, stocks only: past-year return with the latest quarter counted double, ranked against every tracked stock; 99 = strongest) - omitted entirely (not just unlabeled) for free/guest, along with any indicator added later. |
| description | string | Long-form company business description |
| website | string | Company website URL |
| employees | integer | Full-time employee count |
| officers | array | Top 5 executives: name, title, total_pay |
| updated_at | string | Data freshness timestamp (ISO 8601 UTC) |
| rating | object | pro Composite technical score: score (0-10), direction (POSITIVE/NEUTRAL/NEGATIVE), signals (per-indicator breakdown). Computed from the same indicators block, no extra AI cost. |
| signals | object | pro Flat labeled technical signals - overall + rsi/macd/bollinger/sma200/sma50/williams_r/ultimate_osc/vix_fix/williams_ad/td_sequential/elliott_wave, each with a plain-English label pre-interpreted for programmatic use. |
| stance_signals | array | pro Unified list of per-source directional calls - technical rating, AI summary (near_term + longer_term), insider/institutional sentiment, analyst consensus, and any active screener signals. Each entry: stance (POSITIVE/NEGATIVE/NEUTRAL), conviction (0-10), horizon (INTRADAY/SWING/POSITION/LONG_TERM), edge_quality (PROVEN/OBSERVATION/UNKNOWN - that source's own signal_backtest track record), source, raw_label, as_of. A source with no data for this stock is simply omitted, not returned as null. |
| relative_strength | object | pro Multi-window relative strength vs SPY, QQQ, and the stock's GICS sector ETF. windows: 5d/20d/60d/120d/12m → stock_return_pct plus rs_vs_spy/rs_vs_qqq/rs_vs_sector (percentage-point spread, stock return minus benchmark return - not a ratio). verdict: one-line plain-language read, e.g. "Laggard - weak near- and long-term". Windows/benchmarks with insufficient history are simply omitted; null if not precomputed yet for this symbol. |
| ai_verdict / ai_headline | string / string | pro The minimum useful AI-narrative slice, precomputed (no extra AI cost) - positive/neutral/negative verdict and a one-line "why". For the full text (summary/key_points/risks/near_term/longer_term), call get_stock_research. |
| ai_score / ai_score_band | number | null / string | null | pro 0-100 AI research composite score - same 0-100 scale/band convention as get_signals' signal_score but a distinct field/pipeline. Band: Weak / Moderate / Strong / Very Strong. Null if no ai_summary doc exists yet. |
| forensic_scores | object | pro Three classic forensic-accounting formulas computed from balance sheet/income statement/cash flow data, refreshed on each company's own filing cadence (roughly annual): altman_z {score, zone: safe/grey/distress} - Altman 1968 bankruptcy-risk composite; piotroski_f {score 0-9, strength: strong/moderate/weak} - Piotroski 2000 fundamental-strength score; beneish_m {score, likely_manipulator: bool} - Beneish 1999 earnings-manipulation-likelihood score (a screening heuristic, not a determination of actual manipulation). Every sub-block also carries a note explaining what it measures and known caveats - e.g. Altman Z isn't meaningful for banks/insurers and can flag REITs or client-money-float businesses as "distress" by design, not because anything is wrong. score: null means genuinely not computable for this company (common for financial-sector names), not an error. computed_at: ISO 8601 timestamp. No trading signal is derived from these scores anywhere in this API today. |
| sector_context | object | pro Where this stock's fundamentals sit versus the other tracked equities in its own sector: revenue_growth, gross_margin and operating_margin, each {value, sector_median, percentile, n} - percentile is 0-100 (share of sector peers below this stock, ties counted half), n the number of peers with data. Purely descriptive positioning - no interpretation or direction. A metric is omitted when the stock has no value or the sector has fewer than 15 peers with data; the whole block is omitted when nothing is computable. Sectors are pooled globally across all tracked equities; baseline refreshed daily (as_of). get_stock (not get_stocks) also returns trend: {period: "quarterly", points: [...]}, oldest first - the same three metrics for the last few quarters (revenue growth is year-over-year), each as {value, sector_median, n} beside the sector median for that quarter, so you can see whether a company is gaining or losing ground on its peers. Off-cycle fiscal quarters are matched to the nearest calendar quarter; a quarter or metric is left out where either side lacks data. |
get_stocks free+
Batch stock data for up to 25 symbols in a single call - the same fields get_stock returns for the same key/symbol, so this is a true batch, not a thinned-down scan. Returns prices, fundamentals, and indicators keyed by symbol. Each symbol in the batch counts as one call toward your daily limit. Pro tier adds the same precomputed rating/signals/relative_strength blocks as get_stock, together with forensic_scores, market_risk and sector_context (without its quarterly trend), plus ai_verdict/ai_headline/ai_score/ai_score_band per symbol - no extra AI cost. Not included even on Pro: stance_signals and the full ai_summary text - call get_stock/get_stock_research for those.
| Parameter | Type | Default | Description |
|---|---|---|---|
| symbols | array of strings | required | Stock tickers (max 25). Symbols with hyphens (e.g. BRK-B) are supported. Invalid symbols are silently skipped. |
Response includes the count of matched symbols plus a map with per-symbol data in the same format as get_stock. Requested symbols not found in the database are omitted from the result.
get_stock_history free+
Daily OHLCV price history for a ticker. Returns bars sorted oldest-first.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| symbol | string | - | Ticker symbol |
| days | integer | 90 | Number of trading days to return. Guest and free: max 365 (1 year). Pro: full history, up to 20,000 trading days - most established names go back decades. A full pull can be 10,000+ bars, so request only the window you need. |
Response fields
| Field | Type | Description |
|---|---|---|
| symbol | string | Ticker |
| days_requested | integer | The days you asked for, before any tier cap |
| days_returned | integer | Bars in this response (same as count) |
| count | integer | Bars actually returned (may be less if data is newer) |
| history | array | OHLCV bars: date, open, high, low, close, volume |
| history_available | object | {bars, earliest_date} - how much daily history exists for this ticker in total, regardless of the window returned |
| pro_unlocks | string | Present when a guest/free call asked for more than 365 days and was capped: says what Pro unlocks (the full history) |
get_market_pulse free
Live market health snapshot in a single call. Aggregates VIX, Fear & Greed index, market breadth, and key index prices - no AI cost, always live data.
Use this as a lightweight context check before making any investment decisions. Replaces the need to call multiple separate endpoints for basic macro state.
No parameters - returns the current market snapshot.
Response fields
| Field | Type | Description |
|---|---|---|
| vix | number | VIX level at last pipeline run |
| fear_greed.value | number | Fear & Greed index 0-100 |
| fear_greed.description | string | Label: "extreme fear" · "fear" · "neutral" · "greed" · "extreme greed" |
| breadth.oversold_pct | number | % of tracked stocks with RSI < 30 |
| breadth.overbought_pct | number | % of tracked stocks with RSI > 70 |
| breadth.neutral_pct | number | % of tracked stocks with RSI 30-70 |
| breadth.universe_size | integer | Total stocks in the tracked universe |
| indices.spy / qqq / iwm | object | Live price, change_pct, RSI for SPY / QQQ / IWM |
| bonds_commodities.tlt / gld | object | TLT (long bonds) and GLD (gold) - price, change_pct, RSI |
| updated_at | string | ISO 8601 UTC timestamp of breadth + fear/greed snapshot - vix/indices/bonds_commodities above are live, but this snapshot comes from the same market intelligence pipeline as get_market_assessment (~4x/day, weekdays only, during market hours - dead overnight/weekends) |
get_earnings_calendar free+
Upcoming earnings dates for all stocks in the Stocklake universe, within a configurable look-ahead window. Dates sourced from market data - treat is_estimate: true dates as approximate.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| days | integer | 7 | Look-ahead window in days (max 30) |
Response
| Field | Type | Description |
|---|---|---|
| window_days | number | Effective look-ahead window applied |
| from_date | string | Window start (UTC ISO) |
| to_date | string | Window end (UTC ISO) |
| count | number | Total results returned |
| results[].symbol | string | Ticker symbol |
| results[].name | string | Company short name |
| results[].sector | string | Sector |
| results[].market_cap | number | Market capitalisation in reporting currency |
| results[].price | number | Current stock price |
| results[].rsi | number | null | Current RSI - useful for pre-earnings momentum screening |
| results[].earnings_date | string | Expected earnings timestamp (UTC ISO) |
| results[].is_estimate | boolean | True if the date is an estimate - treat as approximate |
| results[].eps_trailing | number | null | Trailing 12-month EPS |
| results[].eps_forward | number | null | Forward EPS estimate |
Example response
get_screener free
Filter and rank stocks from the Stocklake universe - fundamentals, technicals, and (Pro) AI signals in one tool. Presets provide one-call screens for common setups.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| preset | string | - | oversold (RSI≤35, above SMA200) · overbought (RSI≥65) · momentum (RSI 50-70, above SMA200, up 0.5%+) · high_conviction (ai_score≥70, Pro only) |
| sector | string | - | e.g. "Technology", "Healthcare" |
| country | string | - | e.g. "United States", "Germany" |
| min_rsi / max_rsi | number | - | Exact RSI bounds (e.g. min_rsi=30, max_rsi=50 = post-oversold recovery zone) |
| sma_trend | string | - | above_200 / below_200 - price vs 200-day MA |
| macd_signal | string | - | positive / negative - MACD line vs signal line |
| min_perf_1d / max_perf_1d | number | - | 1-day performance % bounds (e.g. min_perf_1d=2.0 = up 2%+ today) |
| min_volume | integer | - | Minimum daily volume. e.g. 1000000 |
| min_market_cap_b / max_market_cap_b | number | - | Market cap in billions of US dollars, compared against market_cap_usd (non-USD listings are converted first) |
| max_pe_forward | number | - | Maximum forward P/E |
| analyst_rating | string | - | strong_buy / buy / hold / sell / strong_sell |
| min_ai_score | integer | - | Minimum AI score 0-100 - Pro tier only. Gates on the same ai_score field returned below (renamed 2026-08-24 from the retired 0-10 min_flag_score). |
| sort_by | string | market_cap | market_cap / rsi / perf_1d / volume / analyst_rating / rating / ai_score (Pro) |
| sort_dir | string | desc | asc / desc |
| limit | integer | 20 | 1-25. Each returned stock counts as one call toward your daily limit. |
Response fields (per result)
| Field | Type | Description |
|---|---|---|
| symbol, name, sector, industry, country | string | Stock identity |
| price, change_pct, volume | number | Current price, 1-day change %, day volume |
| market_cap, pe_forward | number | Fundamentals (market_cap in the listing's own currency) |
| market_cap_usd, currency | number | null, string | Market cap in US dollars (what the market_cap sort and cap filters use) and the listing currency |
| rsi | number | RSI value |
| macd_signal | string | positive / negative / neutral |
| sma200_trend | string | above / below |
| analyst_rating | string | buy / hold / sell etc. |
| rating | number | 0-10 technical composite score |
| ai_verdict | string | Pro only - positive / neutral / negative |
| ai_score | number | null | Pro only - 0-100 AI research composite score, same scale/band convention as get_signals' signal_score but a distinct field/pipeline. Null if no ai_summary doc exists yet. |
| ai_score_band | string | null | Pro only - Weak / Moderate / Strong / Very Strong, or null |
get_market_movers free
Top market movers from the Stocklake universe - gainers, losers, and most active by volume. A fast way to see what's moving in the market right now.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| category | string | all | gainers / losers / most_active / all (all returns all 3 categories) |
| limit | integer | 10 | Results per category (max 20). Each returned stock counts as one call toward your daily limit - a symbol appearing in more than one category counts once per category. |
| min_market_cap_b | number | - | Filter to stocks above this market cap in billions of US dollars (e.g. 1.0 = $1B+ only), compared against market_cap_usd |
Response
Returns gainers[], losers[], most_active[] (whichever categories requested). Each entry: symbol, name, sector, price, change_pct, volume, rsi, market_cap (listing currency), market_cap_usd, currency, analyst_rating, atr_pct (volatility as % of price - omitted when the underlying reading is missing or corrupted). pro adds ai_verdict / ai_headline / ai_score (0-100) / ai_score_band (Weak/Moderate/Strong/Very Strong) - a big move's price/volume/RSI alone doesn't say whether it matters; the headline is the "why".
get_indicator_history pro
Daily indicator snapshots for a symbol - up to 2 years of history. Default returns RSI, MACD histogram, Bollinger band position, and 20/200-day SMA per day - enough for most charting and trend analysis. Pass full=true to also get Williams %R, VIX Fix, Williams A/D trend, DeMark TD Sequential, and analyst rating/target, which barely change day to day and roughly double response size over a long window.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| symbol | string | - | Ticker symbol |
| days | integer | 90 | Number of calendar days to look back. Max 730 (2 years). |
| full | boolean | false | false returns the 5 basic fields below per day; true adds the 8 specialized/slow-moving fields marked "full only". |
Response fields
| Field | Type | Description |
|---|---|---|
| symbol | string | Ticker |
| days | integer | Days requested |
| full | boolean | Echoes the requested full param |
| count | integer | Snapshots returned |
| snapshots | array | Snapshots sorted oldest-first (see fields below). Empty (with a note field instead) if fewer than 3 found. |
| snapshots[].recorded_at | string | Snapshot date, YYYY-MM-DD |
| snapshots[].price | number | Price at snapshot time |
| snapshots[].rsi | number | RSI(14) value |
| snapshots[].macd_histogram | number | MACD histogram (line − signal) |
| snapshots[].bb_pct | number | Bollinger band position 0-100: 0 = at lower band, 100 = at upper band |
| snapshots[].sma20 / sma200 | number | 20-day and 200-day simple moving averages |
| snapshots[].williams_r | number | full only. Williams %R (0 to −100) |
| snapshots[].ultimate_osc | number | full only. Ultimate Oscillator (0-100; >70 overbought, <30 oversold) |
| snapshots[].vix_fix_value | number | full only. Williams VIX Fix synthetic fear gauge (higher = more fear) |
| snapshots[].williams_ad_trend | string | full only. rising / falling / flat |
| snapshots[].td_signal | string | null | full only. The most recent completed TD Sequential setup or countdown as of that day, named for the move that is running out: DOWNTREND_EXHAUSTION_SETUP / UPTREND_EXHAUSTION_SETUP / DOWNTREND_EXHAUSTION_COUNTDOWN / UPTREND_EXHAUSTION_COUNTDOWN / null |
| snapshots[].td_phase | string | null | full only. setup_active / setup_complete / countdown_active / countdown_done / null |
| snapshots[].analyst_rating | string | null | full only. buy / outperform / hold / underperform / sell / null |
| snapshots[].analyst_target | number | null | full only. Mean analyst price target |
get_stock_financials free+
Raw financial statements - balance sheet, income statement, and cash flow line items. This is the underlying statement data itself, not a derived summary - for the forensic-accounting scores computed FROM these statements (Altman Z / Piotroski F / Beneish M), see get_stock's forensic_scores block instead.
Each returned statement is shaped {line_item_name: {period_end_iso: value}} - e.g. balance_sheet["Total Revenue"]["2025-12-31"] - so you get every available period per line item and can compute your own trends/deltas/CAGRs, not just the latest value. Values are in the company's reporting currency (financial_currency), which can differ from the trading currency. ~50-60 curated line items per statement (not a raw dump of every reported row); coverage genuinely varies by symbol and sector - a bank has no "Inventory" line, a company with no buyback program has no "Repurchase Of Capital Stock" entry. A missing line item means the company doesn't report it, not a fetch error.
Free and guest get the latest fiscal year: all three statements, one period per line item, and the statement filter works. Asking for quarterly or both returns that latest annual year with quarterly: null and a pro_unlocks note, not an error. Pro gets up to 5 fiscal years, the ~7-8 most recent quarters, and period=both.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| symbol | string | - | Ticker symbol. Also accepts a company name as a fallback when it uniquely resolves to one symbol. |
| period | string | annual | annual (Pro: up to 5 fiscal years; free: the latest fiscal year), quarterly (Pro: up to ~7-8 most recent quarters), or both (Pro). Free/guest asking for quarterly/both get the latest annual year plus pro_unlocks. |
| statement | string | all | all, balance_sheet, income_stmt, or cash_flow - restricts which statement(s) come back. |
Response fields
| Field | Type | Description |
|---|---|---|
| symbol | string | Ticker |
| period | string | Echoes the requested period |
| statement | string | Echoes the requested statement |
| period_end | string | Latest annual fiscal-year-end on file, for reference |
| financial_currency | string | Reporting currency of the statement values, e.g. USD, EUR, JPY |
| annual | object | null | Present when period is annual or both, and always for free/guest. On free/guest it holds only the latest fiscal year (periods has one date). {periods: [...], balance_sheet: {...}, income_stmt: {...}, cash_flow: {...}} (narrowed to one statement key if statement isn't all). null with an annual_note if this symbol hasn't been widened yet. |
| quarterly | object | null | Present when period is quarterly or both. Same shape as annual. null with a quarterly_note if not yet fetched, or if this symbol genuinely has no usable quarterly data. Always null for free/guest (see pro_unlocks). |
| annual_periods_available | integer | Free/guest only: how many fiscal years are on file, i.e. what Pro would return |
| pro_unlocks | string | Free/guest only: what Pro adds for this symbol (more fiscal years, quarterly statements) |
| note | string | Present instead of annual/quarterly when this symbol has no financials data on file at all (not yet synced, or a non-equity with no statement data - ETFs/crypto/forex/indices aren't covered by this tool). |
get_analyst_trend pro
How analyst consensus on a stock has moved over time - the trajectory of the rating and the price targets, not just today's value. get_stock gives the current analyst_rating and analyst_target; this tool answers "are analysts getting more or less positive on this name?" with one row per day, up to a year back. Snapshots are taken once per weekday, so a 90-day window is roughly 60 rows. History begins July 2026 and grows daily.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| symbol | string | - | Ticker symbol. A company name is accepted as a fallback when it resolves to exactly one symbol. |
| days | integer | 90 | Number of calendar days to look back. Max 365. |
Response fields
| Field | Type | Description |
|---|---|---|
| symbol | string | Ticker |
| days | integer | Days requested (after clamping to 1-365) |
| count | integer | Snapshots returned |
| snapshots | array | Snapshots sorted oldest-first (see fields below). Empty, with a note field instead, if fewer than 2 exist in the window - a single point is not a trend. |
| snapshots[].date | string | Snapshot date, YYYY-MM-DD |
| snapshots[].analyst_rating | string | null | Consensus label: strong_buy / buy / hold / underperform / sell / strong_sell. Derived from analyst_rating_score on days the source reports no label. |
| snapshots[].analyst_rating_score | number | null | Mean recommendation: 1.0 = strong buy, 5.0 = strong sell (lower is more positive). Same scale as get_stock. |
| snapshots[].analyst_count | integer | null | Number of analysts contributing |
| snapshots[].analyst_target | number | null | Mean analyst price target |
| snapshots[].analyst_target_high / analyst_target_low | number | null | Highest and lowest individual price target |
| snapshots[].analyst_target_median | number | null | Median price target |
| snapshots[].price | number | null | The stock's price on that date, so a target can be read against where the stock actually traded |
A field is null on a day the source reported none - a symbol's rating can be null on some days even when its price targets are present, because the source occasionally drops the consensus label. A weekday can also be missing entirely when the daily snapshot did not run; those days cannot be reconstructed, so the date is simply absent. Most of the tracked universe has a usable history; ETFs and other instruments with no analyst coverage return an empty snapshots array. For price and indicator history, see get_indicator_history - this tool covers analyst consensus only.
get_economic_calendar free+
Upcoming and recently-released macro/economic events - interest rate decisions, CPI, GDP, PMI, unemployment, payrolls, retail sales, and more.
Two buckets: released_recent always carries a real actual value (never blank) plus diff - a plain arithmetic difference, actual minus previous, never a beat/miss or consensus judgment, since point-in-time consensus is not available. upcoming never carries an actual value. Every item in both buckets carries key_event: true for the handful of event types that reliably move markets on their own (rate decisions, CPI, GDP, headline Non-Farm Payrolls) - an event-TYPE flag only, never a beat/miss or directional judgment on the number itself.
Free vs Pro. Every tier gets the same tool, filters and response shape - only the window differs. Guest and free: up to 7 days ahead (days), 2 days back (lookback_days) and 20 results per bucket (limit). Pro: up to 14 days ahead, 7 days back and 50 per bucket. A guest/free value above its cap is served at the cap, and the response adds capped and a pro_unlocks note - never an error.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| days | integer | 3 | Look-ahead window in days for upcoming events. Max 7 on guest/free, 14 on Pro. |
| lookback_days | integer | 2 | Look-back window in days for recently-released events. Max 2 on guest/free, 7 on Pro. Actual values arrive with about a 1-day reporting lag - keep this at 2+ to reliably see real releases. |
| limit | integer | 20 | Max results per bucket - released_recent and upcoming each capped independently. Max 20 on guest/free, 50 on Pro. |
| major_only | boolean | false | Restrict to the 8 largest economies: United States, Euro Area, United Kingdom, Japan, China, Germany, France, Canada. |
| key_events_only | boolean | false | Restrict to rate decisions, CPI, GDP, and headline Non-Farm Payrolls - the subset flagged key_event: true. |
Response fields
| Field | Type | Description |
|---|---|---|
| window_days | integer | Effective look-ahead window applied |
| lookback_days | integer | Effective look-back window applied |
| today | string | Server's current date, YYYY-MM-DD (UTC) |
| released_recent | array | Recently-released events, major-economy-first then most-recent-first |
| released_recent[].country | string | Country or region name |
| released_recent[].event | string | Event name |
| released_recent[].date | string | Release date, YYYY-MM-DD |
| released_recent[].time | string | null | Release time, UTC, when known |
| released_recent[].actual | string | Reported value. Always present in this bucket. |
| released_recent[].previous | string | null | Prior period's value |
| released_recent[].consensus | string | null | Market consensus, when one is available (often null - see note above) |
| released_recent[].diff | string | null | actual minus previous, signed (e.g. "+0.1", "-2.7"). Null if either value is missing or non-numeric. Never a beat/miss judgment. |
| released_recent[].key_event | boolean | true for rate decisions, CPI, GDP, or headline Non-Farm Payrolls |
| upcoming | array | Not-yet-released events, major-economy-first then soonest-first. Same fields as released_recent except no actual/diff. |
| released_total / upcoming_total | integer | How many events matched before the row limit was applied. |
| truncated_note | string | Present only when the row limit cut a list. Lists are major-economy-first, so a cut list can end days before the window does; narrow with key_events_only or major_only. |
| capped | object | Guest/free only, present only when a value was above the free cap. One entry per capped param, e.g. {"days": {"requested": 14, "served": 7}}. |
| pro_unlocks | string | Present alongside capped: what Pro unlocks (14 days ahead, 7 back, 50 per bucket). |
get_stock_news free+ AI
Returns AI-analysed news articles for a ticker. Each article has been processed by our AI pipeline - raw article content is not exposed. Free/guest get up to 5 headlines (title and date, no AI fields); Pro gets up to 50 articles with a full AI summary, plus this symbol's live signal_score, over a 90-day window.
One article per event: articles about the same event are merged into the newest one, so limit counts distinct events. Articles without a usable summary are left out.
When no articles are found, the ticker is automatically queued for a background refresh. Re-queuing an already-pending ticker does not count against your limit.
Parameters
| Name | Type | Description |
|---|---|---|
| symbol | string | Ticker symbol |
| limit | integer | Max articles to return. Default 10. Guest and free: up to 5. Pro: up to 50. |
| days | integer | Look-back window in days. Default 30. Guest and free: max 30. Pro: max 90. |
Response
Outer envelope fields:
| Field | Type | Description |
|---|---|---|
| symbol | string | Ticker |
| status | string | ok empty - see below |
| count | integer | Number of articles returned |
| days | integer | Effective look-back window in days (guest and free max 30, Pro max 90) |
| articles | array | Article objects (see below) |
| message | string | Present when status is empty |
Status values:
- ok - articles returned
- empty - no news found for this window; pipeline triggered in background if data was stale
Per-article fields:
| Field | Type | Description |
|---|---|---|
| title | string | Article headline |
| published_at | datetime | Publication timestamp (ISO 8601) |
| ai_sentiment | string | Pro only. POSITIVE / NEUTRAL / NEGATIVE / MIXED |
| ai_summary | string | Pro only. Full AI-generated summary of the article's relevance to the stock |
| signal_score | number | null | Pro only. If this symbol has a currently-active news-sourced signal, every article shows that LIVE score - same value get_signals/get_stock_research report, kept in sync as the signal is re-scored (a per-symbol value, so every article for the symbol shows the same number then). Always a single number even then - for a genuinely two-sided signal (real opposing bull/bear theses, direction NEUTRAL), this is the stronger of the two sides. When there's no active signal for the symbol, each article instead gets its own per-article magnitude computed from that article's own AI classification - so different articles can show different numbers in that case. Null only when neither a live signal nor a computable per-article value exists. |
| signal_score_band | string | null | Pro only. Weak / Moderate / Strong / Very Strong. Null when signal_score is null. |
| collapsed_count | integer | Present only when several articles reported the same event (for example one analyst's target change carried by several outlets). Only the newest is returned; this is the number of articles merged into it. |
Note: there is no field called news_score anywhere on this API - signal_score is the one name, whether it resolves to a per-symbol live signal (preferred here when one exists) or a per-article magnitude (the fallback here when it doesn't, and the norm on get_news_feed, ranked by its own AI-assessed strength).
get_stock_research pro AI
Full research bundle for a symbol in one call - replaces 4 separate calls: get_stock + get_stock_news + get_insider_activity + get_signals (filtered to one symbol), plus the AI-generated summary (verdict, narrative, key points, risks) bundled in as ai_summary. All data is pre-computed by the nightly AI pipeline; no live AI calls on request.
Parameters
| Name | Type | Description |
|---|---|---|
| symbol | string | Ticker symbol |
Response sections
| Section | Key fields |
|---|---|
| stock | symbol, name, sector, price, change_pct, market_cap, pe_forward, pe_trailing, beta, dividend_yield, week52_high/low, analyst_rating, analyst_target, rsi, sma200_trend |
| ai_summary | verdict, ai_score (0-100) / ai_score_band (Weak/Moderate/Strong/Very Strong - the AI research composite, same scale/band convention as signal_score but a distinct field/pipeline), summary, key_points[] (3-5 specific positive/neutral observations), risks[] (2-3 specific risk factors), price_at_generation (stock price when the summary was generated), generated_at, headline (one-sentence plain-language take), near_term {stance, confidence} (view over <4 weeks, technicals/momentum-weighted), longer_term {stance, confidence} (view over a multi-month horizon, fundamentals/analyst/institutional-flow-weighted) - headline/near_term/longer_term are null on summaries generated before this schema shipped; fall back to verdict/ai_score until that symbol's next regeneration |
| news | Last 3 AI-flagged articles, one per event: title, published_at, ai_sentiment, ai_summary, signal_score (0-100)/signal_score_band, and collapsed_count (articles merged into it) when several reported the same event |
| sentiment | signal, signal_score (0-100) / signal_score_band (Weak/Moderate/Strong/Very Strong - no separate "insider_score" field, same name/formula as every other signal_score on this API), insider_trend (buying/selling/neutral, or null with no transactions in the window), institutional_pct, updated_at |
| signals | Up to the 5 most recent signals for this symbol in the last 90 days (array - a symbol can have more than one over that window): direction, signal_score (0-100 - always a single number, even for a NEUTRAL/two-sided idea, see get_signals' own signal_score row above), signal_score_band, source, rationale, expires, flagged_at. Recency-gated, not gated on whether Stocklake's own trading engine still holds the signal live. Empty array if none in that window. |
| directional_conflict | Only present when ai_summary.verdict and the most recent active signal's direction genuinely disagree (e.g. verdict=negative alongside an active POSITIVE signal) - these come from independent AI pipelines with different horizons and can legitimately point opposite ways. Fields: ai_summary_verdict, signal_direction, note. Absent (not null) when there's nothing to compare or the two agree. |
| forensic_scores | Same object as get_stock's forensic_scores block - three classic forensic-accounting formulas: altman_z {score, zone: safe/grey/distress}, piotroski_f {score 0-9, strength: strong/moderate/weak}, beneish_m {score, likely_manipulator: bool}, each with its own note. score: null means genuinely not computable for this company (common for financial-sector names), not an error. Absent (no key at all) if this symbol has no forensic_scores doc yet. |
get_insider_activity free+ AI
Insider transactions for a stock, from regulatory insider filings for the US, Germany, the Netherlands and Spain. Where no regulatory filing is on record, market data fills the gap and the response says so. The filing facts are free: every tier gets buy/sell counts and the individual filings behind them. Pro adds the AI read of insider and institutional activity and the institutional holder data.
- Free / guest:
insider_buys,insider_sells,summaryand the 5 most recenttransactionsover a fixed 90-day window. A largerdaysis capped at 90 and the response says so indays_note. No AI fields, no institutional holders. - Pro:
daysup to 365, up to 50 transactions, plussignal,signal_score,insider_signal/inst_signal,ai_commentary,top_holders,inst_ownership,total_holdersandholder_count_divergence.
The counts and the rows come from the same merge and the same window, so they always agree, and the free counts match what Pro returns for the same window. Coverage outside the US is narrower than in the US, so an empty list for a non-US company often means no filing on record, not a broken lookup. Institutional holders are merged from two feeds and refreshed nightly.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| symbol | string | ✓ | - | Ticker symbol (e.g. AAPL, TSLA) |
| days | integer | 90 | Insider-transaction window in days. Pro: 1-365. Free/guest: 1-90 (a larger value is capped at 90). Applies to transactions, insider_buys and insider_sells. |
Response fields
| Field | Type | Description |
|---|---|---|
| symbol | string | Ticker |
| insider_buys | int | Insider buy filings in the window (open-market purchases; grants, gifts and option exercises are excluded) |
| insider_sells | int | Insider sell filings in the window |
| transactions | array | The filings behind those counts, newest first: date, name, role, type (BUY/SELL), shares, price, value. Free/guest: up to 5. Pro: up to 50. |
| summary | string | One-line factual readout computed from the returned transactions/counts above: buy/sell counts, dollar totals, insider count and date range. Always agrees with the counts and rows next to it. |
| insider_buy_value | number | Total value of the buy filings in the window (listing currency) |
| insider_sell_value | number | Total value of the sell filings in the window (listing currency) |
| window_days | int | The window actually applied |
| source / source_name | string | null | Which kind of feed was used: regulatory_filing or market_data (gap fill only). Null when nothing is on record. |
| updated_at | string | ISO 8601 UTC time the filings behind transactions were last fetched. |
| days_requested | int | Free/guest only. The days you asked for, before the 90-day cap. |
| days_note | string | Free/guest only, present when days was capped. |
| transactions_note | string | Free/guest only, present when there are more filings in the window than the 5 returned. |
| note | string | Present when no insider buys or sells are on record in the window. |
| pro_unlocks | string | Free/guest only. What Pro adds. |
| signal | string | pro Combined AI sentiment: STRONG_POSITIVE, POSITIVE, NEUTRAL, NEGATIVE, STRONG_NEGATIVE |
| signal_score | number | null | pro 0-100, higher = stronger/more notable - the exact same field, formula, scale and bands as every other signal_score on this API. |
| signal_score_band | string | null | pro Weak/Moderate/Strong/Very Strong. Null when signal_score is null. |
| insider_signal | string | pro Insider-only AI signal: POSITIVE, NEGATIVE, NEUTRAL, NONE |
| inst_signal | string | pro Institutional-only AI signal: POSITIVE, NEGATIVE, NEUTRAL, NONE |
| ai_commentary / ai_commentary_as_of | string | null | pro A separately-generated AI narrative (names, amounts, direction) on its own refresh cadence, with the time it was written. It can lag the current filings - trust summary and transactions if they disagree. |
| top_holders | array | pro Up to 15 institutional holders: name, shares, pct_held, sources, share_counts_by_source |
| holder_count_divergence | object | null | pro Non-null when the two holder feeds (filings, market_data) disagree on share counts by the same factor, which means holder share counts for this symbol may be unreliable |
| inst_ownership | number | null | pro Institutional ownership percentage as a float (e.g. 74.55) |
| total_holders | int | null | pro Total institutional holders |
Example response
get_signals pro AI
Live AI signal queue - stocks actively flagged by the Stocklake pipeline as worth attention. Sourced from sector screening, news analysis, and sentiment signals. Signals expire daily; this always reflects the pipeline's current view.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| direction | string | - | POSITIVE · NEGATIVE · NEUTRAL - filter by trade direction. NEUTRAL covers both a flat/undecided read and a genuinely two-sided idea (real opposing bull/bear theses - see signal_score below). Omit for all. |
| min_signal_score | integer | 60 | Minimum composite signal score (0-100) - blends conviction/confidence/flag_score, source track record, and real technical factors. This is the field to filter on. |
| source | string | - | Filter by signal source: news · screener · sentiment |
| limit | integer | 25 | Max signals to return (max 50 - pass a higher value explicitly for the broader feed). Results sorted by recency. Each returned signal counts as one call toward your daily limit. |
Response fields
| Field | Type | Description |
|---|---|---|
| count | integer | Number of signals returned |
| window | string | "24h" if fresh activity was found, otherwise a note that the response falls back to the most recent signals regardless of age |
| signals[].symbol | string | Ticker |
| signals[].direction | string | POSITIVE · NEGATIVE · NEUTRAL |
| signals[].signal_score | number | Composite AI score 0-100 - the current, single source of truth for signal quality. Always a single number, including for a NEUTRAL signal (a genuinely two-sided idea, real opposing bull/bear theses) - in that case this is the STRONGER of the two sides, since that's the more actionable fact; the two-sided detail is in rationale. |
| signals[].signal_score_band | string | null | Human-readable label: Weak · Moderate · Strong · Very Strong. Null only when signal_score itself is null. |
| signals[].source | string | Primary pipeline source that flagged this stock |
| signals[].sources | array | All sources that contributed (when merged across sources) |
| signals[].rationale | string | AI rationale - why the pipeline flagged this stock |
| signals[].expires | string | Date after which this signal is considered stale (YYYY-MM-DD) |
| signals[].flagged_at | string | ISO 8601 UTC timestamp when this signal was last flagged by the pipeline |
CMA above is a NEUTRAL signal - the pipeline sees a genuine bull case (37/100) and bear case (62/100) at once, no directional consensus. signal_score reports the STRONGER side (62), so a high score alongside NEUTRAL means real conviction with a contested direction, not "nothing going on" - the two-sided detail is in rationale.
get_news_feed pro AI
Market-wide AI-flagged news briefing - top articles across all tracked stocks ranked by signal strength. Unlike get_stock_news (per-symbol), this scans the entire universe and surfaces the most notable news regardless of ticker. No URLs or source domains exposed.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| min_signal_score | integer | 60 | Minimum signal_score (0-100) used to select articles server-side. Replaces the old min_flag_score (0-10, gated on the legacy ai_flag_score field) - 2026-08-24, signal_score consistency initiative. |
| days | integer | 3 | Look-back window in days (max 10) |
| limit | integer | 10 | Max articles returned (max 25) |
Each article also carries signal_score (0-100, always a single number) and signal_score_band ("Weak"/"Moderate"/"Strong"/"Very Strong"). Prefers this symbol's LIVE news-sourced signal score if one was raised in the last 90 days - same value get_signals/get_stock_news report for that symbol, kept in sync as it's re-scored, and not gated on whether Stocklake's own trading engine still considers the signal live (a dropped/expired signal still shows here); this is a per-symbol fact, not a per-article judgment, so two articles about the same stock always show the same value. Otherwise a per-article magnitude computed from that article's own AI classification, so every article still gets a real, rankable number. There is no separate news_score field - one name for "how strong is this idea," whether it's backed by a formal signal or just this article's own classification.
One article per event: when several articles report the same event, the highest-ranked one is kept and carries collapsed_count, the number of articles merged into it. limit counts distinct events. Articles without a usable summary are left out.
get_market_assessment pro AI
Combined macro regime + market outlook in a single call. Refreshed ~4x/day, weekdays only, during market hours (~2h apart) - dead overnight and on weekends, not a continuous 4-hourly cadence. Check regime_stale / outlook_stale before treating this as current. Returns two complementary perspectives:
- Regime (
regime_*fields) - answers "how much equity risk to take" → use for position sizing and asset allocation - Outlook (
outlook_*fields) - answers "which direction and sectors to trade" → use for sector preference and directional bias
Note: market_context is a point-in-time snapshot from when the AI ran - not live. Use get_market_pulse for live prices.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| history_count | integer | 0 | Include last N prior assessments for each perspective (0-3). Returns regime_history[] and outlook_history[]. |
Response - Regime fields
| Field | Type | Description |
|---|---|---|
| regime | string | RISK_OFF / CAUTIOUS / NEUTRAL / AGGRESSIVE |
| risk_appetite_score | number | 0-100. Plain re-expression of regime as a score (RISK_OFF ≈ 10 → AGGRESSIVE ≈ 90). Higher = the tape currently supports more risk-taking. |
| macro_score | number | null | 0-100. The REAL, continuous number regime buckets into 4 categories - a blend of arithmetic inputs (VIX level, breadth oversold/overbought skew, SKEW-vs-VIX divergence, TD-exhaustion ratio) and the AI's own regime_strength read. Distinct from risk_appetite_score, which is just a coarse 4-value lookup on regime alone - macro_score is the finer-grained real number. Null on an assessment from before this field existed (2026-08-26). |
| regime_strength | number | null | 1-10. The AI's own read of regime conviction - one of the two inputs blended into macro_score above. |
| macro_score_trend | object | {change_7d, change_30d, direction} - whether macro_score itself is improving/deteriorating/stable over the trailing 7/30 days, computed automatically (no history_count needed). A bare 33 doesn't say whether the environment is getting worse or just stabilized after a worse reading - this does. Either leg is null without enough history yet. |
| regime_bias | string | "Long Setups Only" / "Short Setups Only" / "Both Directions" - whether current market conditions favor one trade direction over the other |
| regime_bias_note | string | Plain-language sentence explaining what regime_bias means, framed as a market-conditions read |
| regime_confidence | number | 1-10. Clarity of the regime call. |
| regime_rationale | string | Core thesis in plain language |
| key_risks | string[] | 2-3 tail risks that could invalidate the call |
| watch_for | string[] | Triggers that would cause a regime change |
| vix_at_assessment | number | VIX level when assessment was made |
| regime_updated_at | string | ISO 8601 UTC timestamp of last assessment |
| indicators.macro_data | object | Macro data: yield_spread_10y2y, fed_funds_rate, cpi_index (BLS index level ~332, not YoY %), unemployment, breakeven_10y, usd_index, m2 - each with value, date, delta_3m |
| indicators.volatility_term_structure | object | VIX / VIX3M / VIX6M last 5 closes + contango/backwardation signal |
| indicators.market_sentiment | object | Fear & Greed value (0-100) and label |
| indicators.breadth | object | Live market-wide RSI breadth (universe_size, oversold/overbought/neutral counts + percentages) - same live numbers as get_market_pulse's breadth, bundled here too so a regime read doesn't need a second call. |
| market_context | object | Point-in-time snapshot: price/RSI/SMA200/perf for SPY, QQQ, IWM, TLT, GLD, VIX, TNX, HYG, sector ETFs. Recorded when AI ran - not live. |
Response - Outlook fields
| Field | Type | Description |
|---|---|---|
| outlook | string | POSITIVE / NEUTRAL / NEGATIVE |
| outlook_conviction | number | 1-10. Strength of the directional call. |
| equity_view | string | Plain language directional narrative |
| preferred_sectors | string[] | Sectors to overweight |
| avoided_sectors | string[] | Sectors to underweight |
| catalyst | string | Primary catalyst driving the outlook |
| outlook_key_risk | string | Key risk to the outlook thesis |
| outlook_rationale | string | Detailed reasoning |
| outlook_updated_at | string | ISO 8601 UTC timestamp of last assessment |
| regime_history[] | object[] | Prior regime states (when history_count > 0): regime, risk_appetite_score, macro_score, regime_bias, regime_confidence, vix_at_assessment, updated_at |
| outlook_history[] | object[] | Prior outlook states (when history_count > 0): outlook, conviction, at |
get_sector_intelligence pro AI
AI-assessed sector intelligence with signals (LEADING/STRONG/NEUTRAL/WEAK/LAGGING), drivers, alerts, and computed statistics. Pass a sector for deep single-sector analysis, or omit for all 11 sectors at once - the all-sectors call doubles as the rotation view (sort_by_strength + history_count). Refreshed ~4x/day, weekdays only, during market hours (~2h apart) - dead overnight and on weekends, not a continuous 4-hourly cadence. Check the returned updated_at before treating this as current.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| sector | string | - | None | Sector name (e.g. Technology, Healthcare). Omit to list all sectors. |
| sort_by_strength | boolean | - | false | All-sectors call only: sort LEADING→LAGGING instead of alphabetical - for finding leading vs lagging sectors |
| history_count | integer | - | 0 | All-sectors call only: include last N prior signal states per sector (0-3) |
Response fields
| Field | Type | Description |
|---|---|---|
| sector | string | Sector name |
| signal | string | LEADING / STRONG / NEUTRAL / WEAK / LAGGING |
| cycle_stage | string | Sector cycle phase (e.g. MARKUP, MARKDOWN, ACCUMULATION, DISTRIBUTION) |
| rotation_signal | string | Money-flow read (e.g. ACCUMULATE, DISTRIBUTE, HOLD) |
| sector_score | number | null | 0-100. The REAL, continuous number signal buckets into 5 categories (LEADING/STRONG/NEUTRAL/WEAK/LAGGING) - a blend of arithmetic inputs (RSI/perf percentiles, top-5 concentration, SMA200 breadth) and the AI's own strength_score read. Comparable across all 11 sectors on one absolute scale. Null on an assessment from before this field existed (2026-08-26). |
| strength_score | number | null | 1-10. The AI's own read of sector strength - one of the two inputs blended into sector_score above. |
| sector_score_trend | object | Single-sector call only. {change_7d, change_30d, direction} - whether sector_score is improving/deteriorating/stable over the trailing 7/30 days, computed automatically. This is the only trend view available for one sector at all - history_count only applies to the all-sectors call. Two sectors both reading STRONG/68 can be moving in opposite directions; this tells them apart. Either leg is null without enough history yet. |
| confidence | number | AI confidence 1-10 |
| drivers | string | AI narrative of sector drivers |
| alert | string | Notable condition if applicable (breadth divergence, extreme RSI, etc.) |
| stats.avg_rsi | number | Sector-average RSI |
| stats.sma200_breadth_pct | number | % of stocks above their 200-day MA |
| stats.oversold_pct / overbought_pct | number | RSI distribution extremes |
| stats.avg_perf_1w_pct / avg_perf_1m_pct | number | Average sector performance 1W / 1M |
| updated_at | string | ISO 8601 when the assessment was made |
| history[] | array | Present when history_count > 0 (all-sectors call) - prior {signal, confidence, sector_score, at} |
| sectors[] / count | array / integer | Present when sector param is omitted - all sectors assessed |
get_earnings_intelligence pro AI
Upcoming earnings with AI context per stock - combines the earnings calendar with AI pipeline data to surface which events are worth monitoring. Sorted by earnings date ascending (soonest first).
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| days_ahead | integer | 14 | Look-ahead window in days (max 30) |
| sector | string | - | Filter to one sector (optional) |
| min_ai_score | integer | - | Only return stocks with AI score ≥ this value, 0-100 (optional). Renamed 2026-08-24 from the retired 0-10 min_flag_score - gates on the same ai_score field returned below. Applied before limit truncates the result. |
| limit | integer | 25 | Max results to return (max 25). Each returned stock counts as one call toward your daily limit. |
Response fields (per result)
| Field | Type | Description |
|---|---|---|
| symbol, name, sector | string | Stock identity |
| earnings_date | string | ISO UTC timestamp of expected earnings release |
| is_estimate | boolean | Whether the date is estimated |
| price, rsi, market_cap | number | Current technicals |
| eps_trailing, eps_forward | number | Earnings expectations context |
| ai_verdict | string | positive / neutral / negative (from nightly AI pipeline) |
| ai_score | number | null | 0-100 AI research composite score, same scale/band convention as get_signals' signal_score but a distinct field/pipeline. Null if no ai_summary doc exists yet. |
| ai_score_band | string | null | Weak / Moderate / Strong / Very Strong, or null |
| ai_risks | string[] | Top 2 AI-identified risk factors |
| analyst_rating, analyst_target | string / number | Wall Street consensus |
get_watchlist pro AI
The caller's Stocklake watchlist - the symbols starred on the web dashboard at /dashboard - enriched with live price, technicals, and AI verdict. No parameters; resolves your account automatically from your API key or OAuth session.
Parameters
None.
Response fields
| Field | Type | Description |
|---|---|---|
| count | integer | Number of symbols on the watchlist |
| items[].symbol, name, sector | string | Stock identity |
| items[].price, change_pct, rsi, market_cap | number | Live snapshot |
| items[].analyst_rating | string | null | strong_buy / buy / hold / sell / strong_sell |
| items[].atr_pct | number | Average True Range as % of price (volatility). Omitted if the underlying indicator reading is missing or corrupted. |
| items[].ai_verdict | string | positive / neutral / negative (from nightly AI pipeline) |
| items[].ai_headline | string | One-line "why" behind the verdict |
| items[].ai_score | number | null | 0-100 AI research composite score - same 0-100 scale/band convention as get_signals' signal_score but a distinct field/pipeline. Null if no ai_summary doc exists yet. |
| items[].ai_score_band | string | null | Weak / Moderate / Strong / Very Strong, or null |
| items[].added_at | string | ISO UTC timestamp - when the symbol was starred |
| items[].price_at_add | number | Price at the moment it was starred, for a "since added" delta |
Read-only - starring/unstarring a symbol is web-only for now (no add_to_watchlist/remove_from_watchlist tool yet). Returns count: 0, items: [] if nothing is starred.