Skip to main content
A decision brief is the context a user needs to think about one symbol, with none of the trade advice. The spine is /v2/coverage/v2/snapshot/v2/valuation, all on the Free plan; add /v2/filings or /v2/insider only when the prompt asks for primary-source risk or insider activity. This is a context product, not an advisor: report what the data says, never tell the user to buy, sell, hold, or size anything. This page walks one filled brief end to end. The reusable answer templates (the bullet skeletons you’d paste into an agent) live in agent recipes; this guide is the worked example that shows why each line is there.

The spine

GET /v2/coverage?symbol=AAPL    # confirm support + asset_type, once
GET /v2/snapshot?symbol=AAPL    # quote, performance, 52w range, fundamentals_quick
GET /v2/valuation?symbol=AAPL   # multiples vs 5-year history
Coverage is the cheap insurance call: it tells you the symbol is in the universe and which families it supports before you build on data that might be unsupported. Snapshot and valuation are the brief’s body. For a plain “give me a brief,” those three are the whole job; /v2/fundamentals, /v2/filings, and /v2/insider are depth you add on request, not by default. The route selection rationale is owned by Choose endpoints; this page just uses it.

Worked example: a brief on AAPL

The prompt: “Quick brief on Apple, and is there any unusual insider selling?” That second clause earns the optional /v2/insider call. Two fixtures drive the answer below. From /v2/snapshot?symbol=AAPL (quote, performance, and range shown; the live response also returns the full fundamentals_quick block, sector, and industry):
GET /v2/snapshot?symbol=AAPL (trimmed)
{
  "data": {
    "symbol": "AAPL",
    "as_of": "2026-06-08T13:07:36Z",
    "freshness": "end_of_day",
    "market_status": "closed",
    "cache_age_seconds": 0,
    "quote": { "price": 308.73, "change_pct": 0.45, "previous_close": 307.34 },
    "performance": { "pct_1m": 7.0, "pct_ytd": 13.62, "pct_1y": 53.8, "vs_spy_pct_1y": 28.01 },
    "range_52w": { "high": 316.94, "low": 194.3, "position_pct": 92.2, "drawdown_from_high_pct": -3.03 },
    "fundamentals_quick": {
      "pe_ttm": { "value": 36.81, "vs_5y": "near_5y_high" },
      "fcf_yield_pct": 2.86,
      "dividend_yield_pct": 0.35
    }
  }
}
The headline multiples are objects, not bare floats: pe_ttm (and ps_ttm, pb, ev_ebitda_ttm) ship computable values as { value, vs_5y?, caveat? }, so the number lives at fundamentals_quick.pe_ttm.value. vs_5y bands the ratio within AAPL’s own five-year history (near_5y_high here); it is not a cheapness verdict and not a peer comparison. fcf_yield_pct and dividend_yield_pct stay flat floats. From /v2/insider?symbol=AAPL (the 90-day rollup; the live response also returns up to 10 recent_transactions). /v2/insider is a paid route, so this call needs a Starter or Builder key — a Free key gets 403 PLAN_UPGRADE_REQUIRED:
GET /v2/insider?symbol=AAPL (summary, trimmed)
{
  "data": {
    "symbol": "AAPL",
    "as_of": "2026-06-06T07:17:18Z",
    "freshness": "end_of_day",
    "market_status": "closed",
    "cache_age_seconds": 2370,
    "summary_90d": {
      "market_activity": {
        "buy_count": 0,
        "sell_count": 13,
        "net_shares_market_only": -397759,
        "net_value_usd": -111705105.08,
        "net_direction": "selling"
      },
      "all_activity": {
        "transactions": 43,
        "net_shares_all_kinds": 25895,
        "transactions_by_kind": {
          "open_market_sale": 13,
          "derivative_exercise": 22,
          "tax_withholding": 6,
          "gift": 2
        }
      },
      "unique_insiders": 7,
      "notices": ["recent_transactions_limited_to_10"]
    }
  }
}
In MCP these are stockcontext_snapshot({ "symbol": "AAPL" }) and stockcontext_insider({ "symbol": "AAPL" }); the envelopes match the REST responses exactly.

The brief this supports

Answer first, then the facts, then a freshness line that’s honest about the two routes having different ages, then the calls used:
Apple is trading near its 52-week high after a strong year, and insiders have been net sellers on the open market over the past 90 days. At 308.73 (+0.45% on the day) it sits at the 92nd percentile of its 52-week range, 3.03% off the high of 316.94. It’s up 53.8% over the year (28.01 points ahead of SPY) and 13.62% year to date, on a trailing P/E of 36.81 (near_5y_high in its own five-year range) with a 2.86% free-cash-flow yield and a 0.35% dividend. On insiders: over the trailing 90 days there were 13 open-market sales and zero buys across 7 insiders, for net open-market selling of about -$111.7M (net_shares_market_only -397,759). Across every Form 4 kind, all_activity.net_shares_all_kinds is +25,895 — derivative exercises and grants net positive — so don’t conflate the two. The open-market selling is directional, but it’s routine for a mega-cap and says nothing about price on its own. Freshness: snapshot end_of_day, as_of 2026-06-08T13:07:36Z, market closed. Insider rollup end_of_day, as_of 2026-06-06T07:17:18Z; Form 4 data settles overnight, so it lags the quote by design. Calls used: /v2/snapshot, /v2/insider.
Three things make that a good brief, not a generated one:
  • The freshness line carries both timestamps. The quote is end_of_day; the insider rollup is also end_of_day but older, with its own cache_age_seconds (2370 here, ~40 minutes). Both carry freshness, as_of, market_status, and cache_age_seconds. Collapsing them into one “current as of now” would misrepresent the older half. Cite each route’s own freshness and as_of. The enum and how to detect it are owned by the freshness reference.
  • The negative net value keeps its sign, its scope, and its caveat. net_value_usd (-111705105.08) and net_shares_market_only are open-market only; all_activity.net_shares_all_kinds (+25,895) covers every Form 4 kind, including derivative exercises and grants. Report the open-market figure as net selling and say so, but never conflate it with the all-kinds total — they can point opposite ways. Dropping the sign, the scope, or the routine-for-a-mega-cap caveat would all mislead.
  • The truncation notice is respected. notices: ["recent_transactions_limited_to_10"] means the detail line-item list is capped at the request limit (default 10, flagged recent_transactions_limited_to_N). The 90-day summary aggregates every Form 4 in the trailing window, scanning up to the latest 200 filings (flagged scanned_latest_200_filings_only if it hits that scan cap), so the rollup counts are complete even though the line items aren’t. Don’t quote “13 sales” as if it were the full picture if the user wants every transaction; point them at the cap.

When the data says “no answer”

If coverage flags a family as unsupported (a foreign private issuer for /v2/filings and /v2/insider, or an ETF for valuation), the brief states that the data isn’t available for that symbol and stops. It does not substitute a guess, and it does not retry an unsupported response as if it were an outage. A brief that admits a gap is more useful than one that fills it with invention.

Agent recipes

The reusable brief and answer templates to drop into an agent.