Api Screener

Stock screener with in-memory + PG fallback. Soft paywall: free users get 3-row teaser + locked: true so they can see what the screener does before upgrading (user-panel Marcus deal-breaker).

QA 2026-10-13 P1 (R3): a viewer who may not see vendor prices gets the price-derived filters and sorts REFUSED, not applied and named in filters_not_applied -- a filter applied on a withheld column answered range questions about it, which recovers the column. The service ranks that viewer's rows by ticker, never by market cap (_price_blind).

get/api/screener

Request

  • Base URL: https://www.oxfordledge.com (the document declares no server; this is the origin it was published from)
  • URL: https://www.oxfordledge.com/api/screener
  • Auth: none declared

Response

Successful Response

_vendor_prices_withheldboolean nullable

OWNER R3 (2026-10-12): true on an anonymous teaser whose vendor-price columns were nulled because OL_PUBLIC_VENDOR_PRICES is off. FE (screener-options.ts) then shows _price_notice instead of reading the nulls as zero. Absent otherwise.

_price_noticestring nullable

The plain-language withheld-price notice that travels with _vendor_prices_withheld (services/public_price_gate.py NOTICE_KEY).

price_filters_availableboolean nullable

QA 2026-10-13 P1: false when this viewer may not see vendor prices, so the price-derived filters (P/E, EV/EBITDA, EBIT/EV, market cap, dividend yield, P/B, near 52-week low) are refused rather than applied. FE disables those inputs.

filters_not_appliedstring[] nullable

The requested filter/sort params that were REFUSED and not applied (services/public_price_gate.SCREENER_PRICE_FILTER_KEYS). Absent when nothing was refused.

filters_not_applied_reasonstring nullable

Why filters_not_applied were refused: they need market prices, which are shown to signed-in users.

totalinteger nullable

Rows that matched the applied filters before any teaser cap. The FE count reads it as 'N matches'.

universe_sizeinteger nullable

Tickers scanned (the snapshot universe plus the viewer's recently viewed tickers).

coverage_notestring nullable

Plain-language description of the scanned universe.

coverageobject nullable

{total_checked, passed, filtered_out, applied_filters, post_filters}: which filters shaped the rows. FE banner reads it.

lockedboolean nullable

True on the free/anonymous teaser: only the first rows are returned and the rest need an upgrade. FE renders the lock row (screener-options.ts _scrLockInfo).

locked_totalinteger nullable

True match count behind a locked teaser, so the lock row and count can say 'N matches (3 shown)'.

upgradeobject nullable

{message, url} for the lock row's call to action. Present only when locked is true.

insider_filterobject nullable

P0 2026-10-18: present when the request carried insider_days / insider_min_buys / insider_net_positive. {applied, available, days, min_buys, net_positive, window, counting, tickers_matched | message}. applied and available are both true only when every row passed the Form 4 insider aggregate (rows then carry insiderBuys / insiderSells / insiderNet / insiderNetShares); false with a 503 and no rows when the aggregate could not be read. The FE shows no row under an insider caption unless both are true.

Changes

No recorded changes to this operation across all 1 revision of this API.