{
  "openapi": "3.0.1",
  "info": {
    "title": "Google Play Scraper — Reviews, Ratings & Sentiment Analysis",
    "description": "Google Play Scraper extracts app reviews, ratings, reviewer details, dates, versions, and feedback, with sentiment analysis to identify positive, negative, and neutral opinions. Analyze app performance, user feedback, competitors, and market trends at scale.",
    "version": "0.1",
    "x-build-id": "IMcOZgIbYpdHfa3CZ"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/scrapier~google-play-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-scrapier-google-play-scraper",
        "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/scrapier~google-play-scraper/runs": {
      "post": {
        "operationId": "runs-sync-scrapier-google-play-scraper",
        "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/scrapier~google-play-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-scrapier-google-play-scraper",
        "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": {
          "mode": {
            "title": "🎯 What should this run collect?",
            "enum": [
              "scrapeReviews",
              "scrapeAppUrls",
              "scrapeAppSearch",
              "scrapeSimilarApps"
            ],
            "type": "string",
            "description": "Reviews mode is the main job of this actor: it pulls user reviews for every app you list. The other three modes return app records instead of reviews."
          },
          "appTargets": {
            "title": "📲 Apps (package IDs or Play Store links)",
            "type": "array",
            "description": "One app per line. Both a package ID (com.example.app) and a full Play Store link work. Bulk is supported — this is the big difference from a single-app reviews run: list 20 apps and every one of them is collected in the same run. Leave this empty to let the search terms below decide which apps are used.",
            "items": {
              "type": "string"
            }
          },
          "searchTerms": {
            "title": "🔎 Search terms (keyword search + app discovery)",
            "type": "array",
            "description": "One keyword per line, e.g. habit tracker. In keyword-search mode each term is searched on the Play Store and the matching apps are returned as app records. In the reviews, app-records and similar-apps modes these terms are also used to pick the apps automatically whenever the target-apps field above is left empty.",
            "items": {
              "type": "string"
            }
          },
          "storefrontCountry": {
            "title": "🌍 Storefront country",
            "enum": [
              "us",
              "ar",
              "au",
              "at",
              "bd",
              "be",
              "bo",
              "br",
              "bg",
              "ca",
              "cl",
              "cn",
              "co",
              "cr",
              "hr",
              "cy",
              "cz",
              "dk",
              "do",
              "ec",
              "eg",
              "ee",
              "fi",
              "fr",
              "de",
              "gh",
              "gr",
              "gt",
              "hk",
              "hu",
              "is",
              "in",
              "id",
              "ie",
              "il",
              "it",
              "jp",
              "jo",
              "kz",
              "ke",
              "kw",
              "lv",
              "lb",
              "lt",
              "lu",
              "my",
              "mt",
              "mx",
              "ma",
              "nl",
              "nz",
              "ng",
              "no",
              "om",
              "pk",
              "pa",
              "py",
              "pe",
              "ph",
              "pl",
              "pt",
              "qa",
              "ro",
              "ru",
              "sa",
              "rs",
              "sg",
              "sk",
              "si",
              "za",
              "kr",
              "es",
              "lk",
              "se",
              "ch",
              "tw",
              "tz",
              "th",
              "tn",
              "tr",
              "ua",
              "ae",
              "gb",
              "uy",
              "ve",
              "vn"
            ],
            "type": "string",
            "description": "Which Google Play storefront to read. Reviews, ratings and app records are all storefront-specific, so this changes what comes back."
          },
          "maxRecords": {
            "title": "🔢 Maximum rows for the whole run",
            "minimum": 0,
            "type": "integer",
            "description": "Hard ceiling on how many rows the run stores in total (reviews plus app summaries). Leave empty or 0 to keep going until every target is exhausted."
          },
          "maxReviewsPerApp": {
            "title": "⭐ Maximum reviews per app",
            "minimum": 0,
            "type": "integer",
            "description": "Per-app ceiling, applied on top of the run-wide maximum. Example: 5 apps x 40 = up to 200 review rows. 0 means no per-app limit.",
            "default": 0
          },
          "sortReviewsBy": {
            "title": "🔀 Review order",
            "enum": [
              "mostRelevant",
              "newest",
              "rating"
            ],
            "type": "string",
            "description": "Most relevant is what the Play Store shows by default. Newest returns the freshest reviews first, which is what review-monitoring runs usually want. Rating walks the ratings-ordered list.",
            "default": "mostRelevant"
          },
          "reviewsPageSize": {
            "title": "📄 Reviews per request",
            "minimum": 10,
            "maximum": 199,
            "type": "integer",
            "description": "How many reviews are asked for at a time (10-199). Larger values finish a big app in fewer round trips; smaller values give tighter control over the run-wide maximum.",
            "default": 100
          },
          "includeAppSummary": {
            "title": "📊 Add a per-app ratings summary row",
            "type": "boolean",
            "description": "Emits one extra row per app carrying the full app record plus the rating breakdown in percent, the ratings-per-1000-installs ratio, and stats over the reviews actually collected (average score, star mix, developer-reply rate, and the AI sentiment mix when analysis is on).",
            "default": true
          },
          "resumeFromToken": {
            "title": "↪️ Resume token",
            "type": "string",
            "description": "Continue a previous reviews run instead of starting over. Take the value from the run's key-value store key lastCursor. Applies to the first app in the list."
          },
          "starRatings": {
            "title": "⭐ Keep only these star ratings",
            "type": "array",
            "description": "Pick one or more star levels, e.g. 1 and 2 to work only on unhappy users. Each selected level is collected on its own pass, so a 1-star-only run really returns 1-star reviews rather than filtering a mixed page down to a handful.",
            "items": {
              "type": "string",
              "enum": [
                "1",
                "2",
                "3",
                "4",
                "5"
              ]
            }
          },
          "reviewsPostedAfter": {
            "title": "📅 Only reviews posted after",
            "type": "string",
            "description": "Absolute date (2026-01-31) or a relative window such as 30 days or 6 months. Reviews older than this are dropped."
          },
          "reviewsPostedBefore": {
            "title": "📆 Only reviews posted before",
            "type": "string",
            "description": "Absolute date or relative window. Reviews newer than this are dropped — combine with the field above for a fixed window."
          },
          "containsKeywords": {
            "title": "🔍 Must contain any of these words",
            "type": "array",
            "description": "One term per line. A review is kept only when its text contains at least one of them (case-insensitive), e.g. crash, refund, subscription.",
            "items": {
              "type": "string"
            }
          },
          "excludeKeywords": {
            "title": "🚫 Drop reviews containing any of these words",
            "type": "array",
            "description": "One term per line. A review is dropped as soon as its text contains one of them (case-insensitive).",
            "items": {
              "type": "string"
            }
          },
          "appVersionFilter": {
            "title": "🔖 Only this app version",
            "type": "string",
            "description": "Keep reviews written on a specific release. Accepts an exact version (9.1.68.1888) or a prefix such as 9.1 to match a whole release line."
          },
          "minThumbsUp": {
            "title": "👍 Minimum helpful votes",
            "minimum": 0,
            "type": "integer",
            "description": "Keep only reviews with at least this many thumbs-up. Useful for surfacing the complaints other users agreed with. 0 keeps everything.",
            "default": 0
          },
          "onlyWithDeveloperReply": {
            "title": "↩️ Only reviews the developer answered",
            "type": "boolean",
            "description": "Keeps just the reviews that carry a developer reply — handy for auditing support quality and reply latency.",
            "default": false
          },
          "deduplicateReviews": {
            "title": "🧹 Drop repeated review IDs",
            "type": "boolean",
            "description": "Removes a review that was already stored earlier in the same run (can happen when several star levels or pages return the same entry).",
            "default": true
          },
          "enableSentimentAnalysis": {
            "title": "🤖 Classify each review with AI",
            "type": "boolean",
            "description": "Adds sentiment, a -1 to 1 sentiment score, the dominant emotion, up to 5 topics, a review category (bug report / feature request / praise / complaint / question / spam / other), a spam flag, a one-line summary and the detected language.",
            "default": false
          },
          "aiModel": {
            "title": "🧠 AI model / provider",
            "enum": [
              "claude-haiku-4-5",
              "claude-sonnet-5",
              "claude-opus-4-8",
              "gpt-4o-mini",
              "gpt-4o",
              "gpt-4.1-mini",
              "gpt-4.1",
              "o3-mini",
              "gemini-2.0-flash-lite",
              "gemini-2.0-flash",
              "gemini-2.5-flash",
              "gemini-2.5-pro",
              "grok-3-mini",
              "grok-3",
              "deepseek-chat",
              "deepseek-reasoner",
              "sonar",
              "sonar-pro",
              "mistral-small-latest",
              "mistral-large-latest"
            ],
            "type": "string",
            "description": "The provider is taken from the model name: claude-* = Anthropic, gpt-*/o1/o3 = OpenAI, gemini-* = Google, grok-* = xAI, deepseek-* = DeepSeek, sonar* = Perplexity, mistral-* = Mistral. A cheap mini/flash/haiku model is plenty for review classification.",
            "default": "claude-haiku-4-5"
          },
          "aiApiKey": {
            "title": "🔑 Your AI provider key",
            "type": "string",
            "description": "Your own key for the provider you picked above. It is stored as a secret and used only to classify the reviews of this run. Leave it empty to fall back to the matching environment variable (ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, XAI_API_KEY, DEEPSEEK_API_KEY, PERPLEXITY_API_KEY or MISTRAL_API_KEY). With no key at all the AI columns stay empty."
          },
          "aiMaxReviews": {
            "title": "🎚️ Maximum reviews sent to the model",
            "minimum": 0,
            "type": "integer",
            "description": "Cost guard: only the first N collected reviews of the run are classified, the rest keep empty AI columns. 0 means classify every collected review.",
            "default": 0
          },
          "action": {
            "title": "🔁 action (legacy)",
            "enum": [
              "scrapeReviews",
              "scrapeAppSearch",
              "scrapeAppUrls",
              "scrapeSimilarApps"
            ],
            "type": "string",
            "description": "Legacy alias for the mode field."
          },
          "scrapeReviews.appId": {
            "title": "🔁 scrapeReviews.appId (legacy)",
            "type": "string",
            "description": "Legacy single-app reviews target. Merged into the target-apps list above."
          },
          "scrapeReviews.country": {
            "title": "🔁 scrapeReviews.country (legacy)",
            "type": "string",
            "description": "Legacy storefront for the reviews mode."
          },
          "scrapeAppSearch.keywords": {
            "title": "🔁 scrapeAppSearch.keywords (legacy)",
            "type": "array",
            "description": "Legacy search keywords. Merged into the search-terms list above.",
            "items": {
              "type": "string"
            }
          },
          "scrapeAppSearch.country": {
            "title": "🔁 scrapeAppSearch.country (legacy)",
            "type": "string",
            "description": "Legacy storefront for the keyword-search mode."
          },
          "scrapeAppUrls.urls": {
            "title": "🔁 scrapeAppUrls.urls (legacy)",
            "type": "array",
            "description": "Legacy app URL list. Merged into the target-apps list above.",
            "items": {
              "type": "string"
            }
          },
          "scrapeSimilarApps.urls": {
            "title": "🔁 scrapeSimilarApps.urls (legacy)",
            "type": "array",
            "description": "Legacy source-app list for the similar-apps mode. Merged into the target-apps list above.",
            "items": {
              "type": "string"
            }
          },
          "count": {
            "title": "🔁 count (legacy)",
            "minimum": 0,
            "type": "integer",
            "description": "Legacy run-wide row limit. Same meaning as the maximum-rows field above."
          },
          "cursor": {
            "title": "🔁 cursor (legacy)",
            "type": "string",
            "description": "Legacy resume token. Same meaning as the resume-token field above."
          },
          "proxyConfiguration": {
            "title": "🛡️ Proxy",
            "type": "object",
            "description": "Apify Proxy settings used by the automatic route ladder.",
            "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
                  }
                }
              },
              "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}