{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/patternfetch-com/json-schema/patternfetch-com-scan-request-schema.json",
  "title": "ScanRequest",
  "description": "Optional filters for the screener (POST /v1/scan). Every field is optional; an absent field puts no constraint on that axis. A filter-less scan returns the top of the universe (limit defaults to 50).",
  "x-generated": "2026-10-31",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/_original/patternfetch-com-api-openapi.json#/components/schemas/ScanRequest",
  "type": "object",
  "properties": {
    "assetClass": {
      "type": "string",
      "enum": [
        "stock",
        "crypto",
        "all"
      ],
      "description": "Restrict to US stocks/ETFs, crypto pairs, or all (default all)."
    },
    "regime": {
      "type": "string",
      "enum": [
        "up",
        "down",
        "range"
      ],
      "description": "Only tickers whose current regime trend matches (up=uptrend, down=downtrend, range=sideways)."
    },
    "tf": {
      "type": "string",
      "enum": [
        "1m",
        "5m",
        "15m",
        "30m",
        "1h",
        "4h",
        "1d",
        "1w"
      ],
      "description": "Only signals computed on this timeframe (the universe is currently precomputed at 1d)."
    },
    "pattern": {
      "type": "string",
      "description": "Require the ticker's top pattern to be this one, e.g. double_bottom, double_top, head_and_shoulders, bullish_engulfing, bearish_engulfing, hammer."
    },
    "minLift": {
      "type": "number",
      "minimum": -1,
      "maximum": 1,
      "description": "Drop tickers whose top pattern does not beat its OWN pattern-free baseline by at least this many rate points (0.02 = 2pp; 0 = at or above baseline; negative values allowed). PREFER THIS OVER minBaseRate: a raw base rate is not comparable across bullish and bearish rows, so minBaseRate:0.55 mostly selects bullish patterns in a rising universe before any of them carries information, whereas minLift selects patterns that measurably add something. Rows whose evidence carries no baseline are always excluded — absence of a lift is not a lift of 0."
    },
    "minBaseRate": {
      "type": "number",
      "minimum": 0,
      "maximum": 1,
      "description": "Drop tickers whose top-pattern backtested base rate is below this (0..1). Kept for existing consumers; see minLift for the drift-free equivalent, which is the better filter for an unbiased shortlist."
    },
    "limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 500,
      "description": "Max rows to return (default 50)."
    }
  }
}