{"openapi":"3.0.3","info":{"title":"Treasury Risk Analyzer API","description":"Deterministic financial intelligence for autonomous AI Treasury/CFO agents, paid per call in USDC on Base via x402 — no account, no API key. Two payment rails are accepted on every paid route: Circle Gateway batched payments and standard x402 `exact` (EIP-3009) payments, so any x402 v2 client can pay. Exposes three atomic capabilities — treasury/portfolio risk analysis, FX exposure analysis, and liquidity forecasting — plus a composite POST /treasury-decision endpoint that orchestrates all three to answer \"can we safely execute this payment today?\" All share one deterministic engine and one agent-native response format. No LLM is used to produce or estimate a financial value. Requests are validated before payment: invalid input returns a free 400 and is never charged.","version":"1.10.0","contact":{"name":"Kyootek","email":"cm@kyootek.io","url":"https://agents.kyootek.io"},"x-guidance":"Start with GET /demo (free) to see a full real output. For \"can we pay this invoice today?\" call POST /treasury-decision; for a cash runway check call POST /liquidity. Invalid input returns a free 400; paid routes answer 402 with x402 v2 requirements (USDC on Base). Plain-language docs: https://agents.kyootek.io/docs","license":{"name":"ISC","url":"https://opensource.org/license/isc-license-txt"}},"servers":[{"url":"https://portfolio-risk-analyzer-g9ao.onrender.com","description":"Public production deployment (Base mainnet)"}],"paths":{"/":{"get":{"summary":"Machine-readable service description","description":"Free endpoint for agent discovery — name, mission, endpoints, and pricing.","operationId":"getServiceDescription","security":[],"responses":{"200":{"description":"Service description.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceDescription"}}}},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/health":{"get":{"summary":"Liveness check","description":"Free endpoint. Always returns 200 while the service is up.","operationId":"getHealth","security":[],"responses":{"200":{"description":"Service is healthy.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"ok"}}}}}},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/demo":{"get":{"summary":"Free demo on fixed sample data","description":"Runs one of the paid tools on the fixed example input documented in this spec and returns the exact, full output the paid route returns, plus the paid route to call next. Does not accept custom input. Default tool is the treasury decision for a EUR 750,000 supplier invoice. Limited per IP (default 20 calls per hour; see the RateLimit-* response headers).","operationId":"getDemo","security":[],"parameters":[{"name":"tool","in":"query","required":false,"schema":{"type":"string","enum":["treasury-decision","treasury-risk","fx-exposure","liquidity"],"default":"treasury-decision"}}],"responses":{"200":{"description":"Demo result on fixed sample data.","content":{"application/json":{"schema":{"type":"object","required":["status","demo","tool","input","result","next_step"],"properties":{"status":{"type":"string","example":"success"},"demo":{"type":"boolean","example":true},"notice":{"type":"string"},"tool":{"type":"string"},"scenario":{"type":"string"},"input":{"type":"object","description":"The fixed input that was analysed (same shape as the paid route's request body)."},"result":{"type":"object","description":"The paid route's full response for that input."},"next_step":{"type":"object","properties":{"method":{"type":"string"},"url":{"type":"string"},"price":{"type":"string"}}},"other_demos":{"type":"array","items":{"type":"string"}}}}}}},"400":{"description":"Unknown `tool` value.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/treasury-risk":{"post":{"summary":"Deterministic treasury/portfolio risk analysis","description":"Computes volatility, Sharpe/Sortino/Calmar, VaR/Expected Shortfall, multi-dimensional concentration, per-asset risk contribution, and correlated multi-factor stress scenarios (shocks propagate to unshocked symbols via covariance-based beta mapping, not treated as zero) from historical per-period returns and portfolio weights. Requires USDC payment via the x402 protocol (Circle Gateway) — see the 402 response below for the payment flow. Also available at the legacy path POST /analyze (identical behavior).","operationId":"postTreasuryRisk","security":[],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.10"},"protocols":[{"x402":{}}]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyzeRequest"},"examples":{"corporateTreasury":{"summary":"Multi-currency corporate treasury — USD/EUR/GBP cash, USDC and a sukuk fund, 36 monthly returns in USD","value":{"baseCurrency":"USD","returns":{"USDCASH":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"EURCASH":[0.0322,0.0186,-0.0166,-0.0109,0.0172,-0.0254,0.0003,-0.0122,-0.008,0.0095,0.0107,-0.0056,-0.0353,-0.0401,0.001,-0.0176,-0.0535,-0.0263,0.0014,0.0294,-0.0106,0.0028,0.0199,0.0112,0.0097,0.0084,-0.0262,-0.0016,0.0029,0.032,-0.0095,-0.0194,0.008,0.0141,0.056,0.0251],"GBPCASH":[0.0321,-0.0108,-0.0218,-0.0401,0.0243,-0.0144,-0.0006,-0.012,-0.0218,0.016,0.0238,-0.0233,-0.0113,-0.0051,0.0211,-0.0173,-0.0332,-0.0291,0.0412,-0.0067,0.0319,0.0095,0.0217,0.0371,-0.0059,-0.0362,0.0034,0.0031,0.0034,0.0079,0.0037,0.0111,-0.0047,-0.014,-0.0048,0.0047],"USDC":[0.001,0.0001,-0.0002,0.0002,0.0001,0.0002,-0.0001,0,-0.0003,-0.0001,0.0007,0.0007,-0.0001,0.0003,-0.0004,-0.0004,0.0003,-0.0007,-0.0003,0.0002,-0.0007,0,-0.0002,-0.0003,0.0001,-0.0001,0.0005,-0.0008,0.0005,-0.0003,0.0002,-0.0005,-0.0004,-0.0004,-0.0003,-0.0001],"SUKUK":[-0.0052,0.0038,0.0132,0.015,0.0009,0.015,0.0024,-0.0044,-0.0009,-0.0006,0.0014,0.001,-0.0002,0,0.0129,0.0017,0.0096,0.0013,0.0167,0.0007,0.0033,0.0057,-0.0009,0.0004,-0.0088,-0.0094,0.0067,0.0081,0.0105,-0.0008,0.0093,-0.0054,-0.0037,0.0064,-0.0019,0.0055]},"weights":{"USDCASH":0.45,"EURCASH":0.25,"GBPCASH":0.1,"USDC":0.12,"SUKUK":0.08},"riskFreeRate":0,"periodsPerYear":12,"confidenceLevels":[0.95,0.99],"currencyExposure":{"USD":0.65,"EUR":0.25,"GBP":0.1},"stressScenarios":[{"name":"EUR -10% vs USD","shocks":{"EURCASH":-0.1}},{"name":"USD strength: EUR -8%, GBP -8%","shocks":{"EURCASH":-0.08,"GBPCASH":-0.08}}]}}}}}},"responses":{"200":{"description":"Risk analysis report (agent-native envelope).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyzeReport"}}}},"400":{"description":"Invalid request body (see `error.message` for the specific validation failure). Input is validated before payment is requested, so a 400 is never charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"description":"Payment Required (x402). No valid payment was presented. The `payment-required` response header carries a base64-encoded JSON object describing how to pay — see `PaymentRequirements` below. Use an x402-aware client (e.g. `circle services pay`, `@x402/fetch` or the `treasury-risk-mcp` MCP server) to pay and retry automatically; do not attempt to construct the payment by hand.","headers":{"payment-required":{"description":"Base64-encoded JSON PaymentRequirements object.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","description":"Empty body; payment details are in the `payment-required` header."}}}},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/analyze":{"post":{"summary":"Deterministic treasury/portfolio risk analysis (legacy alias)","description":"Identical to POST /treasury-risk, kept for backward compatibility with earlier integrations.","operationId":"postAnalyzeLegacyAlias","security":[],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.10"},"protocols":[{"x402":{}}]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyzeRequest"}}}},"responses":{"200":{"description":"Risk analysis report (agent-native envelope).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyzeReport"}}}},"400":{"description":"Invalid request body. Validated before payment is requested, so a 400 is never charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment Required (x402) — see POST /treasury-risk for the full payment flow documentation."}}}},"/fx-exposure":{"post":{"summary":"Deterministic FX exposure analysis","description":"Computes gross/net exposure, currency concentration, natural hedges, stress scenarios, and hedge priority from a list of receivable/ payable/cash positions by currency. Requires USDC payment via the x402 protocol (Circle Gateway) — see the 402 response for the payment flow.","operationId":"postFxExposure","security":[],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.25"},"protocols":[{"x402":{}}]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FxAnalyzeRequest"},"examples":{"corporateTreasury":{"summary":"EUR receivable, GBP payable, both unhedged","value":{"baseCurrency":"USD","positions":[{"currency":"EUR","type":"receivable","amount":500000,"hedged":false},{"currency":"GBP","type":"payable","amount":200000,"hedged":false}],"fxRates":{"EUR":1.08,"GBP":1.27},"stressShockPct":0.1}}}}}},"responses":{"200":{"description":"FX exposure report (agent-native envelope).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FxAnalyzeReport"}}}},"400":{"description":"Invalid request body. Validated before payment is requested, so a 400 is never charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"description":"Payment Required (x402). Payment requirements are carried in the base64-encoded `payment-required` response header, not the body.","headers":{"payment-required":{"description":"Base64-encoded JSON PaymentRequirements object.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","description":"Empty body; payment details are in the `payment-required` header."}}}},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/liquidity":{"post":{"summary":"Deterministic liquidity forecast","description":"Projects daily cash balance from opening cash and a list of scheduled cash flow events over a forecast horizon, flags minimum-buffer breaches, and classifies liquidity status. Optionally also computes standard working-capital ratios (DSO/DPO/DIO/cash conversion cycle) from a supplied balance snapshot. Requires USDC payment via the x402 protocol (Circle Gateway) — see the 402 response for the payment flow.","operationId":"postLiquidity","security":[],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.50"},"protocols":[{"x402":{}}]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LiquidityRequest"},"examples":{"bufferBreach":{"summary":"Opening cash 800k, one 500k outflow, 500k required buffer","value":{"openingCash":800000,"startDate":"2026-09-14","horizonDays":30,"minimumCashBuffer":500000,"cashFlows":[{"date":"2026-09-27","amount":-500000,"category":"payable","description":"Supplier invoice"}]}}}}}},"responses":{"200":{"description":"Liquidity forecast report (agent-native envelope).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LiquidityReport"}}}},"400":{"description":"Invalid request body. Validated before payment is requested, so a 400 is never charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"description":"Payment Required (x402). Payment requirements are carried in the base64-encoded `payment-required` response header, not the body.","headers":{"payment-required":{"description":"Base64-encoded JSON PaymentRequirements object.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","description":"Empty body; payment details are in the `payment-required` header."}}}},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/treasury-decision":{"post":{"summary":"Composite payment decision (\"can we safely execute this payment today?\")","description":"Orchestrates the liquidity, FX exposure, and (optionally) treasury risk capabilities to produce a PAY/REVIEW/DO_NOT_PAY decision with a confidence score. The payment is injected as an outflow into the liquidity forecast and as a new unhedged payable position in the FX exposure analysis. Requires USDC payment via the x402 protocol (Circle Gateway) — see the 402 response for the payment flow. This is decision-support output, not an instruction to execute any transaction.","operationId":"postTreasuryDecision","security":[],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"2.00"},"protocols":[{"x402":{}}]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TreasuryDecisionRequest"},"examples":{"centralScenario":{"summary":"Can we pay a EUR 750,000 invoice today?","value":{"baseCurrency":"USD","payment":{"amount":750000,"currency":"EUR","date":"2026-09-14"},"liquidity":{"openingCash":5000000,"startDate":"2026-09-14","horizonDays":30,"minimumCashBuffer":1000000},"fxExposure":{"fxRates":{"EUR":1.08}}}}}}}},"responses":{"200":{"description":"Treasury decision report (agent-native envelope).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TreasuryDecisionReport"}}}},"400":{"description":"Invalid request body (may be prefixed with `liquidity:`, `fxExposure:`, or `treasuryRisk:` if the error originates in that sub-section). Validated before payment is requested, so a 400 is never charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"description":"Payment Required (x402). Payment requirements are carried in the base64-encoded `payment-required` response header, not the body.","headers":{"payment-required":{"description":"Base64-encoded JSON PaymentRequirements object.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","description":"Empty body; payment details are in the `payment-required` header."}}}},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}}},"components":{"securitySchemes":{"x402":{"type":"apiKey","in":"header","name":"PAYMENT-SIGNATURE","description":"Pay-per-call in USDC on Base mainnet (eip155:8453) via x402 v2 — no account or API key. Call the endpoint without this header to receive a 402 whose base64 `payment-required` header lists two accepted options for the same price and payee: (1) Circle Gateway batched (`extra.name: GatewayWalletBatched`, e.g. `circle services pay` or the `@circle-fin/x402-batching` client) and (2) standard x402 `exact` with EIP-3009 USDC (`extra.name: USD Coin`, e.g. `@x402/fetch`, `@x402/axios` or the Coinbase x402 SDK). Sign one option and retry with this header set. Invalid request bodies are rejected with a free 400 before any payment is requested."}},"responses":{"Unauthorized":{"description":"Reserved for future use. This service currently has no authentication layer beyond per-call x402 payment on the paid routes."},"Forbidden":{"description":"Reserved for future use (e.g. access restrictions on a given resource)."},"NotFound":{"description":"The requested path does not exist."},"RateLimited":{"description":"Too many requests. Enforced by the application on the free GET /demo route (per IP, fixed one-hour window; see the Retry-After header). On other routes a 429 may originate from the hosting platform.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"InternalError":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"ServiceUnavailable":{"description":"Service temporarily unavailable (e.g. cold start on the free hosting tier, or platform-level maintenance)."}},"schemas":{"ServiceDescription":{"type":"object","properties":{"name":{"type":"string","example":"Treasury Risk Analyzer"},"mission":{"type":"string"},"category":{"type":"string"},"endpoints":{"type":"object","additionalProperties":{"type":"object","properties":{"price":{"type":"string"},"description":{"type":"string"}}}},"ai_involvement":{"type":"string"}}},"ErrorEnvelope":{"type":"object","properties":{"status":{"type":"string","enum":["error"]},"error":{"type":"object","properties":{"code":{"type":"string","example":"INVALID_INPUT"},"message":{"type":"string"}}}}},"PaymentRequirements":{"type":"object","description":"Decoded shape of the base64 `payment-required` response header (x402 v2).","properties":{"x402Version":{"type":"integer","example":2},"resource":{"type":"object","properties":{"url":{"type":"string"},"description":{"type":"string"},"mimeType":{"type":"string"}}},"accepts":{"type":"array","items":{"type":"object","properties":{"scheme":{"type":"string","example":"exact"},"network":{"type":"string","example":"eip155:8453","description":"CAIP-2 network id (eip155:8453 = Base mainnet)"},"asset":{"type":"string","description":"USDC contract address"},"amount":{"type":"string","description":"Amount in the asset's smallest unit (e.g. 100000 = $0.10 USDC at 6 decimals)"},"payTo":{"type":"string","description":"Seller wallet address"},"maxTimeoutSeconds":{"type":"integer"}}}}}},"AnalyzeRequest":{"type":"object","required":["returns","weights"],"properties":{"returns":{"type":"object","description":"Per-period historical return series by symbol. All series must be the same length (≥2 observations).","additionalProperties":{"type":"array","items":{"type":"number"}},"example":{"USDCASH":[0,0,0],"EURCASH":[0.0121,-0.0187,0.0065],"GBPCASH":[0.0094,-0.0203,0.0071]}},"weights":{"type":"object","description":"Portfolio weights by symbol. Must cover exactly the same symbols as `returns` and sum to 1.","additionalProperties":{"type":"number"},"example":{"USDCASH":0.6,"EURCASH":0.3,"GBPCASH":0.1}},"riskFreeRate":{"type":"number","description":"Annualized risk-free rate, e.g. 0.04 for 4%.","default":0},"periodsPerYear":{"type":"number","description":"Periods per year in the return series (252 for daily equities, 365 for daily crypto).","default":252},"confidenceLevels":{"type":"array","items":{"type":"number"},"description":"Confidence levels for VaR/Expected Shortfall. Supported: 0.9, 0.95, 0.975, 0.99, 0.995.","default":[0.95,0.99]},"baseCurrency":{"type":"string","default":"USD"},"minimumAcceptableReturn":{"type":"number","description":"Per-period MAR used for downside deviation / Sortino ratio.","default":0},"benchmarkReturns":{"type":"array","items":{"type":"number"},"description":"Optional per-period benchmark series (same length as each `returns` series) to compute beta and correlation."},"currencyExposure":{"type":"object","description":"Optional weight distribution by currency, for concentration analysis.","additionalProperties":{"type":"number"}},"geographyExposure":{"type":"object","description":"Optional weight distribution by geography, for concentration analysis.","additionalProperties":{"type":"number"}},"sectorExposure":{"type":"object","description":"Optional weight distribution by sector, for concentration analysis.","additionalProperties":{"type":"number"}},"stressScenarios":{"type":"array","description":"Optional stress scenarios. Shocks on the listed symbols propagate to unshocked symbols via covariance-based beta mapping (correlated impact), alongside the direct-only impact.","items":{"type":"object","properties":{"name":{"type":"string"},"shocks":{"type":"object","description":"Fractional shock per symbol, e.g. -0.3 for a 30% drop.","additionalProperties":{"type":"number"}}}}}}},"AnalyzeReport":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"analysis_id":{"type":"string","format":"uuid"},"timestamp":{"type":"string","format":"date-time"},"portfolio":{"type":"object","properties":{"base_currency":{"type":"string"},"assets":{"type":"integer"}}},"risk_metrics":{"type":"object","properties":{"annualized_return":{"type":"number"},"annualized_volatility":{"type":"number"},"annualized_downside_deviation":{"type":"number"},"sharpe_ratio":{"type":"number","nullable":true},"sortino_ratio":{"type":"number","nullable":true},"calmar_ratio":{"type":"number","nullable":true},"diversification_ratio":{"type":"number","nullable":true},"beta":{"type":"number","nullable":true},"correlation_to_benchmark":{"type":"number","nullable":true},"max_drawdown":{"type":"number"},"value_at_risk":{"type":"object","additionalProperties":{"type":"object","properties":{"parametric":{"type":"number","nullable":true},"historical":{"type":"number"}}}},"expected_shortfall":{"type":"object","additionalProperties":{"type":"object","properties":{"parametric":{"type":"number","nullable":true},"historical":{"type":"number"}}}},"hhi":{"type":"number"}}},"concentration":{"type":"object","additionalProperties":{"type":"object","properties":{"hhi":{"type":"number"},"effectiveCount":{"type":"number","nullable":true}}}},"risk_contribution":{"type":"object","additionalProperties":{"type":"number"}},"stress_test":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"portfolioImpact":{"type":"number","description":"Total portfolio impact including both direct shocks and correlated implied shocks."},"directOnlyImpact":{"type":"number","description":"Naive portfolio impact from directShocks alone, ignoring correlation to unshocked symbols — kept for comparison."},"directShocks":{"type":"object","description":"The user-specified shocks that matched a portfolio symbol.","additionalProperties":{"type":"number"}},"impliedShocks":{"type":"object","description":"Shocks inferred for portfolio symbols not directly named in the scenario, via factor-beta mapping on the historical covariance matrix of the directly-shocked symbols. Empty if every portfolio symbol was directly shocked, or if none of the scenario's shocks matched a portfolio symbol. A value is exactly 0 when the relationship was not propagated — see `propagation` for the reason.","additionalProperties":{"type":"number"}},"propagation":{"type":"object","description":"Per unshocked symbol, why its implied shock is what it is. `propagated` only when the regression on the usable drivers is significant (F-test p < 0.05); `not_significant` (implied shock 0), `zero_variance` (the symbol never moved historically), or `no_usable_driver` (every shocked symbol was excluded, see excludedDrivers).","additionalProperties":{"type":"object","properties":{"status":{"type":"string","enum":["propagated","not_significant","zero_variance","no_usable_driver"]},"rSquared":{"type":"number","nullable":true},"pValue":{"type":"number","nullable":true}}}},"excludedDrivers":{"type":"array","description":"Shocked symbols NOT used to infer other symbols' moves: `zero_variance` (no historical movement to learn from) or `extrapolation` (the shock exceeds 50 of the symbol's own per-period standard deviations — a regime change such as a stablecoin depeg, outside the range the correlation was estimated on). Their direct shock still counts in portfolioImpact.","items":{"type":"object","properties":{"symbol":{"type":"string"},"reason":{"type":"string","enum":["zero_variance","extrapolation"]},"sigmaMultiple":{"type":"number","nullable":true}}}},"unmatchedSymbols":{"type":"array","description":"Scenario shock keys that did not match any portfolio symbol (e.g. a macro factor name) — excluded from both direct and implied impact.","items":{"type":"string"}}}}},"risk_classification":{"type":"object","properties":{"level":{"type":"string","enum":["LOW","MEDIUM","HIGH"]},"score":{"type":"integer","minimum":0,"maximum":100}}},"warnings":{"type":"array","items":{"type":"string"}},"data_quality":{"type":"object","properties":{"sample_size":{"type":"integer"},"minimum_recommended_sample_size":{"type":"integer"},"sufficient_sample_size":{"type":"boolean"},"benchmark_provided":{"type":"boolean"}}},"methodology":{"type":"object","additionalProperties":{"type":"string"}},"limitations":{"type":"array","items":{"type":"string"}}}},"FxPosition":{"type":"object","required":["currency","type","amount"],"properties":{"currency":{"type":"string","example":"EUR"},"type":{"type":"string","enum":["receivable","payable","cash"]},"amount":{"type":"number","minimum":0},"hedged":{"type":"boolean","default":false}}},"FxAnalyzeRequest":{"type":"object","required":["positions","fxRates"],"properties":{"baseCurrency":{"type":"string","default":"USD"},"positions":{"type":"array","items":{"$ref":"#/components/schemas/FxPosition"}},"fxRates":{"type":"object","description":"Units of baseCurrency per 1 unit of each foreign currency present in `positions`.","additionalProperties":{"type":"number"},"example":{"EUR":1.08,"GBP":1.27}},"stressShockPct":{"type":"number","description":"Fractional depreciation applied to each foreign currency in the stress scenario.","default":0.1},"totalTreasuryValueBase":{"type":"number","description":"Optional total treasury value (in baseCurrency) used to normalize the risk score. Defaults to total gross FX exposure if omitted."}}},"FxAnalyzeReport":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"analysis_id":{"type":"string","format":"uuid"},"timestamp":{"type":"string","format":"date-time"},"base_currency":{"type":"string"},"fx_metrics":{"type":"object","properties":{"gross_exposure":{"type":"object","additionalProperties":{"type":"number"}},"net_exposure":{"type":"object","additionalProperties":{"type":"number"}},"hedged_net_exposure":{"type":"object","additionalProperties":{"type":"number"}},"unhedged_net_exposure":{"type":"object","additionalProperties":{"type":"number"}},"unhedged_ratio":{"type":"number"},"currency_concentration":{"type":"object","properties":{"hhi":{"type":"number"},"effectiveCount":{"type":"number","nullable":true}}}}},"natural_hedges":{"type":"array","items":{"type":"object","properties":{"currency":{"type":"string"},"offsetAmount":{"type":"number"}}}},"stress_test":{"type":"array","items":{"type":"object","properties":{"scenario":{"type":"string"},"currency":{"type":"string"},"impact":{"type":"number","description":"Economic P&L in base currency of the shock on the UNHEDGED net exposure (hedged positions assumed fully offset)."},"impactBeforeHedges":{"type":"number","description":"Same shock applied to the whole net exposure, ignoring hedges — for comparison."}}}},"hedge_priority":{"type":"array","items":{"type":"string"}},"risk_classification":{"type":"object","properties":{"level":{"type":"string","enum":["LOW","MEDIUM","HIGH"]},"score":{"type":"integer","minimum":0,"maximum":100}}},"warnings":{"type":"array","items":{"type":"string"}},"data_quality":{"type":"object"},"methodology":{"type":"object","additionalProperties":{"type":"string"}},"limitations":{"type":"array","items":{"type":"string"}}}},"CashFlow":{"type":"object","required":["date","amount"],"properties":{"date":{"type":"string","format":"date","example":"2026-09-27"},"amount":{"type":"number","description":"Signed amount; positive is an inflow, negative is an outflow."},"category":{"type":"string","maxLength":50,"example":"payable"},"description":{"type":"string","maxLength":200}}},"LiquidityRequest":{"type":"object","required":["openingCash","horizonDays","minimumCashBuffer"],"properties":{"baseCurrency":{"type":"string","default":"USD"},"openingCash":{"type":"number"},"startDate":{"type":"string","format":"date","description":"Defaults to today (UTC) if omitted."},"horizonDays":{"type":"integer","minimum":1,"maximum":3650},"minimumCashBuffer":{"type":"number","minimum":0},"cashFlows":{"type":"array","items":{"$ref":"#/components/schemas/CashFlow"},"description":"Each date must be on or after startDate; dates beyond the horizon are excluded from the projection (and flagged in warnings/data_quality) rather than rejected."},"workingCapital":{"$ref":"#/components/schemas/WorkingCapitalInput"}}},"WorkingCapitalInput":{"type":"object","description":"Optional standard accounting ratios (DSO/DPO/DIO/cash conversion cycle) computed from a balance snapshot and period flow — independent of the cashFlows-based daily projection above.","required":["accountsReceivable","accountsPayable","periodCreditSales","periodCOGS","periodDays"],"properties":{"accountsReceivable":{"type":"number","minimum":0,"description":"AR balance snapshot, in baseCurrency."},"accountsPayable":{"type":"number","minimum":0,"description":"AP balance snapshot, in baseCurrency."},"periodCreditSales":{"type":"number","minimum":0,"description":"Credit sales over the reference period, in baseCurrency."},"periodCOGS":{"type":"number","minimum":0,"description":"Cost of goods sold / purchases over the reference period, in baseCurrency."},"periodDays":{"type":"number","minimum":0,"exclusiveMinimum":true,"maximum":3650,"description":"Length of the reference period in days (e.g. 365 for a trailing year, 90 for a quarter).","example":365},"inventory":{"type":"number","minimum":0,"description":"Optional inventory balance snapshot — enables days_inventory_outstanding and a full cash conversion cycle."}}},"LiquidityReport":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"analysis_id":{"type":"string","format":"uuid"},"timestamp":{"type":"string","format":"date-time"},"base_currency":{"type":"string"},"forecast":{"type":"object","properties":{"start_date":{"type":"string","format":"date"},"horizon_days":{"type":"integer"},"opening_cash":{"type":"number"},"minimum_cash_position":{"type":"number"},"minimum_date":{"type":"string","format":"date"},"projected_cash_peak":{"type":"number"},"peak_date":{"type":"string","format":"date"},"required_buffer":{"type":"number"},"shortfall":{"type":"number"},"buffer_breach":{"type":"boolean"}}},"liquidity_status":{"type":"string","enum":["HEALTHY","WARNING","CRITICAL"]},"recommended_action":{"type":"string","nullable":true},"projection":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date"},"cashBalance":{"type":"number"}}}},"working_capital":{"type":"object","description":"Present only if workingCapital was supplied in the request.","properties":{"days_sales_outstanding":{"type":"number","nullable":true},"days_payable_outstanding":{"type":"number","nullable":true},"days_inventory_outstanding":{"type":"number","nullable":true},"cash_conversion_cycle":{"type":"number","nullable":true},"includes_inventory":{"type":"boolean"}}},"risk_classification":{"type":"object","properties":{"level":{"type":"string","enum":["LOW","MEDIUM","HIGH"]},"score":{"type":"integer","minimum":0,"maximum":100}}},"warnings":{"type":"array","items":{"type":"string"}},"data_quality":{"type":"object"},"methodology":{"type":"object","additionalProperties":{"type":"string"}},"limitations":{"type":"array","items":{"type":"string"}}}},"PaymentInput":{"type":"object","required":["amount","currency"],"properties":{"amount":{"type":"number","minimum":0,"exclusiveMinimum":true},"currency":{"type":"string","example":"EUR"},"date":{"type":"string","format":"date","description":"Defaults to liquidity.startDate (or today) if omitted."},"description":{"type":"string","maxLength":200}}},"TreasuryDecisionRequest":{"type":"object","required":["payment","liquidity","fxExposure"],"properties":{"baseCurrency":{"type":"string","default":"USD"},"payment":{"$ref":"#/components/schemas/PaymentInput"},"liquidity":{"description":"Same shape as LiquidityRequest, minus baseCurrency (the payment is auto-injected as an additional cash flow outflow).","type":"object","required":["openingCash","horizonDays","minimumCashBuffer"],"properties":{"openingCash":{"type":"number"},"startDate":{"type":"string","format":"date"},"horizonDays":{"type":"integer","minimum":1,"maximum":3650},"minimumCashBuffer":{"type":"number","minimum":0},"cashFlows":{"type":"array","items":{"$ref":"#/components/schemas/CashFlow"}},"workingCapital":{"$ref":"#/components/schemas/WorkingCapitalInput"}}},"fxExposure":{"description":"Same shape as the /fx-exposure request body minus baseCurrency; positions is optional (the payment is auto-injected as a new unhedged payable position). fxRates must include the payment currency's rate if it differs from baseCurrency.","type":"object","properties":{"positions":{"type":"array","items":{"$ref":"#/components/schemas/FxPosition"}},"fxRates":{"type":"object","additionalProperties":{"type":"number"}},"stressShockPct":{"type":"number","default":0.1},"totalTreasuryValueBase":{"type":"number"}}},"treasuryRisk":{"description":"Optional. Same shape as AnalyzeRequest (treasury/portfolio risk) — if omitted, that dimension is not evaluated and is excluded from the decision matrix.","$ref":"#/components/schemas/AnalyzeRequest"}}},"TreasuryDecisionReport":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"analysis_id":{"type":"string","format":"uuid"},"timestamp":{"type":"string","format":"date-time"},"base_currency":{"type":"string"},"payment":{"type":"object","properties":{"amount":{"type":"number"},"currency":{"type":"string"},"amount_base_currency":{"type":"number"},"date":{"type":"string","format":"date"}}},"decision":{"type":"string","enum":["PAY","REVIEW","DO_NOT_PAY"]},"confidence":{"type":"number","minimum":0,"maximum":1,"description":"Deterministic data-completeness score, not a probability of a good outcome."},"components":{"type":"object","properties":{"liquidity":{"type":"object","properties":{"status":{"type":"string","enum":["HEALTHY","WARNING","CRITICAL"]},"minimum_cash_position":{"type":"number"},"minimum_date":{"type":"string","format":"date"},"required_buffer":{"type":"number"},"shortfall":{"type":"number"}}},"fx_exposure":{"type":"object","properties":{"risk_level":{"type":"string","enum":["LOW","MEDIUM","HIGH"]},"score":{"type":"integer"},"context":{"type":"string","enum":["full_book","payment_only"],"description":"full_book if fxExposure.positions was supplied; payment_only if the payment itself was the only position, in which case risk_level reflects its own stress impact rather than book-level concentration."},"net_exposure_payment_currency":{"type":"number"},"currency_concentration_hhi":{"type":"number","nullable":true}}},"treasury_risk":{"type":"object","properties":{"evaluated":{"type":"boolean"},"risk_level":{"type":"string","enum":["LOW","MEDIUM","HIGH"]},"score":{"type":"integer"}}}}},"warnings":{"type":"array","items":{"type":"string"}},"data_quality":{"type":"object"},"methodology":{"type":"object","additionalProperties":{"type":"string"}},"limitations":{"type":"array","items":{"type":"string"}}}}}}}