{"openapi":"3.1.0","info":{"title":"TickerTrace API","description":"**Free, open API** for institutional ETF activity — daily holdings changes, conviction scores, sector flow, and cross-fund divergences.\n\nTrack what institutional ETF managers are buying and selling. See `/api/v1/funds` and `/api/v1/stats` for the current list of tracked funds and providers.\n\nAI agents: this API is also available as a remote MCP server at `https://api.tickertrace.pro/mcp` (open, read-only), and an agent-oriented overview lives at `/llms.txt`.\n\nPair with [TraderMatrix.Pro](https://www.tradermatrix.pro/?ref=MPHINANCE) if you want a trading agent that uses this data.","version":"2.0.0"},"servers":[{"url":"https://api.tickertrace.pro"}],"paths":{"/health":{"get":{"tags":["public"],"summary":"Health","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/signals":{"get":{"tags":["public"],"summary":"Get Signals","description":"Full signal payload — conviction-scored buys/sells, daily changes,\nsector flow, divergences. Fully open, no API key required.\n\n`category` splits the two fund families: 'active-equity' (ARK, Avantis,\nCorgi, Sprott, Amplify's thematic line) or 'option-income' (YieldMax, Kurv,\nREX, Roundhill, NestYield, NicholasX, Amplify's overlay line). Omit it for\nthe historical all-funds behaviour.\n\nNote that conviction scoring is only meaningful for 'active-equity'. An\noption-income fund's stock book is collateral for its overlay and churns by\ndesign, so its daily deltas are mechanics, not a view on the company.","operationId":"get_signals_api_v1_signals_get","parameters":[{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(active-equity|option-income)$"},{"type":"null"}],"description":"Restrict to one fund category. Omit for all funds.","title":"Category"},"description":"Restrict to one fund category. Omit for all funds."},{"name":"limit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":200,"minimum":1},{"type":"null"}],"description":"Entries per ranked list (signals buying/selling, briefing topBuys/topSells/crossFundConvergence/activeStreaks). Omit for the default top lists (10 signals each side; briefing 3/3/5/10). The order is identical; a larger limit only extends it. Echoed back as `limit` when given, so a client can tell an older server ignored it.","title":"Limit"},"description":"Entries per ranked list (signals buying/selling, briefing topBuys/topSells/crossFundConvergence/activeStreaks). Omit for the default top lists (10 signals each side; briefing 3/3/5/10). The order is identical; a larger limit only extends it. Echoed back as `limit` when given, so a client can tell an older server ignored it."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","properties":{"previousDate":{"type":["string","null"],"description":"Date of the earlier snapshot the deltas in this response are measured against (the prior trading-day file for daily deltas; the ~7 / ~30 calendar-day lookback for weekly / monthly changes). Null with fewer than two snapshots. Not the span of a catch-up fund: its deltas are null (see catchUpSince)."},"comparisonTradingDays":{"type":["integer","null"],"description":"Trading days between previousDate and asOfDate (1 = consecutive sessions; more across a holiday or a missed scrape)."},"signals":{"type":"object","properties":{"buying":{"type":"array","items":{"type":"object","properties":{"fundDetails":{"type":"array","items":{"type":"object","properties":{"aum":{"type":["number","null"],"description":"Fund AUM in billions of US dollars ($B); legacy field; null when AUM is unavailable."},"aumUsd":{"type":["integer","null"],"description":"Fund AUM in whole US dollars; null when AUM is unavailable."}},"additionalProperties":true}}},"additionalProperties":true}},"selling":{"type":"array","items":{"type":"object","properties":{"fundDetails":{"type":"array","items":{"type":"object","properties":{"aum":{"type":["number","null"],"description":"Fund AUM in billions of US dollars ($B); legacy field; null when AUM is unavailable."},"aumUsd":{"type":["integer","null"],"description":"Fund AUM in whole US dollars; null when AUM is unavailable."}},"additionalProperties":true}}},"additionalProperties":true}}},"additionalProperties":true},"changes":{"type":"array","items":{"type":"object","properties":{"positionUsd":{"type":["integer","null"],"description":"Estimated signed position value in whole USD: weight percent × fund AUM / 100. Uses latest fund AUM, including historical entry estimates; null when AUM is unavailable. Option values are premiums, not underlying notional."},"activeFlowUsd":{"type":["integer","null"],"description":"Estimated signed active allocation flow in whole USD: activeWeightDelta percentage points × latest fund AUM / 100. Not actual execution proceeds; null when AUM is unavailable."},"direction":{"type":"string","enum":["buying","selling","unchanged"],"description":"Which way the position was traded, from the split-adjusted share count: a fund whose share count rose is buying, one whose count fell is selling, no share move is unchanged (NEW is buying, REMOVED is selling; the active delta decides only when no share count is usable). Use this for ADD/TRIM labels. It can legitimately disagree with the sign of activeWeightDelta, which nets the trade against the fund's pro-rata flow (a buy smaller than the day's inflow is buying with a slightly negative active tilt). The direction= query filter keys off the activeWeightDelta sign."},"price":{"type":["number","null"],"description":"The fund's own per-share mark on the snapshot date (reported market value / shares): an end-of-day valuation, never an execution price. Null when the issuer reports no market value."}},"additionalProperties":true}},"briefing":{"type":"object","properties":{"topBuys":{"type":"array","items":{"type":"object","properties":{"fundDetails":{"type":"array","items":{"type":"object","properties":{"aum":{"type":["number","null"],"description":"Fund AUM in billions of US dollars ($B); legacy field; null when AUM is unavailable."},"aumUsd":{"type":["integer","null"],"description":"Fund AUM in whole US dollars; null when AUM is unavailable."}},"additionalProperties":true}}},"additionalProperties":true}},"topSells":{"type":"array","items":{"type":"object","properties":{"fundDetails":{"type":"array","items":{"type":"object","properties":{"aum":{"type":["number","null"],"description":"Fund AUM in billions of US dollars ($B); legacy field; null when AUM is unavailable."},"aumUsd":{"type":["integer","null"],"description":"Fund AUM in whole US dollars; null when AUM is unavailable."}},"additionalProperties":true}}},"additionalProperties":true}},"crossFundConvergence":{"type":"array","items":{"type":"object","properties":{"fundDetails":{"type":"array","items":{"type":"object","properties":{"aum":{"type":["number","null"],"description":"Fund AUM in billions of US dollars ($B); legacy field; null when AUM is unavailable."},"aumUsd":{"type":["integer","null"],"description":"Fund AUM in whole US dollars; null when AUM is unavailable."}},"additionalProperties":true}}},"additionalProperties":true}},"notableOptions":{"type":"array","items":{"type":"object","properties":{"record":{"type":"object","properties":{"positionUsd":{"type":["integer","null"],"description":"Estimated signed position value in whole USD: weight percent × fund AUM / 100. Uses latest fund AUM, including historical entry estimates; null when AUM is unavailable. Option values are premiums, not underlying notional."},"activeFlowUsd":{"type":["integer","null"],"description":"Estimated signed active allocation flow in whole USD: activeWeightDelta percentage points × latest fund AUM / 100. Not actual execution proceeds; null when AUM is unavailable."},"direction":{"type":"string","enum":["buying","selling","unchanged"],"description":"Which way the position was traded, from the split-adjusted share count: a fund whose share count rose is buying, one whose count fell is selling, no share move is unchanged (NEW is buying, REMOVED is selling; the active delta decides only when no share count is usable). Use this for ADD/TRIM labels. It can legitimately disagree with the sign of activeWeightDelta, which nets the trade against the fund's pro-rata flow (a buy smaller than the day's inflow is buying with a slightly negative active tilt). The direction= query filter keys off the activeWeightDelta sign."},"price":{"type":["number","null"],"description":"The fund's own per-share mark on the snapshot date (reported market value / shares): an end-of-day valuation, never an execution price. Null when the issuer reports no market value."}},"additionalProperties":true}},"additionalProperties":true}}},"additionalProperties":true},"activity":{"type":"object","properties":{"accumulating":{"type":"array","items":{"type":"object","properties":{"positionUsd":{"type":["integer","null"],"description":"Estimated signed position value in whole USD: weight percent × fund AUM / 100. Uses latest fund AUM, including historical entry estimates; null when AUM is unavailable. Option values are premiums, not underlying notional."},"activeFlowUsd":{"type":["integer","null"],"description":"Estimated signed active allocation flow in whole USD: activeWeightDelta percentage points × latest fund AUM / 100. Not actual execution proceeds; null when AUM is unavailable."},"direction":{"type":"string","enum":["buying","selling","unchanged"],"description":"Which way the position was traded, from the split-adjusted share count: a fund whose share count rose is buying, one whose count fell is selling, no share move is unchanged (NEW is buying, REMOVED is selling; the active delta decides only when no share count is usable). Use this for ADD/TRIM labels. It can legitimately disagree with the sign of activeWeightDelta, which nets the trade against the fund's pro-rata flow (a buy smaller than the day's inflow is buying with a slightly negative active tilt). The direction= query filter keys off the activeWeightDelta sign."},"price":{"type":["number","null"],"description":"The fund's own per-share mark on the snapshot date (reported market value / shares): an end-of-day valuation, never an execution price. Null when the issuer reports no market value."}},"additionalProperties":true}},"reducing":{"type":"array","items":{"type":"object","properties":{"positionUsd":{"type":["integer","null"],"description":"Estimated signed position value in whole USD: weight percent × fund AUM / 100. Uses latest fund AUM, including historical entry estimates; null when AUM is unavailable. Option values are premiums, not underlying notional."},"activeFlowUsd":{"type":["integer","null"],"description":"Estimated signed active allocation flow in whole USD: activeWeightDelta percentage points × latest fund AUM / 100. Not actual execution proceeds; null when AUM is unavailable."},"direction":{"type":"string","enum":["buying","selling","unchanged"],"description":"Which way the position was traded, from the split-adjusted share count: a fund whose share count rose is buying, one whose count fell is selling, no share move is unchanged (NEW is buying, REMOVED is selling; the active delta decides only when no share count is usable). Use this for ADD/TRIM labels. It can legitimately disagree with the sign of activeWeightDelta, which nets the trade against the fund's pro-rata flow (a buy smaller than the day's inflow is buying with a slightly negative active tilt). The direction= query filter keys off the activeWeightDelta sign."},"price":{"type":["number","null"],"description":"The fund's own per-share mark on the snapshot date (reported market value / shares): an end-of-day valuation, never an execution price. Null when the issuer reports no market value."}},"additionalProperties":true}},"optionsActivity":{"type":"array","items":{"type":"object","properties":{"positionUsd":{"type":["integer","null"],"description":"Estimated signed position value in whole USD: weight percent × fund AUM / 100. Uses latest fund AUM, including historical entry estimates; null when AUM is unavailable. Option values are premiums, not underlying notional."},"activeFlowUsd":{"type":["integer","null"],"description":"Estimated signed active allocation flow in whole USD: activeWeightDelta percentage points × latest fund AUM / 100. Not actual execution proceeds; null when AUM is unavailable."},"direction":{"type":"string","enum":["buying","selling","unchanged"],"description":"Which way the position was traded, from the split-adjusted share count: a fund whose share count rose is buying, one whose count fell is selling, no share move is unchanged (NEW is buying, REMOVED is selling; the active delta decides only when no share count is usable). Use this for ADD/TRIM labels. It can legitimately disagree with the sign of activeWeightDelta, which nets the trade against the fund's pro-rata flow (a buy smaller than the day's inflow is buying with a slightly negative active tilt). The direction= query filter keys off the activeWeightDelta sign."},"price":{"type":["number","null"],"description":"The fund's own per-share mark on the snapshot date (reported market value / shares): an end-of-day valuation, never an execution price. Null when the issuer reports no market value."}},"additionalProperties":true}}},"additionalProperties":true}},"additionalProperties":true}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stats":{"get":{"tags":["public"],"summary":"Get Stats","description":"Global stats — funds tracked, unique underlyings, options counts.","operationId":"get_stats_api_v1_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/sectors":{"get":{"tags":["public"],"summary":"Get Sectors","description":"Sector-level inflows / outflows.","operationId":"get_sectors_api_v1_sectors_get","parameters":[{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(active-equity|option-income)$"},{"type":"null"}],"description":"Restrict to one fund category. Omit for all funds.","title":"Category"},"description":"Restrict to one fund category. Omit for all funds."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/changes":{"get":{"tags":["public"],"summary":"Get Changes","description":"Guarded equity position changes, with opt-in uncapped pagination/export.\n\nWithout page/size, legacy limit=50 (max 5000) and response shape/order stay\nunchanged. Supply page or size for stable magnitude/fund/ticker/type ordering\nand total/page/size/pages/snapshot metadata. Pass snapshot on later pages:\n409 means the input snapshots changed; restart at page 1. format=csv exports\nevery filtered row, ignoring limit/page/size. Weekly/monthly compare ~7/~30\ncalendar days; carried/catch-up funds follow the same existing guards.","operationId":"get_changes_api_v1_changes_get","parameters":[{"name":"provider","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider"}},{"name":"fund","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fund"}},{"name":"direction","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Direction"}},{"name":"period","in":"query","required":false,"schema":{"type":"string","pattern":"^(daily|weekly|monthly)$","default":"daily","title":"Period"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":5000,"minimum":1,"default":50,"title":"Limit"}},{"name":"page","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"description":"Opt into uncapped pagination; 1-based. Default page 1 when size is provided.","title":"Page"},"description":"Opt into uncapped pagination; 1-based. Default page 1 when size is provided."},{"name":"size","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":2000,"minimum":1},{"type":"null"}],"description":"Rows per page, max 2000. Opts into paging; default 2000 when page is provided. Overrides legacy limit.","title":"Size"},"description":"Rows per page, max 2000. Opts into paging; default 2000 when page is provided. Overrides legacy limit."},{"name":"snapshot","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"description":"Token from page 1; later pages return 409 if the snapshot changed.","title":"Snapshot"},"description":"Token from page 1; later pages return 409 if the snapshot changed."},{"name":"sector","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Exact sector filter, applied before paging/export.","title":"Sector"},"description":"Exact sector filter, applied before paging/export."},{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"description":"Case-insensitive ticker/company/fund search.","title":"Q"},"description":"Case-insensitive ticker/company/fund search."},{"name":"type","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(NEW|REMOVED|CHANGED)$"},{"type":"null"}],"description":"Raw change type; REMOVED is EXIT in the app. Direction uses active delta, not this raw type.","title":"Type"},"description":"Raw change type; REMOVED is EXIT in the app. Direction uses active delta, not this raw type."},{"name":"format","in":"query","required":false,"schema":{"type":"string","pattern":"^(json|csv)$","description":"csv exports all filtered rows, ignoring limit/page/size; JSON is the default.","default":"json","title":"Format"},"description":"csv exports all filtered rows, ignoring limit/page/size; JSON is the default."},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(active-equity|option-income)$"},{"type":"null"}],"description":"Restrict to one fund category. Omit for all funds.","title":"Category"},"description":"Restrict to one fund category. Omit for all funds."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","properties":{"changes":{"type":"array","items":{"type":"object","properties":{"positionUsd":{"type":["integer","null"],"description":"Estimated signed position value in whole USD: weight percent × fund AUM / 100. Uses latest fund AUM, including historical entry estimates; null when AUM is unavailable. Option values are premiums, not underlying notional."},"activeFlowUsd":{"type":["integer","null"],"description":"Estimated signed active allocation flow in whole USD: activeWeightDelta percentage points × latest fund AUM / 100. Not actual execution proceeds; null when AUM is unavailable."},"direction":{"type":"string","enum":["buying","selling","unchanged"],"description":"Which way the position was traded, from the split-adjusted share count: a fund whose share count rose is buying, one whose count fell is selling, no share move is unchanged (NEW is buying, REMOVED is selling; the active delta decides only when no share count is usable). Use this for ADD/TRIM labels. It can legitimately disagree with the sign of activeWeightDelta, which nets the trade against the fund's pro-rata flow (a buy smaller than the day's inflow is buying with a slightly negative active tilt). The direction= query filter keys off the activeWeightDelta sign."},"price":{"type":["number","null"],"description":"The fund's own per-share mark on the snapshot date (reported market value / shares): an end-of-day valuation, never an execution price. Null when the issuer reports no market value."}},"additionalProperties":true}},"previousDate":{"type":["string","null"],"description":"Date of the earlier snapshot the deltas in this response are measured against (the prior trading-day file for daily deltas; the ~7 / ~30 calendar-day lookback for weekly / monthly changes). Null with fewer than two snapshots. Not the span of a catch-up fund: its deltas are null (see catchUpSince)."},"comparisonTradingDays":{"type":["integer","null"],"description":"Trading days between previousDate and asOfDate (1 = consecutive sessions; more across a holiday or a missed scrape)."},"total":{"type":"integer","description":"All rows matching filters, before paging. Present only with page/size."},"page":{"type":"integer","description":"1-based page; present only with page/size."},"size":{"type":"integer","description":"Page size (1–2000); present only with page/size."},"pages":{"type":"integer","description":"Total pages; 0 for an empty filtered universe."},"snapshot":{"type":"string","description":"Opaque comparison-window snapshot token. Pass on later pages; 409 means restart at page 1."}},"additionalProperties":true}},"text/csv":{"schema":{"type":"string","description":"format=csv: uncapped filtered export; unknown values are blank."}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"409":{"description":"Snapshot token no longer matches. Restart at page 1."},"503":{"description":"Snapshot changed repeatedly during computation. Retry."}}}},"/api/v1/institutional":{"get":{"tags":["public"],"summary":"Get Institutional","description":"Institutions-as-a-whole flow over a daily/weekly/monthly window.\n\nBlends every stock-picking fund (pure option-income funds excluded) into\none AUM-weighted portfolio and reports which tickers that combined book is\nnet buying and net selling. The 'combined average weight' view — what\ninstitutions in aggregate are accumulating or trimming.","operationId":"get_institutional_api_v1_institutional_get","parameters":[{"name":"period","in":"query","required":false,"schema":{"type":"string","pattern":"^(daily|weekly|monthly)$","default":"daily","title":"Period"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/institutional-trend":{"get":{"tags":["public"],"summary":"Get Institutional Trend","description":"Per-ticker institutional flow across day/week/month at once.\n\nEach ticker carries its blended-weight change over all three horizons\n(one fixed denominator, so they're directly comparable and overlayable)\nplus an accumulation/distribution signal. Ranked by the monthly move.\nPowers the trend-overlay visual: sustained buying vs. the moment selling\nstarts.","operationId":"get_institutional_trend_api_v1_institutional_trend_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":15,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/fund/{fund}":{"get":{"tags":["public"],"summary":"Get Fund","description":"Fund holdings detail — top holdings, options count, AUM.","operationId":"get_fund_api_v1_fund__fund__get","parameters":[{"name":"fund","in":"path","required":true,"schema":{"type":"string","title":"Fund"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","properties":{"previousDate":{"type":["string","null"],"description":"Date of the earlier snapshot the deltas in this response are measured against (the prior trading-day file for daily deltas; the ~7 / ~30 calendar-day lookback for weekly / monthly changes). Null with fewer than two snapshots. Not the span of a catch-up fund: its deltas are null (see catchUpSince)."},"comparisonTradingDays":{"type":["integer","null"],"description":"Trading days between previousDate and asOfDate (1 = consecutive sessions; more across a holiday or a missed scrape)."},"aum":{"type":["number","null"],"description":"Fund AUM in billions of US dollars ($B); legacy field; null when AUM is unavailable."},"aumUsd":{"type":["integer","null"],"description":"Fund AUM in whole US dollars; null when AUM is unavailable."},"topHoldings":{"type":"array","items":{"type":"object","properties":{"positionUsd":{"type":["integer","null"],"description":"Estimated signed position value in whole USD: weight percent × fund AUM / 100. Uses latest fund AUM, including historical entry estimates; null when AUM is unavailable. Option values are premiums, not underlying notional."}},"additionalProperties":true}},"optionHoldings":{"type":"array","items":{"type":"object","properties":{"positionUsd":{"type":["integer","null"],"description":"Estimated signed position value in whole USD: weight percent × fund AUM / 100. Uses latest fund AUM, including historical entry estimates; null when AUM is unavailable. Option values are premiums, not underlying notional."}},"additionalProperties":true}},"recentChanges":{"type":"array","items":{"type":"object","properties":{"positionUsd":{"type":["integer","null"],"description":"Estimated signed position value in whole USD: weight percent × fund AUM / 100. Uses latest fund AUM, including historical entry estimates; null when AUM is unavailable. Option values are premiums, not underlying notional."},"activeFlowUsd":{"type":["integer","null"],"description":"Estimated signed active allocation flow in whole USD: activeWeightDelta percentage points × latest fund AUM / 100. Not actual execution proceeds; null when AUM is unavailable."},"direction":{"type":"string","enum":["buying","selling","unchanged"],"description":"Which way the position was traded, from the split-adjusted share count: a fund whose share count rose is buying, one whose count fell is selling, no share move is unchanged (NEW is buying, REMOVED is selling; the active delta decides only when no share count is usable). Use this for ADD/TRIM labels. It can legitimately disagree with the sign of activeWeightDelta, which nets the trade against the fund's pro-rata flow (a buy smaller than the day's inflow is buying with a slightly negative active tilt). The direction= query filter keys off the activeWeightDelta sign."},"price":{"type":["number","null"],"description":"The fund's own per-share mark on the snapshot date (reported market value / shares): an end-of-day valuation, never an execution price. Null when the issuer reports no market value."}},"additionalProperties":true}}},"additionalProperties":true}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/fund-effectiveness":{"get":{"tags":["public"],"summary":"Get All Fund Effectiveness","description":"Compare all option-income funds side-by-side. Returns effectiveness\nanalysis for every fund with options data, sorted by composite score.","operationId":"get_all_fund_effectiveness_api_v1_fund_effectiveness_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/fund-effectiveness/{fund}":{"get":{"tags":["public"],"summary":"Get Fund Effectiveness","description":"Fund effectiveness analysis — option-income strategy execution.","operationId":"get_fund_effectiveness_api_v1_fund_effectiveness__fund__get","parameters":[{"name":"fund","in":"path","required":true,"schema":{"type":"string","title":"Fund"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ticker/{ticker}":{"get":{"tags":["public"],"summary":"Get Ticker","description":"Cross-fund ticker detail — who's buying/selling this?","operationId":"get_ticker_api_v1_ticker__ticker__get","parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","title":"Ticker"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","properties":{"previousDate":{"type":["string","null"],"description":"Date of the earlier snapshot the deltas in this response are measured against (the prior trading-day file for daily deltas; the ~7 / ~30 calendar-day lookback for weekly / monthly changes). Null with fewer than two snapshots. Not the span of a catch-up fund: its deltas are null (see catchUpSince)."},"comparisonTradingDays":{"type":["integer","null"],"description":"Trading days between previousDate and asOfDate (1 = consecutive sessions; more across a holiday or a missed scrape)."},"holdings":{"type":"array","items":{"type":"object","properties":{"aum":{"type":["number","null"],"description":"Fund AUM in billions of US dollars ($B); legacy field; null when AUM is unavailable."},"aumUsd":{"type":["integer","null"],"description":"Fund AUM in whole US dollars; null when AUM is unavailable."},"positionUsd":{"type":["integer","null"],"description":"Estimated signed position value in whole USD: weight percent × fund AUM / 100. Uses latest fund AUM, including historical entry estimates; null when AUM is unavailable. Option values are premiums, not underlying notional."}},"additionalProperties":true}},"changes":{"type":"array","items":{"type":"object","properties":{"positionUsd":{"type":["integer","null"],"description":"Estimated signed position value in whole USD: weight percent × fund AUM / 100. Uses latest fund AUM, including historical entry estimates; null when AUM is unavailable. Option values are premiums, not underlying notional."},"activeFlowUsd":{"type":["integer","null"],"description":"Estimated signed active allocation flow in whole USD: activeWeightDelta percentage points × latest fund AUM / 100. Not actual execution proceeds; null when AUM is unavailable."},"direction":{"type":"string","enum":["buying","selling","unchanged"],"description":"Which way the position was traded, from the split-adjusted share count: a fund whose share count rose is buying, one whose count fell is selling, no share move is unchanged (NEW is buying, REMOVED is selling; the active delta decides only when no share count is usable). Use this for ADD/TRIM labels. It can legitimately disagree with the sign of activeWeightDelta, which nets the trade against the fund's pro-rata flow (a buy smaller than the day's inflow is buying with a slightly negative active tilt). The direction= query filter keys off the activeWeightDelta sign."},"price":{"type":["number","null"],"description":"The fund's own per-share mark on the snapshot date (reported market value / shares): an end-of-day valuation, never an execution price. Null when the issuer reports no market value."}},"additionalProperties":true}}},"additionalProperties":true}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stock/{ticker}":{"get":{"tags":["public"],"summary":"Get Stock","description":"Per-stock page payload — holders + the institutional A/D trend & history.","operationId":"get_stock_api_v1_stock__ticker__get","parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","title":"Ticker"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","properties":{"holdings":{"type":"array","items":{"type":"object","properties":{"aum":{"type":["number","null"],"description":"Fund AUM in billions of US dollars ($B); legacy field; null when AUM is unavailable."},"aumUsd":{"type":["integer","null"],"description":"Fund AUM in whole US dollars; null when AUM is unavailable."},"positionUsd":{"type":["integer","null"],"description":"Estimated signed position value in whole USD: weight percent × fund AUM / 100. Uses latest fund AUM, including historical entry estimates; null when AUM is unavailable. Option values are premiums, not underlying notional."}},"additionalProperties":true}}},"additionalProperties":true}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/divergences":{"get":{"tags":["public"],"summary":"Get Divergences","description":"Cross-fund divergences — same ticker, opposite directions.\n\nEach entry carries `crossCategory`: true when the buying and selling sides\nare different fund families. Those are not real disagreements — one manager\nmade a call on the company, the other needed something to write contracts\nagainst — so they sort last. Pass category='active-equity' to drop them.","operationId":"get_divergences_api_v1_divergences_get","parameters":[{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(active-equity|option-income)$"},{"type":"null"}],"description":"Restrict to one fund category. Omit for all funds.","title":"Category"},"description":"Restrict to one fund category. Omit for all funds."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/layering-patterns":{"get":{"tags":["public"],"summary":"Get Layering Patterns","description":"Cross-fund layering — 3+ stock-pickers opening the SAME new position in days.\n\nSurfaces tickers where multiple institutional funds independently entered a\nbrand-new position within `window_days` trading days, ranked by a conviction\nscore that favors cross-family agreement. The entry *sequence* (who moved\nfirst) is the part only daily data can show.","operationId":"get_layering_patterns_api_v1_layering_patterns_get","parameters":[{"name":"window_days","in":"query","required":false,"schema":{"type":"integer","maximum":30,"minimum":2,"default":7,"title":"Window Days"}},{"name":"min_funds","in":"query","required":false,"schema":{"type":"integer","maximum":10,"minimum":2,"default":3,"title":"Min Funds"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","properties":{"patterns":{"type":"array","items":{"type":"object","properties":{"consensusAum":{"type":["number","null"],"description":"Combined participating fund AUM in billions of USD, rounded to three decimals; not capital invested in this ticker; null if any AUM is unknown."},"consensusAumUsd":{"type":["integer","null"],"description":"Combined participating fund AUM in whole USD (sum of unrounded individual AUM); null if any AUM is unknown."},"positionUsdTotal":{"type":["integer","null"],"description":"Estimated total entry-position value in whole USD: sum of entry weights × latest respective fund AUM / 100. Null if any AUM is unknown."},"entrySequence":{"type":"array","items":{"type":"object","properties":{"aum":{"type":["number","null"],"description":"Fund AUM in billions of US dollars ($B); legacy field; null when AUM is unavailable."},"aumUsd":{"type":["integer","null"],"description":"Fund AUM in whole US dollars; null when AUM is unavailable."},"positionUsd":{"type":["integer","null"],"description":"Estimated signed position value in whole USD: weight percent × fund AUM / 100. Uses latest fund AUM, including historical entry estimates; null when AUM is unavailable. Option values are premiums, not underlying notional."}},"additionalProperties":true}}},"additionalProperties":true}}},"additionalProperties":true}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/briefing":{"get":{"tags":["public"],"summary":"Get Briefing","description":"Pre-market briefing — top buys, top sells, multi-provider convergence,\nactive streaks, and notable new option positions.","operationId":"get_briefing_api_v1_briefing_get","parameters":[{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(active-equity|option-income)$"},{"type":"null"}],"description":"Restrict to one fund category before scoring. Omit for all funds; active-equity is recommended for stock conviction.","title":"Category"},"description":"Restrict to one fund category before scoring. Omit for all funds; active-equity is recommended for stock conviction."},{"name":"limit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":200,"minimum":1},{"type":"null"}],"description":"Entries per list (topBuys, topSells, crossFundConvergence, activeStreaks). Omit for 3 / 3 / 5 / 10. Same order; a larger limit only extends it.","title":"Limit"},"description":"Entries per list (topBuys, topSells, crossFundConvergence, activeStreaks). Omit for 3 / 3 / 5 / 10. Same order; a larger limit only extends it."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","properties":{"topBuys":{"type":"array","items":{"type":"object","properties":{"fundDetails":{"type":"array","items":{"type":"object","properties":{"aum":{"type":["number","null"],"description":"Fund AUM in billions of US dollars ($B); legacy field; null when AUM is unavailable."},"aumUsd":{"type":["integer","null"],"description":"Fund AUM in whole US dollars; null when AUM is unavailable."}},"additionalProperties":true}}},"additionalProperties":true}},"topSells":{"type":"array","items":{"type":"object","properties":{"fundDetails":{"type":"array","items":{"type":"object","properties":{"aum":{"type":["number","null"],"description":"Fund AUM in billions of US dollars ($B); legacy field; null when AUM is unavailable."},"aumUsd":{"type":["integer","null"],"description":"Fund AUM in whole US dollars; null when AUM is unavailable."}},"additionalProperties":true}}},"additionalProperties":true}},"crossFundConvergence":{"type":"array","items":{"type":"object","properties":{"fundDetails":{"type":"array","items":{"type":"object","properties":{"aum":{"type":["number","null"],"description":"Fund AUM in billions of US dollars ($B); legacy field; null when AUM is unavailable."},"aumUsd":{"type":["integer","null"],"description":"Fund AUM in whole US dollars; null when AUM is unavailable."}},"additionalProperties":true}}},"additionalProperties":true}},"notableOptions":{"type":"array","items":{"type":"object","properties":{"record":{"type":"object","properties":{"positionUsd":{"type":["integer","null"],"description":"Estimated signed position value in whole USD: weight percent × fund AUM / 100. Uses latest fund AUM, including historical entry estimates; null when AUM is unavailable. Option values are premiums, not underlying notional."},"activeFlowUsd":{"type":["integer","null"],"description":"Estimated signed active allocation flow in whole USD: activeWeightDelta percentage points × latest fund AUM / 100. Not actual execution proceeds; null when AUM is unavailable."},"direction":{"type":"string","enum":["buying","selling","unchanged"],"description":"Which way the position was traded, from the split-adjusted share count: a fund whose share count rose is buying, one whose count fell is selling, no share move is unchanged (NEW is buying, REMOVED is selling; the active delta decides only when no share count is usable). Use this for ADD/TRIM labels. It can legitimately disagree with the sign of activeWeightDelta, which nets the trade against the fund's pro-rata flow (a buy smaller than the day's inflow is buying with a slightly negative active tilt). The direction= query filter keys off the activeWeightDelta sign."},"price":{"type":["number","null"],"description":"The fund's own per-share mark on the snapshot date (reported market value / shares): an end-of-day valuation, never an execution price. Null when the issuer reports no market value."}},"additionalProperties":true}},"additionalProperties":true}}},"additionalProperties":true}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/activity":{"get":{"tags":["public"],"summary":"Get Activity","description":"Bucket changes into accumulating, reducing, and optionsActivity over a\ndaily, weekly (~7d) or monthly (~30d) window. Includes option records\nwith decoded details.","operationId":"get_activity_api_v1_activity_get","parameters":[{"name":"period","in":"query","required":false,"schema":{"type":"string","pattern":"^(daily|weekly|monthly)$","default":"daily","title":"Period"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","properties":{"accumulating":{"type":"array","items":{"type":"object","properties":{"positionUsd":{"type":["integer","null"],"description":"Estimated signed position value in whole USD: weight percent × fund AUM / 100. Uses latest fund AUM, including historical entry estimates; null when AUM is unavailable. Option values are premiums, not underlying notional."},"activeFlowUsd":{"type":["integer","null"],"description":"Estimated signed active allocation flow in whole USD: activeWeightDelta percentage points × latest fund AUM / 100. Not actual execution proceeds; null when AUM is unavailable."},"direction":{"type":"string","enum":["buying","selling","unchanged"],"description":"Which way the position was traded, from the split-adjusted share count: a fund whose share count rose is buying, one whose count fell is selling, no share move is unchanged (NEW is buying, REMOVED is selling; the active delta decides only when no share count is usable). Use this for ADD/TRIM labels. It can legitimately disagree with the sign of activeWeightDelta, which nets the trade against the fund's pro-rata flow (a buy smaller than the day's inflow is buying with a slightly negative active tilt). The direction= query filter keys off the activeWeightDelta sign."},"price":{"type":["number","null"],"description":"The fund's own per-share mark on the snapshot date (reported market value / shares): an end-of-day valuation, never an execution price. Null when the issuer reports no market value."}},"additionalProperties":true}},"reducing":{"type":"array","items":{"type":"object","properties":{"positionUsd":{"type":["integer","null"],"description":"Estimated signed position value in whole USD: weight percent × fund AUM / 100. Uses latest fund AUM, including historical entry estimates; null when AUM is unavailable. Option values are premiums, not underlying notional."},"activeFlowUsd":{"type":["integer","null"],"description":"Estimated signed active allocation flow in whole USD: activeWeightDelta percentage points × latest fund AUM / 100. Not actual execution proceeds; null when AUM is unavailable."},"direction":{"type":"string","enum":["buying","selling","unchanged"],"description":"Which way the position was traded, from the split-adjusted share count: a fund whose share count rose is buying, one whose count fell is selling, no share move is unchanged (NEW is buying, REMOVED is selling; the active delta decides only when no share count is usable). Use this for ADD/TRIM labels. It can legitimately disagree with the sign of activeWeightDelta, which nets the trade against the fund's pro-rata flow (a buy smaller than the day's inflow is buying with a slightly negative active tilt). The direction= query filter keys off the activeWeightDelta sign."},"price":{"type":["number","null"],"description":"The fund's own per-share mark on the snapshot date (reported market value / shares): an end-of-day valuation, never an execution price. Null when the issuer reports no market value."}},"additionalProperties":true}},"optionsActivity":{"type":"array","items":{"type":"object","properties":{"positionUsd":{"type":["integer","null"],"description":"Estimated signed position value in whole USD: weight percent × fund AUM / 100. Uses latest fund AUM, including historical entry estimates; null when AUM is unavailable. Option values are premiums, not underlying notional."},"activeFlowUsd":{"type":["integer","null"],"description":"Estimated signed active allocation flow in whole USD: activeWeightDelta percentage points × latest fund AUM / 100. Not actual execution proceeds; null when AUM is unavailable."},"direction":{"type":"string","enum":["buying","selling","unchanged"],"description":"Which way the position was traded, from the split-adjusted share count: a fund whose share count rose is buying, one whose count fell is selling, no share move is unchanged (NEW is buying, REMOVED is selling; the active delta decides only when no share count is usable). Use this for ADD/TRIM labels. It can legitimately disagree with the sign of activeWeightDelta, which nets the trade against the fund's pro-rata flow (a buy smaller than the day's inflow is buying with a slightly negative active tilt). The direction= query filter keys off the activeWeightDelta sign."},"price":{"type":["number","null"],"description":"The fund's own per-share mark on the snapshot date (reported market value / shares): an end-of-day valuation, never an execution price. Null when the issuer reports no market value."}},"additionalProperties":true}}},"additionalProperties":true}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/holdings":{"get":{"tags":["public"],"summary":"Get All Holdings","description":"Every latest holding row across every tracked fund (equities, options, cash,\ntreasuries, swaps), with today's raw `weightDelta` / `sharesDelta`, the\ndrift-adjusted `activeWeightDelta` (the website's Δ Weight; null for a fund\ncatching up from stale data), the snapshot `dte`, and an `assetClass`.\n\nWith no query parameters this is the full unpaginated book (backward\ncompatible, ~20k rows). Use `fund`/`asset`/`q`/`sort` and `page`/`size` to\npage it, or `format=csv` for an uncapped export. `total` is the filtered\nrow count; `count` is the rows in this response. Heavy — 30/minute.","operationId":"get_all_holdings_api_v1_holdings_get","parameters":[{"name":"fund","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Restrict to ONE fund's full book (stocks, option legs, Treasuries, cash); case-insensitive, 422 on a malformed ticker. Omit for every fund.","title":"Fund"},"description":"Restrict to ONE fund's full book (stocks, option legs, Treasuries, cash); case-insensitive, 422 on a malformed ticker. Omit for every fund."},{"name":"asset","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(equity|option|cash|treasury|swap|other)$"},{"type":"null"}],"description":"Restrict to one asset class (`assetClass` on each row).","title":"Asset"},"description":"Restrict to one asset class (`assetClass` on each row)."},{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"description":"Case-insensitive substring of ticker, name or option underlying.","title":"Q"},"description":"Case-insensitive substring of ticker, name or option underlying."},{"name":"sort","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(value|weight|delta|absdelta|expiry)$"},{"type":"null"}],"description":"value = marketValue, weight, delta = activeWeightDelta (signed), absdelta = its magnitude, expiry = option expiry. Rows with no value always sort last. Omit for the natural file order.","title":"Sort"},"description":"value = marketValue, weight, delta = activeWeightDelta (signed), absdelta = its magnitude, expiry = option expiry. Rows with no value always sort last. Omit for the natural file order."},{"name":"dir","in":"query","required":false,"schema":{"type":"string","pattern":"^(asc|desc)$","default":"desc","title":"Dir"}},{"name":"page","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"description":"1-based page. Giving `page` or `size` switches on pagination; omit both for the full (filtered) list.","title":"Page"},"description":"1-based page. Giving `page` or `size` switches on pagination; omit both for the full (filtered) list."},{"name":"size","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":500,"minimum":1},{"type":"null"}],"description":"Rows per page (default 100 once paginating, max 500).","title":"Size"},"description":"Rows per page (default 100 once paginating, max 500)."},{"name":"format","in":"query","required":false,"schema":{"type":"string","pattern":"^(json|csv)$","description":"csv streams the whole filtered set (uncapped export; ignores page/size).","default":"json","title":"Format"},"description":"csv streams the whole filtered set (uncapped export; ignores page/size)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","properties":{"previousDate":{"type":["string","null"],"description":"Date of the earlier snapshot the deltas in this response are measured against (the prior trading-day file for daily deltas; the ~7 / ~30 calendar-day lookback for weekly / monthly changes). Null with fewer than two snapshots. Not the span of a catch-up fund: its deltas are null (see catchUpSince)."},"comparisonTradingDays":{"type":["integer","null"],"description":"Trading days between previousDate and asOfDate (1 = consecutive sessions; more across a holiday or a missed scrape)."},"total":{"type":"integer","description":"Rows matching the filters (before paging)."},"page":{"type":"integer"},"size":{"type":"integer"},"pages":{"type":"integer"},"holdings":{"type":"array","items":{"type":"object","properties":{"positionUsd":{"type":["integer","null"],"description":"Estimated signed position value in whole USD: weight percent × fund AUM / 100. Uses latest fund AUM, including historical entry estimates; null when AUM is unavailable. Option values are premiums, not underlying notional."},"weightDelta":{"type":["number","null"],"description":"Raw day-over-day weight change in percentage points (includes price drift). Null for a catch-up fund."},"sharesDelta":{"type":["number","null"],"description":"Day-over-day share change. Null for a catch-up fund."},"activeWeightDelta":{"type":["number","null"],"description":"Drift-adjusted weight change (percentage points): the manager-attributable move, equal to the website Δ Weight. 0 when unchanged; null for a catch-up fund (see catchUpSince)."},"catchUpSince":{"type":"string","description":"Present on a catch-up fund: its daily deltas are withheld (null) because they would span a stale gap since this date."},"assetClass":{"type":"string","enum":["equity","option","cash","treasury","swap","other"]},"dte":{"type":["number","null"],"description":"Days to expiry as written in the issuer snapshot (options only; null otherwise). Not recomputed from today."}},"additionalProperties":true}}},"additionalProperties":true}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/fund/{fund}/rotation":{"get":{"tags":["public"],"summary":"Get Fund Rotation","description":"Allocation-rotation report for funds that publish one (currently ULTI and\nULTY): holdings grouped by theme/sector over time, weekly drift, churn since\nthe prior snapshot and unmapped names. Served exactly as the nightly job\nwrites it, plus `stale` and `snapshotAsOfDate`. 404 for any other fund.","operationId":"get_fund_rotation_api_v1_fund__fund__rotation_get","parameters":[{"name":"fund","in":"path","required":true,"schema":{"type":"string","title":"Fund"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/options-listings/schedule":{"get":{"tags":["public"],"summary":"Get Options Listings Schedule","description":"The \"MWF Elite\" 0DTE schedule: the 12 symbols approved for Monday / Wednesday\n/ Friday weekly expirations (excluding SPY and QQQ), whether today (ET) is an\nexpiration day, and the next one — NYSE holidays skipped. The website's\noptions-listings box uses the same rules.","operationId":"get_options_listings_schedule_api_v1_options_listings_schedule_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/funds":{"get":{"tags":["public"],"summary":"List Funds","description":"List all tracked funds, enriched with holdings counts and top holding.\n\nBackward-compatible superset of the old shape (fund/provider/category/aum\nare still present) — now also holdingsCount, optionsCount, topHolding.\nPowers the /funds index page.","operationId":"list_funds_api_v1_funds_get","parameters":[{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(active-equity|option-income)$"},{"type":"null"}],"description":"Restrict to one fund category. Omit for all funds.","title":"Category"},"description":"Restrict to one fund category. Omit for all funds."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","properties":{"funds":{"type":"array","items":{"type":"object","properties":{"aum":{"type":["number","null"],"description":"Fund AUM in billions of US dollars ($B); legacy field; null when AUM is unavailable."},"aumUsd":{"type":["integer","null"],"description":"Fund AUM in whole US dollars; null when AUM is unavailable."}},"additionalProperties":true}}},"additionalProperties":true}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/income":{"get":{"tags":["public"],"summary":"Income Overview","description":"Every option-income fund, classified by structure.\n\n\"Income ETF\" is not one thing. These funds fall into five structurally\ndifferent shapes and a view that renders them identically misrepresents\nfour of them:\n\n  covered-call  owns the stocks, writes calls against them\n  synthetic     no shares at all — Treasuries plus a replicating structure\n  leap-proxy    long-dated index calls; the income leg is written and\n                expires intraday, so it is ABSENT from end-of-day holdings\n  swap          total-return swap, no option rows\n  short-equity  short stock positions\n\nEach fund carries the six coverage tiles (call coverage, weighted\nmoneyness, weighted DTE, upside room, capped names, collateral mix). Any\ntile that cannot be computed from the current data is null rather than 0 —\nUnderlying_Price is genuinely absent for several funds.","operationId":"income_overview_api_v1_income_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","properties":{"funds":{"type":"array","items":{"type":"object","properties":{"aum":{"type":["number","null"],"description":"Fund AUM in billions of US dollars ($B); legacy field; null when AUM is unavailable."},"aumUsd":{"type":["integer","null"],"description":"Fund AUM in whole US dollars; null when AUM is unavailable."}},"additionalProperties":true}}},"additionalProperties":true}}}}}}},"/api/v1/income/{fund}":{"get":{"tags":["public"],"summary":"Income Fund","description":"One income fund's full book — one row per underlying, not per contract.\n\n`incomeLegVisible` is false for leap-proxy funds (QDTE/XDTE/RDTE): their\n0DTE contracts open and expire inside a session, so no end-of-day file has\never contained one. That is a property of the strategy, not a gap in the\nscrape, and the UI states it rather than implying the fund writes nothing.","operationId":"income_fund_api_v1_income__fund__get","parameters":[{"name":"fund","in":"path","required":true,"schema":{"type":"string","title":"Fund"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","properties":{"aum":{"type":["number","null"],"description":"Fund AUM in billions of US dollars ($B); legacy field; null when AUM is unavailable."},"aumUsd":{"type":["integer","null"],"description":"Fund AUM in whole US dollars; null when AUM is unavailable."}},"additionalProperties":true}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/options/{underlying}":{"get":{"tags":["public"],"summary":"Option Structures","description":"Every fund's option legs on one underlying, grouped into structures.\n\n`structures` pairs the book as held (synthetic-long/short, call/put\nspreads with credit/debit side, collars, singles). `trades` pairs the\nday-over-day changes by equal absolute contract change (roll / synthetic\n/ spread / collar / pair / single), each fund compared against its own\nprevious snapshot. Legs carry signed `contracts` (negative = written),\n`optionType` CALL/PUT, `isFlex`, and `change` vs. that snapshot.","operationId":"option_structures_api_v1_options__underlying__get","parameters":[{"name":"underlying","in":"path","required":true,"schema":{"type":"string","title":"Underlying"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tickers":{"get":{"tags":["public"],"summary":"List Tickers","description":"Most widely-held underlying tickers across all funds — the /stocks index.\n\n`sort=funds` (default) ranks by how many funds hold the name; `sort=weight`\nranks by total weight summed across funds. Each row carries net daily\nweight change for momentum.","operationId":"list_tickers_api_v1_tickers_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":100,"title":"Limit"}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","pattern":"^(funds|weight)$","default":"funds","title":"Sort"}},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(active-equity|option-income)$"},{"type":"null"}],"description":"Restrict to one fund category. Omit for all funds.","title":"Category"},"description":"Restrict to one fund category. Omit for all funds."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/signal-performance":{"get":{"tags":["public"],"summary":"Get Signal Performance","description":"Backtest: did the historical buy/sell signals actually work?\n\n\nNOT A VALIDATION METRIC — read the caveats before quoting this number.\n\nMeasured 2026-09-03 against a properly benchmarked rerun, this figure is\nnot interpretable as-is and its dashboard card was removed for that reason:\n\n  * No benchmark. The buying win rate (~54.7%) sits BELOW the base rate of\n    the tracked universe (60.9% over 21 trading days), so a number that\n    reads like a pass mark is in fact underperformance. A win rate without\n    a base rate says nothing.\n  * It keys off the raw `Weight` column, not activeWeightDelta. Per\n    CLAUDE.md, raw weight's sign agrees with the fund's actual share change\n    only ~49% of the time — so this measures a signal the product does not\n    serve.\n  * No category filter: option-income funds' collateral churn is counted as\n    stock-picking conviction.\n  * Forward windows are calendar days where they should be trading days.\n\nKept and still served because external consumers may depend on the shape,\nand the underlying per-provider counts are real. Fixing it means adding a\nbase-rate benchmark and switching to active weight; until then, do not\nsurface it as evidence the signals work.\n\nPre-computed nightly by `python -m api.signal_performance`; served\nfrom a JSON cache on disk so the request path is fast. Aggregates\nmedian forward return + win rate across all historical signals,\noverall and per fund family.","operationId":"get_signal_performance_api_v1_signal_performance_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/options-listings":{"get":{"tags":["public"],"summary":"Get Options Listings","description":"CBOE Options Scanner — daily diff of CBOE's published option universe.\n\nDetects stocks gaining options for the first time (Symbol Directory) and\nweekly-options promotions / demotions (Available Weeklys). Returns the\nlast 7 days of scan history; `latest` is the newest scan.\n\nStandalone CBOE market data — refreshed each weekday morning by\n`python cboe_scanner.py` in the GitHub Actions workflow.","operationId":"get_options_listings_api_v1_options_listings_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/tradermatrix":{"get":{"tags":["marketing"],"summary":"Tradermatrix Handoff","description":"Where to take this data next. Returns the TraderMatrix referral URL and\na short pitch — designed for agentic clients that want a 'now what?' answer.","operationId":"tradermatrix_handoff_api_v1_tradermatrix_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"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"},"DollarFields":{"type":"object","properties":{"aum":{"type":["number","null"],"description":"Fund AUM in billions of US dollars ($B); legacy field; null when AUM is unavailable."},"aumUsd":{"type":["integer","null"],"description":"Fund AUM in whole US dollars; null when AUM is unavailable."},"positionUsd":{"type":["integer","null"],"description":"Estimated signed position value in whole USD: weight percent × fund AUM / 100. Uses latest fund AUM, including historical entry estimates; null when AUM is unavailable. Option values are premiums, not underlying notional."},"activeFlowUsd":{"type":["integer","null"],"description":"Estimated signed active allocation flow in whole USD: activeWeightDelta percentage points × latest fund AUM / 100. Not actual execution proceeds; null when AUM is unavailable."}},"additionalProperties":true}}},"tags":[{"name":"public","description":"Open data endpoints. No API key, no auth — just the data."},{"name":"marketing","description":"Pointers to TraderMatrix.Pro and other useful destinations."},{"name":"auth","description":"Email + password account endpoints. Hidden from the dashboard UI; kept for any future internal use."}]}