# GET /v2/scan

**Live scan**

Filter the live ticker universe with a SQL WHERE clause expressed in our SQL grammar. Returns matching tickers sorted by your chosen column. Columns in `q`, `order`, and `fields` are the customer-facing names listed on /api/schema and /api/flags. No translation layer.

## Plan access

- **Plan access.** Included on every plan, Hobby through Enterprise.
- **Rate limit.** Hobby 60/min · Pro 2,000/min · Scale 10,000/min.
- **Universe.** All ~12,000 tracked tickers on every plan.

## Query / path parameters

| Name | In | Type | Required | Description |
|------|----|----|----------|-------------|
| `q` | query | string | no | SQL WHERE expression. Required unless `rule` is supplied. Max 4000 chars. Semicolons, comments, and write-side keywords (INSERT/UPDATE/DELETE/DROP/etc.) are rejected. Example: `above_sma_50 AND day_change_pct > 5`. |
| `rule` | query | string | no | Slug of a saved rule (see `/v2/rules`). Its `q`, `universe_id`, `order`, `dir`, and `fields` become defaults; any of those passed as query-string parameters override. |
| `universe` | query | string | no | Slug of a system universe (`top_10`, `top_100`) or one of your own (`/v2/universes`). Scopes the scan to those tickers. When omitted, the scan runs across all ~12,000 tracked tickers. |
| `asof` | query | string | no | Optional. Run the WHERE against historical daily state for the given `YYYY-MM-DD` (or full ISO). Plan history depth applies. |
| `order` | query | string | no | Column to sort by. Must be a valid identifier (lowercase letters, digits, underscore). Default: `day_change_pct`. |
| `dir` | query | string | no | Sort direction. Enum: `asc`, `desc`. Default: `desc`. |
| `fields` | query | string | no | Comma-separated list of extra columns to include in each result row. Default columns are always present: ticker, name, asset_type, price, day_change_pct, gap_pct, relative_volume, market_cap. Example: `pe_ratio,rsi_14`. |
| `limit` | query | integer | no | Page size. Max 100. Default: `50`. |
| `cursor` | query | string | no | Opaque cursor from the previous response. |

## Status codes

- **200** — Page of matching rows with `as_of`, `query`, `count`, `next_cursor`, and `results`. If the response was scoped (explicit `?universe=` or plan default), `_meta.scope` describes it.
- **400** — Malformed `q`, unknown column, invalid `order`/`dir`/`fields`, or invalid cursor.
- **402** — Query references a premium signal and your plan does not include premium signals.
- **404** — Referenced `rule` or `universe` does not exist.

## Sample response

```json
{
  "as_of": "2026-05-15T13:31:02.000Z",
  "query": {
    "q": "gap_up_3pct AND market_cap < 2000000000",
    "limit": 10,
    "order": "day_change_pct",
    "dir": "desc",
    "fields": [],
    "full": false,
    "universe": null,
    "rule": null
  },
  "count": 3,
  "next_cursor": null,
  "results": [
    {
      "ticker": "OWLT",
      "name": "Owlet, Inc.",
      "asset_type": "CS",
      "price": 4.21,
      "day_change_pct": 0.142,
      "gap_pct": 0.061,
      "relative_volume": 4.8,
      "market_cap": 81000000
    },
    {
      "ticker": "DJT",
      "name": "Trump Media & Technology Group",
      "asset_type": "CS",
      "price": 28.74,
      "day_change_pct": 0.118,
      "gap_pct": 0.054,
      "relative_volume": 3.2,
      "market_cap": 1840000000
    },
    {
      "ticker": "RIVN",
      "name": "Rivian Automotive",
      "asset_type": "CS",
      "price": 13.45,
      "day_change_pct": 0.092,
      "gap_pct": 0.041,
      "relative_volume": 2.7,
      "market_cap": 1390000000
    }
  ]
}
```

## Examples

### Trillion-dollar caps with momentum

Request:

```shell
curl "https://api.tickerbot.io/v2/scan?q=market_cap%3E1000000000000%20AND%20above_sma_50&limit=3" \
  -H "Authorization: Bearer YOUR_KEY"
```

Response (`200`):

```json
{
  "as_of": "2026-05-14T11:41:01.000Z",
  "query": { "q": "market_cap>1000000000000 AND above_sma_50", "limit": 3, "order": "day_change_pct", "dir": "desc", "fields": [], "full": false, "universe": null, "rule": null },
  "count": 3,
  "next_cursor": null,
  "results": [
    { "ticker": "GOOGL","name": "Alphabet Inc. Class A","asset_type": "CS","price": 402.42,"day_change_pct": 0.0389,"gap_pct":-0.0045,"relative_volume": 1.005,"market_cap": 4821825618850 },
    { "ticker": "GOOG", "name": "Alphabet Inc. Class C","asset_type": "CS","price": 398.74,"day_change_pct": 0.0389,"gap_pct":-0.0050,"relative_volume": 0.938,"market_cap": 4789235074076 },
    { "ticker": "TSLA", "name": "Tesla, Inc.",          "asset_type": "CS","price": 445.77,"day_change_pct": 0.0241,"gap_pct": 0.0012,"relative_volume": 1.241,"market_cap": 1430000000000 }
  ]
}
```

### Gap-up small-caps without earnings this week

Request:

```shell
curl "https://api.tickerbot.io/v2/scan?q=gap_up_3pct%20AND%20volume_unusual_2x%20AND%20market_cap%20%3C%202000000000%20AND%20NOT%20earnings_this_week&fields=pe_ratio" \
  -H "Authorization: Bearer YOUR_KEY"
```

Response (`200`):

```json
{
  "as_of": "2026-05-14T11:41:01.000Z",
  "query": { "q": "gap_up_3pct AND volume_unusual_2x AND market_cap < 2000000000 AND NOT earnings_this_week", "limit": 50, "order": "day_change_pct", "dir": "desc", "fields": ["pe_ratio"], "full": false, "universe": null, "rule": null },
  "count": 7,
  "next_cursor": null,
  "results": [
    { "ticker": "OWLT", "name": "Owlet, Inc.", "asset_type": "CS", "price": 4.21, "day_change_pct": 0.142, "gap_pct": 0.061, "relative_volume": 4.8, "market_cap": 81000000, "pe_ratio": null },
    "(...)"
  ]
}
```

## Notes

- For WHERE clauses that exceed practical URL length, use `POST /v2/scan` with the same parameters in a JSON body.
- Cursors carry the (order-value, ticker) pair from the last row. Sort stability is guaranteed (`ticker ASC` is the tie-breaker).

---

Interactive sandbox + parameter editor: https://tickerbot.io/api/endpoints/scan/live
