{
  "openapi": "3.0.1",
  "info": {
    "title": "App Store Monitor — Version, Price, Rating & Listing Changes",
    "description": "Watch App Store and Google Play listings on a schedule and get one row per change: new versions with release notes, price and in-app purchase changes, rating moves past your threshold, title and description edits, developer, category, size, minimum OS and installs band. Or a full snapshot.",
    "version": "0.1",
    "x-build-id": "p9VXsWPnMuifaOeLc"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/insight.solutions~app-store-monitor/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-insight.solutions-app-store-monitor",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/insight.solutions~app-store-monitor/runs": {
      "post": {
        "operationId": "runs-sync-insight.solutions-app-store-monitor",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/insight.solutions~app-store-monitor/run-sync": {
      "post": {
        "operationId": "run-sync-insight.solutions-app-store-monitor",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "required": [
          "apps"
        ],
        "properties": {
          "apps": {
            "title": "Apps to watch",
            "type": "array",
            "description": "One app per entry. An App Store URL (`https://apps.apple.com/us/app/spotify-music-and-podcasts/id324684580`, with or without the name in it), a numeric App Store ID (`324684580`), a Google Play URL (`https://play.google.com/store/apps/details?id=com.spotify.music`) or an Android package name (`com.spotify.music`) all work. An App Store **bundle ID** looks exactly like an Android package, so write it with a prefix: `ios:com.spotify.client`. The country in a URL is ignored — `countries` decides which storefronts are read. The same app written twice is read and billed once.",
            "items": {
              "type": "string"
            }
          },
          "mode": {
            "title": "Mode",
            "enum": [
              "monitor",
              "snapshot"
            ],
            "type": "string",
            "description": "`snapshot` returns every listing whole — one paid `app` row per app per country, no check fee — and stores a baseline for any listing that has none yet, so a later monitor run has something to compare against. `monitor` reads every listing — one paid `app-check` each, changed or not, the first sighting included — compares it with the previous run and returns one paid `change` row per family that changed. A listing seen for the first time gets a `baseline` row; an unchanged one gets no row of its own. Schedule monitor mode daily.",
            "default": "monitor"
          },
          "countries": {
            "title": "Countries",
            "type": "array",
            "description": "Two-letter storefront codes. Each app is read in each country and gets its own row and its own history: price, rating, title and even availability differ between storefronts. `gb`, not `uk`. Up to 50.",
            "default": [
              "us"
            ],
            "items": {
              "type": "string"
            }
          },
          "language": {
            "title": "Google Play language",
            "type": "string",
            "description": "The language Google Play pages are requested in (`hl`), for example `en`, `de` or `pt-BR`. App Store listings always come in the storefront's own language.",
            "default": "en"
          },
          "watch": {
            "title": "Changes to report (monitor mode)",
            "type": "array",
            "description": "Which change families are worth a row. Applied **before** anything is billed: a family you did not tick is never charged for, and the snapshot still moves past it, so ticking it later reports what happens next rather than everything since.",
            "items": {
              "type": "string",
              "enum": [
                "version",
                "price",
                "rating",
                "listing",
                "metadata"
              ],
              "enumTitles": [
                "Version — new version number, store update date, release notes",
                "Price — price, currency, free/paid, in-app purchases and their price range",
                "Rating — star rating or rating count past the thresholds below",
                "Listing — title, subtitle or short description, description",
                "Metadata — developer, category, genres, content rating, minimum OS, size, screenshots, languages, installs band, ads"
              ]
            },
            "default": [
              "version",
              "price",
              "rating",
              "listing",
              "metadata"
            ]
          },
          "ratingDeltaThreshold": {
            "title": "Star rating move to report",
            "minimum": 0,
            "maximum": 5,
            "type": "number",
            "description": "Report a rating change when the average rating has moved at least this many stars since it was last reported. Compared with the last *reported* value, not yesterday's, so a slow slide is still caught once it adds up. `0` reports every move.",
            "default": 0.1
          },
          "ratingCountDeltaPct": {
            "title": "Rating count move to report (%)",
            "minimum": 0,
            "maximum": 1000,
            "type": "number",
            "description": "Report a rating-count change when the number of ratings has moved at least this many percent since it was last reported. `0` reports every move — on a popular app, that is every run.",
            "default": 5
          },
          "emitUnchanged": {
            "title": "Also return unchanged listings (monitor mode)",
            "type": "boolean",
            "description": "Also write a full `app` row for every listing that was compared and had no change, billed as an app row on top of its app check. Off by default: a monitor's job is to stay quiet when nothing moved.",
            "default": false
          },
          "includeDescription": {
            "title": "Include the full description",
            "type": "boolean",
            "description": "Put the whole store description on `app` rows. `descriptionLength` is always there. Change rows never carry the description twice: they carry the lines added and removed and the first 200 changed characters.",
            "default": true
          },
          "includeReleaseNotes": {
            "title": "Include release notes",
            "type": "boolean",
            "description": "Put the current version's release notes (\"What's new\") on `app` rows and, in full, on `version` change rows.",
            "default": true
          },
          "includeScreenshots": {
            "title": "Include screenshot URLs",
            "type": "boolean",
            "description": "Put every screenshot URL on `app` rows. `screenshotCount` is always there; the URLs are 40 per app on some Play listings, so they are off by default.",
            "default": false
          },
          "webhookUrl": {
            "title": "Webhook URL (optional, monitor mode)",
            "type": "string",
            "description": "When a monitor run finds at least one change, POST one JSON digest of the change rows to this URL. Ten-second timeout, one retry, 64 KB cap, and a redirect to another host is never followed. Treated as a secret: only its host is ever logged. A failed POST is a free `webhook-failed` row and never fails the run. Leave empty for no webhook."
          },
          "stateStoreName": {
            "title": "State store name",
            "type": "string",
            "description": "Name of the key-value store that holds each listing's last snapshot — one record per app per country. The Actor creates it on its first run and reads it back on every run after; that memory is what makes this a monitor. Keep one store per watchlist: two schedules sharing a store would compare against the same snapshots, so the second stops with a clear message instead of double-reporting. Snapshots not seen for 90 days expire.",
            "default": "app-store-monitor-state"
          },
          "maxApps": {
            "title": "Maximum apps per run",
            "minimum": 1,
            "maximum": 5000,
            "type": "integer",
            "description": "Apps past this many are not read and not charged; one free row lists them.",
            "default": 500
          },
          "maxConcurrency": {
            "title": "Requests in parallel",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "How many lookups and Play pages are in flight at once. Each parallel worker keeps its own proxy session, and its successive requests are spaced 300–600 ms apart.",
            "default": 4
          },
          "maxRunSecs": {
            "title": "Run time budget (seconds)",
            "minimum": 30,
            "maximum": 3600,
            "type": "integer",
            "description": "Wall-clock budget for the whole run. When it is reached the Actor stops fetching, keeps and bills what it already delivered, and writes a free `timeout` row for each listing it never reached — those keep their snapshots.",
            "default": 240
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Apple's lookup and Google Play's app pages both answer through Apify's datacenter proxy, so that is the default and its cost is inside the event prices. Switch to the RESIDENTIAL group if a store starts refusing it; a refused listing is a free `blocked` row after one retry from a fresh exit.",
            "default": {
              "useApifyProxy": true
            }
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}