{
  "title": "Apple App Store Search & App Metadata Monitor",
  "type": "object",
  "schemaVersion": 1,
  "properties": {
    "mode": {
      "title": "What to discover",
      "type": "string",
      "editor": "select",
      "enum": [
        "search",
        "lookup"
      ],
      "enumTitles": [
        "Keyword search",
        "Known app IDs"
      ],
      "default": "search",
      "description": "Search returns Apple API relevance order. Lookup returns known app metadata without a rank."
    },
    "queries": {
      "title": "Search keywords",
      "type": "array",
      "editor": "stringList",
      "items": {
        "type": "string"
      },
      "default": [],
      "description": "Up to six phrases, each at most 100 characters. Used only in search mode; empty uses budget.",
      "prefill": [
        "budget"
      ]
    },
    "countries": {
      "title": "Storefront countries",
      "type": "array",
      "editor": "stringList",
      "items": {
        "type": "string"
      },
      "default": [
        "us"
      ],
      "description": "Up to three two-letter Apple storefront country codes. Examples: us, gb, ca, de, jp. At most six keyword-country combinations per run."
    },
    "appIds": {
      "title": "Known app IDs or Apple URLs",
      "type": "array",
      "editor": "stringList",
      "items": {
        "type": "string"
      },
      "default": [],
      "description": "Up to 100 numeric IDs or https://apps.apple.com/.../id... links. Used only in lookup mode. Empty lookup uses ChatGPT and Spotify."
    },
    "resultsPerSource": {
      "title": "Apps per keyword search",
      "type": "integer",
      "default": 10,
      "minimum": 1,
      "maximum": 100,
      "description": "A deliberate first-page window per keyword and country. Search may return fewer. No hidden pagination; lookup observes all selected IDs."
    },
    "maxResults": {
      "title": "Maximum saved records",
      "type": "integer",
      "default": 30,
      "minimum": 1,
      "maximum": 1000,
      "description": "Total billable row cap. A row represents one app in one source/country context. A cap that cuts a selected window prevents any history commit."
    },
    "comparePrevious": {
      "title": "Compare with previous complete run",
      "type": "boolean",
      "default": false,
      "description": "Save observations after every requested source window finishes. Compare price, rating, rating count, version and rank against the same named scope."
    },
    "onlyChanges": {
      "title": "Save only new or changed records",
      "type": "boolean",
      "default": false,
      "description": "Enables comparison and skips unchanged rows without dataset-item charges. First complete run establishes the baseline."
    },
    "snapshotName": {
      "title": "Comparison snapshot",
      "type": "string",
      "editor": "textfield",
      "default": "default",
      "description": "1–80 letters, numbers, underscores or hyphens. History is scoped to mode, countries, keyword/ID selection and search window."
    },
    "maxRunSeconds": {
      "title": "Run budget in seconds",
      "type": "integer",
      "default": 90,
      "minimum": 30,
      "maximum": 120,
      "description": "Shared deadline. All Apple request starts are spaced by at least 3.1 seconds within this run; 403/429 stops subsequent requests."
    }
  }
}
