{"openapi":"3.0.3","info":{"title":"PSX Lens API","version":"1.0.0","description":"Pakistan Stock Exchange data layer for research agents. Deterministic, sourced, timestamped. Never returns fabricated numbers.\n\nTools: get_company, get_quote, get_price_history, get_financials, get_dividends, get_corporate_actions, get_announcements, get_news, get_sector, get_sector_peers, get_sector_valuation, screen_stocks, compare_stocks, get_market_snapshot, get_index."},"servers":[{"url":"/","description":"this host"}],"paths":{"/health":{"get":{"operationId":"health","summary":"Liveness","responses":{"200":{"description":"ok"}}}},"/v1/market/status":{"get":{"operationId":"get_market_status","summary":"Pakistan market calendar status (Asia/Karachi)","responses":{"200":{"description":"status"}}}},"/v1/market/snapshot":{"get":{"operationId":"get_market_snapshot","summary":"Indices, breadth, freshness","responses":{"200":{"description":"snapshot"}}}},"/v1/companies":{"get":{"operationId":"list_companies","summary":"Company universe","parameters":[{"name":"limit","in":"query","schema":{"type":"integer"}},{"name":"cursor","in":"query","schema":{"type":"string"}},{"name":"sector","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"page"}}}},"/v1/companies/{symbol}":{"get":{"operationId":"get_company","summary":"Company profile, quote, computed ratios","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"company"},"400":{"description":"INVALID_SYMBOL"},"404":{"description":"DATA_NOT_FOUND"}}}},"/v1/quotes/{symbol}":{"get":{"operationId":"get_quote","summary":"Current quote. Always delayed when sourced from PSX portal. Never live.","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"quote"},"404":{"description":"DATA_NOT_FOUND"},"409":{"description":"DATA_STALE or DATA_UNVERIFIED"}}}},"/v1/prices/{symbol}":{"get":{"operationId":"get_price_history","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string"}},{"name":"date_from","in":"query","schema":{"type":"string","format":"date"}},{"name":"date_to","in":"query","schema":{"type":"string","format":"date"}},{"name":"limit","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"ohlcv"}}}},"/v1/financials/{symbol}":{"get":{"operationId":"get_financials","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"statements"}}}},"/v1/dividends/{symbol}":{"get":{"operationId":"get_dividends","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"dividends plus trailing/5y fields"}}}},"/v1/corporate-actions/{symbol}":{"get":{"operationId":"get_corporate_actions","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"actions"}}}},"/v1/announcements":{"get":{"operationId":"get_announcements","parameters":[{"name":"symbol","in":"query","schema":{"type":"string"}},{"name":"date_from","in":"query","schema":{"type":"string","format":"date"}},{"name":"date_to","in":"query","schema":{"type":"string","format":"date"}},{"name":"limit","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"announcements"}}}},"/v1/news":{"get":{"operationId":"get_news","description":"published_at and event_date are separate. A republished old event is not a new event.","responses":{"200":{"description":"news"}}}},"/v1/sectors":{"get":{"operationId":"list_sectors","responses":{"200":{"description":"sectors"}}}},"/v1/sectors/{id}":{"get":{"operationId":"get_sector","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"sector"}}}},"/v1/sectors/{id}/peers":{"get":{"operationId":"get_sector_peers","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"peers"}}}},"/v1/sectors/{id}/valuation":{"get":{"operationId":"get_sector_valuation","description":"Medians. Loss-making companies are excluded from median PE.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"valuation"}}}},"/v1/indices":{"get":{"operationId":"list_indices","responses":{"200":{"description":"indices"}}}},"/v1/indices/{id}":{"get":{"operationId":"get_index","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"index"}}}},"/v1/compare":{"get":{"operationId":"compare_stocks","parameters":[{"name":"symbols","in":"query","required":true,"schema":{"type":"string"},"example":"FFC,EFERT"}],"responses":{"200":{"description":"side-by-side"}}}},"/v1/screener":{"get":{"operationId":"screen_stocks","summary":"Filter the delayed snapshot. GET-first so GET-only agents can run a market-wide screen.","parameters":[{"name":"dividend_yield_min","in":"query","schema":{"type":"number"}},{"name":"daily_change_max","in":"query","schema":{"type":"number"},"description":"change_pct <= this. 0 means at or below previous close."},{"name":"drawdown_5d_min","in":"query","schema":{"type":"number"},"description":"at least this many percent below the 5-day high"},{"name":"drawdown_20d_min","in":"query","schema":{"type":"number"}},{"name":"drawdown_mode","in":"query","schema":{"type":"string","enum":["any","all"]},"description":"OR (any) or AND (all) between the two drawdown gates. Default any when both are set."},{"name":"pe_min","in":"query","schema":{"type":"number"}},{"name":"pe_max","in":"query","schema":{"type":"number"}},{"name":"limit","in":"query","schema":{"type":"integer"}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"matches plus total and next_cursor"}}},"post":{"operationId":"screen_stocks_post","summary":"Same filters as GET, accepted as a JSON body","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreenRequest"}}}},"responses":{"200":{"description":"matches"}}}},"/v1/freshness":{"get":{"operationId":"get_freshness","responses":{"200":{"description":"dataset freshness"}}}},"/ready":{"get":{"operationId":"ready","summary":"Postgres reachable and config valid","responses":{"200":{"description":"ready"},"503":{"description":"not ready"}}}},"/v1/me/session":{"post":{"operationId":"create_anonymous_session","responses":{"201":{"description":"token + user"}}}},"/v1/me/portfolio":{"get":{"operationId":"get_my_portfolio","responses":{"200":{"description":"portfolio"},"401":{"description":"UNAUTHORIZED"}}}},"/v1/me/analyze":{"get":{"operationId":"analyze_my_portfolio","responses":{"200":{"description":"analysis"}}}},"/v1/ai/tools":{"get":{"operationId":"list_ai_tools","responses":{"200":{"description":"catalog"}}}},"/v1/stocks/{symbol}/analytics":{"get":{"operationId":"get_stock_analytics","summary":"5d/20d performance, drawdowns, 52-week range, 30d liquidity, reference prices","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"analytics"}}}},"/v1/stocks/{symbol}/financials":{"get":{"operationId":"get_stock_financials","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"income statement periods"}}}},"/v1/stocks/{symbol}/dividends":{"get":{"operationId":"get_stock_dividends","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"payout history and trailing yield"}}}},"/v1/stocks/{symbol}/valuation":{"get":{"operationId":"get_stock_valuation","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"pe yield market cap"}}}},"/v1/stocks/{symbol}/announcements":{"get":{"operationId":"get_stock_announcements","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"filings and notices"}}}},"/v1/stocks/{symbol}/research":{"get":{"operationId":"research_stock","summary":"Canonical dated source-aware research package for one symbol","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"research package"}}}},"/v1/stocks/{symbol}/rh":{"get":{"operationId":"research_stock_alias","summary":"Legacy alias of /v1/stocks/{symbol}/research","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"research package"}}}},"/v1/ai/research/{symbol}":{"get":{"operationId":"research_stock_ai_alias","summary":"Alias of /v1/stocks/{symbol}/research","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"research package"}}}},"/v1/ai/sources/{symbol}":{"get":{"operationId":"get_data_sources","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"provenance"}}}},"/v1/donations":{"post":{"operationId":"create_donation","responses":{"200":{"description":"pending donation"}}}}},"components":{"schemas":{"Error":{"type":"object","required":["error","message"],"properties":{"error":{"type":"string","enum":["DATA_NOT_FOUND","DATA_STALE","DATA_UNVERIFIED","SOURCE_UNAVAILABLE","INVALID_SYMBOL","MARKET_CLOSED","RATE_LIMITED","UNAUTHORIZED","FORBIDDEN","INVALID_REQUEST","INTERNAL"]},"message":{"type":"string"},"symbol":{"type":"string"}}},"ScreenRequest":{"type":"object","properties":{"dividend_yield_min":{"type":"number"},"daily_change_max":{"type":"number"},"daily_change_min":{"type":"number"},"drawdown_5d_min":{"type":"number"},"drawdown_20d_min":{"type":"number"},"pe_max":{"type":"number"},"pe_min":{"type":"number"},"market_cap_min":{"type":"number"},"sectors":{"type":"array","items":{"type":"string"}},"inside_kse100":{"type":"boolean","nullable":true},"limit":{"type":"integer"}}}}}}