{"openapi":"3.1.0","info":{"title":"Fahali Intelligence API","version":"1.0.0","description":"Structured market intelligence endpoints for AI agents, MCP tools, and institutional consumers. All responses conform to the canonical Fahali Intelligence schema family. Observation, not financial advice — every surface carries this disclaimer."},"servers":[{"url":"https://app.fahaliai.com","description":"Production"},{"url":"http://localhost:5000","description":"Local development"}],"paths":{"/api/market/movers":{"get":{"summary":"Top market movers by detection activity","description":"Returns the top 25 symbols ranked by alert frequency over the last 24 hours. No authentication required.","operationId":"getMarketMovers","responses":{"200":{"description":"Top movers list","content":{"application/json":{"schema":{"type":"object","properties":{"movers":{"type":"array","items":{"type":"object","properties":{"symbol":{"type":"string"},"alertCount":{"type":"integer"},"avgConfidence":{"type":"number"},"lastAlert":{"type":"string","format":"date-time"}}}},"asOf":{"type":"string","format":"date-time"}}}}}}}}},"/api/public/stats":{"get":{"summary":"Live platform stats (public)","description":"Real-time coverage: instruments monitored, detections in last 24h, last detection time. No authentication. Returns no engine count by design — the per-engine record is at /api/track-record/engines.","operationId":"getPublicStats","responses":{"200":{"description":"Live stats","content":{"application/json":{"schema":{"type":"object","properties":{"instrumentsMonitored":{"type":"integer"},"detections24h":{"type":"integer"},"lastDetectionAt":{"type":"string","format":"date-time"},"asOf":{"type":"string","format":"date-time"}}}}}}}}},"/api/institutional/signals":{"get":{"summary":"Detection signals feed (public)","description":"Recent detection signals with engine, direction/phase, confidence, and judged outcome fields. Asset-balanced (crypto + US equities/ETFs). No authentication.","operationId":"getInstitutionalSignals","parameters":[{"name":"symbol","in":"query","required":false,"schema":{"type":"string"},"description":"Exact symbol filter (e.g. BTCUSDT). Queries the DB directly."},{"name":"asset","in":"query","required":false,"schema":{"type":"string","enum":["crypto","equity"]},"description":"Asset-class filter."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer"},"description":"Cap results."}],"responses":{"200":{"description":"Signals list","content":{"application/json":{"schema":{"type":"object","properties":{"signals":{"type":"array","items":{"type":"object"}},"count":{"type":"integer"},"timestamp":{"type":"integer"}}}}}}}}},"/api/alerts":{"get":{"summary":"Recent alerts (public)","description":"Recent detection alerts with verdicts. Optional symbol filter. No authentication.","operationId":"getAlerts","parameters":[{"name":"symbol","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Alerts list","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/engines/status":{"get":{"summary":"Engine liveness (public)","description":"Per-engine status across the 18 canonical engines: last fired, 1h/24h/7d counts, and a firing/active/quiet/dormant status (event-gated engines are quiet by design). Includes market-session context. No authentication.","operationId":"getEngineStatus","responses":{"200":{"description":"Engine status","content":{"application/json":{"schema":{"type":"object","properties":{"engines":{"type":"array","items":{"type":"object"}},"market_context":{"type":"object"},"asof":{"type":"string","format":"date-time"}}}}}}}}},"/api/case-studies":{"get":{"summary":"Track record — predicted vs. outcome (public)","description":"Verified detections with the forecast made, the realized outcome (direction/magnitude correct or not), and entry/horizon prices. Append-only; includes misses. No authentication.","operationId":"getCaseStudies","responses":{"200":{"description":"Case studies","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/track-record/scorecard":{"get":{"summary":"Accuracy scorecard with base-rate lift (public)","description":"Direction / magnitude / crash-catch axes measured as lift over base rate (not a vanity win-rate). No authentication.","operationId":"getScorecard","responses":{"200":{"description":"Scorecard","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/billing/checkout":{"post":{"summary":"Create a Stripe checkout session","description":"Starts a subscription checkout for a pricing tier. Requires authentication (Firebase ID token as Bearer). Returns a Stripe-hosted checkout URL.","operationId":"createCheckout","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tier":{"type":"string","enum":["retail","professional","elite","institutional","enterprise"]}},"required":["tier"]}}}},"responses":{"200":{"description":"Checkout session","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"}}}}}},"401":{"description":"Authentication required"}}}},"/agent/verdict":{"get":{"summary":"Get structured market verdict","description":"Returns direction (bullish/bearish/neutral), confidence score, reasoning chain, expected move percentage, and forecast horizon for one or more symbols. Optionally includes contagion risk data.","operationId":"getMarketVerdict","parameters":[{"name":"symbols","in":"query","description":"Comma-separated trading symbols (e.g. 'BTCUSDT,ETHUSDT'). Omitting returns top signals across all symbols.","required":false,"schema":{"type":"string"}},{"name":"includeContagion","in":"query","description":"If true, enriches response with contagion risk from tail_dependence table.","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Market verdict intelligence","headers":{"X-Fahali-Direction-Confidence":{"schema":{"type":"integer","enum":[1]}},"X-Fahali-Schema-Version":{"schema":{"type":"string","enum":["1.0"]}},"X-Fahali-Contagion-Included":{"schema":{"type":"integer","enum":[0,1]}}},"content":{"application/json":{"schema":{"type":"object","properties":{"schemaVersion":{"type":"string","enum":["1.0"]},"updatedAt":{"type":"string","format":"date-time"},"count":{"type":"integer"},"data":{"type":"array","items":{"$ref":"#/components/schemas/SpectraIntelligence"}}}}}}},"503":{"description":"Database not ready","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/agent/portfolio-risk":{"get":{"summary":"Get portfolio risk assessment","description":"Returns overall risk score, value-at-risk, expected drawdown, per-position risk breakdown, and contagion risk. Requires connected exchange accounts for personalized data.","operationId":"getPortfolioRisk","parameters":[],"responses":{"200":{"description":"Portfolio risk assessment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpectraPortfolioRiskAssessment"}}}}}}},"/agent/capital-flow":{"get":{"summary":"Get capital flow intelligence","description":"Returns the latest measured 60-minute candle-derived USD order-flow imbalance for requested symbols, or the strongest available readings when no symbol is supplied. A zero detection score does not erase a measured netFlowUsd value. This is not exchange aggressor tape, fund flow, participant identity, or a forecast.","operationId":"getCapitalFlow","parameters":[{"name":"symbol","in":"query","description":"Optional single trading symbol. Base aliases such as BTC resolve to a preferred quoted pair and the resolution is returned.","required":false,"schema":{"type":"string"}},{"name":"symbols","in":"query","description":"Optional comma-separated symbols.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Maximum returned rows, 1-100.","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":10}},{"name":"since","in":"query","description":"Optional ISO-8601 freshness bound, no more than seven days old.","required":false,"schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Capital flow intelligence","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpectraCapitalFlowResponse"}}}},"400":{"description":"Invalid query parameter","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/agent/microstructure-proxy":{"get":{"summary":"Get public-market absorption observations","description":"Returns active hidden-liquidity observations derived from public aggregate trades and order-book snapshots. The interpretation is a proxy: Fahali does not observe dark-pool prints, identify participants, measure hidden volume, or attach a calibrated outcome probability.","operationId":"getMicrostructureProxy","parameters":[{"name":"symbol","in":"query","description":"Optional single instrument. Unambiguous base aliases such as BTC resolve to a preferred quoted pair and the resolution is returned.","required":false,"schema":{"type":"string"}},{"name":"symbols","in":"query","description":"Optional comma-separated instruments.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Maximum returned observations, 1-100.","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":10}},{"name":"since","in":"query","description":"Optional ISO-8601 lower bound, no more than 30 days old. Defaults to seven days.","required":false,"schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Public-market microstructure observations","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MicrostructureProxyResponse"}}}},"400":{"description":"Invalid time bound"},"500":{"description":"Source query failed; never interpreted as no activity"}}}},"/agent/unusual-money-movement":{"get":{"summary":"Find unusual money movement","description":"Returns symbols whose latest candle-derived buy-versus-sell volume imbalance crossed the requested uncalibrated detection-score threshold. Raw measurements and label conflicts remain visible. Fahali does not identify wallets, institutions, individual trade prints, or whether one participant caused the movement.","operationId":"getUnusualMoneyMovement","parameters":[{"name":"symbols","in":"query","description":"Optional comma-separated symbols.","schema":{"type":"string"}},{"name":"minimum_confidence","in":"query","description":"Minimum uncalibrated detection score; not an outcome probability.","schema":{"type":"number","minimum":0,"maximum":1,"default":0.5}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":10}},{"name":"since","in":"query","description":"ISO-8601 lower bound, no more than seven days ago. Defaults to 24 hours.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Current unusual-money-movement observations","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnusualMoneyMovementResponse"}}}},"400":{"description":"Invalid filter"},"503":{"description":"Order-flow data source unavailable"}}}},"/agent/contagion":{"get":{"summary":"Get contagion map","description":"Returns cross-asset contagion and tail dependence map: nodes (symbols with risk scores), edges (pairwise correlation strength), and clusters of correlated assets.","operationId":"getContagionMap","parameters":[],"responses":{"200":{"description":"Contagion map","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpectraContagionMap"}}}}}}},"/agent/daily-brief":{"get":{"summary":"Get daily market intelligence brief","description":"Returns a yesterday-vs-today diff: alert volume change, critical alerts, current market regime, and prior intel post reference. Free tier returns regime + headline; Professional tier gets full delta with prior-period comparison. Sources: alerts, agent_events, spectra_intel_posts. Observation, not financial advice.","operationId":"getDailyBrief","parameters":[],"responses":{"200":{"description":"Daily brief","content":{"application/json":{"schema":{"type":"object","properties":{"as_of":{"type":"string","format":"date-time"},"since":{"type":"string","format":"date-time"},"alert_activity":{"type":"object","properties":{"new_alerts_24h":{"type":"integer"},"prior_24h":{"type":"integer"},"change":{"type":"integer"},"critical_alerts":{"type":"integer"},"symbols_affected":{"type":"integer"}}},"regime":{"type":"object","properties":{"regime":{"type":"string"},"confidence":{"type":"number"},"as_of":{"type":"string","format":"date-time"}},"nullable":true},"prior_intel":{"type":"object","properties":{"slug":{"type":"string"},"claim":{"type":"string"},"published_at":{"type":"string","format":"date-time"}},"nullable":true},"note":{"type":"string"}}}}}}}}},"/agent/market-briefing":{"get":{"summary":"Executive market briefing","description":"Synthesised market-wide read: risk score, regime, and the notable detections behind them. Fields the underlying subsystems disagreed on are listed in `contradictions` and dropped from the payload rather than averaged — `withheld` and `withheldReasons` name what is missing and why, so a consumer never has to infer absence. Requires a paid-scope key.","operationId":"getMarketBriefing","responses":{"200":{"description":"Market briefing","content":{"application/json":{"schema":{"type":"object","properties":{"schemaVersion":{"type":"string"},"status":{"type":"string","description":"OK or PARTIAL — PARTIAL means subsystems disagreed"},"contradictions":{"type":"array","items":{"type":"object"}},"withheld":{"type":"array","items":{"type":"string"}},"withheldReasons":{"type":"object"},"asOf":{"type":"string","format":"date-time"},"marketRiskScore":{"type":"number"},"riskLevel":{"type":"string"},"marketStateSnapshotId":{"type":"string"},"subScores":{"type":"array","items":{"type":"object"}}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Key lacks paid scope — response carries an upgrade offer","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/track-record/lead-time":{"get":{"summary":"Verified lead time — the judged record","description":"How far ahead each engine tended to warn, per stratum, with sample sizes and misses included. No key required. Returns STRATA and no aggregate: any headline figure must be derived from `trackRecord`, and `headline` carries its own selection basis. When a stratum is below the publishability threshold it is withheld rather than rounded up — `headlineWithheldReason` and `abstentionReason` say so explicitly.","operationId":"getLeadTime","responses":{"200":{"description":"Judged lead-time record","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"snapshotId":{"type":"string"},"asOf":{"type":"string","format":"date-time"},"dataAsOf":{"type":"string","format":"date-time"},"dataAgeHours":{"type":"number"},"staleAfterHours":{"type":"integer"},"claimTier":{"type":"string"},"dataOrigin":{"type":"string"},"calculationStatus":{"type":"string"},"trackRecord":{"type":"array","items":{"type":"object"},"description":"One entry per measured stratum"},"headline":{"type":"object"},"headlineWithheldReason":{"type":["string","null"]},"headlineSelection":{"type":"object"},"abstentionReason":{"type":["string","null"]},"provenance":{"type":"object"}}}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Firebase ID token (logged-in user) for billing and portfolio endpoints."}},"schemas":{"SpectraDirection":{"type":"string","enum":["bullish","bearish","neutral","unknown"]},"SpectraSeverity":{"type":"string","enum":["critical","high","moderate","low"]},"SpectraRiskLevel":{"type":"string","enum":["critical","high","moderate","low"]},"SpectraActionType":{"type":"string","enum":["hold","reduce","increase","exit","hedge","watch"]},"SpectraVerdict":{"type":"object","properties":{"direction":{"$ref":"#/components/schemas/SpectraDirection"},"confidence":{"type":"number","minimum":0,"maximum":1},"uncertainty":{"type":"number","minimum":0,"maximum":1},"expectedMovePct":{"type":"number","nullable":true},"forecastHorizon":{"type":"string","enum":["12h","24h","72h","7d","30d"]},"severity":{"$ref":"#/components/schemas/SpectraSeverity"},"urgencyScore":{"type":"number","minimum":0,"maximum":1}},"required":["direction","confidence","uncertainty","forecastHorizon","severity","urgencyScore"]},"SpectraReasoning":{"type":"object","properties":{"steps":{"type":"array","items":{"type":"string"}},"toolsUsed":{"type":"array","items":{"type":"string"}},"conflictScore":{"type":"number","minimum":0,"maximum":1},"missingSignals":{"type":"array","items":{"type":"string"}},"cycleCount":{"type":"integer","minimum":1}},"required":["steps","toolsUsed","conflictScore","missingSignals","cycleCount"]},"SpectraCapitalFlow":{"type":"object","properties":{"netFlowUsd":{"type":["number","null"]},"direction":{"type":["string","null"],"enum":["buy_side","sell_side","balanced","withheld",null]},"confidence":{"type":["number","null"],"description":"Uncalibrated unusualness score, not measurement presence or probability."},"trend":{"type":"string","enum":["withheld"]}},"required":["netFlowUsd","direction","confidence","trend"]},"SpectraContagion":{"type":"object","properties":{"risk":{"$ref":"#/components/schemas/SpectraRiskLevel"},"confidence":{"type":"number"},"affectedSymbols":{"type":"array","items":{"type":"object","properties":{"symbol":{"type":"string"},"correlation":{"type":"number"},"expectedImpactPct":{"type":"number"},"timeToMaterializeHours":{"type":"number"}}}}},"required":["risk","confidence","affectedSymbols"]},"SpectraAction":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/SpectraActionType"},"targetExposure":{"type":"number","nullable":true},"timeframe":{"type":"string","enum":["immediate","24h","72h","7d"]},"rationale":{"type":"string"}},"required":["type","timeframe","rationale"]},"SpectraProvenance":{"type":"object","properties":{"source":{"type":"string","enum":["predictions","alerts","agent_verdict","derived"]},"modelVersion":{"type":"string"},"engineNames":{"type":"array","items":{"type":"string"}},"walkForwardValidated":{"type":"boolean"},"dataAsOf":{"type":"string","format":"date-time"}},"required":["source","modelVersion","engineNames","walkForwardValidated","dataAsOf"]},"SpectraAiMetadata":{"type":"object","properties":{"schemaVersion":{"type":"string","enum":["1.0"]},"reasoningTrace":{"type":"boolean"},"confidenceNormalized":{"type":"boolean"},"schemaStable":{"type":"boolean"},"lastModelRetrain":{"type":"string","format":"date","nullable":true}},"required":["schemaVersion","reasoningTrace","confidenceNormalized","schemaStable"]},"SpectraIntelligence":{"type":"object","properties":{"symbol":{"type":"string"},"timestamp":{"type":"string","format":"date-time"},"verdict":{"$ref":"#/components/schemas/SpectraVerdict"},"reasoning":{"$ref":"#/components/schemas/SpectraReasoning"},"capitalFlow":{"$ref":"#/components/schemas/SpectraCapitalFlow"},"contagion":{"$ref":"#/components/schemas/SpectraContagion"},"action":{"$ref":"#/components/schemas/SpectraAction"},"provenance":{"$ref":"#/components/schemas/SpectraProvenance"},"aiMetadata":{"$ref":"#/components/schemas/SpectraAiMetadata"}},"required":["symbol","timestamp","verdict","reasoning","provenance","aiMetadata"]},"SpectraPortfolioRiskAssessment":{"type":"object","properties":{"portfolio":{"type":"object","properties":{"totalValue":{"type":"number"},"overallRiskScore":{"type":"number"},"overallRiskLevel":{"$ref":"#/components/schemas/SpectraRiskLevel"},"expectedDrawdownPct":{"type":["number","null"],"description":"Expected shortfall at 95%: the mean loss across the worst 5% of observations in the window, percent, positive for a loss. Historical measurement over the book's own return distribution, NOT a forecast. Null when unmeasurable — read riskMetricsBasis.reason."},"valueAtRisk95":{"type":["number","null"],"description":"Historical Value-at-Risk at 95% in currency, positive for a loss: on the worst 1 day in 20 of the window, the book lost at least this much. Historical measurement, NOT a forecast. Null when unmeasurable."},"riskMetricsBasis":{"type":"object","description":"How the drawdown and VaR figures were produced, or why they are absent.","properties":{"method":{"type":"string","enum":["historical_simulation","unmeasured"]},"reason":{"type":"string"},"observations":{"type":"integer"},"coveredWeightPct":{"type":"number","description":"Share of book weight with usable price history. The estimate treats this subset as representative; below 60% it abstains."},"uncoveredSymbols":{"type":"array","items":{"type":"string"}},"varLevel":{"type":"number"},"positionAligned":{"type":"boolean","description":"True when series were aligned by position rather than bar timestamp — a weaker basis."}},"required":["method"]}},"required":["totalValue","overallRiskScore","overallRiskLevel","expectedDrawdownPct","valueAtRisk95"]},"positions":{"type":"array","items":{"type":"object","properties":{"symbol":{"type":"string"},"allocation":{"type":"number"},"riskScore":{"type":"number"},"riskLevel":{"$ref":"#/components/schemas/SpectraRiskLevel"},"unrealizedPnlPct":{"type":"number","description":"P&L since entry, percent. Historical and already realized — NOT a forecast. Renamed 2026-08-06 from `expectedMovePct`, a forward-looking name that misrepresented this backward-looking figure."},"correlationToPortfolio":{"type":["number","null"],"description":"Not computed. Always null — never fabricated (2026-07-20)."},"recommendation":{"type":"object","properties":{"action":{"$ref":"#/components/schemas/SpectraActionType"},"rationale":{"type":"string"}},"required":["action","rationale"]}},"required":["symbol","allocation","riskScore","riskLevel","unrealizedPnlPct","correlationToPortfolio","recommendation"],"description":"Zero-allocation holdings are excluded before this array is built — a risk system must not score or recommend on an asset the user does not own."}},"analysisStatus":{"type":"object","description":"Reconciliation between the VaR/drawdown coverage figure and the uncovered-symbol list. PARTIAL when coveredWeightPct reads near-complete while symbols still lack price history, or when the risk metrics are unmeasured outright.","properties":{"status":{"type":"string","enum":["OK","PARTIAL"]},"reason":{"type":"string"}},"required":["status"]},"contagionRisk":{"type":"object","properties":{"highestRiskSymbol":{"type":"string"},"affectedCount":{"type":"integer"},"expectedPortfolioImpactPct":{"type":["number","null"],"description":"Magnitude of the estimated portfolio move, percent, measured as a beta-weighted response to the shock asset's own empirical lower-tail return. Null when it cannot be measured for this book — read basis.reason. Never 0 as a stand-in for unknown."},"basis":{"type":"object","description":"How the estimate was produced, or why it is absent.","properties":{"method":{"type":"string","enum":["beta_weighted_empirical_tail","unmeasured"]},"reason":{"type":"string"},"shockSymbol":{"type":"string"},"shockPct":{"type":["number","null"],"description":"Measured lower-tail move of the shock asset, percent."},"portfolioMovePct":{"type":["number","null"],"description":"Signed portfolio move. Negative is adverse; positive means the book hedges the shock."},"portfolioBeta":{"type":["number","null"]},"coveredWeightPct":{"type":"number"},"tailPercentile":{"type":"number"}},"required":["method"]}},"required":["highestRiskSymbol","affectedCount","expectedPortfolioImpactPct"]},"provenance":{"$ref":"#/components/schemas/SpectraProvenance"},"aiMetadata":{"$ref":"#/components/schemas/SpectraAiMetadata"}},"required":["portfolio","positions","analysisStatus","contagionRisk","provenance","aiMetadata"]},"SpectraContagionMap":{"type":"object","properties":{"nodes":{"type":"array","items":{"type":"object","properties":{"symbol":{"type":"string"},"riskScore":{"type":"number"},"riskLevel":{"$ref":"#/components/schemas/SpectraRiskLevel"},"confidence":{"type":"number"}},"required":["symbol","riskScore","riskLevel","confidence"]}},"edges":{"type":"array","items":{"type":"object","properties":{"source":{"type":"string"},"target":{"type":"string"},"strength":{"type":"number"},"correlation":{"type":"number"},"confidence":{"type":"number"},"severity":{"type":"string","description":"Derived from the edge's own measured strength (tail_correlation), never carried through from the upstream engine's contagion_risk label. Edges below a 0.1 materiality floor are not emitted at all (see server/lib/contagionGraph.ts classifyEdgeSeverity).","enum":["low","moderate","high","extreme"]},"lagHours":{"type":["number","null"],"description":"tail_dependence has no lag column. Always null today; never a fabricated constant."},"sampleSize":{"type":"integer","description":"How many times this (source, target) pair was independently re-observed within the endpoint's 1-hour lookback -- NOT a statistical sample size for the correlation coefficient itself, which tail_dependence does not expose."}},"required":["source","target","strength","correlation","confidence","severity","lagHours","sampleSize"]}},"clusters":{"type":"array","items":{"type":"object","properties":{"symbols":{"type":"array","items":{"type":"string"}},"riskLevel":{"$ref":"#/components/schemas/SpectraRiskLevel"},"leadSymbol":{"type":"string","description":"Absent unless a directed edge into this cluster has a strict out-degree winner AND that winner's out-degree exceeds the runner-up's by at least 20% (a 1-edge margin over a large base is not treated as confident). Never alphabetical, never symbols[0]."},"leadOutDegree":{"type":"integer","description":"Present whenever the cluster has at least one directed edge, regardless of whether the margin was enough to claim leadSymbol -- lets a consumer see a thin-margin case for what it is."},"runnerUpOutDegree":{"type":"integer","description":"Present whenever there is a second out-degree candidate to compare against. Absent when leadOutDegree has no rival (a lone directed edge)."},"lagHours":{"type":"number","description":"Absent unless at least one edge from the lead carries an observed lag. tail_dependence has no lag column today, so this is always absent."},"edgeCount":{"type":"integer"}},"required":["symbols","riskLevel","edgeCount"]}},"provenance":{"$ref":"#/components/schemas/SpectraProvenance"},"aiMetadata":{"$ref":"#/components/schemas/SpectraAiMetadata"}},"required":["nodes","edges","clusters","provenance","aiMetadata"]},"SpectraCapitalFlowResponse":{"type":"object","properties":{"dataState":{"type":"string","enum":["measured","partial","no_data","error"]},"headline":{"type":"string"},"claim":{"type":"object"},"scope":{"type":"object"},"resolutions":{"type":"array","items":{"type":"object"}},"symbol":{"type":["string","null"]},"netFlowUsd":{"type":["number","null"],"description":"Compatibility field for a one-symbol response. Null is no matching observation; zero is a measured balanced window."},"direction":{"type":["string","null"],"enum":["buy_side","sell_side","balanced","withheld",null]},"confidence":{"type":["number","null"],"description":"Uncalibrated unusualness score; not measurement presence and not a probability."},"confidenceMeaning":{"type":"string"},"basis":{"type":"string","enum":["latest_measured_60m_imbalance_usd"]},"dataOrigin":{"type":"string","enum":["order_flow_imbalance_proxy"]},"disclaimer":{"type":"string"},"trend":{"type":"string","enum":["withheld"]},"trendWithheldReason":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"symbol":{"type":"string"},"canonicalInstrumentId":{"type":["string","null"]},"assetClass":{"type":"string"},"venue":{"type":"null"},"observedAt":{"type":["string","null"],"format":"date-time"},"ageMinutes":{"type":["number","null"]},"freshness":{"type":"string","enum":["current","stale","last_session","unknown"]},"windowMinutes":{"type":"integer","enum":[60]},"netFlowUsd":{"type":["number","null"]},"direction":{"type":"string","enum":["buy_side","sell_side","balanced","withheld"]},"detectionScore":{"type":["number","null"]},"isProbability":{"type":"boolean","enum":[false]},"signalConflict":{"type":"boolean"},"withheldReason":{"type":["string","null"]},"observation":{"type":"string"}}}},"notReturned":{"type":"array","items":{"type":"object"}},"conflicts":{"type":"array","items":{"type":"object"}},"summary":{"type":"object"},"limitations":{"type":"object"},"evidence":{"type":"object"},"provenance":{"$ref":"#/components/schemas/SpectraProvenance"},"asOf":{"type":"string","format":"date-time"}},"required":["dataState","headline","basis","dataOrigin","disclaimer","trend","data","summary","provenance"]},"MicrostructureProxyResponse":{"type":"object","properties":{"status":{"type":"string","enum":["ok"]},"dataState":{"type":"string","enum":["measured","partial","no_data","error"]},"headline":{"type":"string"},"claim":{"type":"object"},"scope":{"type":"object"},"resolutions":{"type":"array","items":{"type":"object"}},"data":{"type":"array","items":{"type":"object","properties":{"sourceAlertId":{"type":["number","null"]},"symbol":{"type":"string"},"canonicalInstrumentId":{"type":["string","null"]},"assetClass":{"type":"string"},"venue":{"type":["string","null"]},"quoteCurrency":{"type":["string","null"]},"observedAt":{"type":["string","null"],"format":"date-time"},"ageMinutes":{"type":["number","null"]},"freshness":{"type":"string","enum":["current","recent","historical","unknown"]},"direction":{"type":"string","enum":["buy_side","sell_side","withheld"]},"severity":{"type":"string"},"detectionScore":{"type":["number","null"],"description":"Uncalibrated composite observation score, not a probability."},"isProbability":{"type":"boolean","enum":[false]},"outcomeProbability":{"type":["number","null"],"description":"Null until a calibrated outcome model exists."},"observation":{"type":"string"},"evidence":{"type":"object"},"evidencePlain":{"type":"object"}}}},"notReturned":{"type":"array","items":{"type":"object"}},"conflicts":{"type":"array","items":{"type":"object"}},"summary":{"type":"object"},"limitations":{"type":"object"},"disclaimer":{"type":"string"},"evidence":{"type":"object"},"provenance":{"type":"object"},"asOf":{"type":"string","format":"date-time"}},"required":["status","dataState","headline","data","summary","limitations","disclaimer","provenance","asOf"]},"UnusualMoneyMovementResponse":{"type":"object","properties":{"dataState":{"type":"string","enum":["measured","no_data"]},"headline":{"type":"string"},"claim":{"type":"object"},"dataOrigin":{"type":"string","enum":["candle_derived_order_flow_proxy"]},"data":{"type":"array","items":{"type":"object","properties":{"symbol":{"type":"string"},"canonicalInstrumentId":{"type":["string","null"]},"assetClass":{"type":"string","enum":["crypto","equity"]},"venue":{"type":"null"},"observedAt":{"type":["string","null"],"format":"date-time"},"buyVolumeBaseUnits":{"type":["number","null"]},"sellVolumeBaseUnits":{"type":["number","null"]},"totalVolumeBaseUnits":{"type":["number","null"]},"referencePrice":{"type":["number","null"]},"netFlowUsd":{"type":["number","null"]},"direction":{"type":"string","enum":["buy_side","sell_side","balanced","withheld"]},"detectionScore":{"type":["number","null"]},"scoreType":{"type":"string","enum":["uncalibrated_order_flow_detection_score"]},"isProbability":{"type":"boolean","enum":[false]},"sourceSignal":{"type":["string","null"]},"signalConflict":{"type":"boolean"},"withheldReason":{"type":["string","null"]},"observation":{"type":"string"}}}},"count":{"type":"integer"},"qualifyingCount":{"type":"integer"},"notReturned":{"type":"array","items":{"type":"object"}},"conflicts":{"type":"array","items":{"type":"object"}},"coverage":{"type":"object"},"limitations":{"type":"object"},"evidence":{"type":"object"},"provenance":{"$ref":"#/components/schemas/SpectraProvenance"},"asOf":{"type":"string","format":"date-time"}},"required":["dataState","headline","claim","dataOrigin","data","count","coverage","limitations","provenance","asOf"]}}}}