{
  "openapi": "3.0.1",
  "info": {
    "title": "App Store & Google Play Reviews Scraper: iOS & Android API",
    "description": "Scrape App Store and Google Play reviews in one run and one fixed JSON format: every review you ask for (no hidden cap), the right app and country in every row, rating, text, date, version, developer reply. Monitor mode outputs only new reviews and alerts you on negative ones.",
    "version": "1.1",
    "x-build-id": "QsDfrQHYPooaybQrX"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/cleanyield~app-store-google-play-reviews/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-cleanyield-app-store-google-play-reviews",
        "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/cleanyield~app-store-google-play-reviews/runs": {
      "post": {
        "operationId": "runs-sync-cleanyield-app-store-google-play-reviews",
        "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/cleanyield~app-store-google-play-reviews/run-sync": {
      "post": {
        "operationId": "run-sync-cleanyield-app-store-google-play-reviews",
        "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": {
          "apps": {
            "title": "Apps (App Store and/or Google Play)",
            "type": "array",
            "description": "One app per line. Accepts App Store URLs (https://apps.apple.com/us/app/instagram/id389801252), App Store numeric ids (389801252), Google Play URLs (https://play.google.com/store/apps/details?id=com.instagram.android) and Android package names (com.instagram.android). To pass an iOS bundle id, prefix it: appstore:com.burbn.instagram. Both stores can be mixed in one run. For competitor comparison, list your own app first, then competitors. Not required if you use a saved list (savedListName). Inputs written for other popular review scrapers also work (appIds, startUrls, country, language, maxItems, sort): see 'Migrating from other scrapers' in the README.",
            "items": {
              "type": "string"
            }
          },
          "countries": {
            "title": "Countries (App Store)",
            "type": "array",
            "description": "Two-letter App Store country codes. App Store reviews are separate per country storefront, so each country is fetched separately (up to ~500 most recent reviews per country, an Apple limit). The first country is also used for the Google Play listing. Example: us, gb, ca, au, de, br, ar. Default if empty: us.",
            "items": {
              "type": "string"
            }
          },
          "languages": {
            "title": "Languages (Google Play)",
            "type": "array",
            "description": "Google Play groups reviews by language, not by country. Each language is fetched separately. Use codes like en, es, pt, de, fr, ja, pt-BR. Example: en, es. Default if empty: en.",
            "items": {
              "type": "string"
            }
          },
          "devices": {
            "title": "Devices (Google Play)",
            "type": "array",
            "description": "Google Play keeps separate reviews per device. phone (default) is what the store shows first. Add tablet, chromebook, watch, tv or car to also get reviews written on those devices (each device is fetched separately and every review has a device field). Example: phone, tablet. Default if empty: phone.",
            "items": {
              "type": "string"
            }
          },
          "maxReviewsPerApp": {
            "title": "Maximum reviews per app (per country / language)",
            "minimum": 1,
            "maximum": 100000,
            "type": "integer",
            "description": "Stop after this many reviews for each app in each App Store country or Google Play language (counting only reviews that pass your filters). Caps your cost: you pay only for reviews returned. App Store gives at most ~500 recent reviews per country. In monitor mode this caps how many new reviews a run can return. Example: 200. Default if empty: 500."
          },
          "sortBy": {
            "title": "Sort order",
            "enum": [
              "newest",
              "mostHelpful",
              "rating"
            ],
            "type": "string",
            "description": "newest = most recent first (default, required for monitor mode and for date filters to stop early). mostHelpful = reviews with the most helpful votes first (on Google Play this is the store's 'Most relevant' order). For only 5-star or only 1-star reviews, use the star filters instead of a sort. rating = highest stars first (Google Play only; App Store falls back to newest). Default if empty: newest."
          },
          "minRating": {
            "title": "Minimum stars",
            "minimum": 1,
            "maximum": 5,
            "type": "integer",
            "description": "Only return reviews with at least this many stars (1–5). Leave empty for all. Example: 4 to collect positive reviews for testimonials."
          },
          "maxRating": {
            "title": "Maximum stars",
            "minimum": 1,
            "maximum": 5,
            "type": "integer",
            "description": "Only return reviews with at most this many stars (1–5). Example: 2 to get only negative reviews (1–2★) for your support team. Use the same value in minimum and maximum to get exactly one star level (filtered server-side on Google Play)."
          },
          "reviewsSince": {
            "title": "Only reviews since",
            "type": "string",
            "description": "Only return reviews written or edited on or after this date. Accepts a date (2026-10-01) or a relative period (7 days, 2 weeks, 3 months). With newest-first sorting the Actor stops paging as soon as it passes this date, so it is fast and cheap. Example: 30 days."
          },
          "reviewsUntil": {
            "title": "Only reviews until",
            "type": "string",
            "description": "Only return reviews written or edited on or before this date (a date alone includes that whole day). Accepts 2026-10-31 or a relative period (7 days). Combine with 'Only reviews since' for a date range. Example: 2026-10-31."
          },
          "keywords": {
            "title": "Keywords",
            "type": "array",
            "description": "Only return reviews whose title or text contains at least one of these words or phrases (case- and accent-insensitive). You pay only for matching reviews. Example: crash, refund, battery.",
            "items": {
              "type": "string"
            }
          },
          "appVersions": {
            "title": "App versions",
            "type": "array",
            "description": "Only return reviews written on these app versions. A version also matches its sub-versions: 2.1 matches 2.1.3. Reviews without a version are excluded when this is set. Example: 8.12, 8.13.",
            "items": {
              "type": "string"
            }
          },
          "omitAuthorNames": {
            "title": "Omit reviewer names (privacy)",
            "type": "boolean",
            "description": "On by default: authorName is always null, so the output contains no personal names (data minimization). Turn it off only if you need the public display name of each reviewer, for example to reply to them.",
            "default": true
          },
          "monitorMode": {
            "title": "Monitor mode (only new reviews)",
            "type": "boolean",
            "description": "For scheduled runs: remember the reviews already seen and output only new ones (changeType=new) and reviews whose author edited the rating or text (changeType=changed). You pay only for those, plus a small per-app check fee. The first run saves a baseline. Schedule the Actor daily or weekly from the Schedules tab. Forces newest-first sorting.",
            "default": false
          },
          "monitorStateName": {
            "title": "Monitor state name",
            "type": "string",
            "description": "Optional name of the storage that keeps the reviews already seen. Use the same name across scheduled runs to compare against them. Leave empty to derive it automatically from the apps, countries, languages and star filters. Lowercase letters, numbers and hyphens only. Example: my-app-reviews-daily."
          },
          "notifyWebhookUrl": {
            "title": "Webhook URL for alerts",
            "type": "string",
            "description": "Optional. When monitor mode finds new reviews, POST a JSON summary (title, lines, items with negative reviews first) to this URL. Works with Zapier, Make and n8n (use it to send emails too). Example: https://hooks.zapier.com/hooks/catch/123/abc"
          },
          "notifySlackWebhookUrl": {
            "title": "Slack webhook URL for alerts",
            "type": "string",
            "description": "Optional. Slack incoming-webhook URL. In monitor mode you get a message with the new 1–2★ reviews (stars, app, store, version, text and link) and the actionable alerts. Example: https://hooks.slack.com/services/T000/B000/XXXX"
          },
          "notifyOnlyNegative": {
            "title": "Alert only when there are negative reviews",
            "type": "boolean",
            "description": "If on, the webhook/Slack alert is sent only when the run found new 1–2★ reviews or an actionable alert. If off, you are notified whenever there are new reviews.",
            "default": false
          },
          "proMode": {
            "title": "Pro mode: topics, urgency score, AI conclusion and suggested replies (paid add-on)",
            "type": "boolean",
            "description": "One checkbox for all extras. Each review gets: topics (crashes_bugs, payments_billing, login_account, ads, performance, ux_design, update_regression, customer_support, privacy_security, notifications, missing_feature, praise), priorityScore (0–100 urgency to sort your support queue), insight (one-sentence AI conclusion based only on the review), suggestedReply (AI reply draft for 1–3★ reviews, in the review's language) and appDetails (developer, developer website, category, store rating, reputation score 0–100 and rating trend). Also turns on the actionable alerts and competitor comparison below. The Pro fee is charged only for reviews that received the AI conclusion. Off by default: the basic run stays cheap and fast.",
            "default": false
          },
          "generateReport": {
            "title": "Actionable alerts and competitor comparison (paid add-on)",
            "type": "boolean",
            "description": "Deterministic alerts per app: spike of 1–2★ reviews vs the previous week, average rating drop week over week, a new app version rated lower than the previous one, negative Google Play reviews left without a developer reply, and how your app (the first app of each store in the list) ranks against the competitors you listed. Stored as REPORT (JSON) and REPORT_MD (Markdown) and included in monitor alerts. Charged per app only when there is enough data to compare.",
            "default": false
          },
          "outputFormat": {
            "title": "Output format",
            "enum": [
              "standard",
              "leader-compatible"
            ],
            "type": "string",
            "description": "standard = this Actor's fields (recommended). leader-compatible = the field names used by other popular review scrapers (id, userName, date, score, scoreText, title, text, replyText, replyDate, version, thumbsUp, criterias, url, appId, country, language), plus reviewId, store, appName and schemaVersion, so you can switch without changing your integration.",
            "default": "standard"
          },
          "maxTotalReviews": {
            "title": "Maximum reviews for the whole run",
            "minimum": 1,
            "type": "integer",
            "description": "Optional cap for the entire run across all apps, countries, languages and devices (maxReviewsPerApp caps each one). Leave empty for no total cap. Example: 1000."
          },
          "savedListName": {
            "title": "Saved list name",
            "type": "string",
            "description": "Optional. Give your list of apps a name (for example my-competitors) and the Actor remembers it: next runs with the same name use the saved apps plus any you add in 'apps', so scheduled runs need no edits. Lowercase letters, numbers and hyphens."
          },
          "saveList": {
            "title": "Save apps to the list",
            "type": "boolean",
            "description": "If on (default), apps typed in 'apps' are added to the saved list. Turn off to use the saved list without changing it.",
            "default": true
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Not needed: both stores answer without a proxy. If a store starts blocking, the Actor automatically retries through Apify datacenter proxy. Set a proxy here only if you want to force one.",
            "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}