{
  "openapi": "3.0.1",
  "info": {
    "title": "Google Play Reviews - App Ratings, Replies & Countries",
    "description": "Collect Google Play reviews and ratings for any app across country storefronts. Search by app name or use a Google Play URL. Returns one row per review with rating, text, author, date, app version, thumbs-up count, developer reply, and storefront country.",
    "version": "1.0",
    "x-build-id": "cOiIgCKUcW82qUzK4"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/abotapi~google-play-reviews-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-abotapi-google-play-reviews-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/abotapi~google-play-reviews-scraper/runs": {
      "post": {
        "operationId": "runs-sync-abotapi-google-play-reviews-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/abotapi~google-play-reviews-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-abotapi-google-play-reviews-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",
        "required": [
          "mode"
        ],
        "properties": {
          "mode": {
            "title": "Mode",
            "enum": [
              "search",
              "url"
            ],
            "type": "string",
            "description": "How to select apps. 'search' resolves app names to apps via Google Play; 'url' takes Google Play app links directly.",
            "default": "search"
          },
          "queries": {
            "title": "App name searches",
            "type": "array",
            "description": "App names or keywords to look up (for example 'Instagram', 'Spotify'). Each term resolves to the top matching app(s) and its reviews are collected. Ignored in URL mode.",
            "default": [
              "Instagram"
            ],
            "items": {
              "type": "string"
            }
          },
          "appsPerQuery": {
            "title": "Apps per search term or listing page",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "How many top matching apps to take for each search term, and for each search, developer, category or collection page pasted in URL mode. Use 1 for the single best match.",
            "default": 1
          },
          "urls": {
            "title": "Google Play URLs",
            "type": "array",
            "description": "Google Play links: app pages (including hl/gl, reviewId, showAllReviews and the legacy market.android.com form), search pages, developer pages (dev?id= or developer?id=), category pages and collection pages. A bare package id (com.instagram.android) also works. Listing pages (search, developer, category, collection) expand to the top apps on the page, capped by Apps per search term. The country in the link (gl=) is used only if you leave Countries empty.",
            "default": [
              "https://play.google.com/store/apps/details?id=com.instagram.android&hl=en&gl=us",
              "https://play.google.com/store/apps/details?id=com.instagram.android",
              "https://play.google.com/store/apps/details?id=com.instagram.android&hl=de&gl=de",
              "https://play.google.com/store/apps/details?id=com.instagram.android&reviewId=x",
              "https://play.google.com/store/apps/details?id=com.instagram.android&showAllReviews=true",
              "https://market.android.com/details?id=com.instagram.android",
              "https://play.google.com/store/search?q=instagram&c=apps&hl=en&gl=us",
              "https://play.google.com/store/apps/dev?id=5700313618786177705",
              "https://play.google.com/store/apps/developer?id=Instagram",
              "https://play.google.com/store/apps/category/SOCIAL",
              "https://play.google.com/store/apps/collection/topselling_free"
            ],
            "items": {
              "type": "string"
            }
          },
          "appIdOrUrl": {
            "title": "App ID or URL (alias)",
            "type": "string",
            "description": "Single-app shortcut: a Google Play app link or package id (e.g. com.supercell.brawlstars). Switches the run to URL mode and replaces the Start URLs list, so only this one app is scraped. Leave empty to use Start URLs or Search queries."
          },
          "countries": {
            "title": "Countries",
            "type": "array",
            "description": "ISO 2-letter country codes to collect reviews from (for example us, gb, de, jp). Each country is a separate review stream. Leave empty to use the country from each URL (URL mode) or 'us' (search mode). Use 'all' to sweep a broad built-in set of major countries.",
            "items": {
              "type": "string"
            }
          },
          "language": {
            "title": "Language",
            "type": "string",
            "description": "Review language / locale (ISO code, for example en, es, de, ja). Controls the language of returned reviews and metadata.",
            "default": "en"
          },
          "sortBy": {
            "title": "Sort reviews by",
            "enum": [
              "newest",
              "mostHelpful",
              "rating",
              "mostRelevant"
            ],
            "type": "string",
            "description": "Order reviews are returned in per country.",
            "default": "newest"
          },
          "minRating": {
            "title": "Minimum rating",
            "minimum": 1,
            "maximum": 5,
            "type": "integer",
            "description": "Keep only reviews with at least this star rating (1 to 5). Leave empty for all."
          },
          "maxRating": {
            "title": "Maximum rating",
            "minimum": 1,
            "maximum": 5,
            "type": "integer",
            "description": "Keep only reviews with at most this star rating (1 to 5). Leave empty for all."
          },
          "rating": {
            "title": "Exact star rating (alias)",
            "minimum": 1,
            "maximum": 5,
            "type": "integer",
            "description": "Keep only reviews with exactly this star rating (1-5). Shortcut for setting both Min and Max rating; an explicit Min/Max wins."
          },
          "keywords": {
            "title": "Keywords",
            "type": "array",
            "description": "Keep only reviews whose text contains at least one of these words or phrases (case-insensitive). Empty = no text filter. Reviews that do not match are never counted toward Max reviews and never billed.",
            "items": {
              "type": "string"
            }
          },
          "appVersion": {
            "title": "App versions",
            "type": "array",
            "description": "Keep only reviews written on exactly one of these app versions (e.g. 69.414). Empty = all versions.",
            "items": {
              "type": "string"
            }
          },
          "startDate": {
            "title": "From date",
            "type": "string",
            "description": "Keep reviews on or after this day (YYYY-MM-DD, UTC). With newest-first sorting the walk stops as soon as it passes this date."
          },
          "endDate": {
            "title": "To date",
            "type": "string",
            "description": "Keep reviews on or before this day (YYYY-MM-DD, UTC)."
          },
          "recentDays": {
            "title": "Only the last N days",
            "minimum": 0,
            "type": "integer",
            "description": "Keep only reviews from the last N days (0 = no limit). Combined with From date, the later bound wins.",
            "default": 0
          },
          "fetchDetails": {
            "title": "Enrich with app details",
            "type": "boolean",
            "description": "Also attach app metadata (developer, average score, ratings count, installs, category, icon, price, description) to each review. Adds an extra lookup per app.",
            "default": false
          },
          "maxItems": {
            "title": "Max reviews",
            "minimum": 0,
            "maximum": 1000000,
            "type": "integer",
            "description": "Maximum number of reviews to collect in total. 0 means no limit (stops at Max pages per country across all countries). Predictable, keeps the first run cheap.",
            "default": 20
          },
          "maxPages": {
            "title": "Max pages per country",
            "minimum": 0,
            "type": "integer",
            "description": "Optional per-country safety bound on review pages read (about 40 reviews per page). Leave empty to walk every result page Google Play serves, up to a hard limit of 1000 pages per country. This does NOT cap the number of reviews — the run stops at Max reviews."
          },
          "proxy": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Connection settings. The default works on any Apify plan.",
            "default": {
              "useApifyProxy": true
            }
          },
          "resumeFromRunId": {
            "title": "Resume from a previous run",
            "type": "string",
            "description": "Run id (or dataset id) of an earlier run of this Actor. Reviews it already collected are skipped, so this run only fetches new ones. Leave empty for a normal run. Do not combine with Incremental mode unless this is the very first incremental run for a new State key — an established incremental baseline already tracks what was seen."
          },
          "incrementalMode": {
            "title": "Incremental mode (recurring monitoring)",
            "type": "boolean",
            "description": "For scheduling this Actor to run repeatedly against the SAME app/country/filter set. The Actor remembers what it saw last time (keyed by State key below, or an automatic hash of your search/filter settings) and marks each review NEW, UPDATED, UNCHANGED, REAPPEARED, or EXPIRED. Unlike Resume from a previous run, you never need to paste a run id. Compared: every review field (rating, text, author, date, thumbs-up, app version, developer reply). Excluded: the app-level fields added by Enrich with app details (appName, appDeveloper, appScore, appRatingsCount, appInstalls and similar), because they describe the app, not the review. Off by default so normal runs are unaffected.",
            "default": false
          },
          "stateKey": {
            "title": "State key (optional)",
            "type": "string",
            "description": "Name this monitoring campaign so Incremental mode's memory is explicit and stable, instead of an automatic hash of your search/filter settings. Use different State keys for different campaigns you want tracked separately. Leave empty to let the Actor derive one from mode, queries/urls, countries, language, sortBy, minRating/maxRating, and fetchDetails."
          },
          "emitUnchanged": {
            "title": "Include unchanged reviews in output",
            "type": "boolean",
            "description": "Only used with Incremental mode. When off (default), a review identical to what the previous run saw is skipped — it is not returned and not billed. Turn this on to also return those unchanged reviews (changeType: \"UNCHANGED\") — this returns, and bills for, extra rows.",
            "default": false
          },
          "emitExpired": {
            "title": "Report reviews that disappeared",
            "type": "boolean",
            "description": "Only used with Incremental mode. When on, a review the previous run saw but this run no longer finds (deleted, or no longer reachable) is returned once as a tombstone row (changeType: \"EXPIRED\") — this returns, and bills for, an extra row per disappeared review. Only reported after a run that fully re-walked every tracked app/country stream (no Max reviews cap hit, no Resume from a previous run); a partial run never reports EXPIRED, since it cannot tell \"deleted\" apart from \"not reached yet\".",
            "default": false
          },
          "ignoreFieldsForChanges": {
            "title": "Ignore fields when detecting changes (incremental mode only)",
            "type": "array",
            "description": "Only used with Incremental mode. Output field names (for example thumbsUp, developerReply or developerReplyDate; review rows are flat, so no dotted paths are needed) that are left out when deciding whether a review changed, use thumbsUp if you do not want helpful-vote changes to mark a review UPDATED. The ignored fields still appear in the output rows. Changing this list never re-reports unchanged reviews as UPDATED.",
            "items": {
              "type": "string"
            }
          },
          "mcpConnectors": {
            "title": "Pipe results into your apps (optional)",
            "type": "array",
            "description": "Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify, Settings, API & Integrations, then select it here. Notion gets a rich page-per-item export; other connectors get a best-effort write. Leave empty to skip; never changes the dataset output. Supported: Notion, Linear, Airtable, Apify."
          },
          "notionParentPageUrl": {
            "title": "Notion parent page (Notion connector only)",
            "type": "string",
            "description": "URL or id of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors."
          },
          "maxNotifyListings": {
            "title": "Max items to export per connector",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "Cap on items written to each connector per run. Does not affect the dataset.",
            "default": 50
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}