{"openapi":"3.1.0","info":{"title":"VecViz Agent API","description":"Quantitative research analytics for agents.","version":"1.0.0"},"paths":{"/v1/read/{ticker}":{"get":{"tags":["vna"],"summary":"Read Ticker","description":"Everything known about ONE ticker: VNA target price, channels, VecEvents,\nV-Score, and a digest of which price-probability bands exist.\n\nStart here for any single-ticker question -- it is self-sufficient, so no\nfollow-up call is needed just to learn the V-Score.\n\n`v_score` carries its own scale (-12..+12, the sum of six single-horizon\nscores of -2..+2). A null value means not published for this ticker at this\nmodel date, which `meta.warnings` states explicitly -- on a signed scale a\nbare null is otherwise read as neutral.\n\nThis is not the route for a LIST of tickers. /v1/universe takes a `tickers`\nsubset and returns the same fields for up to a hundred names at once.","operationId":"read_ticker_v1_read__ticker__get","parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","description":"Stock ticker symbol, e.g. NVDA","title":"Ticker"},"description":"Stock ticker symbol, e.g. NVDA"},{"name":"as_of","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Dataset version token from a prior response","title":"As Of"},"description":"Dataset version token from a prior response"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Read Ticker V1 Read  Ticker  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/vecevents/{ticker}":{"get":{"tags":["vna"],"summary":"Vecevent Matrix","description":"The per-VecEvent by per-Vector-Set contribution matrix, read-only.\n\nRecomputes nothing: every value comes straight from the VNA dataset, so this\nis what the widget shows.","operationId":"vecevent_matrix_v1_vecevents__ticker__get","parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","description":"Stock ticker symbol","title":"Ticker"},"description":"Stock ticker symbol"},{"name":"vector_sets","in":"query","required":false,"schema":{"type":"string","description":"'all', or a comma-separated list like vs1,vs11","default":"all","title":"Vector Sets"},"description":"'all', or a comma-separated list like vs1,vs11"},{"name":"as_of","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"As Of"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Vecevent Matrix V1 Vecevents  Ticker  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/vecevents/reviewed":{"post":{"tags":["vna"],"summary":"Vecevent Matrix Reviewed","description":"The reviewed matrix: the caller's overrides and new events, folded in.\n\nThe counterpart to ``/vecevents/{ticker}``, which is read-only. Here the\nCALLER supplies the review decisions -- which VecEvent biases and trends\nthey judged wrong, and which narratives the set does not yet capture -- and\nevery downstream number is computed server-side.\n\nThat division is the point. The judgement is irreducibly the reviewer's; the\ngeometry is not, and a reviewer who hand-computes a contribution or a core\nwidth will get it wrong in a way nothing catches. So this returns the\nfeatured-set selection, the reviewed contributions, the isolation maths and\na per-column tie-out, and the caller renders them verbatim.\n\nIt reuses the same arithmetic as ``vna_scenario``, so the Wtd-Avg\n``post_review_target`` equals the baseline plus the sum of the individual\nper-change impacts. `tie_out` says whether it did; report it rather than\nburying a discrepancy.","operationId":"vecevent_matrix_reviewed_v1_vecevents_reviewed_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_vecevent_matrix_reviewed_v1_vecevents_reviewed_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Vecevent Matrix Reviewed V1 Vecevents Reviewed Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/vna/whatif":{"post":{"tags":["vna"],"summary":"Vna Whatif","description":"Re-run the VNA cascade with one existing VecEvent's bias changed.\n\nReturns the full cascade, old versus new, plus the per-Vector-Set standalone\ntarget prices. For an event that does not exist yet, use /vna/new-event.","operationId":"vna_whatif_v1_vna_whatif_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_vna_whatif_v1_vna_whatif_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Vna Whatif V1 Vna Whatif Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/vna/new-event":{"post":{"tags":["vna"],"summary":"Vna New Event","description":"Re-price the VNA cascade with a brand-new VecEvent folded in.\n\nA new event has no vector-set footprint, so it mirrors the footprint of the\nexisting VecEvent whose start date is closest to one year ago; the response\nnames which one under `mirrored_from`.","operationId":"vna_new_event_v1_vna_new_event_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_vna_new_event_v1_vna_new_event_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Vna New Event V1 Vna New Event Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/vna/scenario":{"post":{"tags":["vna"],"summary":"Vna Scenario","description":"Re-price the VNA cascade under a changed or added VecEvent.\n\nOne entry point for both scenarios, because which one applies is a fact\nabout the data rather than a choice the caller should have to get right:\nname an event the ticker already has and its bias is CHANGED; name one it\ndoes not and the event is ADDED. `mode` in the response says which happened.\n\nAn added event has no vector-set footprint of its own, so it mirrors the\nexisting VecEvent whose start date is closest to one year ago; the response\nnames it under `mirrored_from`.\n\nEvent names must be exact -- substring matching is disabled upstream because\nit resolved to the wrong event. Use the names from /v1/read.","operationId":"vna_scenario_v1_vna_scenario_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_vna_scenario_v1_vna_scenario_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Vna Scenario V1 Vna Scenario Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/tickers":{"get":{"tags":["vna"],"summary":"List Tickers","description":"Every ticker with VNA coverage. Free -- agents need it to plan calls.","operationId":"list_tickers_v1_tickers_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response List Tickers V1 Tickers Get"}}}}}}},"/v1/ppf/{ticker}":{"get":{"tags":["ppf"],"summary":"Price Probability Forecast","description":"Forecast price bands by horizon, and when they reach a target price.\n\nTen bands at six horizons: the expected upper/lower bounds (EUB/EDB), the\n95% and 99% bounds in each direction, and their sigma counterparts. Pass\n`target_price` to also get the interpolated calendar date each band crosses\nit; a null crossing means that band does not reach the target within 252D.\n\nBands a ticker's source model does not publish are omitted rather than\nreturned as null, and named in `coverage.bands_absent` — so an absent band\nis distinguishable from a failed one and is not worth retrying.","operationId":"price_probability_forecast_v1_ppf__ticker__get","parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","description":"Stock ticker symbol, e.g. NVDA","title":"Ticker"},"description":"Stock ticker symbol, e.g. NVDA"},{"name":"horizons","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated subset of 1D,10D,21D,63D,126D,252D. Default: all.","title":"Horizons"},"description":"Comma-separated subset of 1D,10D,21D,63D,126D,252D. Default: all."},{"name":"bands","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated subset of the 10 band labels. Default: all present.","title":"Bands"},"description":"Comma-separated subset of the 10 band labels. Default: all present."},{"name":"target_price","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"If given, adds the date each band reaches this price.","title":"Target Price"},"description":"If given, adds the date each band reaches this price."},{"name":"as_of","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Dataset version token from a prior response","title":"As Of"},"description":"Dataset version token from a prior response"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Price Probability Forecast V1 Ppf  Ticker  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/ppf":{"get":{"tags":["ppf"],"summary":"Ppf Universe","description":"Which tickers have forecast bands, and how complete each one is.\n\nFree, because an agent planning a screen should not spend quota to learn\nwhich tickers are worth a call. Note this universe is slightly wider than\n/v1/tickers, which reports VNA coverage.","operationId":"ppf_universe_v1_ppf_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Ppf Universe V1 Ppf Get"}}}}}}},"/v1/price-likelihood/{ticker}":{"get":{"tags":["price-likelihood"],"summary":"Price Likelihood","description":"Everything VecViz says about one price for one ticker.\n\nFive readings of the same question:\n\n* **ppf** — the forecast bands and the date each reaches the price. When the\n  expected bound never reaches it inside 252 days, the price is a tail\n  outcome at every horizon, not merely an unlikely one.\n* **vector_sets** — each channel's standalone target, how far the price sits\n  from that channel's centre in VLs, and the tops and bottoms it is anchored\n  on. `weight_at_or_past` says how much of the model's conviction already\n  sits at or beyond the price — the difference between a re-weighting story\n  and a tail.\n* **vecevents** — how many brand-new VecEvents it would take and of what\n  bias and trend, plus every re-characterisation of an existing event ranked\n  by impact and the fewest changes that close the gap. The chosen set is\n  re-priced through the reviewed-matrix path, so the target is computed\n  rather than summed.\n* **option** — the model-implied value of the put or call the direction\n  implies, struck at the price itself and interpolated onto it rather than\n  snapped to the grid. No market implied volatility exists here, so it\n  cannot say cheap or rich.\n* **v_score** — whether the aggregate agrees with the direction, and which\n  horizons back it most emphatically. The per-horizon scores are a separate\n  computation on a different scale and can disagree with the aggregate;\n  `reconciles_with_aggregate` says whether they do today.\n\nCosts 1 unit. `sections` narrows the work — `vecevents` is the expensive one.","operationId":"price_likelihood_v1_price_likelihood__ticker__get","parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","description":"Stock ticker symbol, e.g. SPY","title":"Ticker"},"description":"Stock ticker symbol, e.g. SPY"},{"name":"price","in":"query","required":true,"schema":{"type":"number","description":"The price being asked about, in dollars","title":"Price"},"description":"The price being asked about, in dollars"},{"name":"expiry_days","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Adds the option's fair value at this expiry, interpolated between the two bracketing horizons.","title":"Expiry Days"},"description":"Adds the option's fair value at this expiry, interpolated between the two bracketing horizons."},{"name":"sections","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated subset of ppf, vector_sets, vecevents, option, v_score. Default: all.","title":"Sections"},"description":"Comma-separated subset of ppf, vector_sets, vecevents, option, v_score. Default: all."},{"name":"as_of","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Dataset version token from a prior response","title":"As Of"},"description":"Dataset version token from a prior response"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Price Likelihood V1 Price Likelihood  Ticker  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/vector-sets/{ticker}/anchors":{"get":{"tags":["price-likelihood"],"summary":"Vector Set Anchors","description":"The tops and bottoms each Vector Set is anchored on.\n\nA Vector Set is drawn over two or three historical turning points. This\nreturns each one's date, price and whether it was a top or a bottom, in\nchronological order, plus the span and price range of the set.\n\nRead-only and recomputes nothing. Costs 1 unit.","operationId":"vector_set_anchors_v1_vector_sets__ticker__anchors_get","parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","description":"Stock ticker symbol, e.g. SPY","title":"Ticker"},"description":"Stock ticker symbol, e.g. SPY"},{"name":"vector_sets","in":"query","required":false,"schema":{"type":"string","description":"'all', or a comma-separated list like vs1,vs11","default":"all","title":"Vector Sets"},"description":"'all', or a comma-separated list like vs1,vs11"},{"name":"as_of","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Dataset version token from a prior response","title":"As Of"},"description":"Dataset version token from a prior response"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Vector Set Anchors V1 Vector Sets  Ticker  Anchors Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/diversifiers/{ticker}":{"get":{"tags":["diversifiers"],"summary":"Diversifiers","description":"Top-ranked tickers that would most diversify an exposure to this one.\n\n**Stage 1 — diversification.** Correlates the subject against every other\ncovered ticker on all three published methods (VecEvent, Fingerprint,\nPearson), averages the three, and keeps the lowest quintile.\n\n**Stage 2 — quality.** Ranks that pool on\n\n    mean(VNA_PctUpside, EUB_Ret) x Wgt Up x (V-Score + 12) / (24 x -95D_Ret)\n\n— expected upside, scaled by the strength-weighting of the ticker's upward\nchannels and by the V-Score mapped onto 0..1, divided by the downside it\nwould take to get there.\n\nA high rank means **least correlated AND well positioned**, never least\ncorrelated on its own. `screen` reports what each filter removed, including\nthe tickers dropped for publishing no V-Score — a null there means \"not\npublished\", not \"neutral\", so they are excluded rather than scored as zero.\n\nEvery row carries its **EqLiq**, a 1-10 liquidity decile. Nothing in the\nscore penalises illiquidity, so check it before acting: a top-ranked name at\nEqLiq 1 is thinly traded.\n\nCosts 10 units — a universe screen, priced like a sector cut.","operationId":"diversifiers_v1_diversifiers__ticker__get","parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","description":"The ticker whose exposure you want to diversify","title":"Ticker"},"description":"The ticker whose exposure you want to diversify"},{"name":"top_n","in":"query","required":false,"schema":{"type":"integer","description":"How many ranked names to return, 1-100.","default":20,"title":"Top N"},"description":"How many ranked names to return, 1-100."},{"name":"quintile","in":"query","required":false,"schema":{"type":"number","description":"Fraction of the correlation distribution to keep as candidates. 0.2 is the lowest quintile.","default":0.2,"title":"Quintile"},"description":"Fraction of the correlation distribution to keep as candidates. 0.2 is the lowest quintile."},{"name":"as_of","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Dataset version token from a prior response","title":"As Of"},"description":"Dataset version token from a prior response"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Diversifiers V1 Diversifiers  Ticker  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/metric-history":{"get":{"tags":["metric-history"],"summary":"Metric History","description":"One metric's full published history, its summary statistics, and a chart.\n\nEvery other tool on this surface answers at the latest model date. This one\nanswers \"how has it moved\". Supply ``entity_b`` to get the ratio as well --\nthe same ratio the OpenBB ``metric_ratio_table`` publishes, from the same\nfunction.\n\nLevels (``a``, ``b``) are raw. The ratio is computed on values shifted by the\nmetric's own offset so it cannot go negative, so on V-Score and\nVNA_PctUpside ``ratio`` is deliberately not ``a / b``; ``ratio_basis`` spells\nout which applies.","operationId":"metric_history_v1_metric_history_get","parameters":[{"name":"entity_a","in":"query","required":true,"schema":{"type":"string","description":"Ticker or sector whose history you want.","title":"Entity A"},"description":"Ticker or sector whose history you want."},{"name":"entity_b","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional comparator: a ticker, a sector, or 'rest'. Supplying it adds a per-date ratio alongside both levels.","title":"Entity B"},"description":"Optional comparator: a ticker, a sector, or 'rest'. Supplying it adds a per-date ratio alongside both levels."},{"name":"metric","in":"query","required":false,"schema":{"type":"string","description":"VV-Data-Table column, e.g. V-Score, EUB_Ret, VNA_PctUpside.","default":"V-Score","title":"Metric"},"description":"VV-Data-Table column, e.g. V-Score, EUB_Ret, VNA_PctUpside."},{"name":"start_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO or MM/DD/YYYY.","title":"Start Date"},"description":"ISO or MM/DD/YYYY."},{"name":"end_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO or MM/DD/YYYY.","title":"End Date"},"description":"ISO or MM/DD/YYYY."},{"name":"rolling_window","in":"query","required":false,"schema":{"type":"integer","maximum":252,"minimum":2,"description":"Trailing-mean window.","default":21,"title":"Rolling Window"},"description":"Trailing-mean window."},{"name":"theme","in":"query","required":false,"schema":{"type":"string","description":"Chart theme: light or dark.","default":"light","title":"Theme"},"description":"Chart theme: light or dark."},{"name":"as_of","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Dataset version token.","title":"As Of"},"description":"Dataset version token."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Metric History V1 Metric History Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/metric-context/{ticker}":{"get":{"tags":["metric-context"],"summary":"Metric Context","description":"Why one metric's value is what it is, for one ticker.\n\nResolves the metric, horizon and value at the latest model date (and\nchecks a quoted figure against it), then positions the value eight ways:\n\n* **history** — its percentile in the ticker's own published history.\n* **peers** — percentile rank, z-score, median and extremes within the\n  ticker's sector, its industry and the whole universe on the same date.\n* **sigma** — the Sigma model's reading of the same bound, the ratio and\n  difference, and a note on why the two models differ.\n* **shape** — the thirteen V-Score criteria beside their bullish and\n  bearish historical analogues, and the raw shape columns against peers.\n* **v_score** — both scales, with whether they reconcile today.\n* **vna** — whether the VNA target corresponds, which Vector Set channel\n  is centred on the price the return implies, its anchors, its standalone\n  target and the VecEvents that carry it.\n* **vecevents** — the catalogue and how its size compares to the universe.\n* **realized** — trailing return, forward return if closed, liquidity.\n\nCosts 1 unit. `sections` narrows the work.","operationId":"metric_context_v1_metric_context__ticker__get","parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","description":"Stock ticker symbol, e.g. NVDA","title":"Ticker"},"description":"Stock ticker symbol, e.g. NVDA"},{"name":"metric","in":"query","required":false,"schema":{"type":"string","description":"The metric being asked about: a VV Data Table column (99D_Ret, 95U_Ret, EUB_Ret, V-Score, VNA_PctUpside, RangeUp, WtdAvg Angle, DaysSinceLastTop, EqLiq ...) or one of the thirteen V-Score criteria by its spider name (Top Top Prox, Avg Up Angle, Wgt Up Angles ...). Aliases are accepted. 95D/99D name the 95th/99th-percentile DOWNSIDE bound, not a number of days.","default":"99D_Ret","title":"Metric"},"description":"The metric being asked about: a VV Data Table column (99D_Ret, 95U_Ret, EUB_Ret, V-Score, VNA_PctUpside, RangeUp, WtdAvg Angle, DaysSinceLastTop, EqLiq ...) or one of the thirteen V-Score criteria by its spider name (Top Top Prox, Avg Up Angle, Wgt Up Angles ...). Aliases are accepted. 95D/99D name the 95th/99th-percentile DOWNSIDE bound, not a number of days."},{"name":"horizon_days","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Forecast horizon in trading days: 1, 10, 21, 63, 126 or 252. Default 21. Only the six band returns and the V-Score criteria are published beyond 21.","title":"Horizon Days"},"description":"Forecast horizon in trading days: 1, 10, 21, 63, 126 or 252. Default 21. Only the six band returns and the V-Score criteria are published beyond 21."},{"name":"quoted_value","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The number the reader quoted, if any (e.g. -45 or -0.45 for a return; the sign is forgiven on a directional metric). The response says whether it matches what is published and, if not, the nearest figure that does.","title":"Quoted Value"},"description":"The number the reader quoted, if any (e.g. -45 or -0.45 for a return; the sign is forgiven on a directional metric). The response says whether it matches what is published and, if not, the nearest figure that does."},{"name":"sections","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated subset of history, peers, sigma, shape, v_score, vna, vecevents, realized. Default: all. 'vna' is the expensive one.","title":"Sections"},"description":"Comma-separated subset of history, peers, sigma, shape, v_score, vna, vecevents, realized. Default: all. 'vna' is the expensive one."},{"name":"as_of","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Dataset version token from a prior response","title":"As Of"},"description":"Dataset version token from a prior response"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Metric Context V1 Metric Context  Ticker  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/universe":{"get":{"tags":["universe"],"summary":"Vecviz Universe","description":"Cross-sectional read at the latest model date, for two distinct uses.\n\n**Discovery** -- rank the whole universe on one metric to find candidates,\nthen drill in with /v1/read.\n\n**Batch read** -- pass `tickers` to get the same row of fields for a named\nlist, up to `MAX_TOP_N` per call. Both paths are priced at 1 unit per\nticker, so the saving is in time rather than quota: one call instead of N\navoids N round trips and the per-minute unit limiter. The real discount is\n`sector` or `industry` -- a flat 10 however many names the cut holds.\nPrefer /v1/read when you want DEPTH on one name: it adds VecEvents, the\nchannel breakdown and the PPF digest, none of which this route carries.\nEvery row here carries every field regardless of `sort_by`, so on this path\n`sort_by` only sets the order.\n\nRanking is always within a single model date, because ranking across dates\nwould mix regimes. Tickers with no value in the `sort_by` column cannot be\nranked and are excluded, with the count reported in `meta.warnings` -- on a\nbatch read, compare the returned tickers against what you asked for rather\nthan assuming a 1:1 result.\n\nSorting by `var` puts the WORST downside first (most negative bound), which\nis what \"sort by risk\" means; every other key sorts best-first. Bound fields\nending `_ret` are fractional RETURNS from the model-date price, not price\nlevels.","operationId":"vecviz_universe_v1_universe_get","parameters":[{"name":"sort_by","in":"query","required":false,"schema":{"type":"string","description":"v_score | vna_upside | oar | var | eq_liq | trailing_return","default":"v_score","title":"Sort By"},"description":"v_score | vna_upside | oar | var | eq_liq | trailing_return"},{"name":"top_n","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Rows to return, capped at 1000. The default of 25 is a discovery default; when reading a named `tickers` list, set this to the length of that list or the response is truncated to 25 rows.","default":25,"title":"Top N"},"description":"Rows to return, capped at 1000. The default of 25 is a discovery default; when reading a named `tickers` list, set this to the length of that list or the response is truncated to 25 rows."},{"name":"sector","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Exact sector name; see /v1/catalog","title":"Sector"},"description":"Exact sector name; see /v1/catalog"},{"name":"industry","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Exact industry name; see /v1/catalog. Priced the same as a sector, so a sector is the cheaper cut per name.","title":"Industry"},"description":"Exact industry name; see /v1/catalog. Priced the same as a sector, so a sector is the cheaper cut per name."},{"name":"fields","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"compact | full. Large results compact automatically -- a full-width whole-universe response is ~85,000 tokens.","title":"Fields"},"description":"compact | full. Large results compact automatically -- a full-width whole-universe response is ~85,000 tokens."},{"name":"skip_unknown","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Set true to drop tickers outside coverage instead of being refused. Only ever lowers the charge.","title":"Skip Unknown"},"description":"Set true to drop tickers outside coverage instead of being refused. Only ever lowers the charge."},{"name":"min_eq_liq","in":"query","required":false,"schema":{"anyOf":[{"type":"number","maximum":10,"minimum":1},{"type":"null"}],"description":"Minimum equity-liquidity decile, 1-10. This is a RANK, not a market cap in dollars.","title":"Min Eq Liq"},"description":"Minimum equity-liquidity decile, 1-10. This is a RANK, not a market cap in dollars."},{"name":"tickers","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated tickers to restrict to, e.g. 'AAPL,MSFT,NVDA'. The batch-read path: one call returns every field for up to 1000 named tickers. Charged 1 unit per ticker, the SAME rate as /v1/read -- batching saves round trips and per-minute limiter headroom, not quota. For a real discount ask by `sector` or `industry` (flat 10). Split longer lists across consecutive calls.","title":"Tickers"},"description":"Comma-separated tickers to restrict to, e.g. 'AAPL,MSFT,NVDA'. The batch-read path: one call returns every field for up to 1000 named tickers. Charged 1 unit per ticker, the SAME rate as /v1/read -- batching saves round trips and per-minute limiter headroom, not quota. For a real discount ask by `sector` or `industry` (flat 10). Split longer lists across consecutive calls."},{"name":"as_of","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Dataset version token from a prior response","title":"As Of"},"description":"Dataset version token from a prior response"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Vecviz Universe V1 Universe Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/risk/{ticker}":{"get":{"tags":["universe"],"summary":"Risk History","description":"How a ticker's downside and upside bounds have moved over time.\n\nReturns the series plus where the current value sits in its own history\n(`current_vs_history`), so a caller can say \"this is the 90th percentile of\nits own range\" rather than quoting a bare number.\n\nAvailable history is shorter than the 756-day maximum the parameter allows;\nwhen a request exceeds it, everything available is returned and\n`meta.warnings` says how much that was.","operationId":"risk_history_v1_risk__ticker__get","parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","description":"Stock ticker symbol","title":"Ticker"},"description":"Stock ticker symbol"},{"name":"metric","in":"query","required":false,"schema":{"type":"string","description":"var | oar | both","default":"both","title":"Metric"},"description":"var | oar | both"},{"name":"lookback_days","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Calendar days back, capped at 756","default":252,"title":"Lookback Days"},"description":"Calendar days back, capped at 756"},{"name":"as_of","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"As Of"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Risk History V1 Risk  Ticker  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/filter":{"get":{"tags":["universe"],"summary":"Vecviz Filter","description":"Every ticker clearing ALL of a named screen's criteria at once.\n\nDistinct from /v1/universe, which ranks the whole universe on ONE metric and\nreturns the head of that list: the top of a V-Score sort says nothing about\nwhether those names also cleared an upside test. This applies a conjunction\nand returns the names that survived it.\n\nSay what the screen is EITHER by naming a `mode` -- fixed thresholds\ndeclared server-side, so two callers get the same screen -- OR by passing\nexplicit `*_min` floors. Passing both is refused rather than resolved.\nSector, industry, their `exclude_` counterparts and `min_eq_liq` are scope\nrather than criteria, and combine with either form.\n\nRanked by `rank_score` descending -- `99D_Ret / EqLiq`, liquidity-adjusted\ntail risk. The criteria pick the opportunity and the ranking picks the\nsafest way to take it, so upside does not enter the order: the survivors\nhave already cleared it. The score is NEGATIVE, so descending puts the\nmildest tail first. It is published on every row beside the two fields it\nis built from, so the order can be recomputed rather than taken on trust.\n\nThe response states the thresholds it applied and how many rows each one\nleft standing, so a screen that returns nothing says which criterion emptied\nit. Priced as a universe screen: 10 units, whatever the mode.","operationId":"vecviz_filter_v1_filter_get","parameters":[{"name":"mode","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Named screen. Omit and pass thresholds for a custom screen; passing both is refused.","title":"Mode"},"description":"Named screen. Omit and pass thresholds for a custom screen; passing both is refused."},{"name":"top_n","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Rows to return","default":35,"title":"Top N"},"description":"Rows to return"},{"name":"v_score_min","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Floor on V-Score","title":"V Score Min"},"description":"Floor on V-Score"},{"name":"vna_upside_min","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Floor on VNA_PctUpside","title":"Vna Upside Min"},"description":"Floor on VNA_PctUpside"},{"name":"eub_ret_min","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Floor on EUB_Ret","title":"Eub Ret Min"},"description":"Floor on EUB_Ret"},{"name":"edb_ret_min","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Floor on EDB_Ret (negative)","title":"Edb Ret Min"},"description":"Floor on EDB_Ret (negative)"},{"name":"d99_ret_min","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Floor on 99D_Ret (negative)","title":"D99 Ret Min"},"description":"Floor on 99D_Ret (negative)"},{"name":"sratio_99u_min","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Floor on 99U_Sratio","title":"Sratio 99U Min"},"description":"Floor on 99U_Sratio"},{"name":"min_eq_liq","in":"query","required":false,"schema":{"anyOf":[{"type":"number","maximum":10,"minimum":1},{"type":"null"}],"description":"Minimum EqLiq decile, 1-10 (10 = most liquid)","title":"Min Eq Liq"},"description":"Minimum EqLiq decile, 1-10 (10 = most liquid)"},{"name":"sector","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Restrict to this sector","title":"Sector"},"description":"Restrict to this sector"},{"name":"industry","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Restrict to this industry","title":"Industry"},"description":"Restrict to this industry"},{"name":"exclude_sector","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Drop this sector","title":"Exclude Sector"},"description":"Drop this sector"},{"name":"exclude_industry","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Drop this industry","title":"Exclude Industry"},"description":"Drop this industry"},{"name":"fields","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"compact | full","title":"Fields"},"description":"compact | full"},{"name":"as_of","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"As Of"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Vecviz Filter V1 Filter Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sectors":{"get":{"tags":["universe"],"summary":"List Sectors","description":"Sector names accepted by /v1/universe. Free -- needed to build a query.","operationId":"list_sectors_v1_sectors_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response List Sectors V1 Sectors Get"}}}}}}},"/v1/metric-report":{"get":{"tags":["universe"],"summary":"Vecviz Report All","description":"The All Ticker Average: eight metrics as a cross-sectional mean.\n\nEach metric carries its current cross-sectional mean and a z-score against\nthe full-universe history, so \"the market is unusually X right now\" is\nanswerable as a number rather than an impression.\n\nDistinct from /v1/model-review, which is the daily performance report's\nnarrative. This is a metric snapshot. Costs 1 unit.","operationId":"vecviz_report_all_v1_metric_report_get","parameters":[{"name":"as_of","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Dataset version token from a prior response","title":"As Of"},"description":"Dataset version token from a prior response"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Vecviz Report All V1 Metric Report Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/metric-report/{ticker}":{"get":{"tags":["universe"],"summary":"Vecviz Report Ticker","description":"One ticker's eight metrics, each positioned two ways.\n\n`zscore` is against the ticker's OWN history -- \"is this high for this\nname?\". `cross_sectional_zscore` is against every other ticker on the same\nmodel date -- \"is this high for the market?\". A name can be unremarkable on\none and extreme on the other, which is the point of showing both.\n\nCosts 1 unit.","operationId":"vecviz_report_ticker_v1_metric_report__ticker__get","parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","description":"Stock ticker symbol, e.g. NVDA","title":"Ticker"},"description":"Stock ticker symbol, e.g. NVDA"},{"name":"as_of","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Dataset version token from a prior response","title":"As Of"},"description":"Dataset version token from a prior response"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Vecviz Report Ticker V1 Metric Report  Ticker  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/correlate":{"get":{"tags":["analytics"],"summary":"Correlate","description":"Pairwise correlations among a set of tickers.\n\nThree methods measure different things: `pearson` is ordinary trailing\n252-day return correlation and is what \"correlation\" usually means;\n`vecevent` compares how two names respond to the same event backdrop;\n`fingerprint` compares VecViz shape, which is scale-invariant.\n\nWith exactly two tickers and no `method`, all three are returned together --\ncomparing them is the whole point for a single pair, and needing a separate\ntool for that was a distinction without a difference. Pairs are stored one\nway only, alphabetically, and either order resolves.\n\nOtherwise returns the full matrix plus a `pairs` list sorted by absolute\ncorrelation, so \"what is most correlated here\" needs no post-processing.\nThere is no lookback parameter: the dataset carries a single model date, and\n`window` states the period the numbers actually describe.","operationId":"correlate_v1_correlate_get","parameters":[{"name":"tickers","in":"query","required":true,"schema":{"type":"string","description":"Comma-separated, 2 to 40 symbols","title":"Tickers"},"description":"Comma-separated, 2 to 40 symbols"},{"name":"method","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"pearson | vecevent | fingerprint. Omit with exactly two tickers to get all three side by side.","title":"Method"},"description":"pearson | vecevent | fingerprint. Omit with exactly two tickers to get all three side by side."},{"name":"as_of","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Dataset version token","title":"As Of"},"description":"Dataset version token"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Correlate V1 Correlate Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/correlate/{ticker_a}/{ticker_b}":{"get":{"tags":["analytics"],"summary":"Correlate Pair","description":"All three correlation methods for one pair, so they can be compared.\n\nPairs are stored one way only, alphabetically; this resolves either order.","operationId":"correlate_pair_v1_correlate__ticker_a___ticker_b__get","parameters":[{"name":"ticker_a","in":"path","required":true,"schema":{"type":"string","description":"First ticker","title":"Ticker A"},"description":"First ticker"},{"name":"ticker_b","in":"path","required":true,"schema":{"type":"string","description":"Second ticker","title":"Ticker B"},"description":"Second ticker"},{"name":"as_of","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"As Of"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Correlate Pair V1 Correlate  Ticker A   Ticker B  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/portfolio":{"post":{"tags":["analytics"],"summary":"Portfolio","description":"Three reads on a portfolio: your own, or VecViz's.\n\n`mode=risk_profile` is the full VecViz read on weights you supply -- either\n`{\"NVDA\": 0.4, ...}` or `\"NVDA:0.4,MSFT:0.6\"`. It returns the\nweight-averaged V-Score and VNA upside, and the 21-day 95% downside built\nthrough a covariance matrix (S_ij = sigma_i sigma_j rho_ij) six times: two\nvolatility sources crossed with three correlation methods. The two sources\nare different MODELS, not two estimates of one number -- `95D_Ret` is the\nVector Model's bound and the Sigma set is the Sigma model's -- and each\nconstruct names its own in `volatility_input`. The SPREAD across the six is\nthe honest measure of how much those two choices matter; reporting a single\nnumber would hide a decision the caller never made. Every position must be\nin coverage: a portfolio is a joint claim, and\nquietly dropping an unrecognised name answers a different question with\nweights that no longer sum to what was sent.\n\n`mode=analyze` is the simpler read: per-position risk plus weight-averaged\naggregates that IGNORE correlation, so they are undiversified bounds rather\nthan a portfolio VaR.\n\n`mode=optimize` is a LOOKUP over precomputed model portfolios, not an\noptimisation -- `is_optimisation` is false. Omitting `strategy` returns\nfour; a `target_vol` between published grid points is interpolated and says\nso.","operationId":"portfolio_v1_portfolio_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_portfolio_v1_portfolio_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Portfolio V1 Portfolio Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/portfolio/variants":{"get":{"tags":["analytics"],"summary":"Portfolio Variants","description":"Which precomputed portfolios exist. Free -- needed to build a request.\n\nNot every strategy/max_weight/target_vol combination is published, and\nthe set changes day to day, so this is the difference between an exact\nmatch and a snapped neighbour.","operationId":"portfolio_variants_v1_portfolio_variants_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Portfolio Variants V1 Portfolio Variants Get"}}}}}}},"/v1/options/{ticker}":{"get":{"tags":["analytics"],"summary":"Option Fair Value","description":"VecViz fair value for options on one ticker.\n\nThis is a fair value derived from VecViz's own probability distribution.\nThere is NO market implied-volatility source behind it, so it cannot tell\nyou whether an option is cheap or rich versus where it trades -- only what\nVecViz thinks it is worth.\n\nPositive strikes are calls and negative are puts. Both `expiry_days` and\n`strike` snap to the nearest published grid point (six horizons, 36\nstrikes); `resolved` reports what was actually used and `meta.warnings`\nsays when it differed from the request.\n\nAn empty cell means the model publishes no value at that strike and\nhorizon. That is not an error and is not worth retrying.","operationId":"option_fair_value_v1_options__ticker__get","parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","description":"Stock ticker symbol","title":"Ticker"},"description":"Stock ticker symbol"},{"name":"expiry_days","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Snapped to the nearest of 1, 10, 21, 63, 126, 252","title":"Expiry Days"},"description":"Snapped to the nearest of 1, 10, 21, 63, 126, 252"},{"name":"strike","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Absolute strike price","title":"Strike"},"description":"Absolute strike price"},{"name":"strike_pct","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Strike as a fraction from spot, e.g. 0.10 for +10%","title":"Strike Pct"},"description":"Strike as a fraction from spot, e.g. 0.10 for +10%"},{"name":"option_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"call | put","title":"Option Type"},"description":"call | put"},{"name":"as_of","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"As Of"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Option Fair Value V1 Options  Ticker  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/model-review":{"get":{"tags":["reports"],"summary":"Model Review Index","description":"What the daily model review covers, so a section can be chosen by name.\n\nFree -- picking the right section is how an agent avoids pulling the whole\n17,500-token document to answer one question.","operationId":"model_review_index_v1_model_review_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Model Review Index V1 Model Review Get"}}}}}}},"/v1/model-review/{section}":{"get":{"tags":["reports"],"summary":"Model Review Section","description":"One section of the daily model review, as markdown.\n\nCovers realized performance (breakage rates, 99% bound breaks, average\nreturn by cohort, top and bottom movers), the current outlook, and per-variant\nportfolio performance. Every section is prefixed with the report's own\nheader, so the model date is visible whichever one is read.","operationId":"model_review_section_v1_model_review__section__get","parameters":[{"name":"section","in":"path","required":true,"schema":{"type":"string","description":"A section key from /v1/model-review, or 'full'","title":"Section"},"description":"A section key from /v1/model-review, or 'full'"},{"name":"as_of","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Dataset version token","title":"As Of"},"description":"Dataset version token"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Model Review Section V1 Model Review  Section  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/catalog":{"get":{"tags":["catalog"],"summary":"Catalog","description":"Everything you can ask about: tickers, sectors, industries, coverage,\nand the precomputed portfolio variants. Free.\n\nCall this before naming tickers. A symbol that is not in `tickers` will be\nrefused rather than silently dropped, so checking here is how a request\nbecomes exactly priced instead of partially fulfilled.\n\nCoverage is per-dataset and they genuinely differ -- a few names carry PPF\nbands but no VNA row, and vice versa -- so `coverage` reports each\nseparately rather than implying one universe.","operationId":"catalog_v1_catalog_get","parameters":[{"name":"sections","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated subset of tickers,sectors,industries,coverage,portfolios. Omit for all of them.","title":"Sections"},"description":"Comma-separated subset of tickers,sectors,industries,coverage,portfolios. Omit for all of them."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Catalog V1 Catalog Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/methodology/{topic}":{"get":{"tags":["meta"],"summary":"Methodology","description":"What a number means and how it is derived. Free, and safe to quote.\n\nRead this before presenting a VecViz figure to a user; `citation` is a\none-line attribution suitable for reproducing verbatim.","operationId":"methodology_v1_methodology__topic__get","parameters":[{"name":"topic","in":"path","required":true,"schema":{"type":"string","description":"One of: correlations, option_fair_value, portfolio, ppf, sigma, track_record, v_score, var_oar, vecevents, vna, whatif","title":"Topic"},"description":"One of: correlations, option_fair_value, portfolio, ppf, sigma, track_record, v_score, var_oar, vecevents, vna, whatif"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Methodology V1 Methodology  Topic  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/methodology":{"get":{"tags":["meta"],"summary":"Methodology Index","description":"List every methodology topic with its one-line summary.","operationId":"methodology_index_v1_methodology_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Methodology Index V1 Methodology Get"}}}}}}},"/v1/usage":{"get":{"tags":["meta"],"summary":"Usage","description":"Tier, quota consumed, quota remaining, and when the period resets.","operationId":"usage_v1_usage_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Usage V1 Usage Get"}}}}}}},"/v1/feedback":{"post":{"tags":["meta"],"summary":"Report Feedback","description":"Report a wrong number, a confusing response, or a missing capability.","operationId":"report_feedback_v1_feedback_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_report_feedback_v1_feedback_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Report Feedback V1 Feedback Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/skills":{"get":{"tags":["skills"],"summary":"List Skills","description":"Every published skill: slug, title and one-line summary.\n\nDeliberately does NOT return the bodies. They are thousands of tokens each,\nand an agent listing what is available should not have to receive all of it\nto find out.","operationId":"list_skills_v1_skills_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response List Skills V1 Skills Get"}}}}}}},"/v1/skills/{slug}":{"get":{"tags":["skills"],"summary":"Read Skill","description":"One skill, in full, as markdown.\n\nAn unknown slug is a 404 naming what does exist. The alternative -- serving\na default -- would hand an agent a workflow it did not ask for, and it would\nfollow it.","operationId":"read_skill_v1_skills__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","description":"Skill slug, from /v1/skills","title":"Slug"},"description":"Skill slug, from /v1/skills"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Read Skill V1 Skills  Slug  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/connect":{"post":{"tags":["connect"],"summary":"Connect","description":"Mint a free trial key. No email, no signup.\n\nThe key is returned once and is not recoverable: only its sha256 is stored.\nIt is scoped to a ten-ticker demo universe, capped, and expires.","operationId":"connect_connect_post","parameters":[{"name":"origin","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Origin"}},{"name":"user-agent","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User-Agent"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["connect"],"summary":"Connect Get","description":"The same, for a caller that can only issue a GET.\n\n**A GET mints only when it explicitly asks to, via `?mint=1`.** Anything\nelse gets the page.\n\nThis deliberately does NOT sniff the `Accept` header to guess whether the\ncaller is a browser. That test is backwards for exactly the clients it\nwould exist to stop: link unfurlers in Slack, Discord and iMessage follow\nshared URLs with `Accept: */*`, which does not contain `text/html` and so\nreads as \"not a browser\" -- meaning every time someone pasted a /connect\nlink in a chat, a key would be minted and charged to the daily ceiling\nbefore a human ever clicked it. An explicit flag has no such failure mode.","operationId":"connect_get_connect_get","parameters":[{"name":"mint","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mint"}},{"name":"origin","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Origin"}},{"name":"user-agent","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User-Agent"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/healthz":{"get":{"summary":"Healthz","description":"Liveness probe. Returns an envelope so even health is one shape.","operationId":"healthz_healthz_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"Body_portfolio_v1_portfolio_post":{"properties":{"mode":{"type":"string","title":"Mode","default":"analyze"},"weights":{"title":"Weights"},"strategy":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Strategy"},"max_weight":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Max Weight"},"target_vol":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Target Vol"},"top_n":{"type":"integer","title":"Top N","default":25},"as_of":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"As Of"}},"type":"object","title":"Body_portfolio_v1_portfolio_post"},"Body_report_feedback_v1_feedback_post":{"properties":{"message":{"type":"string","maxLength":4000,"minLength":1,"title":"Message"},"tool":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tool"},"ticker":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ticker"}},"type":"object","required":["message"],"title":"Body_report_feedback_v1_feedback_post"},"Body_vecevent_matrix_reviewed_v1_vecevents_reviewed_post":{"properties":{"ticker":{"type":"string","title":"Ticker"},"overrides":{"title":"Overrides"},"new_events":{"title":"New Events"},"vector_sets":{"title":"Vector Sets","default":"auto"},"as_of":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"As Of"}},"type":"object","required":["ticker"],"title":"Body_vecevent_matrix_reviewed_v1_vecevents_reviewed_post"},"Body_vna_new_event_v1_vna_new_event_post":{"properties":{"ticker":{"type":"string","title":"Ticker"},"vecevent":{"type":"string","title":"Vecevent"},"new_bias":{"type":"string","title":"New Bias"},"new_bias_trend":{"type":"string","title":"New Bias Trend","default":"Steady"},"as_of":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"As Of"}},"type":"object","required":["ticker","vecevent","new_bias"],"title":"Body_vna_new_event_v1_vna_new_event_post"},"Body_vna_scenario_v1_vna_scenario_post":{"properties":{"ticker":{"type":"string","title":"Ticker"},"vecevent":{"type":"string","title":"Vecevent"},"new_bias":{"type":"string","title":"New Bias"},"new_bias_trend":{"type":"string","title":"New Bias Trend","default":"Steady"},"as_of":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"As Of"}},"type":"object","required":["ticker","vecevent","new_bias"],"title":"Body_vna_scenario_v1_vna_scenario_post"},"Body_vna_whatif_v1_vna_whatif_post":{"properties":{"ticker":{"type":"string","title":"Ticker"},"vecevent":{"type":"string","title":"Vecevent"},"new_bias":{"type":"string","title":"New Bias"},"new_bias_trend":{"type":"string","title":"New Bias Trend","default":"Steady"},"as_of":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"As Of"}},"type":"object","required":["ticker","vecevent","new_bias"],"title":"Body_vna_whatif_v1_vna_whatif_post"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}}}