How Scanning Works
A scan asks one question of the whole market: which stocks match these conditions right now? The conditions are a scan payload. You get a payload, send it to POST /api/v2/scan, and get back every matching ticker in a single response. There is no pagination and no per-result cost: one scan is one request, whether it matches 3 stocks or 3,000.
Scanning is the core of the scanr.ai API. Everything else (relative strength, patterns, themes, indicators) either feeds a scan as a filter or enriches its results.
Get a payload
Start from a payload someone, or something, already wrote. In order of how often you'll want them:
- From a sentence.
POST /api/v2/scan/natural(thenatural_scantool over MCP) turns "large caps above the 200-day with RSI under 40" into a payload, with an explanation of each filter. Change it with follow-up sentences throughPOST /api/v2/scan/refine. See Natural-Language Scans. - From the scanr.ai scanner. Build or open a scan in the scanner, click Filters → Export filters (Ctrl+Shift+E), and copy or download the JSON. For a scan you've saved,
POST /api/v2/scan/myscansreturns the same payload to code. See Saved Scans. - By hand, from Building Scan Payloads and the catalog. Best for small edits to a payload you already have, or when a screen must never drift.
All three produce the same JSON, and you can move between them: generate a payload from a sentence, tweak it by hand, save it, open it in the scanner, export it again. Store the payloads you use. Running a stored payload costs one request and no AI credits; generating it again costs credits and can come back slightly different.
Generated and exported payloads are the bare payload, the object with Universe and All. To run one, send it as instructions:
The request
The body has one required key, instructions, which holds the scan payload. Written out, a payload looks like this:
That payload reads: of the common stocks and ADRs listed on the major U.S. exchanges, return every company worth at least $2B whose relative strength against the market is in the top 20%, largest first.
A payload has four parts:
Universe
The universe narrows the market before any filter runs. Within one key, values are alternatives (nasdaq or nyse); across keys, they all apply (an exchange and a type).
Always set Exchange and Type
An empty Exchange admits OTC listings, and an empty Type falls back to a default that includes ETFs. Unless you want those, send the explicit list shown above. Every scanr.ai preset does.
Sector, industry and market cap are not universe keys; they are Stock filters (see Building Scan Payloads).
Filters and groups
Filters live inside groups, and each group sits in one of three arrays:
All: a stock matches the group when it passes every filter in it.Any: a stock matches the group when it passes at least one filter in it.Exclude: stocks that match the group are removed from the result.
The final result is:
Note the union: an All group and an Any group at the same level widen the result rather than narrow it. Most scans need a single All group, optionally with an Exclude group.
Inside a group, filters are organized by category. Each category key holds a map of filter name → list of filter rows:
The full, current list of every filter, with its parameters, defaults and allowed values, is served by GET /api/v2/scan/instructions (below). Building Scan Payloads shows the shape of each category with worked examples.
Timeframes
Technical studies, candlestick patterns and chart patterns run on a timeframe, which is required on each of those filters:
The values are exact: 1w or 1h is a 400. Filters in one scan can use different timeframes, so "daily trend up, 15-minute RSI oversold" is a single payload.
The response
Caching
An identical payload run again within two minutes is answered from cache, with "cached": true. To choose that window, send cache_ttl_seconds in the request body next to instructions: 0 always recomputes, and the most is 900 (15 minutes). During regular market hours a scan on live data is never reused for more than 5 minutes, whatever you ask for. A cached answer still counts as a request.
A scan returns tickers, not rows of data. To show why each stock matched, or to rank the matches, enrich them with the data endpoints, for example POST /api/v2/stocks/get-stock-indicators for relative-strength scores. Run an End-of-Day Screen does exactly that.
When data updates
A scan reads the latest data at the moment it runs:
- Price and volume studies include the current session's in-progress bar during market hours. A daily RSI at 11:00 is computed from today's partial candle; the same scan after the close sees the settled day.
- Relative strength and regime scores are recomputed about once a minute during the session and settle after the close.
- Fundamentals reflect the most recent filing.
Run the same scan at 16:30 ET and at 11:00 ET the next morning and you may get different results; both are correct for their moment. For a stable daily list, run after the close. See Coverage & Freshness for each dataset's schedule.
Discovering filters
Three read-only endpoints describe what a payload can contain. The catalog and the country list answer without a token, so you can explore before you subscribe; the theme list needs one.
The catalog is large (hundreds of KB). Fetch it once and cache it; it changes when new filters ship, not between requests.
Limits
- Every API plan gets the full scanner: every timeframe, OTC and ETF universes, themes and every filter category. Plans differ in request volume, not in what a scan may contain. See Plans & Rate Limits.
- A payload may hold up to 200 filter rows and 1 MiB of JSON.
- Every scan counts as one request against your rate limits and is recorded in your scan history for 30 days.


