{"openapi":"3.1.0","info":{"title":"Stock Market API","description":"A transparent stock market API with full source traceability and documented calculations","version":"0.1.0"},"paths":{"/api/v1/health":{"get":{"tags":["health"],"summary":"Health Check","description":"Liveness probe: returns healthy if the DB is reachable.","operationId":"health_check_api_v1_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}}}},"/api/v1/ready":{"get":{"tags":["health"],"summary":"Readiness Check","description":"Readiness probe: DB + Redis + recent JobRun activity.\n\nReturns 503 if the database is down (the API can't serve anything).\nReturns 200 with status \"degraded\" if Redis is unreachable or no\nrecent JobRun exists — the API still works, but the data pipeline\nor rate-limit infra may need attention.","operationId":"readiness_check_api_v1_ready_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/auth/keys":{"post":{"tags":["Authentication"],"summary":"Create Api Key","description":"Create a new free-tier API key.\n\nThe full API key is only shown once in this response.\nStore it securely - it cannot be retrieved later.","operationId":"create_api_key_api_v1_auth_keys_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Authentication"],"summary":"Revoke Api Key","description":"Revoke the current API key.\n\nThis permanently deactivates the key. Note: There is a 7-day\ncooldown period before a new key can be created with the same email.","operationId":"revoke_api_key_api_v1_auth_keys_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/v1/auth/keys/me":{"get":{"tags":["Authentication"],"summary":"Get Current Key Info","description":"Get information about the current API key.\n\nReturns usage statistics, tier, and limits.","operationId":"get_current_key_info_api_v1_auth_keys_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyInfo"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/v1/auth/keys/rotate":{"post":{"tags":["Authentication"],"summary":"Rotate Api Key","description":"Rotate the current API key.\n\nInvalidates the old key and returns a new one.\nThe new key retains the same tier and subscription.","operationId":"rotate_api_key_api_v1_auth_keys_rotate_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyRotateResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/v1/billing/checkout/stripe":{"post":{"tags":["Billing"],"summary":"Create Stripe Checkout","description":"Create a Stripe checkout session for subscription upgrade.\n\nReturns a URL to redirect the user to for payment.","operationId":"create_stripe_checkout_api_v1_billing_checkout_stripe_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/v1/billing/checkout/stripe/start":{"get":{"tags":["Billing"],"summary":"Start Stripe Checkout","description":"Anonymous Stripe checkout start — used by the public /pricing page.\n\nRedirects the user to Stripe's hosted checkout for the requested plan.\nOn success Stripe webhook creates the API key + subscription.","operationId":"start_stripe_checkout_api_v1_billing_checkout_stripe_start_get","parameters":[{"name":"plan","in":"query","required":true,"schema":{"type":"string","pattern":"^(monthly|yearly|monthly_plus|yearly_plus)$","title":"Plan"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/billing/checkout/crypto":{"post":{"tags":["Billing"],"summary":"Create Crypto Checkout","description":"Create a Coinbase Commerce charge for crypto payment.\n\nReturns a URL to redirect the user to for payment.","operationId":"create_crypto_checkout_api_v1_billing_checkout_crypto_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/v1/billing/subscription":{"get":{"tags":["Billing"],"summary":"Get Subscription","description":"Get current subscription information.","operationId":"get_subscription_api_v1_billing_subscription_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionInfo"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/v1/billing/cancel":{"get":{"tags":["Billing"],"summary":"Payment Cancel","description":"Payment cancellation redirect page.","operationId":"payment_cancel_api_v1_billing_cancel_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"tags":["Billing"],"summary":"Cancel Subscription","description":"Cancel the current subscription.","operationId":"cancel_subscription_api_v1_billing_cancel_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/v1/billing/success":{"get":{"tags":["Billing"],"summary":"Payment Success","description":"Payment success redirect page.","operationId":"payment_success_api_v1_billing_success_get","parameters":[{"name":"session_id","in":"query","required":false,"schema":{"type":"string","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/billing/webhooks/stripe":{"post":{"tags":["Billing"],"summary":"Stripe Webhook","description":"Handle Stripe webhook events.","operationId":"stripe_webhook_api_v1_billing_webhooks_stripe_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookResponse"}}}}}}},"/api/v1/billing/webhooks/coinbase":{"post":{"tags":["Billing"],"summary":"Coinbase Webhook","description":"Handle Coinbase Commerce webhook events.","operationId":"coinbase_webhook_api_v1_billing_webhooks_coinbase_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookResponse"}}}}}}},"/api/v1/companies":{"get":{"tags":["companies"],"summary":"List Companies","description":"List all companies with pagination.","operationId":"list_companies_api_v1_companies_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Items per page","default":20,"title":"Page Size"},"description":"Items per page"},{"name":"sector","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by sector","title":"Sector"},"description":"Filter by sector"},{"name":"exchange","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by exchange","title":"Exchange"},"description":"Filter by exchange"},{"name":"security_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by security type: 'equity' or 'etf'. Omit for both (the default — ETFs are part of the covered universe).","title":"Security Type"},"description":"Filter by security type: 'equity' or 'etf'. Omit for both (the default — ETFs are part of the covered universe)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_CompanyListItem_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/companies/search":{"get":{"tags":["companies"],"summary":"Search Companies","description":"Search companies by ticker or name.\n\nResults are ranked exact-ticker first, then ticker-prefix, then any other\nticker/name substring match (ticker-alphabetical within each tier) so a\nticker lookup returns the intended company first. User-supplied LIKE\nwildcards (``%``/``_``) are escaped and matched literally.","operationId":"search_companies_api_v1_companies_search_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":2,"maxLength":64,"description":"Search query","title":"Q"},"description":"Search query"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_CompanyListItem_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/companies/coverage":{"get":{"tags":["companies"],"summary":"Get Coverage","description":"Full covered-universe listing in a single call.\n\nCompact rows (ticker, name, exchange, sector, country, has_price_data) for\nevery active company, so a consumer can align its universe to ours without\npaging ``/companies`` (capped at MAX_PAGE_SIZE). For full profiles use\n``/companies/bulk``; for calculated metrics use ``/companies/metrics/bulk``.","operationId":"get_coverage_api_v1_companies_coverage_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"exchange","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by exchange (e.g. NASDAQ, NYSE, ASX)","title":"Exchange"},"description":"Filter by exchange (e.g. NASDAQ, NYSE, ASX)"},{"name":"security_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by security type: 'equity' or 'etf'. Omit for both.","title":"Security Type"},"description":"Filter by security type: 'equity' or 'etf'. Omit for both."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoverageResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/companies/bulk":{"get":{"tags":["companies"],"summary":"Bulk Get Companies","description":"Get detailed info for multiple companies in a single call.\n\nAccepts up to 25 comma-separated ticker symbols and returns\ncompany details including latest financials date, data completeness,\nand price data availability.","operationId":"bulk_get_companies_api_v1_companies_bulk_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"tickers","in":"query","required":true,"schema":{"type":"string","description":"Comma-separated list of ticker symbols (max 25)","examples":["AAPL,MSFT,GOOGL"],"title":"Tickers"},"description":"Comma-separated list of ticker symbols (max 25)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkCompanyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/companies/metrics/bulk":{"get":{"tags":["companies"],"summary":"Bulk Get Metrics","description":"Calculated metrics for multiple companies in a single call.\n\nPath is ``/api/v1/companies/metrics/bulk``. Accepts either ``?tickers=`` or\nits alias ``?symbols=`` (max 100). Each ticker is resolved via the same\nlogic as /{ticker}/metrics/summary (latest FY financials, latest market\ndata). Tickers without financial data are reported in `not_found` rather\nthan failing the whole request.","operationId":"bulk_get_metrics_api_v1_companies_metrics_bulk_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"tickers","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated list of ticker symbols (max 100)","examples":["AAPL,MSFT,GOOGL"],"title":"Tickers"},"description":"Comma-separated list of ticker symbols (max 100)"},{"name":"symbols","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Alias for `tickers` (accepted for consumer convenience).","title":"Symbols"},"description":"Alias for `tickers` (accepted for consumer convenience)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkMetricsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/companies/quotes":{"get":{"tags":["companies"],"summary":"Get Quotes","description":"Batch quotes for a watchlist — one call for many symbols.\n\nReturns delayed / end-of-day data (price, change, day range, volume,\nmarket cap, 52-week range) assembled from the latest market-data snapshot\nand daily price history. This is **not** a real-time feed: every quote\ncarries ``is_delayed: true`` plus ``as_of`` / ``updated_at`` so consumers\ncan see exactly how stale each value is. Symbols we don't track, or that\nhave no price/market data, are returned in ``not_found``.","operationId":"get_quotes_api_v1_companies_quotes_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"symbols","in":"query","required":true,"schema":{"type":"string","description":"Comma-separated ticker symbols (max 100)","examples":["NVDA,AMD,CRWD"],"title":"Symbols"},"description":"Comma-separated ticker symbols (max 100)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/companies/{ticker}":{"get":{"tags":["companies"],"summary":"Get Company","description":"Get company details by ticker (supports aliases).","operationId":"get_company_api_v1_companies__ticker__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","title":"Ticker"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/companies/{ticker}/logo":{"get":{"tags":["companies"],"summary":"Company Logo","description":"Company logo bytes, cached in R2.\n\nPUBLIC (no API key) so it can be embedded directly in an ``<img src>``. A real\nlogo is cached for a week; a placeholder only briefly (see below). This is what\n``CompanyDetail.logo_url`` points to. Serves a generic placeholder when we have\nno domain for the company (or the ticker is unknown), so the URL is always safe\nto render.\n\n``theme``/``format`` are honoured by Logo.dev; if no Logo.dev token is\nconfigured we fall back to scraped favicons, which have no variants — the\nrequest still succeeds, it just returns the default artwork.","operationId":"company_logo_api_v1_companies__ticker__logo_get","parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","title":"Ticker"}},{"name":"theme","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Colour variant for your background: auto, light, or dark.","title":"Theme"},"description":"Colour variant for your background: auto, light, or dark."},{"name":"format","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Image format: png, webp, or jpg. png/webp carry transparency.","title":"Format"},"description":"Image format: png, webp, or jpg. png/webp carry transparency."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/companies/{ticker}/financials":{"get":{"tags":["companies"],"summary":"Get Company Financials","description":"Get financial statements for a company.\n\n- ``?period=ttm`` returns a single trailing-twelve-month aggregate (sum of\n  the last 4 standalone quarters for flows; latest quarter for balance-sheet\n  instants).\n- Quarterly rows carry a ``cash_flow_basis`` flag (standalone / cumulative /\n  unknown). Pass ``?cash_flow=standalone`` to de-cumulate SEC year-to-date\n  cash flow into true per-quarter values.","operationId":"get_company_financials_api_v1_companies__ticker__financials_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","title":"Ticker"}},{"name":"period_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by period type (FY, Q1-Q4)","title":"Period Type"},"description":"Filter by period type (FY, Q1-Q4)"},{"name":"period","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Special aggregate period. Use 'ttm' for trailing twelve months.","title":"Period"},"description":"Special aggregate period. Use 'ttm' for trailing twelve months."},{"name":"cash_flow","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Cash-flow basis for quarterly rows. 'standalone' de-cumulates SEC year-to-date cash flow into true per-quarter values.","title":"Cash Flow"},"description":"Cash-flow basis for quarterly rows. 'standalone' de-cumulates SEC year-to-date cash flow into true per-quarter values."},{"name":"quarters_only","in":"query","required":false,"schema":{"type":"boolean","description":"Return only quarterly data (exclude FY/annual)","default":false,"title":"Quarters Only"},"description":"Return only quarterly data (exclude FY/annual)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Number of periods to return","default":20,"title":"Limit"},"description":"Number of periods to return"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FinancialsListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/companies/{ticker}/prices":{"get":{"tags":["companies"],"summary":"Get Company Prices","description":"Historical OHLC price series for charts.\n\nWe hold **daily** OHLCV, so intervals are ``1d`` (default) or ``1wk``\n(resampled from daily) — open to every tier. ``range=1D`` (``interval=15m``)\nis real intraday data for **S&P 500 + ASX 200 only**, gated to paid tiers\n(free-tier keys get a 403 upsell); every other ticker returns an honest\nempty series, not an error. The window is anchored to the most recent\navailable bar/session (not wall-clock now) so series stay correct when the\nlatest data is a few days stale, or when a market is currently closed.","operationId":"get_company_prices_api_v1_companies__ticker__prices_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","title":"Ticker"}},{"name":"range","in":"query","required":false,"schema":{"type":"string","description":"Time range: 1W, 1M, 3M, 6M, 1Y, 5Y, MAX","default":"1M","title":"Range"},"description":"Time range: 1W, 1M, 3M, 6M, 1Y, 5Y, MAX"},{"name":"interval","in":"query","required":false,"schema":{"type":"string","description":"Bar interval: 1d or 1wk","default":"1d","title":"Interval"},"description":"Bar interval: 1d or 1wk"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriceSeriesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/companies/{ticker}/technicals":{"get":{"tags":["companies"],"summary":"Get Company Technicals","description":"Technical indicators (RSI, MACD, SMAs, EMA-20, ATR) from daily prices.\n\nEverything here is derived from our own daily price history — no new data\nsource. Indicators that need more history than we hold (e.g. SMA-200 with\n< 200 bars) come back null rather than fabricated. ``beta`` is passed\nthrough from the company profile snapshot when available.","operationId":"get_company_technicals_api_v1_companies__ticker__technicals_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","title":"Ticker"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TechnicalsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/companies/{ticker}/metrics":{"get":{"tags":["companies"],"summary":"Get Company Metrics","description":"Get calculated metrics for a company.","operationId":"get_company_metrics_api_v1_companies__ticker__metrics_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","title":"Ticker"}},{"name":"period_end","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"description":"Specific period end date","title":"Period End"},"description":"Specific period end date"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/companies/{ticker}/metrics/summary":{"get":{"tags":["companies"],"summary":"Get Company Metrics Summary","description":"Get summary of key metrics for a company.\n\nIncludes 5-year averages for dividend yield, EBITDA margin, and ROE\nwhen historical FY data is available — Fred McNaught's framework\nrelies on these averages over single-year snapshots.\n\nPass ``?period=ttm`` to value the company off trailing-twelve-month\nearnings instead of the latest fiscal year — important for fast growers\nwhose FY P/E understates the current run-rate.","operationId":"get_company_metrics_summary_api_v1_companies__ticker__metrics_summary_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","title":"Ticker"}},{"name":"period","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Reporting basis. Default is latest FY; use 'ttm' for a trailing-twelve-month basis (valuation ratios off the latest 4 quarters).","title":"Period"},"description":"Reporting basis. Default is latest FY; use 'ttm' for a trailing-twelve-month basis (valuation ratios off the latest 4 quarters)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSummary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/companies/{ticker}/sector-stats":{"get":{"tags":["companies"],"summary":"Get Company Sector Stats","description":"Where a company sits within its sector for each aggregated metric.\n\nFor every metric we return the company's own value, the sector median, and\nits rank/percentile among peers that have the metric populated. Replaces\nclient-side \"vs peer median\" estimation. Rank is ascending (1 = lowest\nvalue); interpret direction per metric (low P/E vs high ROE).","operationId":"get_company_sector_stats_api_v1_companies__ticker__sector_stats_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","title":"Ticker"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanySectorStatsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/companies/{ticker}/analyst":{"get":{"tags":["companies"],"summary":"Get Company Analyst Consensus","description":"Third-party analyst consensus + 12-month price target (yfinance source).\n\nReturns the mean/high/low target, consensus rating, and analyst count, plus\na convenience ``upside_pct`` against the latest price. ``has_consensus`` is\nFalse (with null fields) when no analyst coverage is held for the ticker —\na completeness signal rather than an error.","operationId":"get_company_analyst_consensus_api_v1_companies__ticker__analyst_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","title":"Ticker"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalystConsensus"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/companies/{ticker}/metrics/history":{"get":{"tags":["companies"],"summary":"Get Company Metrics History","description":"Per-period metrics over time + rolling averages.","operationId":"get_company_metrics_history_api_v1_companies__ticker__metrics_history_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","title":"Ticker"}},{"name":"periods","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":1,"description":"Number of FY periods to return","default":5,"title":"Periods"},"description":"Number of FY periods to return"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/companies/{ticker}/filings":{"get":{"tags":["companies"],"summary":"Get Company Filings","description":"Get filings for a company — SEC EDGAR (US-listed) and/or ASX reports.\n\n``document_url`` is a permanent link for both sources: SEC rows point at\nEDGAR, ASX rows at our own ``/filings/{accession_number}/download``, which\nredirects to a freshly-signed R2 URL per request. Safe to store or embed.\nUse ``source=sec_edgar`` or ``source=asx`` to filter.","operationId":"get_company_filings_api_v1_companies__ticker__filings_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","title":"Ticker"}},{"name":"form_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by form type (10-K, 10-Q, 8-K, annual, half_year)","title":"Form Type"},"description":"Filter by form type (10-K, 10-Q, 8-K, annual, half_year)"},{"name":"source","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by source: sec_edgar or asx","title":"Source"},"description":"Filter by source: sec_edgar or asx"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Max filings per source","default":10,"title":"Limit"},"description":"Max filings per source"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FilingsListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/companies/{ticker}/filings/{accession_number}/download":{"get":{"tags":["companies"],"summary":"Download Filing","description":"Stable download link for an ASX report — 302s to a fresh presigned URL.\n\nThis is what ``filings[].document_url`` points to for ASX rows, and it never\nexpires: the presigned URL is minted per request, so a link that was stored,\ncached or baked into a page months ago still resolves.\n\n``format=pdf`` (default) is **public** — the PDF is the exchange's own\npublished document, and the link has to work in an end user's browser with no\nkey. ``format=markdown`` returns our markitdown extraction and is key-gated\nlike the rest of the paid data.","operationId":"download_filing_api_v1_companies__ticker__filings__accession_number__download_get","parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","title":"Ticker"}},{"name":"accession_number","in":"path","required":true,"schema":{"type":"string","title":"Accession Number"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","pattern":"^(pdf|markdown)$","description":"pdf | markdown","default":"pdf","title":"Format"},"description":"pdf | markdown"},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"302":{"description":"Redirect to a freshly-signed storage URL"},"401":{"description":"format=markdown without a valid API key"},"404":{"description":"No such filing for this ticker, or no such format"},"503":{"description":"Document storage unavailable"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/companies/{ticker}/holdings":{"get":{"tags":["companies"],"summary":"Get Etf Holdings","description":"Published constituents and sector allocation for an ETF.\n\nSources publish a top-N snapshot rather than the full book, so\n``holdings_weight_total`` reports how much of the fund the listed positions\nactually account for — for a broad index fund that is well under 1.0.\n\nAn empty ``holdings`` list with ``publishes_no_holdings: true`` is a real\nanswer, not a gap: a spot-commodity ETP (IBIT, GBTC) holds a single asset\nand publishes no breakdown.","operationId":"get_etf_holdings_api_v1_companies__ticker__holdings_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","title":"Ticker"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Max constituents to return","default":50,"title":"Limit"},"description":"Max constituents to return"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ETFHoldingsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/companies/{ticker}/news":{"get":{"tags":["companies"],"summary":"Get Company News","description":"Get news articles and press releases for a company.","operationId":"get_company_news_api_v1_companies__ticker__news_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","title":"Ticker"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Max articles to return","default":20,"title":"Limit"},"description":"Max articles to return"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Offset for pagination","default":0,"title":"Offset"},"description":"Offset for pagination"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyNewsListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/companies/{ticker}/completeness":{"get":{"tags":["companies"],"summary":"Get Company Completeness","description":"Per-statement data-completeness breakdown for the latest reporting period.","operationId":"get_company_completeness_api_v1_companies__ticker__completeness_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","title":"Ticker"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/companies/{ticker}/data-issues":{"get":{"tags":["companies"],"summary":"Get Company Data Issues","description":"Data quality issues recorded for this company (provenance / divergence).","operationId":"get_company_data_issues_api_v1_companies__ticker__data_issues_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","title":"Ticker"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by status (open, resolved, etc.)","title":"Status"},"description":"Filter by status (open, resolved, etc.)"},{"name":"issue_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by issue_type (e.g. source_divergence)","title":"Issue Type"},"description":"Filter by issue_type (e.g. source_divergence)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataIssuesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/indices":{"get":{"tags":["indices"],"summary":"List Indices","description":"List all available market indices with member counts.","operationId":"list_indices_api_v1_indices_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexListResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/v1/indices/catalog":{"get":{"tags":["indices"],"summary":"Get Index Catalog","description":"List the benchmark symbols we serve levels for (use these with /quotes).\n\nAnswers \"which index symbols should we use?\" — e.g. ``SPX``, ``IXIC``,\n``DJI``, ``VIX``, ``ASX200``, ``US10Y``. The /quotes endpoint also accepts\ncommon aliases (``^GSPC``, ``SP500``, ``^TNX`` …).","operationId":"get_index_catalog_api_v1_indices_catalog_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexCatalogResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/v1/indices/quotes":{"get":{"tags":["indices"],"summary":"Get Index Quotes","description":"Batch benchmark levels with day change — one call for the index strip.\n\nDelayed / end-of-day (``is_delayed: true``). Accepts canonical symbols and\naliases (``^GSPC``→SPX, ``^TNX``→US10Y, …). Unknown symbols, or ones with no\nlevel history yet, are returned in ``not_found``.","operationId":"get_index_quotes_api_v1_indices_quotes_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"symbols","in":"query","required":true,"schema":{"type":"string","description":"Comma-separated index symbols","examples":["SPX,IXIC,DJI,VIX,US10Y,ASX200"],"title":"Symbols"},"description":"Comma-separated index symbols"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexQuotesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/indices/{symbol}/prices":{"get":{"tags":["indices"],"summary":"Get Index Prices","description":"Historical level series for one benchmark (for sparklines / charts).\n\nSame windowing as ``/companies/{ticker}/prices``: daily bars, ``1d`` or\n``1wk`` (weekly resampled), no intraday. For a yield series (US10Y) only the\n``close`` is populated (OHLC are null).","operationId":"get_index_prices_api_v1_indices__symbol__prices_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}},{"name":"range","in":"query","required":false,"schema":{"type":"string","description":"Time range: 1W, 1M, 3M, 6M, 1Y, 5Y, MAX","default":"1M","title":"Range"},"description":"Time range: 1W, 1M, 3M, 6M, 1Y, 5Y, MAX"},{"name":"interval","in":"query","required":false,"schema":{"type":"string","description":"Bar interval: 1d or 1wk","default":"1d","title":"Interval"},"description":"Bar interval: 1d or 1wk"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexPriceSeriesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/indices/{index_name}":{"get":{"tags":["indices"],"summary":"Get Index Members","description":"List all companies in a given market index (e.g., sp500).","operationId":"get_index_members_api_v1_indices__index_name__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"index_name","in":"path","required":true,"schema":{"type":"string","title":"Index Name"}},{"name":"sector","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by sector","title":"Sector"},"description":"Filter by sector"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexMembersResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/formulas":{"get":{"tags":["formulas"],"summary":"List Formulas","description":"List all formula definitions.","operationId":"list_formulas_api_v1_formulas_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by category","title":"Category"},"description":"Filter by category"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormulasListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/formulas/categories":{"get":{"tags":["formulas"],"summary":"List Categories","description":"List all formula categories.","operationId":"list_categories_api_v1_formulas_categories_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/v1/formulas/{name}":{"get":{"tags":["formulas"],"summary":"Get Formula By Name","description":"Get a specific formula definition by name.\n\nReturns the complete formula documentation including:\n- Display name and category\n- Formula expression\n- Description of what it measures\n- Required input fields\n- XBRL tags used for data extraction\n- Special handling notes\n- Example interpretation","operationId":"get_formula_by_name_api_v1_formulas__name__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","title":"Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormulaDefinition"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stats/top-companies":{"get":{"tags":["stats"],"summary":"Top companies by market cap (live, cached 10 min)","description":"Return the top companies by market cap, server-cached for ~10 minutes.\n\nUses a curated mega-cap universe (Apple, Microsoft, NVIDIA, etc.) and\npulls live price + market cap from yfinance. Sorted by market cap desc.\nThe ``cache`` block exposes age/freshness so callers can decide whether\nto retry — aligns with the project's provenance mission.","operationId":"top_companies_api_v1_stats_top_companies_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":40,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"List of companies with live price, 24h % change, and market cap","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/calendar":{"get":{"tags":["calendar"],"summary":"Get Calendar","description":"Get the filing schedule calendar with filters.\n\nReturns expected and actual filing dates for tracked companies,\nwith status tracking (upcoming, expected, received, overdue)\nand source information.","operationId":"get_calendar_api_v1_calendar_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"year","in":"query","required":false,"schema":{"type":"integer","description":"Filter by fiscal year (defaults to current year)","title":"Year"},"description":"Filter by fiscal year (defaults to current year)"},{"name":"month","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":12,"minimum":1},{"type":"null"}],"description":"Filter by month of expected filing date","title":"Month"},"description":"Filter by month of expected filing date"},{"name":"exchange","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by exchange (NYSE, ASX, etc.)","title":"Exchange"},"description":"Filter by exchange (NYSE, ASX, etc.)"},{"name":"ticker","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by ticker symbol","title":"Ticker"},"description":"Filter by ticker symbol"},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by status (upcoming, expected, received, overdue)","title":"Status"},"description":"Filter by status (upcoming, expected, received, overdue)"},{"name":"filing_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by filing type (10-K, 10-Q, annual, half_year, appendix_4e)","title":"Filing Type"},"description":"Filter by filing type (10-K, 10-Q, annual, half_year, appendix_4e)"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CalendarResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/data-issues":{"get":{"tags":["data quality"],"summary":"List Data Issues","description":"List data quality issues across the dataset, newest first.","operationId":"list_data_issues_api_v1_data_issues_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by status (open, retrying, fixing, resolved, wont_fix)","title":"Status"},"description":"Filter by status (open, retrying, fixing, resolved, wont_fix)"},{"name":"issue_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by issue type (e.g. source_divergence)","title":"Issue Type"},"description":"Filter by issue type (e.g. source_divergence)"},{"name":"severity","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by severity (critical, warning, info)","title":"Severity"},"description":"Filter by severity (critical, warning, info)"},{"name":"ticker","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter to a single ticker","title":"Ticker"},"description":"Filter to a single ticker"},{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"description":"Only return issues created on/after this date","title":"Since"},"description":"Only return issues created on/after this date"},{"name":"until","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"description":"Only return issues created on/before this date","title":"Until"},"description":"Only return issues created on/before this date"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_DataIssueItem_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jobs":{"get":{"tags":["jobs"],"summary":"List Jobs","description":"List recent JobRun rows, newest first.","operationId":"list_jobs_api_v1_jobs_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"job_name","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by job_name","title":"Job Name"},"description":"Filter by job_name"},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by status (running, success, failed, partial)","title":"Status"},"description":"Filter by status (running, success, failed, partial)"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_JobRunItem_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jobs/{job_id}":{"get":{"tags":["jobs"],"summary":"Get Job","description":"Fetch a single JobRun by id.","operationId":"get_job_api_v1_jobs__job_id__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"integer","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobRunItem"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/companies/{ticker}/complete":{"post":{"tags":["completion"],"summary":"Request Completion","description":"Queue a data backfill for a ticker and return a request handle + ETA.\n\n- If a request is already in flight for this ticker, returns that one.\n- If the company already exists and looks complete (and ``force`` is not\n  set), returns immediately without doing any work.\n- Otherwise queues the backfill and returns ``202`` with a poll URL.","operationId":"request_completion_api_v1_companies__ticker__complete_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","title":"Ticker"}},{"name":"force","in":"query","required":false,"schema":{"type":"boolean","description":"Backfill even if the company already looks complete","default":false,"title":"Force"},"description":"Backfill even if the company already looks complete"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompletionStatus"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/companies/{ticker}/completion":{"get":{"tags":["completion"],"summary":"Get Latest Completion","description":"Status of the most recent completion request for this ticker.","operationId":"get_latest_completion_api_v1_companies__ticker__completion_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","title":"Ticker"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompletionStatus"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/companies/{ticker}/completion/{request_id}":{"get":{"tags":["completion"],"summary":"Get Completion","description":"Status of a specific completion request by id.","operationId":"get_completion_api_v1_companies__ticker__completion__request_id__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"ticker","in":"path","required":true,"schema":{"type":"string","title":"Ticker"}},{"name":"request_id","in":"path","required":true,"schema":{"type":"string","title":"Request Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompletionStatus"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/sectors":{"get":{"tags":["sectors"],"summary":"List Sectors","description":"List sectors with the count of active companies in each.\n\nSectors are the canonical GICS names (e.g. ``Information Technology``,\n``Health Care``). ``/sectors/{sector}/stats`` also accepts yfinance-style or\naliased inputs (``Technology``, ``Healthcare``, ``Financial Services``) — they\ncanonicalize to the stored name — but these are the exact strings we store.","operationId":"list_sectors_api_v1_sectors_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SectorListResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/v1/sectors/trending":{"get":{"tags":["sectors"],"summary":"Get Trending Themes","description":"Curated thematic baskets (AI, Semiconductors, EV & Battery…) ranked by\ntoday's move, each with its leading names.\n\nThemes are **curated editorial groupings**, not GICS sectors — a company can\nbelong to several, and membership lives in ``theme_registry`` tagged\n``source: \"curated\"``. For each theme we aggregate the *delayed / end-of-day*\nquotes of the members we cover:\n\n- ``change_pct`` — the basket's combined move. Cap-weighted when every covered\n  constituent has a market cap, otherwise equal-weighted; ``weighting`` says\n  which. (Weights may mix listing currencies for a cross-listed theme — an\n  accepted approximation; the moves themselves are currency-agnostic.)\n- ``change_pct_1m`` / ``change_pct_1y`` — the same cap-weighted basket over\n  1-month and 1-year windows (close-to-close, anchored to the latest data\n  date); ``null`` when a window can't be computed.\n- ``count`` vs ``members_total`` — covered constituents with a move vs the\n  curated registry size, so the coverage gap is visible, not hidden.\n- ``members`` — the FULL covered roster (every ``count`` constituent),\n  best-24h-move first; ``top_movers`` is the same list capped at the leaders.\n  Each row carries its own ``exchange``/``currency`` so ASX names render in A$,\n  plus ``tags`` — a curated, many-to-many sub-category *within* the theme\n  (e.g. \"Chips\" vs \"Labs\" within ``ai``; \"Gold\" vs \"Bitcoin\" within\n  ``store-of-value``). Only themes with a taxonomy defined populate it; ``[]``\n  elsewhere is an honest \"not curated yet\", not a per-row omission.\n\nThe list key is ``sectors`` to match the shape ALFRED's ``/api/sectors`` proxy\nalready consumes.","operationId":"get_trending_themes_api_v1_sectors_trending_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrendingThemesResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/v1/sectors/{sector}/stats":{"get":{"tags":["sectors"],"summary":"Get Sector Stats","description":"Per-metric distributions (min/p25/median/p75/max/mean) for a sector.\n\n``company_count`` is the sector's active-company count; each metric's\n``count`` is how many of those actually have that metric populated — a\ncompleteness signal, not a financial judgement.","operationId":"get_sector_stats_api_v1_sectors__sector__stats_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"sector","in":"path","required":true,"schema":{"type":"string","title":"Sector"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SectorStatsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/news":{"get":{"tags":["news"],"summary":"Get Bulk News","description":"Cached, source-consolidated news for a bulk list of tickers.\n\nOn-demand: a cold ticker is whitelisted and fetched in the background, so its\nfirst response may carry no articles (it appears in ``refreshing`` with a\n``202``). Once cached, duplicate reports of the same story across sources are\nmerged into a single item that lists every source.","operationId":"get_bulk_news_api_v1_news_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"tickers","in":"query","required":false,"schema":{"type":"string","description":"Comma-separated ticker symbols (max 50)","examples":["AAPL,MSFT,NVDA"],"title":"Tickers"},"description":"Comma-separated ticker symbols (max 50)"},{"name":"symbols","in":"query","required":false,"schema":{"type":"string","description":"Alias for `tickers` (accepted for consumer convenience).","title":"Symbols"},"description":"Alias for `tickers` (accepted for consumer convenience)."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Max consolidated stories per ticker","default":10,"title":"Limit"},"description":"Max consolidated stories per ticker"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkNewsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/news/feed":{"get":{"tags":["news"],"summary":"Get Market Feed","description":"Market-wide news feed — freshest stories across the whole collected universe.\n\nUnlike the ticker-scoped ``/news``, this isn't limited to a caller's list: it\nreturns the company stories we hold, each tagged with the ``sectors``\n(trending-theme ids) its ticker belongs to. Coverage spans every sector\nbecause the daily refresh keeps all trending-sector stocks collected.\n\nBy default the All feed is **sector-balanced** (round-robin across sectors) so\none busy sector can't crowd out the rest; pass ``sort=newest`` for strict\nreverse-chronological. Pass ``sector=<id>`` to get just one theme's stories in\na single call (no need to enumerate members). Same delayed/EOD posture and\nstory shape as ``/news``.","operationId":"get_market_feed_api_v1_news_feed_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"sector","in":"query","required":false,"schema":{"type":"string","description":"Narrow to one trending sector (theme id, e.g. `ai`, `energy`).","examples":["energy"],"title":"Sector"},"description":"Narrow to one trending sector (theme id, e.g. `ai`, `energy`)."},{"name":"sort","in":"query","required":false,"schema":{"type":"string","pattern":"^(balanced|newest)$","description":"`balanced` (default) rotates stories across sectors so the All feed isn't dominated by whichever sector published most recently; `newest` is strict reverse-chronological. Ignored when `sector` is set.","default":"balanced","title":"Sort"},"description":"`balanced` (default) rotates stories across sectors so the All feed isn't dominated by whichever sector published most recently; `newest` is strict reverse-chronological. Ignored when `sector` is set."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Max stories","default":20,"title":"Limit"},"description":"Max stories"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketFeedResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/news/market":{"get":{"tags":["news"],"summary":"Get Market News","description":"Market-level commentary — stories that belong to the market, not a ticker.\n\nCurrently sourced from curated YouTube playlists (Bloomberg's *Wall Street\nWeek*), ingested daily. Items are videos: ``url`` opens the video,\n``image_url`` is its thumbnail, ``source`` records provenance. Same delayed\n/EOD posture as the rest of the API.","operationId":"get_market_news_api_v1_news_market_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Max items, newest first","default":20,"title":"Limit"},"description":"Max items, newest first"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketNewsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/news/source-icon/{domain}":{"get":{"tags":["news"],"summary":"Source Icon","description":"Favicon for a news source domain — cached in R2, generic placeholder on miss.\n\nPublic (no API key) so it can be embedded directly in an ``<img src>``; cached\nfor a week. This is what `articles[].image_url` points to when a story has no\nthumbnail of its own.","operationId":"source_icon_api_v1_news_source_icon__domain__get","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/news/brand-image/{source}/{category}":{"get":{"tags":["news"],"summary":"Brand Image","description":"Branded feature image for a document-only news source, by category.\n\nPublic (no API key) so it can be embedded straight into an ``<img src>``;\ncached for a week. This is what `articles[].image_url` points to when\n`image_type == \"source_brand\"` — i.e. a source like ASX announcements, whose\nstories are PDFs and can never carry a scraped image of their own.","operationId":"brand_image_api_v1_news_brand_image__source___category__get","parameters":[{"name":"source","in":"path","required":true,"schema":{"type":"string","title":"Source"}},{"name":"category","in":"path","required":true,"schema":{"type":"string","title":"Category"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/commodities/catalog":{"get":{"tags":["commodities"],"summary":"Get Commodity Catalog","description":"The commodities we serve, their default series and every backing source.\n\nAnswers \"which symbols and what will I get?\": the top-level ``unit`` /\n``frequency`` / ``source`` describe the primary series (daily yfinance\nfutures where a free feed exists, official monthly series otherwise);\n``sources`` lists everything collected, including cross-checks selectable\nvia ``?source=`` on the prices endpoint. ``coverage: \"sparse\"`` flags\nseries with known publication gaps.","operationId":"get_commodity_catalog_api_v1_commodities_catalog_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommodityCatalogResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/v1/commodities/quotes":{"get":{"tags":["commodities"],"summary":"Get Commodity Quotes","description":"Batch commodity prices with period change — one call for a strip.\n\nDelayed / end-of-day. Serves each commodity's **primary** series (daily\nfutures, or the official monthly series for iron ore / coal / uranium /\nlithium / nickel — check ``frequency`` per quote). Accepts aliases\n(``GC=F``→GOLD, ``IRON_ORE``→IRONORE, …); unknown symbols or ones with no\nhistory yet come back in ``not_found``. ``currency=AUD`` derives from the\nlatest stored AUDUSD rate with fx provenance on each quote.","operationId":"get_commodity_quotes_api_v1_commodities_quotes_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"symbols","in":"query","required":true,"schema":{"type":"string","description":"Comma-separated commodity symbols","examples":["GOLD,IRONORE,WTI,COAL"],"title":"Symbols"},"description":"Comma-separated commodity symbols"},{"name":"currency","in":"query","required":false,"schema":{"type":"string","description":"Quote currency: USD or AUD (derived)","default":"USD","title":"Currency"},"description":"Quote currency: USD or AUD (derived)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommodityQuotesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/commodities/{symbol}/prices":{"get":{"tags":["commodities"],"summary":"Get Commodity Prices","description":"Historical price series for one commodity (charts / analysis).\n\nDaily series behave like ``/indices/{symbol}/prices`` (1d/1wk bars, no\nintraday). Monthly-anchor series serve native monthly close-only bars —\n``interval`` comes back ``1mo`` and weekly resampling is rejected.\n``currency=AUD`` converts per-bar with forward-filled daily rates; bars\nwith no usable rate have null prices (honest gaps, see fx service).","operationId":"get_commodity_prices_api_v1_commodities__symbol__prices_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}},{"name":"range","in":"query","required":false,"schema":{"type":"string","description":"Time range: 1W, 1M, 3M, 6M, 1Y, 5Y, MAX","default":"1M","title":"Range"},"description":"Time range: 1W, 1M, 3M, 6M, 1Y, 5Y, MAX"},{"name":"interval","in":"query","required":false,"schema":{"type":"string","description":"Bar interval: 1d or 1wk (daily series only)","default":"1d","title":"Interval"},"description":"Bar interval: 1d or 1wk (daily series only)"},{"name":"currency","in":"query","required":false,"schema":{"type":"string","description":"Bar currency: USD or AUD (derived per-bar)","default":"USD","title":"Currency"},"description":"Bar currency: USD or AUD (derived per-bar)"},{"name":"source","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Source series to serve (default: the primary). See /commodities/catalog for each commodity's sources.","title":"Source"},"description":"Source series to serve (default: the primary). See /commodities/catalog for each commodity's sources."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommodityPriceSeriesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/fx/rates":{"get":{"tags":["fx"],"summary":"Get Fx Rate","description":"Latest stored FX rate (rate = quote ccy per 1 base ccy; AUDUSD = USD per AUD).\n\nFRED (Fed noon buying rate) preferred over the yfinance fallback — the same\nrate the ``currency=AUD`` commodity conversions use, exposed so consumers\ncan convert anything else themselves.","operationId":"get_fx_rate_api_v1_fx_rates_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"pair","in":"query","required":false,"schema":{"type":"string","description":"Currency pair (base+quote, e.g. AUDUSD)","default":"AUDUSD","title":"Pair"},"description":"Currency pair (base+quote, e.g. AUDUSD)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FxRateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/fx/rates/history":{"get":{"tags":["fx"],"summary":"Get Fx Rate History","description":"Daily FX history — one observation per date, fred preferred on collisions.","operationId":"get_fx_rate_history_api_v1_fx_rates_history_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"pair","in":"query","required":false,"schema":{"type":"string","description":"Currency pair (base+quote, e.g. AUDUSD)","default":"AUDUSD","title":"Pair"},"description":"Currency pair (base+quote, e.g. AUDUSD)"},{"name":"range","in":"query","required":false,"schema":{"type":"string","description":"Time range: 1W, 1M, 3M, 6M, 1Y, 5Y, MAX","default":"1Y","title":"Range"},"description":"Time range: 1W, 1M, 3M, 6M, 1Y, 5Y, MAX"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FxRateHistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/payments/plans":{"get":{"tags":["Payments"],"summary":"Get Plans","description":"Return plan pricing and supported networks. No auth required.","operationId":"get_plans_payments_plans_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlansResponse"}}}}}}},"/payments/subscribe":{"post":{"tags":["Payments"],"summary":"Subscribe","description":"Subscribe to a pro plan via x402 payment.\n\nFlow:\n1. If active subscription with >7 days remaining → return it (no charge).\n2. If no x-payment header → return 402 with payment options.\n3. If x-payment header → verify, settle, upgrade key, create subscription + invoice.","operationId":"subscribe_payments_subscribe_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscribeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"APIKeyHeader":[]}]}},"/payments/subscription":{"get":{"tags":["Payments"],"summary":"Get Subscription","description":"Return current subscription status.","operationId":"get_subscription_payments_subscription_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionStatusResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/payments/invoices":{"get":{"tags":["Payments"],"summary":"List Invoices","description":"List all invoices for this API key's email.","operationId":"list_invoices_payments_invoices_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceListResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/payments/invoices/{number}":{"get":{"tags":["Payments"],"summary":"Get Invoice","description":"Get a single invoice. JSON by default, ?format=html for printable, ?format=pdf for download.","operationId":"get_invoice_payments_invoices__number__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"number","in":"path","required":true,"schema":{"type":"string","title":"Number"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","pattern":"^(json|html|pdf)$","default":"json","title":"Format"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/payments/agent-subscribe":{"post":{"tags":["Payments"],"summary":"Agent Subscribe (x402 Gasless Payment)","description":"Gasless one-shot onboarding for AI agents. Pay with USDC on Base via x402 -- no ETH gas needed.\n\n**How it works (2 HTTP calls):**\n\n1. **Call with no payment header** -- receive 402 with payment options (facilitator URL, price, networks).\n2. **Sign the USDC payment with your wallet** (off-chain EIP-712 signature, zero gas).\n3. **Call again with `x-payment` header** -- facilitator settles on-chain, you get an API key + PRO subscription.\n\n**Supported networks:** Base (USDC), Ethereum (USDC), Solana (USDC).\nRecommended: **Base** for lowest settlement cost.\n\n**Pricing:**\n- Pro:      Monthly $19 USDC       | Yearly $99 USDC       (57% savings)\n- Pro Plus: Monthly_plus $49 USDC  | Yearly_plus $249 USDC (57% savings, adds historical data & Parquet downloads)\n\n**Key resolution on repeat calls:**\n- Include `X-API-Key` header to renew that key's subscription.\n- No key header: looks up existing key by your wallet address, or creates a new one.\n- New API keys are returned **once** -- save it immediately.","operationId":"agent_subscribe_payments_agent_subscribe_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentSubscribeRequest"}}},"required":true},"responses":{"200":{"description":"API key and PRO subscription details","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/wallet/challenge":{"post":{"tags":["Wallet Auth"],"summary":"Create Challenge","description":"Generate an EIP-191 sign-in challenge for a wallet address.","operationId":"create_challenge_wallet_challenge_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChallengeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChallengeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/wallet/verify":{"post":{"tags":["Wallet Auth"],"summary":"Verify Signature","description":"Verify an EIP-191 signature and return/create an API key.","operationId":"verify_signature_wallet_verify_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/wallet/session":{"get":{"tags":["Wallet Auth"],"summary":"Get Session","description":"Get wallet session info for the current API key.","operationId":"get_session_wallet_session_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"APIKeyHeader":[]}]}},"/wallet/upgrade":{"post":{"tags":["Wallet Payments"],"summary":"Upgrade Plan","description":"Verify a USDC transfer on-chain and upgrade the API key.","operationId":"upgrade_plan_wallet_upgrade_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentVerifyRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentVerifyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"APIKeyHeader":[]}]}},"/wallet/invoices":{"get":{"tags":["Wallet Payments"],"summary":"List Invoices","description":"List all invoices for the current wallet.","operationId":"list_invoices_wallet_invoices_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"APIKeyHeader":[]}]}},"/wallet/invoices/{number}":{"get":{"tags":["Wallet Payments"],"summary":"Download Invoice","description":"Download a single invoice as PDF.","operationId":"download_invoice_wallet_invoices__number__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"number","in":"path","required":true,"schema":{"type":"string","title":"Number"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/wallet/config":{"get":{"tags":["Wallet Payments"],"summary":"Wallet Config","description":"Return public wallet config (treasury addresses, supported networks).","operationId":"wallet_config_wallet_config_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/wallet/create-solana-tx":{"post":{"tags":["Wallet Payments"],"summary":"Create Solana Tx","description":"Build a Solana SPL USDC transfer transaction and return base64 bytes.","operationId":"create_solana_tx_wallet_create_solana_tx_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SolanaTxRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"APIKeyHeader":[]}]}},"/wallet/solana-blockhash":{"get":{"tags":["Wallet Payments"],"summary":"Solana Blockhash","description":"Proxy: get latest Solana blockhash (avoids CORS issues with public RPCs).","operationId":"solana_blockhash_wallet_solana_blockhash_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/wallet/solana-confirm/{signature}":{"get":{"tags":["Wallet Payments"],"summary":"Solana Confirm","description":"Proxy: check Solana transaction confirmation status.","operationId":"solana_confirm_wallet_solana_confirm__signature__get","parameters":[{"name":"signature","in":"path","required":true,"schema":{"type":"string","title":"Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/calendar/data":{"get":{"summary":"Calendar Data Json","description":"Public JSON endpoint for calendar data (used by the calendar page).","operationId":"calendar_data_json_calendar_data_get","parameters":[{"name":"year","in":"query","required":false,"schema":{"type":"integer","title":"Year"}},{"name":"month","in":"query","required":false,"schema":{"type":"integer","title":"Month"}},{"name":"exchange","in":"query","required":false,"schema":{"type":"string","title":"Exchange"}},{"name":"status","in":"query","required":false,"schema":{"type":"string","title":"Status"}},{"name":"filing_type","in":"query","required":false,"schema":{"type":"string","title":"Filing Type"}},{"name":"ticker","in":"query","required":false,"schema":{"type":"string","title":"Ticker"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","default":200,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agentic/routes":{"get":{"summary":"Agentic Routes","description":"Agentic API route catalog with x402 pricing.","operationId":"agentic_routes_api_v1_agentic_routes_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api":{"get":{"summary":"Api Info","description":"Return the full OpenAPI schema for the Stock Market API.","operationId":"api_info_api_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"APIKeyCreate":{"properties":{"email":{"type":"string","title":"Email"}},"type":"object","required":["email"],"title":"APIKeyCreate","description":"Request body for creating an API key."},"APIKeyInfo":{"properties":{"key_prefix":{"type":"string","title":"Key Prefix"},"email":{"type":"string","title":"Email"},"tier":{"type":"string","title":"Tier"},"is_active":{"type":"boolean","title":"Is Active"},"requests_today":{"type":"integer","title":"Requests Today"},"daily_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Daily Limit"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"}},"type":"object","required":["key_prefix","email","tier","is_active","requests_today","daily_limit","created_at","expires_at"],"title":"APIKeyInfo","description":"API key information (without the full key)."},"APIKeyResponse":{"properties":{"api_key":{"type":"string","title":"Api Key"},"key_prefix":{"type":"string","title":"Key Prefix"},"email":{"type":"string","title":"Email"},"tier":{"type":"string","title":"Tier"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"message":{"type":"string","title":"Message","default":"Save this API key securely. It will not be shown again."}},"type":"object","required":["api_key","key_prefix","email","tier","created_at"],"title":"APIKeyResponse","description":"Response after creating an API key (only time full key is shown)."},"APIKeyRotateResponse":{"properties":{"api_key":{"type":"string","title":"Api Key"},"key_prefix":{"type":"string","title":"Key Prefix"},"message":{"type":"string","title":"Message","default":"Your old API key has been invalidated. Save this new key securely."}},"type":"object","required":["api_key","key_prefix"],"title":"APIKeyRotateResponse","description":"Response after rotating an API key."},"AgentSubscribeRequest":{"properties":{"plan":{"type":"string","enum":["monthly","yearly","monthly_plus","yearly_plus"],"title":"Plan"}},"type":"object","required":["plan"],"title":"AgentSubscribeRequest","description":"Request body for agent subscription (no API key required)."},"AnalystConsensus":{"properties":{"ticker":{"type":"string","title":"Ticker"},"has_consensus":{"type":"boolean","title":"Has Consensus","default":false},"target_mean":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Target Mean"},"target_high":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Target High"},"target_low":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Target Low"},"rating":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rating"},"analyst_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Analyst Count"},"current_price":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Current Price"},"upside_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Upside Pct"},"source":{"type":"string","title":"Source","default":"yfinance"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["ticker"],"title":"AnalystConsensus","description":"Third-party analyst consensus (yfinance pass-through, not our estimate).\n\nData-infrastructure framing: this is sourced data with provenance, surfaced\nso consumers can draw a target line / consensus rating. ``upside_pct`` is a\nconvenience derivation (mean target vs current price), not a recommendation."},"BulkCompanyItem":{"properties":{"ticker":{"type":"string","title":"Ticker"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"exchange":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Exchange"},"sector":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sector"},"industry":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Industry"},"country":{"type":"string","title":"Country","default":"USA"},"security_type":{"type":"string","title":"Security Type","default":"equity"},"id":{"type":"integer","title":"Id"},"cik":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cik"},"fiscal_year_end_month":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Fiscal Year End Month"},"status":{"type":"string","title":"Status","default":"active"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"latest_financials_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Latest Financials Date"},"data_completeness":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Data Completeness"},"has_price_data":{"type":"boolean","title":"Has Price Data","default":false},"price_as_of":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Price As Of"},"long_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Long Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"website":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Website"},"ir_website":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ir Website"},"franking_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Franking Pct"},"franking_ex_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Franking Ex Date"},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url"},"logo_url_dark":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url Dark"},"logo_url_transparent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url Transparent"},"employees":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Employees"},"headquarters_city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Headquarters City"},"headquarters_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Headquarters State"},"market_cap":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Market Cap"},"currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency"},"shares_outstanding":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Shares Outstanding"},"pe_ratio":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Pe Ratio"},"forward_pe":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Forward Pe"},"beta":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Beta"},"dividend_yield":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Dividend Yield"},"fifty_two_week_high":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Fifty Two Week High"},"fifty_two_week_low":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Fifty Two Week Low"},"profile_markdown_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Profile Markdown Url"},"profile_updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Profile Updated At"},"etf":{"anyOf":[{"$ref":"#/components/schemas/ETFProfileSchema"},{"type":"null"}]},"provenance":{"anyOf":[{"$ref":"#/components/schemas/ProvenanceMeta"},{"type":"null"}]},"revenue_by_currency":{"anyOf":[{"items":{"$ref":"#/components/schemas/RevenueCurrencySplit"},"type":"array"},{"type":"null"}],"title":"Revenue By Currency"},"revenue_by_geography":{"anyOf":[{"items":{"$ref":"#/components/schemas/RevenueGeographySplit"},"type":"array"},{"type":"null"}],"title":"Revenue By Geography"},"revenue_by_currency_period":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Revenue By Currency Period"},"revenue_by_currency_basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Revenue By Currency Basis"}},"type":"object","required":["ticker","id","created_at","updated_at"],"title":"BulkCompanyItem","description":"Company detail for bulk response (same as CompanyDetail)."},"BulkCompanyResponse":{"properties":{"companies":{"items":{"$ref":"#/components/schemas/BulkCompanyItem"},"type":"array","title":"Companies"},"total":{"type":"integer","title":"Total"},"not_found":{"items":{"type":"string"},"type":"array","title":"Not Found"}},"type":"object","required":["companies","total","not_found"],"title":"BulkCompanyResponse","description":"Response for bulk company lookup.\n\nShape: list of full CompanyDetail items, with unresolved tickers in\n``not_found``. We chose a list (not a dict-by-ticker) because callers\ntypically iterate the results to render a table; ticker-keyed lookup\nisn't the dominant access pattern. ``BulkMetricsResponse`` uses a dict\ndeliberately — different access pattern, different shape."},"BulkMetricsResponse":{"properties":{"metrics":{"additionalProperties":{"$ref":"#/components/schemas/MetricsSummary"},"type":"object","title":"Metrics"},"not_found":{"items":{"type":"string"},"type":"array","title":"Not Found","default":[]},"total":{"type":"integer","title":"Total"}},"type":"object","required":["metrics","total"],"title":"BulkMetricsResponse","description":"Bulk metrics endpoint — one MetricsSummary per requested ticker.\n\nShape: dict keyed by ticker. We chose a dict (not a list) deliberately —\ncallers of /metrics/bulk almost always look up a single ticker's metrics\ninside a render loop (\"show P/E for AAPL\"), and dict access is the\nnatural pattern. Tickers that don't exist or have no financials are\nomitted from `metrics` and listed in `not_found`.\n\nSibling endpoint `BulkCompanyResponse` uses a list because its callers\niterate, not look up by key."},"BulkNewsResponse":{"properties":{"articles":{"items":{"$ref":"#/components/schemas/ConsolidatedNewsItem"},"type":"array","title":"Articles"},"total":{"type":"integer","title":"Total"},"not_found":{"items":{"type":"string"},"type":"array","title":"Not Found","default":[]},"refreshing":{"items":{"type":"string"},"type":"array","title":"Refreshing","default":[]},"is_delayed":{"type":"boolean","title":"Is Delayed","default":true}},"type":"object","required":["articles","total"],"title":"BulkNewsResponse","description":"Response for the bulk /news endpoint.\n\n``articles`` is whatever is cached now (may be empty for a ticker still\nbeing fetched). ``refreshing`` lists tickers with a background fetch in\nflight — re-poll for those. ``not_found`` are tickers outside our universe."},"CalendarEntry":{"properties":{"id":{"type":"integer","title":"Id"},"ticker":{"type":"string","title":"Ticker"},"company_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Name"},"exchange":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Exchange"},"fiscal_year":{"type":"integer","title":"Fiscal Year"},"fiscal_quarter":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Fiscal Quarter"},"period_end_date":{"type":"string","format":"date","title":"Period End Date"},"filing_type":{"type":"string","title":"Filing Type"},"expected_filing_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Expected Filing Date"},"estimated_filing_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Estimated Filing Date"},"actual_filing_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Actual Filing Date"},"status":{"type":"string","title":"Status"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"source_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Url"},"backup_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Backup Source"},"earnings_call_date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Earnings Call Date"},"days_until_expected":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Days Until Expected"}},"type":"object","required":["id","ticker","fiscal_year","period_end_date","filing_type","status"],"title":"CalendarEntry","description":"A single filing schedule entry on the calendar."},"CalendarResponse":{"properties":{"year":{"type":"integer","title":"Year"},"total":{"type":"integer","title":"Total"},"entries":{"items":{"$ref":"#/components/schemas/CalendarEntry"},"type":"array","title":"Entries"},"summary":{"$ref":"#/components/schemas/CalendarSummary"},"pagination":{"$ref":"#/components/schemas/PaginationMeta"}},"type":"object","required":["year","total","entries","summary","pagination"],"title":"CalendarResponse","description":"Response for the calendar endpoint."},"CalendarSummary":{"properties":{"total_upcoming":{"type":"integer","title":"Total Upcoming","default":0},"total_expected":{"type":"integer","title":"Total Expected","default":0},"total_received":{"type":"integer","title":"Total Received","default":0},"total_overdue":{"type":"integer","title":"Total Overdue","default":0}},"type":"object","title":"CalendarSummary","description":"Aggregate counts for the calendar view."},"ChallengeRequest":{"properties":{"wallet_address":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$","title":"Wallet Address"}},"type":"object","required":["wallet_address"],"title":"ChallengeRequest"},"ChallengeResponse":{"properties":{"message":{"type":"string","title":"Message"},"nonce":{"type":"string","title":"Nonce"}},"type":"object","required":["message","nonce"],"title":"ChallengeResponse"},"CheckoutRequest":{"properties":{"tier":{"type":"string","title":"Tier"},"success_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Success Url"},"cancel_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cancel Url"}},"type":"object","required":["tier"],"title":"CheckoutRequest","description":"Request to create a checkout session."},"CheckoutResponse":{"properties":{"checkout_url":{"type":"string","title":"Checkout Url"},"tier":{"type":"string","title":"Tier"},"price":{"type":"string","title":"Price"}},"type":"object","required":["checkout_url","tier","price"],"title":"CheckoutResponse","description":"Response with checkout URL."},"CommodityCatalogItem":{"properties":{"symbol":{"type":"string","title":"Symbol"},"display_name":{"type":"string","title":"Display Name"},"category":{"type":"string","title":"Category"},"unit":{"type":"string","title":"Unit"},"frequency":{"type":"string","title":"Frequency"},"source":{"type":"string","title":"Source"},"coverage":{"type":"string","title":"Coverage"},"currencies":{"items":{"type":"string"},"type":"array","title":"Currencies","default":["USD","AUD"]},"sources":{"items":{"$ref":"#/components/schemas/CommoditySourceInfo"},"type":"array","title":"Sources"}},"type":"object","required":["symbol","display_name","category","unit","frequency","source","coverage","sources"],"title":"CommodityCatalogItem","description":"A served commodity, its default series and every backing source."},"CommodityCatalogResponse":{"properties":{"commodities":{"items":{"$ref":"#/components/schemas/CommodityCatalogItem"},"type":"array","title":"Commodities"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["commodities","total"],"title":"CommodityCatalogResponse","description":"The commodities available via /commodities/quotes and /{symbol}/prices."},"CommodityPriceSeriesResponse":{"properties":{"symbol":{"type":"string","title":"Symbol"},"display_name":{"type":"string","title":"Display Name"},"category":{"type":"string","title":"Category"},"range":{"type":"string","title":"Range"},"interval":{"type":"string","title":"Interval"},"currency":{"type":"string","title":"Currency"},"unit":{"type":"string","title":"Unit"},"frequency":{"type":"string","title":"Frequency"},"source":{"type":"string","title":"Source"},"fx_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fx Source"},"bars":{"items":{"$ref":"#/components/schemas/OHLCBar"},"type":"array","title":"Bars"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["symbol","display_name","category","range","interval","currency","unit","frequency","source","bars","total"],"title":"CommodityPriceSeriesResponse","description":"Historical series for one commodity from one source series.\n\n``interval`` reports the actual bar cadence — ``1mo`` for monthly-anchor\nsources regardless of the requested interval. AUD bars are converted\nper-bar with forward-filled daily rates; bars with no usable rate keep\nnull prices (honest gaps)."},"CommodityQuote":{"properties":{"symbol":{"type":"string","title":"Symbol"},"display_name":{"type":"string","title":"Display Name"},"category":{"type":"string","title":"Category"},"unit":{"type":"string","title":"Unit"},"currency":{"type":"string","title":"Currency"},"price":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Price"},"change":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change"},"change_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change Pct"},"prev_close":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Prev Close"},"as_of":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"As Of"},"frequency":{"type":"string","title":"Frequency"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"fx_rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Fx Rate"},"fx_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fx Source"},"fx_as_of":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Fx As Of"},"is_delayed":{"type":"boolean","title":"Is Delayed","default":true}},"type":"object","required":["symbol","display_name","category","unit","currency","frequency"],"title":"CommodityQuote","description":"Latest price for a commodity with period-over-period change.\n\n``price``/``change``/``prev_close`` are in ``currency``; for AUD they are\nderived (USD ÷ AUDUSD rate) and the fx fields say which rate was used.\nA null price with ``currency: \"AUD\"`` means no usable FX observation —\nwe never silently serve USD as AUD. For monthly-primary commodities\n(``frequency: \"monthly\"``) the change is month-over-month."},"CommodityQuotesResponse":{"properties":{"quotes":{"items":{"$ref":"#/components/schemas/CommodityQuote"},"type":"array","title":"Quotes"},"not_found":{"items":{"type":"string"},"type":"array","title":"Not Found","default":[]},"currency":{"type":"string","title":"Currency","default":"USD"},"total":{"type":"integer","title":"Total"},"is_delayed":{"type":"boolean","title":"Is Delayed","default":true}},"type":"object","required":["quotes","total"],"title":"CommodityQuotesResponse","description":"Batch commodity quotes — one per resolved symbol."},"CommoditySourceInfo":{"properties":{"source":{"type":"string","title":"Source"},"source_symbol":{"type":"string","title":"Source Symbol"},"role":{"type":"string","title":"Role"},"frequency":{"type":"string","title":"Frequency"},"unit":{"type":"string","title":"Unit"}},"type":"object","required":["source","source_symbol","role","frequency","unit"],"title":"CommoditySourceInfo","description":"One source series backing a commodity (provenance for the catalog)."},"CompanyDetail":{"properties":{"ticker":{"type":"string","title":"Ticker"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"exchange":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Exchange"},"sector":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sector"},"industry":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Industry"},"country":{"type":"string","title":"Country","default":"USA"},"security_type":{"type":"string","title":"Security Type","default":"equity"},"id":{"type":"integer","title":"Id"},"cik":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cik"},"fiscal_year_end_month":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Fiscal Year End Month"},"status":{"type":"string","title":"Status","default":"active"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"latest_financials_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Latest Financials Date"},"data_completeness":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Data Completeness"},"has_price_data":{"type":"boolean","title":"Has Price Data","default":false},"price_as_of":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Price As Of"},"long_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Long Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"website":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Website"},"ir_website":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ir Website"},"franking_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Franking Pct"},"franking_ex_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Franking Ex Date"},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url"},"logo_url_dark":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url Dark"},"logo_url_transparent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url Transparent"},"employees":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Employees"},"headquarters_city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Headquarters City"},"headquarters_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Headquarters State"},"market_cap":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Market Cap"},"currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency"},"shares_outstanding":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Shares Outstanding"},"pe_ratio":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Pe Ratio"},"forward_pe":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Forward Pe"},"beta":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Beta"},"dividend_yield":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Dividend Yield"},"fifty_two_week_high":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Fifty Two Week High"},"fifty_two_week_low":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Fifty Two Week Low"},"profile_markdown_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Profile Markdown Url"},"profile_updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Profile Updated At"},"etf":{"anyOf":[{"$ref":"#/components/schemas/ETFProfileSchema"},{"type":"null"}]},"provenance":{"anyOf":[{"$ref":"#/components/schemas/ProvenanceMeta"},{"type":"null"}]},"revenue_by_currency":{"anyOf":[{"items":{"$ref":"#/components/schemas/RevenueCurrencySplit"},"type":"array"},{"type":"null"}],"title":"Revenue By Currency"},"revenue_by_geography":{"anyOf":[{"items":{"$ref":"#/components/schemas/RevenueGeographySplit"},"type":"array"},{"type":"null"}],"title":"Revenue By Geography"},"revenue_by_currency_period":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Revenue By Currency Period"},"revenue_by_currency_basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Revenue By Currency Basis"}},"type":"object","required":["ticker","id","created_at","updated_at"],"title":"CompanyDetail","description":"Detailed company response with data quality + rich profile info."},"CompanyListItem":{"properties":{"ticker":{"type":"string","title":"Ticker"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"exchange":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Exchange"},"sector":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sector"},"industry":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Industry"},"country":{"type":"string","title":"Country","default":"USA"},"security_type":{"type":"string","title":"Security Type","default":"equity"},"id":{"type":"integer","title":"Id"},"cik":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cik"},"status":{"type":"string","title":"Status","default":"active"}},"type":"object","required":["ticker","id"],"title":"CompanyListItem","description":"Company summary for list endpoints."},"CompanyNewsItem":{"properties":{"id":{"type":"integer","title":"Id"},"ticker":{"type":"string","title":"Ticker"},"title":{"type":"string","title":"Title"},"published_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Published At"},"article_url":{"type":"string","title":"Article Url"},"source_name":{"type":"string","title":"Source Name"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"collected_at":{"type":"string","format":"date-time","title":"Collected At"}},"type":"object","required":["id","ticker","title","article_url","source_name","collected_at"],"title":"CompanyNewsItem","description":"A single news article or press release."},"CompanyNewsListResponse":{"properties":{"ticker":{"type":"string","title":"Ticker"},"total":{"type":"integer","title":"Total"},"articles":{"items":{"$ref":"#/components/schemas/CompanyNewsItem"},"type":"array","title":"Articles"}},"type":"object","required":["ticker","total","articles"],"title":"CompanyNewsListResponse","description":"Response for company news endpoint."},"CompanySectorRank":{"properties":{"value":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Value"},"sector_median":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Sector Median"},"rank":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rank"},"percentile":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Percentile"},"peer_count":{"type":"integer","title":"Peer Count","default":0}},"type":"object","title":"CompanySectorRank","description":"A company's value for one metric plus where it sits among peers."},"CompanySectorStatsResponse":{"properties":{"ticker":{"type":"string","title":"Ticker"},"sector":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sector"},"peer_count":{"type":"integer","title":"Peer Count"},"metrics":{"additionalProperties":{"$ref":"#/components/schemas/CompanySectorRank"},"type":"object","title":"Metrics"}},"type":"object","required":["ticker","peer_count","metrics"],"title":"CompanySectorStatsResponse","description":"A company's standing within its sector across the aggregated metrics."},"CompletionStatus":{"properties":{"request_id":{"type":"string","title":"Request Id"},"ticker":{"type":"string","title":"Ticker"},"status":{"type":"string","title":"Status"},"company_existed":{"type":"boolean","title":"Company Existed"},"progress_pct":{"type":"integer","title":"Progress Pct"},"current_step":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Step"},"steps_total":{"type":"integer","title":"Steps Total"},"steps_completed":{"type":"integer","title":"Steps Completed"},"estimated_seconds_remaining":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Estimated Seconds Remaining"},"estimated_completion_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Estimated Completion At"},"result":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Result"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"requested_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Requested At"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"status_url":{"type":"string","title":"Status Url"},"poll_after_seconds":{"type":"integer","title":"Poll After Seconds","default":3},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"}},"type":"object","required":["request_id","ticker","status","company_existed","progress_pct","steps_total","steps_completed","status_url"],"title":"CompletionStatus","description":"Progress/ETA snapshot for a single data-completion request."},"ConsolidatedNewsItem":{"properties":{"ticker":{"type":"string","title":"Ticker"},"title":{"type":"string","title":"Title"},"published_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Published At"},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"image_type":{"type":"string","title":"Image Type","default":"article"},"sources":{"items":{"$ref":"#/components/schemas/NewsSource"},"type":"array","title":"Sources"},"source_count":{"type":"integer","title":"Source Count"},"collected_at":{"type":"string","format":"date-time","title":"Collected At"},"sectors":{"items":{"type":"string"},"type":"array","title":"Sectors","default":[]}},"type":"object","required":["ticker","title","sources","source_count","collected_at"],"title":"ConsolidatedNewsItem","description":"A single story, with duplicate reports across sources merged together."},"CoverageItem":{"properties":{"ticker":{"type":"string","title":"Ticker"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"exchange":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Exchange"},"sector":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sector"},"country":{"type":"string","title":"Country","default":"USA"},"security_type":{"type":"string","title":"Security Type","default":"equity"},"has_price_data":{"type":"boolean","title":"Has Price Data","default":false},"price_as_of":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Price As Of"},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url"}},"type":"object","required":["ticker"],"title":"CoverageItem","description":"A single covered company in the compact coverage listing."},"CoverageResponse":{"properties":{"total":{"type":"integer","title":"Total"},"companies":{"items":{"$ref":"#/components/schemas/CoverageItem"},"type":"array","title":"Companies"}},"type":"object","required":["total","companies"],"title":"CoverageResponse","description":"Full covered-universe listing in a single call.\n\nLets a consumer align its ticker universe to ours without paging\n``/companies`` (capped at MAX_PAGE_SIZE). Compact by design — for full\nprofiles use ``/companies/bulk``."},"DataIssueItem":{"properties":{"id":{"type":"integer","title":"Id"},"ticker":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ticker"},"issue_type":{"type":"string","title":"Issue Type"},"severity":{"type":"string","title":"Severity"},"description":{"type":"string","title":"Description"},"error_details":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Error Details"},"status":{"type":"string","title":"Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"resolved_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Resolved At"}},"type":"object","required":["id","ticker","issue_type","severity","description","status","created_at"],"title":"DataIssueItem","description":"A single DataIssue row exposed via API."},"DataIssuesResponse":{"properties":{"ticker":{"type":"string","title":"Ticker"},"total":{"type":"integer","title":"Total"},"issues":{"items":{"$ref":"#/components/schemas/DataIssueItem"},"type":"array","title":"Issues"}},"type":"object","required":["ticker","total","issues"],"title":"DataIssuesResponse","description":"Data issues for a single company."},"ETFHoldingItem":{"properties":{"symbol":{"type":"string","title":"Symbol"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"weight_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Weight Pct"}},"type":"object","required":["symbol"],"title":"ETFHoldingItem","description":"One constituent position."},"ETFHoldingsResponse":{"properties":{"ticker":{"type":"string","title":"Ticker"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"as_of":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"As Of"},"holdings":{"items":{"$ref":"#/components/schemas/ETFHoldingItem"},"type":"array","title":"Holdings","default":[]},"holdings_weight_total":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Holdings Weight Total"},"sector_weights":{"items":{"$ref":"#/components/schemas/ETFSectorWeightItem"},"type":"array","title":"Sector Weights","default":[]},"publishes_no_holdings":{"type":"boolean","title":"Publishes No Holdings","default":false},"source_tag":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Tag"}},"type":"object","required":["ticker"],"title":"ETFHoldingsResponse","description":"Published holdings + sector allocation for one ETF."},"ETFProfileSchema":{"properties":{"net_assets":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Net Assets"},"nav":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Nav"},"expense_ratio":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Expense Ratio"},"holdings_turnover":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Holdings Turnover"},"fund_family":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fund Family"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"legal_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Legal Type"},"inception_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Inception Date"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"ytd_return":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Ytd Return"},"three_year_avg_return":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Three Year Avg Return"},"yield_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Yield Pct"},"holdings_count":{"type":"integer","title":"Holdings Count","default":0},"holdings_as_of":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Holdings As Of"},"source_tag":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Tag"},"collected_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Collected At"}},"type":"object","title":"ETFProfileSchema","description":"Fund-level profile, nested on the company detail response for ETFs."},"ETFSectorWeightItem":{"properties":{"sector":{"type":"string","title":"Sector"},"weight_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Weight Pct"}},"type":"object","required":["sector"],"title":"ETFSectorWeightItem","description":"One sector allocation. `sector` matches companies.sector labelling."},"Filing":{"properties":{"accession_number":{"type":"string","title":"Accession Number"},"form_type":{"type":"string","title":"Form Type"},"filing_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Filing Date"},"report_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Report Date"},"primary_document":{"type":"string","title":"Primary Document"},"document_url":{"type":"string","title":"Document Url"},"filing_index_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Filing Index Url"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"source":{"type":"string","title":"Source","default":"sec_edgar"},"markdown_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Markdown Url"}},"type":"object","required":["accession_number","form_type","primary_document","document_url"],"title":"Filing","description":"A single filing (SEC or ASX) with document links."},"FilingsListResponse":{"properties":{"ticker":{"type":"string","title":"Ticker"},"cik":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cik"},"stock_price":{"anyOf":[{"$ref":"#/components/schemas/StockPrice"},{"type":"null"}]},"total":{"type":"integer","title":"Total"},"filings":{"items":{"$ref":"#/components/schemas/Filing"},"type":"array","title":"Filings"}},"type":"object","required":["ticker","total","filings"],"title":"FilingsListResponse","description":"Response for company filings endpoint."},"FinancialsListResponse":{"properties":{"ticker":{"type":"string","title":"Ticker"},"company_id":{"type":"integer","title":"Company Id"},"periods":{"items":{"$ref":"#/components/schemas/FinancialsResponse"},"type":"array","title":"Periods"},"total_periods":{"type":"integer","title":"Total Periods"},"provenance":{"anyOf":[{"$ref":"#/components/schemas/ProvenanceMeta"},{"type":"null"}]}},"type":"object","required":["ticker","company_id","periods","total_periods"],"title":"FinancialsListResponse","description":"Response for listing financial periods for a company."},"FinancialsResponse":{"properties":{"period_end":{"type":"string","format":"date","title":"Period End"},"period_type":{"type":"string","title":"Period Type"},"fiscal_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Fiscal Year"},"fiscal_period":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fiscal Period"},"revenue":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Revenue"},"cost_of_revenue":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Cost Of Revenue"},"gross_profit":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Gross Profit"},"operating_income":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Operating Income"},"research_and_development":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Research And Development"},"depreciation_amortization":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Depreciation Amortization"},"interest_expense":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Interest Expense"},"pretax_income":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Pretax Income"},"income_tax":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Income Tax"},"net_income":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Net Income"},"total_assets":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Total Assets"},"current_assets":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Current Assets"},"total_liabilities":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Total Liabilities"},"current_liabilities":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Current Liabilities"},"total_equity":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Total Equity"},"cash_and_equivalents":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Cash And Equivalents"},"inventory":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Inventory"},"short_term_debt":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Short Term Debt"},"long_term_debt":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Long Term Debt"},"accounts_receivable":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Accounts Receivable"},"accounts_payable":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Accounts Payable"},"property_plant_equipment":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Property Plant Equipment"},"goodwill":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Goodwill"},"intangible_assets":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Intangible Assets"},"operating_cash_flow":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Operating Cash Flow"},"investing_cash_flow":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Investing Cash Flow"},"financing_cash_flow":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Financing Cash Flow"},"capital_expenditures":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Capital Expenditures"},"free_cash_flow":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Free Cash Flow"},"dividends_paid":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Dividends Paid"},"eps_basic":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Eps Basic"},"eps_diluted":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Eps Diluted"},"eps_adjusted":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Eps Adjusted"},"shares_outstanding":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Shares Outstanding"},"cash_flow_basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cash Flow Basis"},"ttm_quarters":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ttm Quarters"},"currency":{"type":"string","title":"Currency","default":"USD"},"accounting_standard":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accounting Standard"},"filed_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Filed Date"},"primary_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Source"},"fields_populated":{"type":"integer","title":"Fields Populated","default":0},"quality_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Quality Score"},"sources":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Sources"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["period_end","period_type"],"title":"FinancialsResponse","description":"Financial data response for a single period."},"FormulaDefinition":{"properties":{"name":{"type":"string","title":"Name"},"display_name":{"type":"string","title":"Display Name"},"category":{"type":"string","title":"Category"},"formula":{"type":"string","title":"Formula"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"required_inputs":{"items":{"type":"string"},"type":"array","title":"Required Inputs","default":[]},"xbrl_tags":{"items":{"type":"string"},"type":"array","title":"Xbrl Tags","default":[]},"unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Unit"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"example":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Example"}},"type":"object","required":["name","display_name","category","formula"],"title":"FormulaDefinition","description":"Definition of a financial formula/metric."},"FormulasListResponse":{"properties":{"formulas":{"items":{"$ref":"#/components/schemas/FormulaDefinition"},"type":"array","title":"Formulas"},"total":{"type":"integer","title":"Total"},"categories":{"items":{"type":"string"},"type":"array","title":"Categories"}},"type":"object","required":["formulas","total","categories"],"title":"FormulasListResponse","description":"Response for listing all formula definitions."},"FxRateHistoryResponse":{"properties":{"pair":{"type":"string","title":"Pair"},"range":{"type":"string","title":"Range"},"rates":{"items":{"$ref":"#/components/schemas/FxRateObservation"},"type":"array","title":"Rates"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["pair","range","rates","total"],"title":"FxRateHistoryResponse","description":"Daily FX history, one observation per date (fred preferred over yfinance)."},"FxRateObservation":{"properties":{"date":{"type":"string","format":"date","title":"Date"},"rate":{"type":"number","title":"Rate"},"source":{"type":"string","title":"Source"}},"type":"object","required":["date","rate","source"],"title":"FxRateObservation"},"FxRateResponse":{"properties":{"pair":{"type":"string","title":"Pair"},"rate":{"type":"number","title":"Rate"},"as_of":{"type":"string","format":"date","title":"As Of"},"source":{"type":"string","title":"Source"}},"type":"object","required":["pair","rate","as_of","source"],"title":"FxRateResponse","description":"Latest stored FX rate. Convention: rate = quote ccy per 1 base ccy\n(AUDUSD = USD per 1 AUD, matching FRED DEXUSAL)."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HealthResponse":{"properties":{"status":{"type":"string","title":"Status"},"timestamp":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Timestamp"},"version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Version"},"environment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment"},"database":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Database"}},"type":"object","required":["status"],"title":"HealthResponse","description":"Health check response."},"IndexCatalogItem":{"properties":{"symbol":{"type":"string","title":"Symbol"},"display_name":{"type":"string","title":"Display Name"},"kind":{"type":"string","title":"Kind"},"source":{"type":"string","title":"Source"}},"type":"object","required":["symbol","display_name","kind","source"],"title":"IndexCatalogItem","description":"A served benchmark and where its level comes from."},"IndexCatalogResponse":{"properties":{"indices":{"items":{"$ref":"#/components/schemas/IndexCatalogItem"},"type":"array","title":"Indices"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["indices","total"],"title":"IndexCatalogResponse","description":"The benchmarks available via /indices/quotes and /indices/{symbol}/prices."},"IndexInfo":{"properties":{"name":{"type":"string","title":"Name"},"display_name":{"type":"string","title":"Display Name"},"member_count":{"type":"integer","title":"Member Count"}},"type":"object","required":["name","display_name","member_count"],"title":"IndexInfo","description":"Summary info about a market index."},"IndexListResponse":{"properties":{"indices":{"items":{"$ref":"#/components/schemas/IndexInfo"},"type":"array","title":"Indices"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["indices","total"],"title":"IndexListResponse","description":"Response for listing available indices."},"IndexMemberItem":{"properties":{"ticker":{"type":"string","title":"Ticker"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"exchange":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Exchange"},"sector":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sector"},"industry":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Industry"},"country":{"type":"string","title":"Country","default":"USA"},"security_type":{"type":"string","title":"Security Type","default":"equity"},"id":{"type":"integer","title":"Id"},"cik":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cik"},"status":{"type":"string","title":"Status","default":"active"},"added_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Added Date"}},"type":"object","required":["ticker","id"],"title":"IndexMemberItem","description":"Company in an index with membership metadata."},"IndexMembersResponse":{"properties":{"index_name":{"type":"string","title":"Index Name"},"display_name":{"type":"string","title":"Display Name"},"members":{"items":{"$ref":"#/components/schemas/IndexMemberItem"},"type":"array","title":"Members"},"total_members":{"type":"integer","title":"Total Members"}},"type":"object","required":["index_name","display_name","members","total_members"],"title":"IndexMembersResponse","description":"Response for listing companies in an index."},"IndexPriceSeriesResponse":{"properties":{"symbol":{"type":"string","title":"Symbol"},"display_name":{"type":"string","title":"Display Name"},"kind":{"type":"string","title":"Kind"},"range":{"type":"string","title":"Range"},"interval":{"type":"string","title":"Interval"},"bars":{"items":{"$ref":"#/components/schemas/OHLCBar"},"type":"array","title":"Bars"},"total":{"type":"integer","title":"Total"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"}},"type":"object","required":["symbol","display_name","kind","range","interval","bars","total"],"title":"IndexPriceSeriesResponse","description":"Historical level series for one benchmark (OHLC; close-only for yields)."},"IndexQuote":{"properties":{"symbol":{"type":"string","title":"Symbol"},"display_name":{"type":"string","title":"Display Name"},"kind":{"type":"string","title":"Kind"},"level":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Level"},"change":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change"},"change_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change Pct"},"prev_close":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Prev Close"},"as_of":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"As Of"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"is_delayed":{"type":"boolean","title":"Is Delayed","default":true}},"type":"object","required":["symbol","display_name","kind"],"title":"IndexQuote","description":"Latest level for a benchmark with day change.\n\nDelayed / end-of-day, like company quotes — ``is_delayed`` is always true.\nFor a yield series (US10Y) ``level`` is the yield in percent (e.g. 4.25) and\n``change`` is in percentage points."},"IndexQuotesResponse":{"properties":{"quotes":{"items":{"$ref":"#/components/schemas/IndexQuote"},"type":"array","title":"Quotes"},"not_found":{"items":{"type":"string"},"type":"array","title":"Not Found","default":[]},"total":{"type":"integer","title":"Total"},"is_delayed":{"type":"boolean","title":"Is Delayed","default":true}},"type":"object","required":["quotes","total"],"title":"IndexQuotesResponse","description":"Batch benchmark quotes — one per resolved symbol."},"InvoiceListResponse":{"properties":{"invoices":{"items":{"$ref":"#/components/schemas/InvoiceResponse"},"type":"array","title":"Invoices"}},"type":"object","required":["invoices"],"title":"InvoiceListResponse"},"InvoiceResponse":{"properties":{"invoice_number":{"type":"string","title":"Invoice Number"},"plan":{"type":"string","title":"Plan"},"amount_usd":{"type":"number","title":"Amount Usd"},"amount_usdc":{"type":"number","title":"Amount Usdc"},"network":{"type":"string","title":"Network"},"tx_hash":{"type":"string","title":"Tx Hash"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["invoice_number","plan","amount_usd","amount_usdc","network","tx_hash","created_at"],"title":"InvoiceResponse"},"JobRunItem":{"properties":{"id":{"type":"integer","title":"Id"},"job_name":{"type":"string","title":"Job Name"},"correlation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Correlation Id"},"started_at":{"type":"string","format":"date-time","title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"status":{"type":"string","title":"Status"},"records_processed":{"type":"integer","title":"Records Processed","default":0},"records_failed":{"type":"integer","title":"Records Failed","default":0},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"}},"type":"object","required":["id","job_name","started_at","status"],"title":"JobRunItem","description":"Read-only view of a JobRun row."},"MarketFeedResponse":{"properties":{"articles":{"items":{"$ref":"#/components/schemas/ConsolidatedNewsItem"},"type":"array","title":"Articles"},"total":{"type":"integer","title":"Total"},"sector":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sector"},"is_delayed":{"type":"boolean","title":"Is Delayed","default":true}},"type":"object","required":["articles","total"],"title":"MarketFeedResponse","description":"Response for the market-wide /news/feed.\n\nNewest consolidated company stories across the collected universe (not scoped\nto a ticker list), each tagged with the ``sectors`` it belongs to. When\n``sector`` is set, the feed is narrowed to that theme's members."},"MarketNewsItem":{"properties":{"title":{"type":"string","title":"Title"},"url":{"type":"string","title":"Url"},"publisher":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Publisher"},"source":{"type":"string","title":"Source"},"published_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Published At"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary"}},"type":"object","required":["title","url","source"],"title":"MarketNewsItem","description":"One market-level story/video (no company attached)."},"MarketNewsResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/MarketNewsItem"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"is_delayed":{"type":"boolean","title":"Is Delayed","default":true}},"type":"object","required":["items","total"],"title":"MarketNewsResponse","description":"Response for /news/market — market commentary, newest first."},"MetricValue":{"properties":{"value":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Value"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"},"formula":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Formula"},"unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Unit"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"}},"type":"object","title":"MetricValue","description":"A single calculated metric with its value and metadata."},"MetricsResponse":{"properties":{"ticker":{"type":"string","title":"Ticker"},"company_id":{"type":"integer","title":"Company Id"},"period_end":{"type":"string","format":"date","title":"Period End"},"period_type":{"type":"string","title":"Period Type"},"metrics":{"additionalProperties":{"$ref":"#/components/schemas/MetricValue"},"type":"object","title":"Metrics"},"data_completeness":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Data Completeness"},"primary_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Source"},"provenance":{"anyOf":[{"$ref":"#/components/schemas/ProvenanceMeta"},{"type":"null"}]}},"type":"object","required":["ticker","company_id","period_end","period_type","metrics"],"title":"MetricsResponse","description":"Calculated metrics response for a company period."},"MetricsSummary":{"properties":{"ticker":{"type":"string","title":"Ticker"},"period_end":{"type":"string","format":"date","title":"Period End"},"pe_ratio":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Pe Ratio"},"pb_ratio":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Pb Ratio"},"ps_ratio":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Ps Ratio"},"peg_ratio":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Peg Ratio"},"enterprise_value":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Enterprise Value"},"ev_to_ebitda":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Ev To Ebitda"},"ev_to_sales":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Ev To Sales"},"fcf_yield":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Fcf Yield"},"fcf_margin":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Fcf Margin"},"rd_intensity":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Rd Intensity"},"asset_turnover":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Asset Turnover"},"gross_margin":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Gross Margin"},"operating_margin":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Operating Margin"},"net_margin":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Net Margin"},"ebit_margin":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Ebit Margin"},"ebitda_margin":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Ebitda Margin"},"roe":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Roe"},"roa":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Roa"},"roic":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Roic"},"effective_tax_rate":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Effective Tax Rate"},"ebit":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Ebit"},"ebitda":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Ebitda"},"revenue_growth":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Revenue Growth"},"earnings_growth":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Earnings Growth"},"ebit_growth":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Ebit Growth"},"ebitda_growth":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Ebitda Growth"},"eps_basic":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Eps Basic"},"eps_diluted":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Eps Diluted"},"eps_adjusted":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Eps Adjusted"},"book_value_per_share":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Book Value Per Share"},"dividend_per_share":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Dividend Per Share"},"dividend_yield":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Dividend Yield"},"dividend_payout":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Dividend Payout"},"dividend_growth":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Dividend Growth"},"franking_credits":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Franking Credits"},"gmroi":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Gmroi"},"debt_to_equity":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Debt To Equity"},"liabilities_to_equity":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Liabilities To Equity"},"current_ratio":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Current Ratio"},"quick_ratio":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Quick Ratio"},"interest_coverage":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Interest Coverage"},"total_debt":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Total Debt"},"net_debt":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Net Debt"},"net_debt_to_ebitda":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Net Debt To Ebitda"},"tangible_book_value":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Tangible Book Value"},"days_sales_outstanding":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Days Sales Outstanding"},"days_payable_outstanding":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Days Payable Outstanding"},"days_inventory_outstanding":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Days Inventory Outstanding"},"cash_conversion_cycle":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Cash Conversion Cycle"},"dividend_yield_5y_avg":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Dividend Yield 5Y Avg"},"ebitda_margin_5y_avg":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Ebitda Margin 5Y Avg"},"roe_5y_avg":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Roe 5Y Avg"},"roa_5y_avg":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Roa 5Y Avg"},"roic_5y_avg":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Roic 5Y Avg"}},"type":"object","required":["ticker","period_end"],"title":"MetricsSummary","description":"Summary of key metrics for quick overview."},"NewsSource":{"properties":{"source_name":{"type":"string","title":"Source Name"},"article_url":{"type":"string","title":"Article Url"}},"type":"object","required":["source_name","article_url"],"title":"NewsSource","description":"One source's link for a consolidated story (full per-source provenance)."},"OHLCBar":{"properties":{"t":{"anyOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"T"},"open":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Open"},"high":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"High"},"low":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Low"},"close":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Close"},"volume":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Volume"}},"type":"object","required":["t"],"title":"OHLCBar","description":"A single OHLC bar in a historical price series."},"PaginatedResponse_CompanyListItem_":{"properties":{"data":{"items":{"$ref":"#/components/schemas/CompanyListItem"},"type":"array","title":"Data"},"meta":{"$ref":"#/components/schemas/PaginationMeta"}},"type":"object","required":["data","meta"],"title":"PaginatedResponse[CompanyListItem]"},"PaginatedResponse_DataIssueItem_":{"properties":{"data":{"items":{"$ref":"#/components/schemas/DataIssueItem"},"type":"array","title":"Data"},"meta":{"$ref":"#/components/schemas/PaginationMeta"}},"type":"object","required":["data","meta"],"title":"PaginatedResponse[DataIssueItem]"},"PaginatedResponse_JobRunItem_":{"properties":{"data":{"items":{"$ref":"#/components/schemas/JobRunItem"},"type":"array","title":"Data"},"meta":{"$ref":"#/components/schemas/PaginationMeta"}},"type":"object","required":["data","meta"],"title":"PaginatedResponse[JobRunItem]"},"PaginationMeta":{"properties":{"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"total_items":{"type":"integer","title":"Total Items"},"total_pages":{"type":"integer","title":"Total Pages"},"has_next":{"type":"boolean","title":"Has Next"},"has_prev":{"type":"boolean","title":"Has Prev"}},"type":"object","required":["page","page_size","total_items","total_pages","has_next","has_prev"],"title":"PaginationMeta","description":"Pagination metadata for list responses."},"PaymentVerifyRequest":{"properties":{"tx_hash":{"type":"string","maxLength":120,"minLength":10,"title":"Tx Hash"},"network":{"type":"string","pattern":"^(base|ethereum|solana)$","title":"Network"},"plan":{"type":"string","pattern":"^(monthly|yearly|monthly_plus|yearly_plus)$","title":"Plan"},"intent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Intent Id"}},"type":"object","required":["tx_hash","network","plan"],"title":"PaymentVerifyRequest"},"PaymentVerifyResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"subscription":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Subscription"},"invoice_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invoice Number"}},"type":"object","required":["success"],"title":"PaymentVerifyResponse"},"PlanInfo":{"properties":{"price_usd":{"type":"number","title":"Price Usd"},"price_usdc":{"type":"string","title":"Price Usdc"},"savings":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Savings"},"tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tier"}},"type":"object","required":["price_usd","price_usdc"],"title":"PlanInfo"},"PlansResponse":{"properties":{"plans":{"additionalProperties":{"$ref":"#/components/schemas/PlanInfo"},"type":"object","title":"Plans"},"networks":{"items":{"type":"string"},"type":"array","title":"Networks"},"token":{"type":"string","title":"Token","default":"USDC"}},"type":"object","required":["plans","networks"],"title":"PlansResponse"},"PriceSeriesResponse":{"properties":{"ticker":{"type":"string","title":"Ticker"},"company_id":{"type":"integer","title":"Company Id"},"range":{"type":"string","title":"Range"},"interval":{"type":"string","title":"Interval"},"currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency"},"bars":{"items":{"$ref":"#/components/schemas/OHLCBar"},"type":"array","title":"Bars"},"total":{"type":"integer","title":"Total"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"}},"type":"object","required":["ticker","company_id","range","interval","bars","total"],"title":"PriceSeriesResponse","description":"Historical OHLC time series for a single company."},"ProvenanceMeta":{"properties":{"last_updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Updated At"},"primary_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Source"},"data_completeness_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Data Completeness Pct"},"last_job_run_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Last Job Run Id"}},"type":"object","title":"ProvenanceMeta","description":"Source-tracking metadata exposed on data responses.\n\nThe project's mission is data completeness, quality, and provenance.\nEvery response that exposes financial data should carry this block so\nconsumers can answer \"how fresh is this?\" and \"where did it come from?\"\nwithout making a second request."},"Quote":{"properties":{"ticker":{"type":"string","title":"Ticker"},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url"},"price":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Price"},"change":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change"},"change_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change Pct"},"prev_close":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Prev Close"},"open":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Open"},"day_high":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Day High"},"day_low":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Day Low"},"volume":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Volume"},"market_cap":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Market Cap"},"fifty_two_week_high":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Fifty Two Week High"},"fifty_two_week_low":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Fifty Two Week Low"},"currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency"},"as_of":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"As Of"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"},"is_delayed":{"type":"boolean","title":"Is Delayed","default":true},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"}},"type":"object","required":["ticker"],"title":"Quote","description":"A single-symbol market quote built from the latest snapshot.\n\nValues come from the most recent ``MarketData`` snapshot plus the latest\ndaily ``Price`` row (for the open / day high / day low / volume). This is\ndelayed / end-of-day data, not a real-time tick — ``is_delayed`` is always\ntrue and ``as_of`` / ``updated_at`` tell the consumer how stale it is."},"QuotesResponse":{"properties":{"quotes":{"items":{"$ref":"#/components/schemas/Quote"},"type":"array","title":"Quotes"},"not_found":{"items":{"type":"string"},"type":"array","title":"Not Found","default":[]},"total":{"type":"integer","title":"Total"},"is_delayed":{"type":"boolean","title":"Is Delayed","default":true}},"type":"object","required":["quotes","total"],"title":"QuotesResponse","description":"Batch quote response — one Quote per resolved symbol.\n\nA list (not a dict) because watchlist callers iterate to render rows.\nSymbols we don't track, or that have no price/market data at all, are\nreturned in ``not_found`` rather than failing the whole request."},"RevenueCurrencySplit":{"properties":{"currency":{"type":"string","title":"Currency"},"pct":{"type":"number","title":"Pct"}},"type":"object","required":["currency","pct"],"title":"RevenueCurrencySplit","description":"One currency's share of revenue, from a disclosed segment note."},"RevenueGeographySplit":{"properties":{"geography":{"type":"string","title":"Geography"},"pct":{"type":"number","title":"Pct"}},"type":"object","required":["geography","pct"],"title":"RevenueGeographySplit","description":"One geography's share of revenue, from a disclosed segment note."},"SectorListResponse":{"properties":{"sectors":{"items":{"$ref":"#/components/schemas/SectorSummary"},"type":"array","title":"Sectors"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["sectors","total"],"title":"SectorListResponse"},"SectorMetricStat":{"properties":{"count":{"type":"integer","title":"Count"},"min":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Min"},"p25":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"P25"},"median":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Median"},"p75":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"P75"},"max":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Max"},"mean":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Mean"}},"type":"object","required":["count"],"title":"SectorMetricStat","description":"Distribution of one metric across the companies in a sector."},"SectorStatsResponse":{"properties":{"sector":{"type":"string","title":"Sector"},"company_count":{"type":"integer","title":"Company Count"},"metrics_with_financials":{"type":"integer","title":"Metrics With Financials"},"stats":{"additionalProperties":{"$ref":"#/components/schemas/SectorMetricStat"},"type":"object","title":"Stats"}},"type":"object","required":["sector","company_count","metrics_with_financials","stats"],"title":"SectorStatsResponse","description":"Per-metric distributions for a single sector.\n\nData-infrastructure framing: these are descriptive distributions of the\npopulated metric values, not investment signals. ``company_count`` is the\nnumber of companies in the sector; each metric's ``count`` reflects how\nmany of those actually have that metric populated (a completeness signal)."},"SectorSummary":{"properties":{"sector":{"type":"string","title":"Sector"},"company_count":{"type":"integer","title":"Company Count"}},"type":"object","required":["sector","company_count"],"title":"SectorSummary","description":"One row in the sector listing."},"SolanaTxRequest":{"properties":{"sender":{"type":"string","title":"Sender"},"plan":{"type":"string","title":"Plan"}},"type":"object","required":["sender","plan"],"title":"SolanaTxRequest"},"StockPrice":{"properties":{"close":{"type":"number","title":"Close"},"date":{"type":"string","format":"date","title":"Date"},"source":{"type":"string","title":"Source"}},"type":"object","required":["close","date","source"],"title":"StockPrice","description":"Latest stock price info."},"SubscribeRequest":{"properties":{"plan":{"type":"string","enum":["monthly","yearly","monthly_plus","yearly_plus"],"title":"Plan"}},"type":"object","required":["plan"],"title":"SubscribeRequest","description":"Request body for subscribing to a plan."},"SubscriptionInfo":{"properties":{"tier":{"type":"string","title":"Tier"},"status":{"type":"string","title":"Status"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"is_active":{"type":"boolean","title":"Is Active"}},"type":"object","required":["tier","status","started_at","expires_at","is_active"],"title":"SubscriptionInfo","description":"Current subscription information."},"SubscriptionStatusResponse":{"properties":{"status":{"type":"string","title":"Status"},"plan":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"days_remaining":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Days Remaining"}},"type":"object","required":["status"],"title":"SubscriptionStatusResponse"},"TechnicalsResponse":{"properties":{"ticker":{"type":"string","title":"Ticker"},"company_id":{"type":"integer","title":"Company Id"},"as_of":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"As Of"},"bars_used":{"type":"integer","title":"Bars Used","default":0},"rsi_14":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Rsi 14"},"macd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Macd"},"macd_signal":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Macd Signal"},"macd_histogram":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Macd Histogram"},"sma_20":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Sma 20"},"sma_50":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Sma 50"},"sma_100":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Sma 100"},"sma_200":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Sma 200"},"ema_20":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Ema 20"},"atr_14":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Atr 14"},"beta":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Beta"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"}},"type":"object","required":["ticker","company_id"],"title":"TechnicalsResponse","description":"Technical indicators derived from daily price history.\n\nAll values are computed from our own daily close/high/low series — no new\ndata source. Indicators needing more history than is available come back\nnull rather than fabricated. ``as_of`` is the date of the most recent bar\nused; ``bars_used`` is how many daily bars fed the computation."},"TrendingTheme":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"change_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change Pct"},"change_pct_1m":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change Pct 1M"},"change_pct_1y":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change Pct 1Y"},"count":{"type":"integer","title":"Count"},"members_total":{"type":"integer","title":"Members Total"},"weighting":{"type":"string","title":"Weighting"},"as_of":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"As Of"},"source":{"type":"string","title":"Source","default":"curated"},"top_movers":{"items":{"$ref":"#/components/schemas/TrendingThemeMover"},"type":"array","title":"Top Movers","default":[]},"members":{"items":{"$ref":"#/components/schemas/TrendingThemeMover"},"type":"array","title":"Members","default":[]}},"type":"object","required":["id","name","count","members_total","weighting"],"title":"TrendingTheme","description":"A curated theme's aggregate move today plus its leading names.\n\nData-infrastructure framing: ``change_pct`` is a descriptive basket move over\nthe constituents we actually cover — not a signal. ``count`` is how many\ncovered members had a computable move; ``members_total`` is the curated\nregistry size, so the coverage gap is visible. ``weighting`` states how the\nbasket move was combined (``market_cap`` or ``equal``); ``source`` records\nthat membership is curated, not derived."},"TrendingThemeMover":{"properties":{"symbol":{"type":"string","title":"Symbol"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"price":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Price"},"change_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change Pct"},"exchange":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Exchange"},"currency":{"type":"string","title":"Currency","default":"USD"},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags","default":[]}},"type":"object","required":["symbol"],"title":"TrendingThemeMover","description":"One constituent row in a theme's ``top_movers`` list.\n\n``exchange`` drives the per-row currency (``ASX`` → ``AUD``) exactly like the\nquotes/movers rows, so a cross-listed theme renders each name in its own\nlisting currency.\n\n``tags`` is a curated, many-to-many sub-category *within* the theme (e.g.\n\"Chips\" vs \"Labs\" within ``ai``; \"Gold\" vs \"Bitcoin\" within\n``store-of-value``) — finer-grained than the theme itself, and finer than\nGICS ``sector``/``industry`` since it groups by thematic role, not\nclassification code. ``[]`` means this theme has no sub-category taxonomy\nyet (most don't) — an honest gap, not an omission per-row."},"TrendingThemesResponse":{"properties":{"sectors":{"items":{"$ref":"#/components/schemas/TrendingTheme"},"type":"array","title":"Sectors"},"as_of":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"As Of"},"weighting":{"type":"string","title":"Weighting","default":"market_cap"},"is_delayed":{"type":"boolean","title":"Is Delayed","default":true}},"type":"object","required":["sectors"],"title":"TrendingThemesResponse","description":"Themes ranked by today's move.\n\nThe list key is ``sectors`` (not ``themes``) to match the shape ALFRED's\n``/api/sectors`` proxy already consumes. Everything is end-of-day / delayed —\n``is_delayed`` and each theme's ``as_of`` say how stale the underlying quotes\nare."},"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"},"VerifyRequest":{"properties":{"wallet_address":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$","title":"Wallet Address"},"signature":{"type":"string","title":"Signature"},"nonce":{"type":"string","title":"Nonce"}},"type":"object","required":["wallet_address","signature","nonce"],"title":"VerifyRequest"},"VerifyResponse":{"properties":{"api_key":{"type":"string","title":"Api Key"},"tier":{"type":"string","title":"Tier"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"}},"type":"object","required":["api_key","tier"],"title":"VerifyResponse"},"WebhookResponse":{"properties":{"status":{"type":"string","title":"Status"},"message":{"type":"string","title":"Message"}},"type":"object","required":["status","message"],"title":"WebhookResponse","description":"Generic webhook response."}},"securitySchemes":{"APIKeyHeader":{"type":"apiKey","in":"header","name":"X-API-Key"}}}}