{
  "openapi": "3.0.1",
  "info": {
    "title": "App Store & Play Review Monitor",
    "description": "Monitors new App Store reviews from Apple's public feed, and optional Play reviews with your own console credentials. Flags low ratings and the app version. The first run only saves a baseline. The public Play page stays off unless you confirm it. Not an archive. Not affiliated with Apple or Google.",
    "version": "1.1",
    "x-build-id": "DWb0N61IbdxxUPtS1"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/mmdincer~app-store-play-review-monitor/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-mmdincer-app-store-play-review-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/mmdincer~app-store-play-review-monitor/runs": {
      "post": {
        "operationId": "runs-sync-mmdincer-app-store-play-review-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/mmdincer~app-store-play-review-monitor/run-sync": {
      "post": {
        "operationId": "run-sync-mmdincer-app-store-play-review-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",
        "properties": {
          "appleAppIds": {
            "title": "Apple app ids",
            "type": "array",
            "description": "App Store apps to watch, one per line. Use the numeric id from the app URL (<code>id324684580</code> in <code>apps.apple.com/.../id324684580</code>) or paste the App Store URL. Up to 10 apps. Combined with countries, at most 20 pairs per run.",
            "items": {
              "type": "string"
            }
          },
          "appleCountries": {
            "title": "Apple storefronts",
            "type": "array",
            "description": "Two-letter storefront codes, for example <code>us</code>, <code>gb</code>, <code>de</code>, <code>tr</code>. <code>uk</code> is read as <code>gb</code>. Reviews differ by country. At most 5. Empty means <code>us</code> when an Apple app is set. The feed holds about the latest 500 reviews per country, not the archive.",
            "default": [
              "us"
            ],
            "items": {
              "type": "string"
            }
          },
          "onlyNew": {
            "title": "New reviews only",
            "type": "boolean",
            "description": "On: the first run saves a baseline in a named key-value store and returns no review rows. Later runs return only reviews that were not saved and that are dated after the previous run (with a two-hour margin). Off: return the reviews currently in the feed and charge for each one, every run. Keep this on for a monitor.",
            "default": true
          },
          "minRating": {
            "title": "Minimum stars",
            "minimum": 1,
            "maximum": 5,
            "type": "integer",
            "description": "Keep reviews with at least this many stars (1 to 5). Reviews outside the range are not delivered and are not charged. Changing this, the maximum, the keywords or the review cap saves a new baseline instead of reporting the old feed as new.",
            "default": 1
          },
          "maxRating": {
            "title": "Maximum stars",
            "minimum": 1,
            "maximum": 5,
            "type": "integer",
            "description": "Keep reviews with at most this many stars. Set this to 2, with the minimum at 1, when you only want the low ratings.",
            "default": 5
          },
          "keywords": {
            "title": "Keywords",
            "type": "array",
            "description": "Optional. Keep a review only when its title or text contains at least one of these words (not case sensitive). Leave empty to keep every review in the star range. At most 30.",
            "items": {
              "type": "string"
            }
          },
          "lowRatingThreshold": {
            "title": "Low-rating alert at or below",
            "minimum": 1,
            "maximum": 5,
            "type": "integer",
            "description": "A delivered review whose stars are this number or lower is marked <code>lowRatingAlert: true</code> and copied into the <code>LOW_RATING_ALERTS</code> key. The default is 2, so 1 and 2 star reviews are alerts. This does not add a second charge, and changing it does not reset the baseline.",
            "default": 2
          },
          "googlePlayPackageNames": {
            "title": "Google Play package names",
            "type": "array",
            "description": "Optional. Package names such as <code>com.example.app</code>, or a <code>play.google.com</code> URL. Ignored while Google Play source is off. Up to 10.",
            "items": {
              "type": "string"
            }
          },
          "googlePlaySource": {
            "title": "Google Play source",
            "enum": [
              "off",
              "official-api",
              "public-page"
            ],
            "type": "string",
            "description": "<b>Off</b> skips Play. <b>Official API</b> calls Google's Android Publisher reviews API with your own service account or access token. It cannot read a competitor's private console. <b>Public page (scraping)</b> reads the public Play page. That path is off unless you also confirm it below. It can break without notice and may conflict with Google Play's terms.",
            "default": "off"
          },
          "googlePlayServiceAccountJson": {
            "title": "Play Console service account JSON",
            "type": "string",
            "description": "Paste the JSON key of a service account that has been invited in Play Console for this app. The Actor exchanges it for a short-lived token (scope <code>androidpublisher</code>) and does not write the key to the dataset or the log. Preferred for a schedule, because an access token expires. Leave empty if you pass an access token instead."
          },
          "googlePlayAccessToken": {
            "title": "Play OAuth access token",
            "type": "string",
            "description": "Alternative to the service account: an OAuth access token with the <code>androidpublisher</code> scope. A Google API key (starting with AIza) is rejected. Used only when the service account field is empty. Not written to the dataset."
          },
          "confirmGooglePlayPageScrape": {
            "title": "Confirm public Play page scraping",
            "type": "boolean",
            "description": "Required only when Google Play source is <b>Public page</b>. Leave this off. Turning it on means you accept an unsupported reader of the public Play page that may conflict with Google Play's terms and can stop working without notice. Rows from that path are labeled <code>fetchedVia: google-play-page</code>.",
            "default": false
          },
          "googlePlayCountries": {
            "title": "Google Play countries (public page only)",
            "type": "array",
            "description": "Storefronts for the public-page path, for example <code>us</code>. Not used by the official API. At most 5. Empty means <code>us</code> when that path is on.",
            "default": [
              "us"
            ],
            "items": {
              "type": "string"
            }
          },
          "stateName": {
            "title": "Watchlist name",
            "type": "string",
            "description": "Name of the saved baseline (letters, digits, - and _). Runs with the same name share a memory. Use another name to watch the same app for a different purpose. The ids are stored in the key-value store <code>app-store-play-review-monitor-state</code>.",
            "default": "default"
          },
          "maxReviewsPerSource": {
            "title": "Max reviews read per source",
            "minimum": 1,
            "maximum": 500,
            "type": "integer",
            "description": "Upper limit of reviews read for one app and country. Apple's feed has at most about 500 (10 pages of 50). A lower cap can miss reviews on a busy app. With new-reviews-only, reviews that are only saved as a baseline are free. With new-reviews-only off, each delivered review is charged.",
            "default": 500
          },
          "requestDelayMs": {
            "title": "Pause between requests (ms)",
            "minimum": 200,
            "maximum": 5000,
            "type": "integer",
            "description": "Pause between feed requests. Apple pages are requested one at a time. The default is 400. Minimum 200.",
            "default": 400
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Optional. Leave Apify Proxy off to request Apple directly. Turn it on and select the <b>residential</b> group when the customer-reviews feed comes back empty: datacenter addresses often receive a valid feed with no reviews, while the same URL still has reviews elsewhere. The Actor does not switch proxy by itself after a refusal. Proxy traffic is billed by Apify separately from the per-review price.",
            "default": {
              "useApifyProxy": false
            }
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}