openapi: 3.0.0 info: title: market-screener.bruno version: 1.0.0 paths: /api/analyze: post: summary: 'Analyze — Validation: empty tickers (expect 400)' operationId: >- users_kanna_documents_bruno_market_screener_api_-_1_llm_analysis_analyze_validation-_empty_tickers_expect_400_bru description: 'Schema validation: minItems: 1. Expect 400.' tags: - LLM Analysis responses: '200': description: '' parameters: - name: Content-Type in: header description: '' required: true schema: type: string example: application/json requestBody: $ref: '#/components/requestBodies/analyze_validation_empty_tickers_expect_400' /health: get: summary: Health Check operationId: >- users_kanna_documents_bruno_market_screener_api_-_1_health_health_check_bru description: 'Confirms the server is running. Expects { status: ''ok'' }.' tags: - Health responses: '200': description: '' /api/finance/market-context: get: summary: Get Market Context operationId: >- users_kanna_documents_bruno_market_screener_api_-_1_market_context_get_market_context_bru description: >- Returns live benchmark data: S&P500 price, 10Y rate, VIX, SPY P/E, XLK P/E, XLRE yield, LQD spread. Served from 1-hour in-memory cache. tags: - Market Context responses: '200': description: '' /api/calls: post: summary: Create Market Call operationId: >- users_kanna_documents_bruno_market_screener_api_-_1_market_calls_create_market_call_bru description: >- Creates a market thesis call. Snapshots current prices + screener signals at creation time for future comparison. The test script saves the returned ID to the {{callId}} collection variable for use in subsequent requests. tags: - Market Calls responses: '200': description: '' parameters: - name: Content-Type in: header description: '' required: true schema: type: string example: application/json requestBody: $ref: '#/components/requestBodies/create_market_call' get: summary: List Calls (empty or existing) operationId: >- users_kanna_documents_bruno_market_screener_api_-_1_market_calls_list_calls_empty_or_existing_bru description: >- Returns all market calls sorted newest first. Returns { calls: [] } if none exist yet. tags: - Market Calls responses: '200': description: '' /api/calls/{{callId}}: delete: summary: Delete Call operationId: >- users_kanna_documents_bruno_market_screener_api_-_1_market_calls_delete_call_bru description: >- Deletes the call created earlier. Returns { ok: true }. Requires {{callId}} to be set. tags: - Market Calls responses: '200': description: '' get: summary: Get Call by ID (with current re-screen) operationId: >- users_kanna_documents_bruno_market_screener_api_-_1_market_calls_get_call_by_id_with_current_re-screen_bru description: >- Fetches the call and re-screens all tickers to show how signal/price has changed since creation. Returns: original call fields + `current` map of ticker → { price, signal, inflatedVerdict, fundamentalVerdict, pe, roe, fcf }. Depends on {{callId}} being set by the Create Market Call request. tags: - Market Calls responses: '200': description: '' /api/calls/00000000-0000-0000-0000-000000000000: get: summary: Get Call — Non-existent ID (expect 404) operationId: >- users_kanna_documents_bruno_market_screener_api_-_1_market_calls_get_call_non-existent_id_expect_404_bru description: A UUID that doesn't exist. Expect 404. tags: - Market Calls responses: '200': description: '' /api/calls/calendar: get: summary: Get Earnings Calendar (call tickers) operationId: >- users_kanna_documents_bruno_market_screener_api_-_1_market_calls_get_earnings_calendar_call_tickers_bru description: >- Returns upcoming earnings dates and dividend events for all tickers across all saved calls. Optional query param ?tickers=AAPL,MSFT to restrict to specific tickers. tags: - Market Calls responses: '200': description: '' /api/calls/calendar?tickers=AAPL,MSFT: get: summary: Get Earnings Calendar — Specific Tickers operationId: >- users_kanna_documents_bruno_market_screener_api_-_1_market_calls_get_earnings_calendar_specific_tickers_bru description: Calendar for specific tickers regardless of saved calls. tags: - Market Calls responses: '200': description: '' parameters: - name: tickers in: query description: '' required: true schema: type: string example: AAPL,MSFT /api/finance/holdings: post: summary: 'Add Holding — Validation: missing shares (expect 400)' operationId: >- users_kanna_documents_bruno_market_screener_api_-_1_portfolio_add_holding_validation-_missing_shares_expect_400_bru description: 'Schema validation: shares is required. Expect 400.' tags: - Portfolio responses: '200': description: '' parameters: - name: Content-Type in: header description: '' required: true schema: type: string example: application/json requestBody: $ref: >- #/components/requestBodies/add_holding_validation_missing_shares_expect_400 /api/finance/portfolio: get: summary: Get Portfolio operationId: >- users_kanna_documents_bruno_market_screener_api_-_1_portfolio_get_portfolio_bru description: >- Screens all non-crypto holdings via Yahoo Finance, then cross-references with signals to produce buy/hold/sell advice. Each row has: ticker, signal, advice, reason, currentPrice, marketValue, gainLossPct. Also returns marketContext. Note: first call after server start may be slow (benchmark cache cold). tags: - Portfolio responses: '200': description: '' /api/finance/holdings/AAPL: delete: summary: Remove Holding — AAPL operationId: >- users_kanna_documents_bruno_market_screener_api_-_1_portfolio_remove_holding_aapl_bru description: 'Removes the AAPL holding from portfolio.json. Expect { ok: true }.' tags: - Portfolio responses: '200': description: '' /api/finance/holdings/ZZZZZZ: delete: summary: Remove Holding — Non-existent (expect 404) operationId: >- users_kanna_documents_bruno_market_screener_api_-_1_portfolio_remove_holding_non-existent_expect_404_bru description: Ticker does not exist in portfolio. Expect 404. tags: - Portfolio responses: '200': description: '' /api/screen/catalysts: get: summary: Get Catalysts operationId: >- users_kanna_documents_bruno_market_screener_api_-_1_screener_get_catalysts_bru description: >- Fetches today's Yahoo Finance news, extracts ticker symbols mentioned, and returns { tickers, stories }. May take 3-5s as it queries multiple news endpoints. tags: - Screener responses: '200': description: '' /api/screen: post: summary: 'Screen — Validation: over 50 tickers (expect 400)' operationId: >- users_kanna_documents_bruno_market_screener_api_-_1_screener_screen_validation-_over_50_tickers_expect_400_bru description: 'Schema validation: maxItems: 50. 51 tickers should return 400.' tags: - Screener responses: '200': description: '' parameters: - name: Content-Type in: header description: '' required: true schema: type: string example: application/json requestBody: $ref: >- #/components/requestBodies/screen_validation_over_50_tickers_expect_400 servers: - url: http://localhost:3000 description: Base Server components: schemas: analyze_tickers: type: object properties: tickers: type: array items: type: string example: tickers: - NVDA - AMD - INTC analyze_validation_empty_tickers_expect_400: type: object properties: tickers: type: array items: type: string example: tickers: [] create_call_validation_short_thesis_expect_400: type: object properties: title: type: string quarter: type: string thesis: type: string tickers: type: array items: type: string example: title: Test quarter: Q1 thesis: short tickers: - AAPL create_market_call: type: object properties: title: type: string quarter: type: string thesis: type: string tickers: type: array items: type: string example: title: AI Infrastructure Supercycle quarter: Q3 2025 thesis: >- Hyperscaler capex remains elevated through 2026 driven by LLM training demand. NVDA, MSFT and AMD are the primary beneficiaries. Entry here as NVDA pulled back 15% from high. tickers: - NVDA - MSFT - AMD add_holding_aapl: type: object properties: ticker: type: string shares: type: integer costBasis: type: integer type: type: string source: type: string example: ticker: AAPL shares: 10 costBasis: 150 type: stock source: Robinhood add_holding_btc-usd_crypto_no_scoring: type: object properties: ticker: type: string shares: type: number costBasis: type: integer type: type: string source: type: string example: ticker: BTC-USD shares: 0.1 costBasis: 50000 type: crypto source: Coinbase add_holding_voo_etf: type: object properties: ticker: type: string shares: type: integer costBasis: type: integer type: type: string source: type: string example: ticker: VOO shares: 5 costBasis: 420 type: etf source: Vanguard add_holding_validation_missing_shares_expect_400: type: object properties: ticker: type: string example: ticker: MSFT screen_mixed_stock_etf_bond: type: object properties: tickers: type: array items: type: string example: tickers: - AAPL - MSFT - GOOGL - VOO - AGG screen_reit_tests_p_ffo_scoring_path: type: object properties: tickers: type: array items: type: string example: tickers: - O - VICI - PLD screen_tech_stocks_tests_technology_sector_override: type: object properties: tickers: type: array items: type: string example: tickers: - NVDA - META - AMZN - TSLA screen_validation_empty_tickers_expect_400: type: object properties: tickers: type: array items: type: string example: tickers: [] screen_validation_over_50_tickers_expect_400: type: object properties: tickers: type: array items: type: string example: tickers: - A - B - C - D - E - F - G - H - I - J - K - L - M - 'N' - O - P - Q - R - S - T - U - V - W - X - 'Y' - Z - AA - BB - CC - DD - EE - FF - GG - HH - II - JJ - KK - LL - MM - NN - OO - PP - QQ - RR - SS - TT - UU - VV - WW - XX - YY requestBodies: analyze_tickers: content: application/json: schema: $ref: '#/components/schemas/analyze_tickers' description: '' required: true analyze_validation_empty_tickers_expect_400: content: application/json: schema: $ref: '#/components/schemas/analyze_validation_empty_tickers_expect_400' description: '' required: true create_call_validation_short_thesis_expect_400: content: application/json: schema: $ref: >- #/components/schemas/create_call_validation_short_thesis_expect_400 description: '' required: true create_market_call: content: application/json: schema: $ref: '#/components/schemas/create_market_call' description: '' required: true add_holding_aapl: content: application/json: schema: $ref: '#/components/schemas/add_holding_aapl' description: '' required: true add_holding_btc-usd_crypto_no_scoring: content: application/json: schema: $ref: '#/components/schemas/add_holding_btc-usd_crypto_no_scoring' description: '' required: true add_holding_voo_etf: content: application/json: schema: $ref: '#/components/schemas/add_holding_voo_etf' description: '' required: true add_holding_validation_missing_shares_expect_400: content: application/json: schema: $ref: >- #/components/schemas/add_holding_validation_missing_shares_expect_400 description: '' required: true screen_mixed_stock_etf_bond: content: application/json: schema: $ref: '#/components/schemas/screen_mixed_stock_etf_bond' description: '' required: true screen_reit_tests_p_ffo_scoring_path: content: application/json: schema: $ref: '#/components/schemas/screen_reit_tests_p_ffo_scoring_path' description: '' required: true screen_tech_stocks_tests_technology_sector_override: content: application/json: schema: $ref: >- #/components/schemas/screen_tech_stocks_tests_technology_sector_override description: '' required: true screen_validation_empty_tickers_expect_400: content: application/json: schema: $ref: '#/components/schemas/screen_validation_empty_tickers_expect_400' description: '' required: true screen_validation_over_50_tickers_expect_400: content: application/json: schema: $ref: '#/components/schemas/screen_validation_over_50_tickers_expect_400' description: '' required: true securitySchemes: {}