{"openapi":"3.1.0","info":{"title":"Bittensor Subnet Screener","description":"Real-time Bittensor subnet intelligence machine-payable per call in USDC on Base via x402: full 129-subnet scored screener grid, hot/cold heat scores, alpha-flow, emission, valuation, and full subnet dossiers. No API key, no account, no subscription. Cheapest tier: $0.005 taster (top 5 hottest subnets).","contact":{"name":"Cipher / Bittensor Subnet Screener","url":"https://screener.brobotapp.com/","email":"bxclawbot@gmail.com"},"version":"2.2.0"},"paths":{"/api/premium/hot-subnets":{"get":{"summary":"Premium Hot Subnets","description":"The x402-gated resource: top 10 hottest subnets by heat score.\nA request here without a valid PAYMENT-SIGNATURE header never reaches\nthis function body — PaymentMiddlewareASGI intercepts it and returns\n402 Payment Required first. This function only runs after a verified,\nsettled payment.","operationId":"premium_hot_subnets_api_premium_hot_subnets_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/premium/taster":{"get":{"summary":"Premium Taster","description":"x402-gated taster ($0.005): the top 5 hottest subnets by heat score.\n\nAdded 2026-11-08 as part of the x402 top3 campaign — the cheapest\ncommodity tier that lowers the listing's price percentile (was p61 with\na $0.01 floor). Purpose: give price-sensitive agents an impulse first\npurchase that verifies the rail and data quality before they trade up\nto the full screener grid ($0.05), AlphaGap, or the subnet dossiers.\nSame live scoring as the premium grid; only the scope is smaller.","operationId":"premium_taster_api_premium_taster_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/premium/screener":{"get":{"summary":"Premium Screener Grid","description":"x402-gated: the FULL ranked Subnet Screener grid — every scored\nsubnet, no default limit. If you're reading this, the x402 middleware\nalready verified + settled a payment for this request.","operationId":"premium_screener_grid_api_premium_screener_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/premium/screener/{netuid}":{"get":{"summary":"Premium Screener Row","description":"x402-gated: a single subnet's full screener row (all score components).","operationId":"premium_screener_row_api_premium_screener__netuid__get","parameters":[{"name":"netuid","in":"path","required":true,"schema":{"type":"integer","title":"Netuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/premium/alphagap":{"get":{"summary":"Premium Alphagap All","description":"x402-gated: the full AlphaGap subnet valuation sweep (all subnets).","operationId":"premium_alphagap_all_api_premium_alphagap_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/premium/alphagap/{netuid}":{"get":{"summary":"Premium Alphagap Subnet","description":"x402-gated: a single subnet's AlphaGap score + its valuation record.","operationId":"premium_alphagap_subnet_api_premium_alphagap__netuid__get","parameters":[{"name":"netuid","in":"path","required":true,"schema":{"type":"integer","title":"Netuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/premium/subnet-intel/{netuid}":{"get":{"summary":"Premium Subnet Intel","description":"x402-gated: full Bittensor subnet intelligence payload — hot/cold heat\nscore, alpha-flow, emission reads, valuation — for one subnet ($0.02).","operationId":"premium_subnet_intel_api_premium_subnet_intel__netuid__get","parameters":[{"name":"netuid","in":"path","required":true,"schema":{"type":"integer","title":"Netuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/premium/subnet-dossier/{netuid}":{"get":{"summary":"Premium Subnet Dossier","description":"x402-gated: full Bittensor subnet dossier — all intelligence fields +\nsubnet identity (github/urls/tags) + AA research thesis & red flags ($0.25).","operationId":"premium_subnet_dossier_api_premium_subnet_dossier__netuid__get","parameters":[{"name":"netuid","in":"path","required":true,"schema":{"type":"integer","title":"Netuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/premium/trader-stream":{"get":{"summary":"Premium Trader Stream","description":"x402-gated: the live subnet-trader decision stream — equity trend,\nopen positions, recent entries/exits/gates, circuit-breaker state.\n\nRead-only: this endpoint is a data window, not a control plane. Every\nfield comes from a live read of the trader's own state files; nothing is\nsynthesized. If a source is unavailable the payload says so explicitly.","operationId":"premium_trader_stream_api_premium_trader_stream_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/budget":{"get":{"summary":"Api Budget Status","description":"This machine's metered-API usage vs. its monthly budget share.","operationId":"api_budget_status_api_budget_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/alphagap":{"get":{"summary":"Api Alphagap All","description":"Third-party AlphaGap (alphagap.io) subnet intelligence: composite\naGap score, flow/dev/eval/social/audit sub-scores, AI-written narrative\naudits, revenue estimates, whale signals, APY. ENRICHMENT ONLY -- not\nused by subnet_trader.py or live_executor.py entry/exit logic. See the\ncompliance note above CREATE TABLE alphagap_scores in app/db.py for the\nToS context behind this integration; data refreshed on a ~30min cycle\nby app.collector.alphagap_collector via app/scheduler.py.","operationId":"api_alphagap_all_api_alphagap_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/alphagap/{netuid}":{"get":{"summary":"Api Alphagap Subnet","description":"Single-subnet AlphaGap record. See /api/alphagap for the compliance note.","operationId":"api_alphagap_subnet_api_alphagap__netuid__get","parameters":[{"name":"netuid","in":"path","required":true,"schema":{"type":"integer","title":"Netuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/alphagap/valuation/all":{"get":{"summary":"Api Alphagap Valuation All","description":"AlphaGap's /benchmarks revenue & valuation research: sourced ARR\nfigures (with confidence tier), buyback mechanism + cumulative USD,\nP/S multiples, customer-quality labels. ENRICHMENT ONLY, same scope and\ncompliance note as /api/alphagap -- see app/db.py above\nCREATE TABLE alphagap_valuation.","operationId":"api_alphagap_valuation_all_api_alphagap_valuation_all_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/alphagap/valuation/{netuid}":{"get":{"summary":"Api Alphagap Valuation Subnet","description":"Single-subnet AlphaGap valuation record. See /api/alphagap/valuation/all.","operationId":"api_alphagap_valuation_subnet_api_alphagap_valuation__netuid__get","parameters":[{"name":"netuid","in":"path","required":true,"schema":{"type":"integer","title":"Netuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/health":{"get":{"summary":"Health","operationId":"health_api_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/tao_usd":{"get":{"summary":"Tao Usd","description":"Live TAO/USD price, cached from the last live poll's tao_price row so\nthis stays free (no extra API call per dashboard load).","operationId":"tao_usd_api_tao_usd_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/tao_market":{"get":{"summary":"Tao Market","description":"Header-widget bundle: live TAO/USD price + 24h sparkline (CoinGecko,\nfree/keyless) and the Bittensor Fear & Greed score (CFGI.io). Each has\nits own in-process TTL cache in app/tao_market.py; a slow/down upstream\nserves the last good value (marked _stale_error) instead of erroring.","operationId":"tao_market_api_tao_market_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/tao_news":{"get":{"summary":"Tao News","description":"Live Bittensor/subnet news headlines from taodaily.io's RSS feed,\ncached ~10min in app/tao_market.py.","operationId":"tao_news_api_tao_news_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/trader/status":{"get":{"summary":"Trader Status","description":"Live paper-trading bot status for the AGENT widget. The bot itself\n(subnet_trader.py) runs on the Mac Mini, not on this box -- this reads\nits real paper_ledger.json over SSH (key-auth, read-only `cat`, no\nwrites from here) and marks equity/pnl using Cipher's own subnet_latest\nprices. On any SSH/parse failure this reports agent=\"offline\" with the\nreal error, never synthetic numbers.","operationId":"trader_status_api_trader_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/live/status":{"get":{"summary":"Live Status","description":"Live-executor + circuit-breaker status for the LIVE trading dashboard.\n\nReturns the LAST background-refreshed snapshot instantly (always). The\n~17s on-chain read (status_json.py under sys py3.9) runs in a background\nwarmer thread, so page paint never blocks on it. On a first-ever request\nbefore the warmer has produced data, we kick one synchronous refresh\nonce so the dashboard never shows an empty first paint.","operationId":"live_status_api_live_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/live/equity":{"get":{"summary":"Live Equity","description":"Live-wallet equity history for a chart like the paper trader's.\n\nReads the cached `live_equity_history.jsonl` (one point per warmer tick,\nthrottled to ~60s, capped to the last 2000) and returns\n{connected: bool, start_equity_tao, points: [{ts, equity}, ...]}. Empty\npoints on a fresh wallet — the curve grows as the background warmer runs.","operationId":"live_equity_api_live_equity_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/quantum_readiness":{"get":{"summary":"Quantum Readiness","description":"READ-ONLY: live Bittensor post-quantum (spec 488) wallet readiness.\n\nReads chain state only — never signs, never writes, never submits an\nextrinsic. Surfaces whether root has enabled hashed/post-quantum signers\nand the current registration deposit so operators can watch for the switch.\nFalls back to a dated neutral payload if the RPC is unreachable so the\nmonitoring read never fails the API.","operationId":"quantum_readiness_api_quantum_readiness_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/live/health":{"get":{"summary":"Live Position Health","description":"Read-only per-open-position trade health for the LIVE trader, so the\noperator can read how each open trade is doing (age, entry->now P&L%,\ndrawdown from its own peak) and decide WHEN to bank manually / nudge a\ntake-profit, instead of waiting for the exit rules to bleed the top away.\nHealth comes from live_state.json (positions carry entry_price, entry_ts,\nhigh_water_price, alpha) crossed with the CURRENT price from this\nscreener's own subnet_latest table. This route NEVER trades, never moves\nmoney, never writes state — it only reads and computes for display.","operationId":"live_position_health_api_live_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/live/readiness":{"get":{"summary":"Live Readiness","description":"Go-readiness grade for the live subnet trader (A-F), built 2026-11-10\nfrom a full audit: driver cadence, upstream data freshness, circuit\nbreaker, evidence-gated trade quality, concentration risk, error log\nhealth. Runs readiness_grader.py as a subprocess (read-only, never\ntrades/writes state) so the scoring logic lives in one place shared by\nboth this API and any CLI/cron use -- see subnet-trader/readiness_grader.py\nfor the full methodology and point weights.","operationId":"live_readiness_api_live_readiness_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/signals/live":{"get":{"summary":"Signals Live","description":"Proxy the LIVE AA trading signal for the hub.\n- Serve cached snapshot instantly when it's < 5 min old.\n- `?refresh=1` forces an upstream attempt (best-effort; honors upstream quote).\n- If upstream has no free quota left, returns the last real signal with\n  `quota_exhausted:true` and `age_seconds` — never an invented number.","operationId":"signals_live_api_signals_live_get","parameters":[{"name":"symbol","in":"query","required":false,"schema":{"type":"string","default":"BTC","title":"Symbol"}},{"name":"refresh","in":"query","required":false,"schema":{"type":"integer","maximum":1,"minimum":0,"default":0,"title":"Refresh"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/trader/history":{"get":{"summary":"Trader History","description":"How long the paper trader has been running, its realized equity curve,\nand when each Go-Live check passes at the current pace. Reads the same\nMac Mini ledger as /api/trader/status. Nothing is invented: a check with\nno realistic date says so.","operationId":"trader_history_api_trader_history_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/trader/performance":{"get":{"summary":"Trader Performance","description":"Trading performance analytics: P&L, win rate, trading duration, etc.\n\nThis endpoint preserves the 28.87% win rate and all P&L metrics.\nEvery field is timestamped to track how long we've been trading.\n\nReturns:\n  - pnl_pct: Overall P&L percentage (28.87% win rate preserved)\n  - pnl_tao: Overall P&L in TAO\n  - trading_start_timestamp: When trading started (ISO format)\n  - trading_duration_days: How many days of trading\n  - current_equity_tao: Current portfolio value in TAO\n  - starting_equity_tao: Initial portfolio value\n  - closed_trades_count: Total number of closed trades","operationId":"trader_performance_api_trader_performance_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/training/progress":{"get":{"summary":"Training Progress","description":"Get complete training progress snapshot.\n\nShows:\n  • How long we've been trading (days, hours, exact duration)\n  • Current P&L and win rate\n  • Training phase (early, validation, optimization, maturity)\n  • Projected metrics (30-day, 90-day, annualized returns)\n  • Milestones reached and upcoming\n  \nReturns:\n  {\n    phase: \"early\" | \"validation\" | \"optimization\" | \"maturity\",\n    duration: {\n      start_timestamp: ISO format,\n      days_trading: int,\n      hours_trading: float,\n      exact_duration: \"24 days, 5 hours, 30 minutes\"\n    },\n    stats: {\n      pnl_tao: float,\n      pnl_pct: 28.87,\n      win_rate_pct: 28.87,\n      closed_trades: 156,\n      open_positions: 5,\n      current_equity: 1287.0,\n      starting_equity: 1000.0\n    },\n    projected_metrics: {\n      annualized_pnl_pct: X,\n      trades_per_day: X,\n      projected_30d_pnl: X,\n      projected_90d_pnl: X,\n      time_to_milestone_55pct: \"X days\"\n    },\n    milestones: { ... }\n  }","operationId":"training_progress_api_training_progress_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/training/summary":{"get":{"summary":"Training Summary","description":"Get human-readable training summary.\n\nOne-liner status: \"24 days trading, 28.87% P&L, 156 closed trades, ready for live\"","operationId":"training_summary_api_training_summary_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/ops/market-systems":{"get":{"summary":"Ops Market Systems","description":"Operations Center: Full market systems breakdown.\n\nComplete view of all market data, trading systems, and metrics.\n\nReturns:\n  {\n    systems: {\n      chart_api: { status, endpoints, sources, cost },\n      trading_bot: { status, mode, pnl, duration, phase },\n      aa_mode: { status, trading_mode, ready_for_live },\n      screener: { status, subnets_tracked, hot_subnets },\n    },\n    performance: {\n      portfolio_value: X,\n      pnl: X,\n      win_rate: X,\n      daily_trades: X,\n    },\n    training_metrics: {\n      duration_days: X,\n      progress_phase: X,\n      milestones: { ... },\n    },\n    market_data: {\n      tao_price_usd: X,\n      tao_24h_change: X,\n      fear_greed_score: X,\n      top_subnets: [ ... ],\n    },\n    health: {\n      chart_api: \"online\" | \"offline\",\n      trading_bot: \"online\" | \"offline\",\n      database: \"ok\" | \"error\",\n    }\n  }","operationId":"ops_market_systems_api_ops_market_systems_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/screener/scorer/log-trade":{"post":{"summary":"Log Subnet Trade","description":"Log a subnet trade for scorer learning.\n\nThe optimizer uses this data to measure which scoring components\nactually predict profitable trades and adjusts weights automatically.\n\nArgs:\n  netuid: Subnet ID (1-4096)\n  symbol: Subnet symbol (e.g., \"TAO\", \"BTC\")\n  score_components: Dict of component scores at entry time\n    {\"momentum\": 75.5, \"volume_activity\": 62.1, \"liquidity_safety\": 88.2, ...}\n  entry_price: Entry price\n  entry_time: ISO timestamp when entered\n  exit_price: Exit price (if trade closed)\n  exit_time: ISO timestamp when exited\n  pnl_pct: Realized P&L as percentage\n  is_profitable: True if P&L > 0\n  trader_note: Human notes about the trade\n  \nReturns:\n  {logged: bool, trade_id: str, message: str}","operationId":"log_subnet_trade_api_screener_scorer_log_trade_post","parameters":[{"name":"netuid","in":"query","required":true,"schema":{"type":"integer","title":"Netuid"}},{"name":"symbol","in":"query","required":true,"schema":{"type":"string","title":"Symbol"}},{"name":"entry_price","in":"query","required":true,"schema":{"type":"number","title":"Entry Price"}},{"name":"entry_time","in":"query","required":true,"schema":{"type":"string","title":"Entry Time"}},{"name":"exit_price","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Exit Price"}},{"name":"exit_time","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Exit Time"}},{"name":"pnl_pct","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Pnl Pct"}},{"name":"is_profitable","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Profitable"}},{"name":"trader_note","in":"query","required":false,"schema":{"type":"string","default":"","title":"Trader Note"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/screener/scorer/optimization-status":{"get":{"summary":"Scorer Optimization Status","description":"Get current scorer optimization status and recommendation.\n\nShows which scoring components are predictive of your actual wins/losses\nand recommends adjustments.\n\nArgs:\n  days: Analyze last N days of trades\n  \nReturns:\n  {\n    status: \"READY\" | \"PENDING_DATA\" | \"NO_DATA\",\n    total_trades_analyzed: int,\n    best_predictor: {component, correlation, avg_in_winners, avg_in_losers},\n    worst_predictor: {component, correlation, ...},\n    components_with_positive_correlation: [list],\n    components_with_negative_correlation: [list],\n    recommendation: str\n  }","operationId":"scorer_optimization_status_api_screener_scorer_optimization_status_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/screener/scorer/optimize":{"post":{"summary":"Optimize Scorer Weights","description":"Run weight optimization based on recent trade history.\n\nAnalyzes all closed trades and suggests new weights to improve future\nperformance. Uses one of three strategies:\n\n- \"correlation\": Weight components by correlation with profitability\n- \"winner_bias\": Boost components that score higher in winning trades\n- \"loss_avoidance\": Reduce components that predict losses\n\nArgs:\n  strategy: Optimization strategy\n  \nReturns:\n  {\n    strategy: str,\n    old_weights: {component: weight, ...},\n    new_weights: {component: weight, ...},\n    total_sample_trades: int,\n    expected_improvement_pct: float,\n    component_performances: {\n      component: {\n        correlation_with_pnl: float,\n        correlation_confidence: float,\n        avg_score_in_winners: float,\n        avg_score_in_losers: float,\n        winner_bias: float,\n        current_weight: float,\n        recommended_weight: float,\n        confidence_level: str,\n        sample_size: int\n      }\n    },\n    recommendation: str\n  }","operationId":"optimize_scorer_weights_api_screener_scorer_optimize_post","parameters":[{"name":"strategy","in":"query","required":false,"schema":{"type":"string","default":"correlation","title":"Strategy"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/screener":{"get":{"summary":"Screener","description":"Ranked list of subnets by heat score. Recomputes live on each call —\ncheap (pure SQLite read + arithmetic, no network) so this stays fresh\nbetween poll cycles.","operationId":"screener_api_screener_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/subnet/{netuid}":{"get":{"summary":"Subnet Detail","operationId":"subnet_detail_api_subnet__netuid__get","parameters":[{"name":"netuid","in":"path","required":true,"schema":{"type":"integer","title":"Netuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/subnet/{netuid}/bars":{"get":{"summary":"Subnet Bars","description":"Raw OHLC bars for a subnet, newest last (chart-ready order).","operationId":"subnet_bars_api_subnet__netuid__bars_get","parameters":[{"name":"netuid","in":"path","required":true,"schema":{"type":"integer","title":"Netuid"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":20000,"minimum":1,"default":2000,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/subnet/{netuid}/score_history":{"get":{"summary":"Subnet Score History","description":"Heat-score trend for a subnet's detail-panel sparkline (real data from\nscreener_scores, the same persisted-score table the ranked list itself\nis built from -- no synthetic/placeholder points). Frontend consumer:\nloadScoreSparkline() in static/index.html.","operationId":"subnet_score_history_api_subnet__netuid__score_history_get","parameters":[{"name":"netuid","in":"path","required":true,"schema":{"type":"integer","title":"Netuid"}},{"name":"hours","in":"query","required":false,"schema":{"type":"integer","maximum":720,"minimum":1,"default":24,"title":"Hours"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tv/history":{"get":{"summary":"Tv History","operationId":"tv_history_api_tv_history_get","parameters":[{"name":"netuid","in":"query","required":true,"schema":{"type":"integer","title":"Netuid"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":20000,"minimum":1,"default":2000,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tv/native-history":{"get":{"summary":"Tv Native History","description":"Real Taostats-native OHLCV for the chart, keyed by the SAME `tf` values\nthe existing #tf-toggle buttons already send (7/30/90/180/0), so the\nfrontend swap is a data-source change only — no UI contract change.","operationId":"tv_native_history_api_tv_native_history_get","parameters":[{"name":"netuid","in":"query","required":true,"schema":{"type":"integer","title":"Netuid"}},{"name":"tf","in":"query","required":false,"schema":{"type":"string","default":"30","title":"Tf"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/portfolio/subnets":{"get":{"summary":"Portfolio Subnets","description":"Owned-subnet portfolio: one row per subnet with any logged buy/sell,\nweighted-average cost basis, live value at the latest subnet_latest price,\nunrealized and realized P&L (same math as the per-subnet panel), plus\ntotals and the most recent trades across all subnets. Read-only.","operationId":"portfolio_subnets_api_portfolio_subnets_get","parameters":[{"name":"recent","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":0,"default":25,"title":"Recent"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/portfolio/onchain":{"get":{"summary":"Portfolio Onchain","description":"Owned subnets as the chain reports them: the latest stake snapshot for\nevery tracked coldkey (wallet_stake_snapshot, filled by the wallet refresh\nand the scheduled wallet poll), valued at the current subnet_latest price.\nThis is the authoritative owned amount. Logged trades are only history and\ncan drift from the chain, so they are reported separately for comparison.\nRead-only; makes no Taostats calls.","operationId":"portfolio_onchain_api_portfolio_onchain_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/research":{"get":{"summary":"List Research","description":"All subnets with any research/watchlist entry, joined with live price\nfor quick portfolio-style scanning.","operationId":"list_research_api_research_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/portfolio":{"get":{"summary":"Portfolio Summary","description":"Every subnet with any position, its weighted P&L, rolled up into a\nsingle portfolio total — the CRM's investor-side dashboard view. Each\nitem also carries a rule-based take-profit signal (see\n_take_profit_signal) grounded in this position's actual P&L% and the\nsubnet's real recorded price momentum — never a fabricated prediction.","operationId":"portfolio_summary_api_portfolio_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/wallets/track":{"post":{"summary":"Track Wallet","description":"Add (or re-affirm) an address to watch. No ownership proof required.","operationId":"track_wallet_api_wallets_track_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrackWalletRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/wallets/{ss58}":{"delete":{"summary":"Untrack Wallet","operationId":"untrack_wallet_api_wallets__ss58__delete","parameters":[{"name":"ss58","in":"path","required":true,"schema":{"type":"string","title":"Ss58"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/wallets":{"get":{"summary":"List Tracked Wallets","description":"Every tracked wallet with its most recently cached stake snapshot,\nrolled up into a total TAO value per wallet. The per-subnet balance_tao\nrows are the TRUE TAO value of each α stake (from Taostats\nbalance_as_tao); the wallet total is the sum of those, plus the free\nbalance from the account snapshot when available. Snapshot data is\nrefreshed by the scheduler (see app/scheduler.py wallet_poll_job), NOT\nfetched live on every dashboard load -- respects Taostats rate limits,\nsame pattern as the subnet screener itself.","operationId":"list_tracked_wallets_api_wallets_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/wallets/{ss58}/refresh":{"get":{"summary":"Refresh Wallet Now","description":"On-demand refresh for a single wallet (e.g. right after adding it, so\nthe user isn't staring at an empty position list until the next\nscheduled poll). Real API call, subject to the same rate-limit-aware\nclient as everything else -- do not call this in a tight loop.","operationId":"refresh_wallet_now_api_wallets__ss58__refresh_get","parameters":[{"name":"ss58","in":"path","required":true,"schema":{"type":"string","title":"Ss58"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/wallets/{ss58}/history":{"get":{"summary":"Wallet Purchase History","description":"Real per-transaction buy/sell (stake/unstake) history for a tracked\nwallet -- answers \"where/when did I actually buy this\" directly from\nTaostats' indexed on-chain delegation events, not a derived estimate.\nFetched live on request (not cached/polled) since this is a lower-traffic\nlookup than the price screener; same read-only trust model as the rest\nof the wallet feature -- no keys, no signing, no execution.\nDELEGATE = staked in (bought alpha with TAO); UNDELEGATE = unstaked out\n(sold alpha back to TAO). alpha_price_in_tao is the real price at the\nexact moment of that transaction, letting a user see their actual\ncost/exit basis per trade, not just a current snapshot.","operationId":"wallet_purchase_history_api_wallets__ss58__history_get","parameters":[{"name":"ss58","in":"path","required":true,"schema":{"type":"string","title":"Ss58"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/wallets/connect/challenge":{"post":{"summary":"Connect Challenge","operationId":"connect_challenge_api_wallets_connect_challenge_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectChallengeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/wallets/connect/verify":{"post":{"summary":"Connect Verify","description":"Step 2 of connect: verify the signed nonce and mark the wallet as\nownership-verified. Single-use -- a captured signature can't be replayed\nagainst a future session.","operationId":"connect_verify_api_wallets_connect_verify_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectVerifyRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/subscribe/checkout":{"post":{"summary":"Create Subscription Checkout","operationId":"create_subscription_checkout_api_subscribe_checkout_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/subscribe/webhook":{"post":{"summary":"Stripe Webhook","operationId":"stripe_webhook_api_subscribe_webhook_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/me/link-whop":{"post":{"summary":"Link Whop Identity","description":"Bind a wallet (already proven via session) to a Whop user id. This is a\nSELF-ASSERTED claim -- the wallet signature proves wallet ownership, not that\nthe caller owns the Whop account. The cryptographically-sound version that\nproves the caller really owns the Whop account ('Sign in with Whop' OAuth,\nticketed as the honest v2) needs client_id/secret the operator must register\nin the Whop dashboard. This binding is the smallest step that actually closes\nthe public ?username= read path, because tier reads now require the session\n(the wallet holder) rather than a guessable username. Do NOT treat whop_user_id\nas identity proof; it is an account-linking convenience until OAuth lands.","operationId":"link_whop_identity_api_me_link_whop_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkWhopRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/automate/prepare-trade":{"post":{"summary":"Prepare Automate Trade","description":"Mint an UNSIGNED staking extrinsic + its signing payload for the customer's\nown wallet. Composes the real chain call against the live finney runtime and\nreturns payload_hex -- the exact bytes the customer's wallet must sign via\nsignRaw (polkadot.js-compatible) -- plus the metadata a signing wallet needs.\nThe server does NOT broadcast here and holds no customer key.","operationId":"prepare_automate_trade_api_automate_prepare_trade_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrepareTradeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/automate/submit-trade":{"post":{"summary":"Submit Automate Trade","description":"Broadcast a customer-signed trade. Reconstructs the signed extrinsic from\nthe CUSTOMER's signature ONLY (the server never sees their key), verifies the\nsignature is from the wallet that owns the intent, submits to finney, and\nrecords the real tx_id + block into the trades ledger (synthetic=0).","operationId":"submit_automate_trade_api_automate_submit_trade_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitTradeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/trade/prepare":{"post":{"summary":"Trade Prepare Alias","operationId":"trade_prepare_alias_api_trade_prepare_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrepareTradeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/trade/submit":{"post":{"summary":"Trade Submit Alias","operationId":"trade_submit_alias_api_trade_submit_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitTradeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/automate/prepared-trades":{"get":{"summary":"List Prepared Trades","description":"Read-only list of the caller's trade intents and their submit status.","operationId":"list_prepared_trades_api_automate_prepared_trades_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","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/me/entitlement":{"get":{"summary":"Get Entitlement","description":"Public: resolve the caller's real tier. Prefers the wallet session\nidentity; falls back to ?username= ONLY as the legacy/internal-testing path.\nNo secrets returned; never defaults an unresolved caller to a paid tier.","operationId":"get_entitlement_api_me_entitlement_get","parameters":[{"name":"username","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Username"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/book":{"get":{"summary":"Api Book","description":"Public: the REAL Kalshi book — read from the actual accounting files.\n\nReturns the honest record: current balance, total P&L, fills, win/loss\nbreakdown computed from the trade log, and the last closed position.\nNever fabricates: if the files are missing, it says so.","operationId":"api_book_api_book_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/operate/closed-trades":{"get":{"summary":"Operate Closed Trades","description":"Concrete proof-of-gating: the hub promises Operate-tier subscribers\n\"live equity and closed-trade history\". This is that feature, actually\nbehind a real tier check for the first time. Queries the REAL trade ledger\n(a separate sqlite file from this app's own screener.db) -- status is\nupper-case 'CLOSED', synthetic=0 excludes the fabricated row found and\nflagged earlier. Honest about what exists: 0 real closed trades today,\nnot a fabricated number to make the tier look more valuable than it is.","operationId":"operate_closed_trades_api_operate_closed_trades_get","parameters":[{"name":"username","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Username"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/premium/hot-subnets-key":{"get":{"summary":"Premium Hot Subnets By Key","description":"Same dataset as the x402-gated /api/premium/hot-subnets, but reachable\nwith a normal API key for Premium ($49/mo) subscribers who'd rather pay\nmonthly than per-call in crypto.","operationId":"premium_hot_subnets_by_key_api_premium_hot_subnets_key_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/sw.js":{"get":{"summary":"Serve Sw","operationId":"serve_sw_sw_js_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/":{"get":{"summary":"Serve Desktop Shell","operationId":"serve_desktop_shell__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/app/":{"get":{"summary":"Serve App Shell","operationId":"serve_app_shell_app__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/app":{"get":{"summary":"Serve App Shell","operationId":"serve_app_shell_app_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/m":{"get":{"summary":"Serve Mobile Shell","operationId":"serve_mobile_shell_m_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/m/":{"get":{"summary":"Serve Mobile Shell","operationId":"serve_mobile_shell_m__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/operate-onboard.html":{"get":{"summary":"Serve Operate Onboard","description":"Post-payment onboarding for the live Operate tier (plan_BFx5y7levvsoU,\n$99.99/mo). Explicit no-cache route (registered before the StaticFiles\nmount) so Cloudflare's edge never serves stale bytes at this URL — the\ndocumented failure mode on this host. Content is the static file\napp/static/operate-onboard.html; see the task handoff for the verification\nthat the Telegram auto-invite promise in the checkout copy is currently\nmanual, not wired.","operationId":"serve_operate_onboard_operate_onboard_html_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/logo/{netuid}":{"get":{"summary":"Serve Logo","description":"Serve a cached subnet logo. Plain sync `def` so FastAPI runs it in the\nthreadpool — the fetch-on-miss path blocks, and this must never stall the\nevent loop or a page load. Never 500s: cached file, else one best-effort\nfetch-and-cache, else a 1x1 transparent SVG.","operationId":"serve_logo_logo__netuid__get","parameters":[{"name":"netuid","in":"path","required":true,"schema":{"type":"integer","title":"Netuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/gm/current":{"get":{"tags":["GM Subnet"],"summary":"Gm Current","description":"Get current GM Subnet (Subnet 18) sentiment snapshot.\n\nReturns:\n{\n    \"timestamp\": \"2026-10-10T14:30:00Z\",\n    \"sentiment\": 0.627,           # 0-1 scale (0.5 = neutral)\n    \"regime\": \"Bullish\",\n    \"confidence\": 0.78,           # How strong the signal is\n    \"trade_signal\": \"buy\",\n    \n    \"sentiment_breakdown\": {\n        \"positive_pct\": 62.7,\n        \"neutral_pct\": 25.1,\n        \"negative_pct\": 12.2\n    },\n    \n    \"validators\": {\n        \"online\": 10245,\n        \"weighted_sentiment\": 0.714,\n        \"top_incentive\": 1.24\n    },\n    \n    \"scoring_impact\": {\n        \"momentum_adjustment\": 0.15,      # +15% weight\n        \"volume_adjustment\": 0.10,       # +10% weight\n        \"applied_to_scorer\": True\n    },\n    \n    \"market_context\": {\n        \"tao_price\": 450.50,\n        \"price_change_24h\": \"+2.5%\",\n        \"fear_greed_index\": 65,\n        \"interpretation\": \"Strong bullish sentiment supported by market\"\n    }\n}","operationId":"gm_current_api_gm_current_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Gm Current Api Gm Current Get"}}}}}}},"/api/gm/history":{"get":{"tags":["GM Subnet"],"summary":"Gm History","description":"Get GM Subnet sentiment history over N hours.\n\nReturns array of sentiment data points, one per block (~12 seconds).\n\nExample response:\n[\n    {\n        \"timestamp\": \"2026-10-10T14:30:00Z\",\n        \"sentiment\": 0.627,\n        \"positive_pct\": 62.7,\n        \"regime\": \"Bullish\",\n        \"validators\": 10245,\n        \"price_tao\": 450.50\n    },\n    ...\n]","operationId":"gm_history_api_gm_history_get","parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","maximum":72,"minimum":1,"default":24,"title":"Hours"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true},"title":"Response Gm History Api Gm History Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/gm/correlation":{"get":{"tags":["GM Subnet"],"summary":"Gm Correlation","description":"Calculate Pearson correlation between GM sentiment and TAO price movement.\n\nMeasures: Does GM Subnet sentiment predict price movements?\n\nReturns:\n{\n    \"window_hours\": 24,\n    \"correlation\": 0.687,        # -1 (inverse) to +1 (aligned)\n    \"p_value\": 0.042,            # < 0.05 = statistically significant\n    \"significance\": \"strong\",    # strong/moderate/weak\n    \"direction\": \"positive\",     # Does bullish predict price up?\n    \"interpretation\": \"Strong positive correlation: when validators are \"\n                     \"bullish, TAO price tends to increase 24h later\",\n    \"sample_size\": 2880,         # Data points in window\n    \"last_calculated\": \"2026-10-10T14:30:00Z\"\n}","operationId":"gm_correlation_api_gm_correlation_get","parameters":[{"name":"window_hours","in":"query","required":false,"schema":{"type":"integer","maximum":168,"minimum":1,"default":24,"title":"Window Hours"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Gm Correlation Api Gm Correlation Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/gm/sentiment-impact":{"get":{"tags":["GM Subnet"],"summary":"Gm Sentiment Impact","description":"Measure how much GM sentiment has impacted trading performance.\n\nShows win rate and average P&L for each sentiment regime.\n\nReturns:\n{\n    \"total_trades\": 156,\n    \"by_regime\": {\n        \"Extreme Bullish\": {\n            \"trades\": 28,\n            \"wins\": 18,\n            \"win_rate\": 0.643,\n            \"avg_pnl\": 0.031,\n            \"total_pnl\": 0.874\n        },\n        \"Bullish\": {...},\n        \"Neutral\": {...},\n        \"Bearish\": {...},\n        \"Extreme Bearish\": {...}\n    },\n    \"best_regime\": \"Extreme Bullish\",\n    \"worst_regime\": \"Extreme Bearish\",\n    \"recommendation\": \"Use GM to filter regime. Concentrate trades when \"\n                     \"sentiment is extremely bullish.\"\n}","operationId":"gm_sentiment_impact_api_gm_sentiment_impact_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Gm Sentiment Impact Api Gm Sentiment Impact Get"}}}}}}},"/api/gm/sentiment-alert":{"post":{"tags":["GM Subnet"],"summary":"Set Sentiment Alert","description":"Configure automated alert when sentiment crosses threshold.\n\nArgs:\n    threshold: Sentiment level (0-1) to trigger alert\n    direction: \"above\" or \"below\"\n    action: What to do when triggered\n            - \"notify\": Send alert only\n            - \"adjust_weights\": Auto-adjust scorer weights\n            - \"close_positions\": Close positions and move to safety\n\nExample:\nPOST /api/gm/sentiment-alert?threshold=0.70&direction=above&action=adjust_weights\n\nTriggers when bullish sentiment > 70%","operationId":"set_sentiment_alert_api_gm_sentiment_alert_post","parameters":[{"name":"threshold","in":"query","required":true,"schema":{"type":"number","maximum":1,"minimum":0,"title":"Threshold"}},{"name":"direction","in":"query","required":false,"schema":{"type":"string","pattern":"^(above|below)$","default":"above","title":"Direction"}},{"name":"action","in":"query","required":false,"schema":{"type":"string","pattern":"^(notify|adjust_weights|close_positions)$","default":"notify","title":"Action"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Set Sentiment Alert Api Gm Sentiment Alert Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/gm/record-trade-outcome":{"post":{"tags":["GM Subnet"],"summary":"Record Trade Outcome","description":"Record trade outcome for accuracy tracking.\n\nUsed to measure if GM sentiment was predictive of profit/loss.","operationId":"record_trade_outcome_api_gm_record_trade_outcome_post","parameters":[{"name":"regime","in":"query","required":true,"schema":{"type":"string","title":"Regime"}},{"name":"pnl_pct","in":"query","required":true,"schema":{"type":"number","title":"Pnl Pct"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Record Trade Outcome Api Gm Record Trade Outcome Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/gm/daily-report":{"get":{"tags":["GM Subnet"],"summary":"Gm Daily Report","description":"Generate comprehensive daily GM Subnet report.\n\nSummary for yesterday:\n- Sentiment trend (bearish → bullish → etc.)\n- Price correlation (did sentiment predict movement?)\n- Trading performance by regime\n- Top validators\n- Recommendation for today","operationId":"gm_daily_report_api_gm_daily_report_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Gm Daily Report Api Gm Daily Report Get"}}}}}}},"/api/gm/health":{"get":{"tags":["GM Subnet"],"summary":"Gm Health","description":"Check GM Subnet integration health.\n\nReturns:\n{\n    \"status\": \"healthy\",\n    \"collector_running\": true,\n    \"last_event\": \"2026-10-10T14:30:00Z\",\n    \"events_24h\": 7200,\n    \"database_size_mb\": 12.5\n}","operationId":"gm_health_api_gm_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Gm Health Api Gm Health Get"}}}}}}},"/api/portfolio/paper-trades":{"get":{"tags":["portfolio"],"summary":"Get Paper Trades Portfolio","description":"Live paper trading portfolio data.\n\nReturns:\n- count: number of open positions\n- total_invested: sum of all entry prices × quantities\n- total_current_value: sum of all current prices × quantities  \n- total_unrealized_pnl: difference\n- total_unrealized_pnl_pct: percentage\n- items: list of all open positions with per-position P&L\n\nThis data is pulled from ~/.hermes/cache/paper_trades.db\nand represents live paper trading execution with sentiment-driven sizing.","operationId":"get_paper_trades_portfolio_api_portfolio_paper_trades_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/webhooks/whop":{"post":{"tags":["whop"],"summary":"Whop Webhook","operationId":"whop_webhook_api_webhooks_whop_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/screener/":{"get":{"summary":"Serve Screener Page","operationId":"serve_screener_page_screener__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/screener":{"get":{"summary":"Serve Screener Page","operationId":"serve_screener_page_screener_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/onboarding/":{"get":{"summary":"Serve Onboarding Page","operationId":"serve_onboarding_page_onboarding__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/onboarding":{"get":{"summary":"Serve Onboarding Page","operationId":"serve_onboarding_page_onboarding_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/sweep_pnl":{"get":{"summary":"Get Sweep Pnl","operationId":"get_sweep_pnl_api_sweep_pnl_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/live_positions_health":{"get":{"summary":"Get Live Positions Health","description":"Open positions with age / P&L / drawdown, straight off live_state.\n\nMirrors what the dashboard's own /api/live/health returns so both\nsurfaces read one set of numbers. Kept here (not re-derived in the\nstatic page) so the mobile sheet and the BW portfolio can't disagree.","operationId":"get_live_positions_health_api_live_positions_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/manual_bank":{"get":{"summary":"Get Manual Bank","operationId":"get_manual_bank_api_manual_bank_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"summary":"Post Manual Bank","description":"Queue a FULL exit of one live position. Never executes here.","operationId":"post_manual_bank_api_manual_bank_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Payload"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/galaxy/now":{"get":{"summary":"Galaxy Now","operationId":"galaxy_now_api_galaxy_now_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/galaxy/range":{"get":{"summary":"Galaxy Range","operationId":"galaxy_range_api_galaxy_range_get","parameters":[{"name":"from","in":"query","required":true,"schema":{"type":"string","title":"From"}},{"name":"to","in":"query","required":true,"schema":{"type":"string","title":"To"}},{"name":"step","in":"query","required":false,"schema":{"type":"string","pattern":"^(1h|1d)$","default":"1h","title":"Step"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/galaxy/at":{"get":{"summary":"Galaxy At","operationId":"galaxy_at_api_galaxy_at_get","parameters":[{"name":"ts","in":"query","required":true,"schema":{"type":"string","title":"Ts"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"CheckoutRequest":{"properties":{"tier":{"type":"string","title":"Tier"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"}},"type":"object","required":["tier"],"title":"CheckoutRequest"},"ConnectChallengeRequest":{"properties":{"ss58":{"type":"string","title":"Ss58"}},"type":"object","required":["ss58"],"title":"ConnectChallengeRequest"},"ConnectVerifyRequest":{"properties":{"ss58":{"type":"string","title":"Ss58"},"nonce":{"type":"string","title":"Nonce"},"signature":{"type":"string","title":"Signature"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"}},"type":"object","required":["ss58","nonce","signature"],"title":"ConnectVerifyRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"LinkWhopRequest":{"properties":{"identifier":{"type":"string","title":"Identifier"}},"type":"object","required":["identifier"],"title":"LinkWhopRequest"},"PrepareTradeRequest":{"properties":{"netuid":{"type":"integer","title":"Netuid"},"side":{"type":"string","title":"Side"},"amount_tao":{"type":"number","title":"Amount Tao"},"hotkey":{"type":"string","title":"Hotkey"},"direction_hint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Direction Hint"}},"type":"object","required":["netuid","side","amount_tao","hotkey"],"title":"PrepareTradeRequest"},"SubmitTradeRequest":{"properties":{"intent_id":{"type":"string","title":"Intent Id"},"signature_hex":{"type":"string","title":"Signature Hex"}},"type":"object","required":["intent_id","signature_hex"],"title":"SubmitTradeRequest"},"TrackWalletRequest":{"properties":{"ss58":{"type":"string","title":"Ss58"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"}},"type":"object","required":["ss58"],"title":"TrackWalletRequest"},"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"}}}}