Endpoints

Scan

A universe-wide query. Pass a SQL WHERE clause as q; we return every ticker that matches it right now. The same query language drives webhooks — what fires asynchronously over there is what returns synchronously here.

GET /v1/scan

One endpoint, one shape. Pass q (and optionally fields, order, dir, limit) as query params.

GET/v1/scan

Find every ticker matching a SQL WHERE clause right now.

A universe-wide query against the current state of every tracked ticker. The `q` parameter is a SQL `WHERE` clause — any column on the schema (numerics, flags, classification fields) is queryable. Returns the list of matching tickers along with the fields you asked about. By default, the response includes the ticker symbol, name, and any field referenced in `q` or `sort`. Pass `full=true` to receive the entire ticker object per match.

Authentication required
Query parameters
NameInTypeRequiredDescription
qquerystring (SQL WHERE clause)required
The condition to match. URL-encode it. Use full numeric literals (e.g. `1500000000`, not `1.5B`).
Example: above_sma_50 AND volume_unusual_2x AND market_cap > 10000000000
fullquerybooleanoptional
If true, each match includes the entire ticker object (same shape as `/v1/tickers/{ticker}`). Otherwise only relevant fields are returned.
Default: false
sortquerystringoptional
Sort field. Prefix with `-` for descending. Any numeric column on the schema is allowed.
Default: -day_change_pct
limitqueryintegeroptional
Max matches in this response. Capped at 500.
Default: 100
Responses
StatusDescription
200List of matching tickers.
400SQL parse error or unknown identifier.

Default — relevant fields only

Request
curl "https://api.tickerbot.io/v1/scan?q=above_sma_50%20AND%20volume_unusual_2x" \
  -H "Authorization: Bearer YOUR_KEY"
Response · 200
{
  "q": "above_sma_50 AND volume_unusual_2x",
  "sort": "-day_change_pct",
  "as_of": "2026-04-30T14:32:11Z",
  "count": 12,
  "returned": 12,
  "matches": [
    { "ticker": "PLTR", "name": "Palantir",          "above_sma_50": true, "volume_unusual_2x": true, "day_change_pct": 6.21 },
    { "ticker": "SOFI", "name": "SoFi Technologies", "above_sma_50": true, "volume_unusual_2x": true, "day_change_pct": 4.82 },
    { "ticker": "RIVN", "name": "Rivian",            "above_sma_50": true, "volume_unusual_2x": true, "day_change_pct": 3.50 }
  ]
}

Numeric thresholds — small caps gapping up on volume, no earnings noise

Request
curl "https://api.tickerbot.io/v1/scan?q=gap_up_3pct%20AND%20volume_unusual_2x%20AND%20market_cap%20%3C%202000000000%20AND%20NOT%20earnings_this_week" \
  -H "Authorization: Bearer YOUR_KEY"
Response · 200
{
  "q": "gap_up_3pct AND volume_unusual_2x AND market_cap < 2000000000 AND NOT earnings_this_week",
  "sort": "-day_change_pct",
  "as_of": "2026-04-30T14:32:11Z",
  "count": 2,
  "returned": 2,
  "matches": [
    { "ticker": "RIOT", "name": "Riot Platforms",   "gap_up_3pct": true, "volume_unusual_2x": true, "market_cap": 1850000000, "earnings_this_week": false, "day_change_pct": 8.41 },
    { "ticker": "MARA", "name": "Marathon Digital", "gap_up_3pct": true, "volume_unusual_2x": true, "market_cap": 1620000000, "earnings_this_week": false, "day_change_pct": 5.74 }
  ]
}

Same scan, full ticker objects

Request
curl "https://api.tickerbot.io/v1/scan?q=above_sma_50%20AND%20volume_unusual_2x&full=true&limit=2" \
  -H "Authorization: Bearer YOUR_KEY"
Response · 200
{
  "q": "above_sma_50 AND volume_unusual_2x",
  "full": true,
  "as_of": "2026-04-30T14:32:11Z",
  "count": 12,
  "returned": 2,
  "matches": [
    { "ticker": "PLTR", "name": "Palantir", "...": "(full ticker object — same shape as /v1/tickers/{ticker})" },
    { "ticker": "SOFI", "name": "SoFi Technologies", "...": "(full ticker object)" }
  ]
}

URL length is the practical ceiling here — typical browsers and servers comfortably handle ~8 KB URLs (≈ 1500 characters of SQL), which covers anything you’d reasonably write by hand. If you ever need to send queries longer than that programmatically, let us know and we’ll add a POST variant.

Default vs. full responses

By default, each match includes only the fields you'd care about — the ticker, name, and any column referenced in q or sort.

Pass ?full=true if you want every match to come back as the entire ticker object (same shape as /v1/tickers/{ticker}). Useful when you want to act on a scan result without making a follow-up call per ticker. Costs you bandwidth — a full ticker object is ~3 KB.