{
  "data": {
    "id": "ISHuTQLI5ebvnqoPk",
    "actId": "OfCoojvD9eGIdwxuz",
    "userId": "yD5UfT6bandvym756",
    "startedAt": "2026-10-22T23:09:27.006Z",
    "finishedAt": "2026-10-22T23:09:32.273Z",
    "status": "SUCCEEDED",
    "meta": {
      "origin": "API"
    },
    "stats": {
      "durationMillis": 5195,
      "runTimeSecs": 5.195,
      "computeUnits": 0.005772222222222222,
      "imageSizeBytes": 311162368
    },
    "options": {
      "useCache": true,
      "betaPackages": false,
      "tag": "funnel-ready-20261023",
      "memoryMbytes": 4096,
      "diskMbytes": 8192
    },
    "exitCode": 0,
    "inputSchema": "{\n  \"title\": \"Google Play collection\",\n  \"type\": \"object\",\n  \"schemaVersion\": 1,\n  \"properties\": {\n    \"mode\": {\n      \"title\": \"What to collect\",\n      \"type\": \"string\",\n      \"editor\": \"select\",\n      \"enum\": [\n        \"reviews\",\n        \"apps\",\n        \"search\"\n      ],\n      \"default\": \"reviews\",\n      \"description\": \"Reviews are separate rows. Apps returns full metadata. Search returns keyword listings, not chart ranks.\"\n    },\n    \"appInputs\": {\n      \"title\": \"Android apps\",\n      \"type\": \"array\",\n      \"editor\": \"stringList\",\n      \"default\": [\n        \"com.whatsapp\"\n      ],\n      \"description\": \"Package IDs or exact HTTPS Google Play details URLs. Up to 1000 inputs; duplicate inputs are removed.\",\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"searchTerms\": {\n      \"title\": \"Search keywords\",\n      \"type\": \"array\",\n      \"editor\": \"stringList\",\n      \"default\": [\n        \"budget planner\"\n      ],\n      \"description\": \"Used only in search mode, up to 1000 terms.\",\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"country\": {\n      \"title\": \"Country\",\n      \"type\": \"string\",\n      \"editor\": \"textfield\",\n      \"default\": \"us\",\n      \"pattern\": \"^[a-z]{2}$\",\n      \"description\": \"Lowercase storefront code, not the reviewer location.\"\n    },\n    \"language\": {\n      \"title\": \"Language\",\n      \"type\": \"string\",\n      \"editor\": \"textfield\",\n      \"default\": \"en\",\n      \"description\": \"Requested Google Play locale; does not guarantee the language of every review.\"\n    },\n    \"sort\": {\n      \"title\": \"Review order\",\n      \"type\": \"string\",\n      \"editor\": \"select\",\n      \"enum\": [\n        \"newest\",\n        \"relevant\",\n        \"rating\"\n      ],\n      \"default\": \"newest\",\n      \"description\": \"Source order. Newest is recommended for review monitoring.\"\n    },\n    \"rating\": {\n      \"title\": \"Only this star rating\",\n      \"type\": \"integer\",\n      \"editor\": \"number\",\n      \"minimum\": 1,\n      \"maximum\": 5,\n      \"description\": \"Optional exact star filter, 1 to 5.\"\n    },\n    \"dateFrom\": {\n      \"title\": \"Reviews from (inclusive)\",\n      \"type\": \"string\",\n      \"editor\": \"textfield\",\n      \"description\": \"Optional ISO 8601, for example 2026-01-01T00:00:00Z. Date-only values mean midnight UTC.\"\n    },\n    \"dateTo\": {\n      \"title\": \"Reviews until (inclusive)\",\n      \"type\": \"string\",\n      \"editor\": \"textfield\",\n      \"description\": \"Optional ISO 8601. To include a whole day, specify its ending time.\"\n    },\n    \"maxReviews\": {\n      \"title\": \"Reviews per app\",\n      \"type\": \"integer\",\n      \"editor\": \"number\",\n      \"default\": 1000,\n      \"minimum\": 1,\n      \"maximum\": 100000,\n      \"description\": \"Overall per-app delivery ceiling across a continuation chain; source availability may be lower.\"\n    },\n    \"maxSearchResults\": {\n      \"title\": \"Listings per keyword\",\n      \"type\": \"integer\",\n      \"editor\": \"number\",\n      \"default\": 50,\n      \"minimum\": 1,\n      \"maximum\": 250,\n      \"description\": \"Upper limit from the public search page. Google may return fewer; no search pagination is promised.\"\n    },\n    \"maxResults\": {\n      \"title\": \"Result cap for this run\",\n      \"type\": \"integer\",\n      \"editor\": \"number\",\n      \"default\": 100000,\n      \"minimum\": 1,\n      \"maximum\": 100000,\n      \"description\": \"Stop this run after this many useful rows; resume remaining work from CHECKPOINT.\"\n    },\n    \"maxRunSeconds\": {\n      \"title\": \"Collection time budget\",\n      \"type\": \"integer\",\n      \"editor\": \"number\",\n      \"default\": 3600,\n      \"minimum\": 10,\n      \"maximum\": 7200,\n      \"description\": \"Soft time budget checked between requests/results. Set Apify Timeout at least 60 seconds higher.\"\n    },\n    \"resumeCheckpointStoreId\": {\n      \"title\": \"Continue from checkpoint storage\",\n      \"type\": \"string\",\n      \"editor\": \"resourcePicker\",\n      \"resourceType\": \"keyValueStore\",\n      \"resourcePermissions\": [\n        \"READ\"\n      ],\n      \"description\": \"Optional checkpoint store of a controlled stopped run of this Actor. Copy CHECKPOINT.input; keep filters unchanged. No concurrent resume.\"\n    },\n    \"ratings\": {\n      \"title\": \"Star rating allow-list\",\n      \"type\": \"array\",\n      \"editor\": \"json\",\n      \"items\": {\n        \"type\": \"integer\",\n        \"minimum\": 1,\n        \"maximum\": 5\n      },\n      \"description\": \"Optional multiple stars, e.g. [1,2]. Do not conflict with the single rating field.\"\n    },\n    \"replyFilter\": {\n      \"title\": \"Developer reply filter\",\n      \"type\": \"string\",\n      \"editor\": \"select\",\n      \"enum\": [\n        \"any\",\n        \"with_reply\",\n        \"without_reply\"\n      ],\n      \"default\": \"any\",\n      \"description\": \"Keep all reviews, only reviews with a developer reply, or only reviews without one.\"\n    },\n    \"keywords\": {\n      \"title\": \"Text contains any keyword\",\n      \"type\": \"array\",\n      \"editor\": \"stringList\",\n      \"items\": {\n        \"type\": \"string\"\n      },\n      \"description\": \"Optional case-insensitive literal matches; any keyword may match. Up to 30.\"\n    },\n    \"appVersions\": {\n      \"title\": \"App version allow-list\",\n      \"type\": \"array\",\n      \"editor\": \"stringList\",\n      \"items\": {\n        \"type\": \"string\"\n      },\n      \"description\": \"Optional exact app version allow-list; missing versions do not match.\"\n    },\n    \"minThumbsUp\": {\n      \"title\": \"Minimum helpful votes\",\n      \"type\": \"integer\",\n      \"editor\": \"number\",\n      \"default\": 0,\n      \"minimum\": 0,\n      \"maximum\": 1000000000,\n      \"description\": \"Only deliver reviews with this many helpful votes or more.\"\n    },\n    \"includeAppDetails\": {\n      \"title\": \"Free app context\",\n      \"type\": \"boolean\",\n      \"editor\": \"checkbox\",\n      \"default\": true,\n      \"description\": \"In reviews mode, fetch app title/developer plus app aggregates for APPS. No result event for context. Extra source/platform usage applies; context failure does not discard reviews.\"\n    }\n  }\n}",
    "readme": "![Google Play Reviews Scraper — API Vault](https://raw.githubusercontent.com/apivault-labs/apivault-labs/5f1007a5432eaf647502e565545573ccd5619193/assets/google-play-reviews-scraper/readme-cover-generated-v1.png)\n\n# Google Play Reviews Scraper — reviews, replies & app insights\n\nTurn Android app feedback into a useful research dataset. Export public **review text, star ratings, dates, app versions, helpful votes and developer replies**. Investigate low-star feedback, find unanswered complaints, compare apps or prepare your own review analysis.\n\n**$0.02 per 1,000 useful delivered rows**, on every Apify plan, plus platform usage. No Actor-start event. App context and delivered-sample analytics add no result events.\n\nNo Google login, Play Console access or external data API key is required. An Apify account/token is needed to call the Apify API. Each review is a separate row. Apple App Store collection and official category charts are outside this product.\n\n## Quick start: export 100 reviews\n\n```json\n{\"mode\":\"reviews\",\"appInputs\":[\"com.whatsapp\"],\"country\":\"us\",\"language\":\"en\",\"maxReviews\":100}\n```\n\nEach delivered review is a separate row, rather than an app summary containing an empty reviews array. Set a small limit first to check whether the chosen locale gives you the feedback you need.\n\n## What you can collect\n\n| Mode | Useful output | Typical use |\n|---|---|---|\n| `reviews` | Review text, stars, dates, votes, app versions and developer replies | Product feedback, issue discovery, review exports |\n| `apps` | App title, developer, description, rating counts, installs labels, category, pricing and public developer links | Competitor research and app catalog enrichment |\n| `search` | Keyword listings with observed search positions | Android app discovery and ASO research |\n\nSearch positions describe the returned keyword page. They are not official category rankings. Google decides how many listings it exposes; the search limit is an upper bound, not guaranteed coverage.\n\n## Choose a useful workflow\n\n| Your goal | Suggested input | What to inspect |\n|---|---|---|\n| Build a review research dataset | `reviews`, explicit locale, larger `maxReviews` | Dataset, counts and source limitations |\n| Find unanswered negative feedback | `ratings: [1, 2]`, `replyFilter: \"without_reply\"` | Delivered text and reply statistics |\n| Investigate an app release | `appVersions`, optional dates and keywords | Exact source-reported version and feedback |\n| Study developer responses | `replyFilter: \"with_reply\"` | Review/reply text and timestamps |\n| Research competing Android apps | `apps` or `search` | Descriptions, pricing, categories and publisher links |\n| Continue a large export | Copy `CHECKPOINT.input` after a controlled stop | Retained page and remaining work |\n\n## Collect thousands of reviews\n\n```json\n{\"mode\":\"reviews\",\"appInputs\":[\"com.whatsapp\",\"com.spotify.music\"],\"maxReviews\":10000,\"maxResults\":20000,\"country\":\"us\",\"language\":\"en\",\"sort\":\"newest\",\"maxRunSeconds\":3600}\n```\n\nThe reviews collector follows Google's continuation tokens in source requests of up to 1,000 records and Dataset delivery batches of up to 200 rows, removes repeated review IDs per app, and saves useful rows incrementally. You can request up to 100,000 delivered reviews per app, 1,000 input apps or keywords, and 100,000 total results per run. These are configured ceilings, not a promise that Google exposes every review or that one run reaches the ceiling. Requests are processed sequentially to keep pagination and budgets predictable.\n\n### Verified collection capacity\n\nThe private runtime verification on October 22, 2026 delivered **100,000 unique useful reviews and 100,000 matching result events**. CSV export and the official Python SDK returned the same ordered review IDs. The run took about **8 minutes 13 seconds** at 512 MB; peak memory was approximately 377 MB. One unusable source row was skipped without a result event and reported in the summary.\n\nA separate 5,000-review verification took about **11 seconds**. These are observed runs, not speed guarantees or complete-history claims. Source conditions, locale, app availability, filtering and platform conditions affect future collections. The 100,000-row capacity was demonstrated for one input, not guaranteed for every app.\n\n## Filter low-star, unanswered and version-specific feedback\n\n```json\n{\"appInputs\":[\"com.spotify.music\"],\"ratings\":[1,2],\"replyFilter\":\"without_reply\",\"keywords\":[\"login\",\"crash\"],\"minThumbsUp\":1,\"maxReviews\":100}\n```\n\n`ratings` accepts several star values. `rating` remains available for one exact star; do not supply conflicting filters. `keywords` uses case-insensitive literal substring matching and accepts a match to any keyword. `appVersions` matches an exact reported version. `replyFilter` accepts `any`, `with_reply`, or `without_reply`; an empty reply counts as no observed reply. Filtered reviews have no result event. Local filters can scan more source pages and consume platform usage even if no reviews match.\n\n## Filter feedback by date and stars\n\n```json\n{\"mode\":\"reviews\",\"appInputs\":[\"com.spotify.music\"],\"rating\":1,\"dateFrom\":\"2026-01-01T00:00:00Z\",\"dateTo\":\"2026-12-31T23:59:59Z\",\"maxReviews\":5000,\"country\":\"us\",\"language\":\"en\"}\n```\n\nDate boundaries are inclusive. Dates without a timezone use UTC; a date without a time means midnight, so specify the day's ending time if you want the whole day. The date filter is applied locally to returned reviews. A narrow filter can require scanning many pages and may reach the time budget before enough matching rows appear. Review timestamps are Google-provided; this Actor does not infer a missing date.\n\n## App details and app keyword search\n\n```json\n{\"mode\":\"apps\",\"appInputs\":[\"https://play.google.com/store/apps/details?id=com.whatsapp\",\"com.spotify.music\"],\"country\":\"gb\",\"language\":\"en\"}\n```\n\n```json\n{\"mode\":\"search\",\"searchTerms\":[\"budget planner\",\"habit tracker\"],\"maxSearchResults\":20,\"country\":\"us\",\"language\":\"en\"}\n```\n\nApp detail fields include public developer email and website where Google supplies them. Missing fields remain null. Detail mode also preserves source screenshots, header image, video links, developer address and ads flag when supplied. Install labels are public thresholds, and any source-provided install counters are not audited download measurements. This Actor does not estimate revenue.\n\n## Output fields\n\n| Field | Meaning |\n|---|---|\n| `recordType`, `appId`, `url` | Result type and Android package identity |\n| `reviewId`, `content`, `score`, `at` | Public review ID, text, 1–5 stars and review timestamp |\n| `userName`, `userImage`, `thumbsUpCount` | Public display name, avatar URL and helpful votes |\n| `appTitle`, `developer` | App context on review rows when enabled and available |\n| `reviewCreatedVersion`, `appVersion` | App versions reported by the source, if available |\n| `replyContent`, `repliedAt` | Developer response and response timestamp, if present |\n| `title`, `developer`, `description`, `genre` | App detail metadata; detail mode only |\n| `ratings`, `reviews`, `score`, `histogram` | App aggregates in detail mode; not a count of rows available to scrape |\n| `searchTerm`, `searchRank` | Query and observed listing position in search mode |\n| `country`, `language`, `scrapedAt` | Requested storefront/locale and collection time |\n\n`country` is the requested storefront, not the author's location. `language` selects the source locale and does not translate text or guarantee every review's language. Fields vary by mode; absent source values are not filled with invented values.\n\n### Illustrative review row\n\nThis is a schema illustration, not captured customer feedback. Missing reply/version fields remain null.\n\n```javascript\n{\n  recordType: \"review\",\n  appId: \"com.example.app\",\n  reviewId: \"illustrative-review-id\",\n  content: \"Illustrative review text.\",\n  score: 2,\n  at: \"2026-10-01T12:00:00Z\",\n  appVersion: null,\n  replyContent: null,\n  country: \"us\",\n  language: \"en\"\n}\n```\n\n## App context and sample insights — no extra result events\n\nIn reviews mode, `includeAppDetails` defaults to true. App title and developer are attached to delivered reviews when lookup succeeds, and `APPS` stores the source-provided app context and aggregate ratings. Context lookup adds a source request and platform usage, but no additional result event. Its failure records a warning and review collection continues. Disable it for a lighter export.\n\n`INSIGHTS` contains, per app, the delivered sample's star histogram, average rating, developer-reply percentage, observed low-star reviews without replies, helpful-vote total and timestamp range. It describes only delivered reviews that passed your filters, across the continuation chain. It does not infer text sentiment or represent all users. INSIGHTS, APPS, SUMMARY and CHECKPOINT are key-value records without Dataset result charges.\n\nCheckpoint state is compressed to reduce transfer and storage costs. Checkpoints from the previous candidate format cannot be resumed with this build; use the original build for those runs or start a new collection. Controlled-stop continuation remains supported. A hard crash can happen between Dataset delivery and checkpoint persistence; automatic crash recovery and exactly-once delivery are not promised.\n\n## Continue a large or budget-limited run\n\n`SUMMARY` stores delivered counts, fetched review pages, filtered/invalid/duplicate counts, target errors and the final collection status. `CHECKPOINT` stores progress and an `input` object for continuing. After the run has stopped, copy `CHECKPOINT.input` into a new run. It includes `resumeCheckpointStoreId`; retain the same app list, mode, locale, filters and per-app target. You may adjust the per-run `maxResults` and time budget.\n\nThe prior checkpoint must belong to this Actor and be accessible to your account. Select its key-value store; only read permission for that selected storage is requested. The Actor reads its own stored checkpoint; inline, user-written row payloads are not accepted. Continuation keeps known delivered IDs and a partially delivered page in a compressed checkpoint, preventing repeats during a normal, controlled limit or budget stop. Do not start multiple continuations from the same checkpoint. Google reviews can change between requests; this is not a frozen snapshot. Only controlled stops produce a resumable checkpoint. Sudden process termination leaves the checkpoint marked running and cannot be resumed automatically; check IDs before retrying and combining interrupted exports. Errors skip the affected target and are recorded unpaid; retry those targets separately.\n\n## Pricing and complete run costs\n\n**$0.02 per 1,000 useful delivered rows** for reviews, app details and search listings, on all plans. **Apify compute, storage and transfer usage is additional and paid by the user.** There is no Actor-start event. Errors, diagnostics, filtered/invalid rows and removed duplicates have no result event. APPS, INSIGHTS, SUMMARY and CHECKPOINT are separate key-value records without result events.\n\n| Useful delivered rows | Result-event cost |\n|---:|---:|\n| 100 | $0.002 |\n| 1,000 | $0.02 |\n| 10,000 | $0.20 |\n| 100,000 | $2.00 |\n\nThe verified 100,000-review export had $2.00 in result fees and about $0.565 in reported platform usage: approximately **$2.565 total, or $0.02565/1,000 rows**. A 5,000-review run was about $0.128 including events and reported usage. These are measured examples and event arithmetic, not an invoice, fixed package price or guarantee. Small or narrowly filtered runs can have higher platform cost per delivered row. Later exports/storage reads and external integrations can add account-level charges.\n\nCheck the Pricing tab and set a spending limit before a large export. Apify's automatic Dataset billing controls the result-event budget; do not treat it as a guarantee that every possible platform charge is included in that cap. No blanket claim of cheapest service or superiority over every scraper is made.\n\n## Limits and diagnostics\n\n| Setting | Default | Maximum |\n|---|---:|---:|\n| `maxReviews` per app | 1,000 | 100,000 |\n| `maxResults` per run | 100,000 | 100,000 |\n| Input apps / search terms | 1 | 1,000 |\n| `maxSearchResults` per keyword | 50 | 250 |\n| `maxRunSeconds` | 3,600 | 7,200 |\n\nSet the Apify run timeout at least 60 seconds higher than the collection budget. A source request has a bounded network timeout; the time budget is checked between requests and deliveries. `PARTIAL_LIMIT`, `PARTIAL_TIME` and `PARTIAL_BUDGET` mean rows were preserved but the requested work is unfinished. `PARTIAL_ERRORS` identifies failed targets or skipped unusable source rows; inspect the counts and error list. A platform-level SUCCEEDED status alone does not prove complete source coverage. An empty valid search or a review feed with no matching reviews can finish with zero rows. Invalid input or all targets failing produces a failed run with no fabricated Dataset row.\n\nGoogle can restrict or change its public endpoints, return fewer records, reorder feedback, or make an app unavailable in a storefront. Review pagination stops on exhaustion, a repeated token, a configured ceiling or a time/spending limit. An endpoint or parser failure is not represented as a successful complete review history. No proxy is required by this candidate; source availability from your selected region may vary.\n\n## API, Python and workflow integrations\n\nUse exact Actor ID **`OfCoojvD9eGIdwxuz`** with the [Apify API](https://docs.apify.com/api/v2/), [official Python client](https://docs.apify.com/api/client/python/) or [official JavaScript client](https://docs.apify.com/api/client/js/).\n\n```python\nimport os\nfrom apify_client import ApifyClient\n\nclient = ApifyClient(os.environ[\"APIFY_TOKEN\"])\nrun = client.actor(\"OfCoojvD9eGIdwxuz\").call(\n    run_input={\n        \"mode\": \"reviews\",\n        \"appInputs\": [\"com.whatsapp\"],\n        \"country\": \"us\",\n        \"language\": \"en\",\n        \"maxReviews\": 100,\n    },\n    build=\"latest\",\n    memory_mbytes=512,\n    timeout_secs=3660,\n    max_total_charge_usd=0.01,\n)\nif run is None:\n    raise RuntimeError(\"The run did not return metadata\")\nfor review in client.dataset(run[\"defaultDatasetId\"]).iterate_items():\n    print(review[\"reviewId\"], review[\"score\"], review[\"content\"])\n```\n\nKeep your token in an environment variable. The example selects the current production build. Use your Apify account token and review the run spending limit before starting.\n\nThe Dataset supports JSON, CSV and Excel exports through the console/API. n8n, Make or your own workflow can call the standard Apify API. No dedicated API Vault Google Play n8n node or Python package is advertised: the historical App Store integration points to a different product. No dedicated marketplace package is required to use the standard Apify API.\n\n## FAQ\n\n**Does it return every review counted on the app page?** No. Star ratings include ratings without text, and Google's public review feed has its own locale, relevance and availability limits. A configured ceiling is not a completeness guarantee.\n\n**Can it collect hundreds or thousands at once?** Yes, it follows review pagination and writes individual records. Start with a small sample and raise both the review limit and run budget for a larger export. A 100,000-row export has been verified on this runtime; source coverage and timing can differ for another app or locale.\n\n**Can I collect developer replies?** Yes, when Google includes reply text and timestamps for that review. Missing replies stay null.\n\n**Does search paginate through all Android apps?** No. Search reads the public keyword results exposed by Google, up to your listing limit. Only review collection promises continuation-token pagination.\n\n**Are diagnostics billed?** No. Only useful Dataset rows trigger the single automatic result event. The key-value summary, errors and checkpoint do not produce result events.\n\n**Can I resume a stopped export?** Yes, after a controlled collection limit, time or spending stop. Use CHECKPOINT.input after the earlier run stops. Keep the same collection inputs; do not resume one checkpoint concurrently. Sudden termination has the checkpoint caveat described above.\n\n**Can I schedule daily monitoring?** You can schedule runs through Apify and use dates/IDs in your workflow. A new independent run does not automatically deduplicate against every prior run. Controlled continuation is a separate feature. This Actor does not send external alerts.\n\n**Is this an official Google product?** No. API Vault collects public Google Play data independently and is not affiliated with Google. The generated cover/avatar are illustrative artwork, not platform logos or screenshots of captured customer data.\n\n<!-- new-actor-funnels-20261023:start -->\n## Python client and n8n workflow\n\nUse the thin [Python client](https://github.com/apivault-labs/apivault-labs/tree/main/packages/apivault-google-play-reviews-scraper) or install it from [PyPI](https://pypi.org/project/apivault-google-play-reviews-scraper/):\n\n```bash\npip install apivault-google-play-reviews-scraper==0.1.0\n```\n\nThe client starts this hosted Actor through the Apify API and reads its dataset. An Apify account and your own API token are required. Actor result charges and infrastructure usage follow the current pricing. The client package has no subscription of its own. Set both Actor collection limits and run charge caps; the dataset download limit does not limit paid collection.\n\n[n8n node source and manual workflow](https://github.com/apivault-labs/apivault-labs/tree/main/community-nodes/n8n-nodes-apivault-google-play-reviews-scraper) are available on GitHub. The workflow is inactive and has no embedded credentials. Its Run operation starts a paid Actor run; Read Existing Run reads a previous run without starting another. The [npm package](https://www.npmjs.com/package/n8n-nodes-apivault-google-play-reviews-scraper) is published as version0.1.0. Install `n8n-nodes-apivault-google-play-reviews-scraper@0.1.0` on a self-hosted n8n instance that allows community nodes. npm publication, when approved, does not establish n8n verification or availability in n8n Cloud.\n<!-- new-actor-funnels-20261023:end -->\n",
    "changelog": "# Changelog\n\n## 0.1 candidate — 2026-10-22\n\nReal paginated Google Play reviews, app details, keyword search, useful-row billing, filters, deduplication and account-scoped continuation. Separate product from the historical Apple App Store prototype. Awaiting owner review before publication.\n\n## Private upgrade — 2026-10-22\n\nBatched Dataset writes, 1000-row source pages, compressed checkpoints, free app context and sample insights, multiple-star/reply/keyword/version/helpful-vote filters, richer detail images, direct review links and $0.02/1000 private candidate pricing. Explicit owner prohibition on publication retained.\n\n## Private artwork and README — 2026-10-22\n\nGenerated matching avatar/cover saved privately. Complete product README restructured with measured capacity/costs, filters, examples and Python integration. Apify text edition omits the repository-relative cover until public image hosting is separately authorized. Runtime, schemas and pricing unchanged. No publication.\n\n## Public-ready packaging candidate — 2026-10-22\n\nPinned public README cover, production/latest SDK example and public-ready text. Runtime, schema, price and owner-installed avatar preserved. Awaiting exact final review; not yet public.\n",
    "actorDefinition": {
      "actorSpecification": 1,
      "name": "google-play-reviews-scraper",
      "title": "Google Play Scraper $0.02/1K | Reviews, Replies & App Search",
      "description": "Collect Google Play review text, star ratings, dates, versions and developer replies. Paginate large review exports, filter dates and ratings, look up app details or search Android apps by keyword.",
      "version": "0.1",
      "buildTag": "googleplay-launch-20261022",
      "minMemoryMbytes": 256,
      "maxMemoryMbytes": 512,
      "dockerfile": "./Dockerfile",
      "input": {
        "title": "Google Play collection",
        "type": "object",
        "schemaVersion": 1,
        "properties": {
          "mode": {
            "title": "What to collect",
            "type": "string",
            "editor": "select",
            "enum": [
              "reviews",
              "apps",
              "search"
            ],
            "default": "reviews",
            "description": "Reviews are separate rows. Apps returns full metadata. Search returns keyword listings, not chart ranks."
          },
          "appInputs": {
            "title": "Android apps",
            "type": "array",
            "editor": "stringList",
            "default": [
              "com.whatsapp"
            ],
            "description": "Package IDs or exact HTTPS Google Play details URLs. Up to 1000 inputs; duplicate inputs are removed.",
            "items": {
              "type": "string"
            }
          },
          "searchTerms": {
            "title": "Search keywords",
            "type": "array",
            "editor": "stringList",
            "default": [
              "budget planner"
            ],
            "description": "Used only in search mode, up to 1000 terms.",
            "items": {
              "type": "string"
            }
          },
          "country": {
            "title": "Country",
            "type": "string",
            "editor": "textfield",
            "default": "us",
            "pattern": "^[a-z]{2}$",
            "description": "Lowercase storefront code, not the reviewer location."
          },
          "language": {
            "title": "Language",
            "type": "string",
            "editor": "textfield",
            "default": "en",
            "description": "Requested Google Play locale; does not guarantee the language of every review."
          },
          "sort": {
            "title": "Review order",
            "type": "string",
            "editor": "select",
            "enum": [
              "newest",
              "relevant",
              "rating"
            ],
            "default": "newest",
            "description": "Source order. Newest is recommended for review monitoring."
          },
          "rating": {
            "title": "Only this star rating",
            "type": "integer",
            "editor": "number",
            "minimum": 1,
            "maximum": 5,
            "description": "Optional exact star filter, 1 to 5."
          },
          "dateFrom": {
            "title": "Reviews from (inclusive)",
            "type": "string",
            "editor": "textfield",
            "description": "Optional ISO 8601, for example 2026-01-01T00:00:00Z. Date-only values mean midnight UTC."
          },
          "dateTo": {
            "title": "Reviews until (inclusive)",
            "type": "string",
            "editor": "textfield",
            "description": "Optional ISO 8601. To include a whole day, specify its ending time."
          },
          "maxReviews": {
            "title": "Reviews per app",
            "type": "integer",
            "editor": "number",
            "default": 1000,
            "minimum": 1,
            "maximum": 100000,
            "description": "Overall per-app delivery ceiling across a continuation chain; source availability may be lower."
          },
          "maxSearchResults": {
            "title": "Listings per keyword",
            "type": "integer",
            "editor": "number",
            "default": 50,
            "minimum": 1,
            "maximum": 250,
            "description": "Upper limit from the public search page. Google may return fewer; no search pagination is promised."
          },
          "maxResults": {
            "title": "Result cap for this run",
            "type": "integer",
            "editor": "number",
            "default": 100000,
            "minimum": 1,
            "maximum": 100000,
            "description": "Stop this run after this many useful rows; resume remaining work from CHECKPOINT."
          },
          "maxRunSeconds": {
            "title": "Collection time budget",
            "type": "integer",
            "editor": "number",
            "default": 3600,
            "minimum": 10,
            "maximum": 7200,
            "description": "Soft time budget checked between requests/results. Set Apify Timeout at least 60 seconds higher."
          },
          "resumeCheckpointStoreId": {
            "title": "Continue from checkpoint storage",
            "type": "string",
            "editor": "resourcePicker",
            "resourceType": "keyValueStore",
            "resourcePermissions": [
              "READ"
            ],
            "description": "Optional checkpoint store of a controlled stopped run of this Actor. Copy CHECKPOINT.input; keep filters unchanged. No concurrent resume."
          },
          "ratings": {
            "title": "Star rating allow-list",
            "type": "array",
            "editor": "json",
            "items": {
              "type": "integer",
              "minimum": 1,
              "maximum": 5
            },
            "description": "Optional multiple stars, e.g. [1,2]. Do not conflict with the single rating field."
          },
          "replyFilter": {
            "title": "Developer reply filter",
            "type": "string",
            "editor": "select",
            "enum": [
              "any",
              "with_reply",
              "without_reply"
            ],
            "default": "any",
            "description": "Keep all reviews, only reviews with a developer reply, or only reviews without one."
          },
          "keywords": {
            "title": "Text contains any keyword",
            "type": "array",
            "editor": "stringList",
            "items": {
              "type": "string"
            },
            "description": "Optional case-insensitive literal matches; any keyword may match. Up to 30."
          },
          "appVersions": {
            "title": "App version allow-list",
            "type": "array",
            "editor": "stringList",
            "items": {
              "type": "string"
            },
            "description": "Optional exact app version allow-list; missing versions do not match."
          },
          "minThumbsUp": {
            "title": "Minimum helpful votes",
            "type": "integer",
            "editor": "number",
            "default": 0,
            "minimum": 0,
            "maximum": 1000000000,
            "description": "Only deliver reviews with this many helpful votes or more."
          },
          "includeAppDetails": {
            "title": "Free app context",
            "type": "boolean",
            "editor": "checkbox",
            "default": true,
            "description": "In reviews mode, fetch app title/developer plus app aggregates for APPS. No result event for context. Extra source/platform usage applies; context failure does not discard reviews."
          }
        }
      },
      "readme": "![Google Play Reviews Scraper — API Vault](https://raw.githubusercontent.com/apivault-labs/apivault-labs/5f1007a5432eaf647502e565545573ccd5619193/assets/google-play-reviews-scraper/readme-cover-generated-v1.png)\n\n# Google Play Reviews Scraper — reviews, replies & app insights\n\nTurn Android app feedback into a useful research dataset. Export public **review text, star ratings, dates, app versions, helpful votes and developer replies**. Investigate low-star feedback, find unanswered complaints, compare apps or prepare your own review analysis.\n\n**$0.02 per 1,000 useful delivered rows**, on every Apify plan, plus platform usage. No Actor-start event. App context and delivered-sample analytics add no result events.\n\nNo Google login, Play Console access or external data API key is required. An Apify account/token is needed to call the Apify API. Each review is a separate row. Apple App Store collection and official category charts are outside this product.\n\n## Quick start: export 100 reviews\n\n```json\n{\"mode\":\"reviews\",\"appInputs\":[\"com.whatsapp\"],\"country\":\"us\",\"language\":\"en\",\"maxReviews\":100}\n```\n\nEach delivered review is a separate row, rather than an app summary containing an empty reviews array. Set a small limit first to check whether the chosen locale gives you the feedback you need.\n\n## What you can collect\n\n| Mode | Useful output | Typical use |\n|---|---|---|\n| `reviews` | Review text, stars, dates, votes, app versions and developer replies | Product feedback, issue discovery, review exports |\n| `apps` | App title, developer, description, rating counts, installs labels, category, pricing and public developer links | Competitor research and app catalog enrichment |\n| `search` | Keyword listings with observed search positions | Android app discovery and ASO research |\n\nSearch positions describe the returned keyword page. They are not official category rankings. Google decides how many listings it exposes; the search limit is an upper bound, not guaranteed coverage.\n\n## Choose a useful workflow\n\n| Your goal | Suggested input | What to inspect |\n|---|---|---|\n| Build a review research dataset | `reviews`, explicit locale, larger `maxReviews` | Dataset, counts and source limitations |\n| Find unanswered negative feedback | `ratings: [1, 2]`, `replyFilter: \"without_reply\"` | Delivered text and reply statistics |\n| Investigate an app release | `appVersions`, optional dates and keywords | Exact source-reported version and feedback |\n| Study developer responses | `replyFilter: \"with_reply\"` | Review/reply text and timestamps |\n| Research competing Android apps | `apps` or `search` | Descriptions, pricing, categories and publisher links |\n| Continue a large export | Copy `CHECKPOINT.input` after a controlled stop | Retained page and remaining work |\n\n## Collect thousands of reviews\n\n```json\n{\"mode\":\"reviews\",\"appInputs\":[\"com.whatsapp\",\"com.spotify.music\"],\"maxReviews\":10000,\"maxResults\":20000,\"country\":\"us\",\"language\":\"en\",\"sort\":\"newest\",\"maxRunSeconds\":3600}\n```\n\nThe reviews collector follows Google's continuation tokens in source requests of up to 1,000 records and Dataset delivery batches of up to 200 rows, removes repeated review IDs per app, and saves useful rows incrementally. You can request up to 100,000 delivered reviews per app, 1,000 input apps or keywords, and 100,000 total results per run. These are configured ceilings, not a promise that Google exposes every review or that one run reaches the ceiling. Requests are processed sequentially to keep pagination and budgets predictable.\n\n### Verified collection capacity\n\nThe private runtime verification on October 22, 2026 delivered **100,000 unique useful reviews and 100,000 matching result events**. CSV export and the official Python SDK returned the same ordered review IDs. The run took about **8 minutes 13 seconds** at 512 MB; peak memory was approximately 377 MB. One unusable source row was skipped without a result event and reported in the summary.\n\nA separate 5,000-review verification took about **11 seconds**. These are observed runs, not speed guarantees or complete-history claims. Source conditions, locale, app availability, filtering and platform conditions affect future collections. The 100,000-row capacity was demonstrated for one input, not guaranteed for every app.\n\n## Filter low-star, unanswered and version-specific feedback\n\n```json\n{\"appInputs\":[\"com.spotify.music\"],\"ratings\":[1,2],\"replyFilter\":\"without_reply\",\"keywords\":[\"login\",\"crash\"],\"minThumbsUp\":1,\"maxReviews\":100}\n```\n\n`ratings` accepts several star values. `rating` remains available for one exact star; do not supply conflicting filters. `keywords` uses case-insensitive literal substring matching and accepts a match to any keyword. `appVersions` matches an exact reported version. `replyFilter` accepts `any`, `with_reply`, or `without_reply`; an empty reply counts as no observed reply. Filtered reviews have no result event. Local filters can scan more source pages and consume platform usage even if no reviews match.\n\n## Filter feedback by date and stars\n\n```json\n{\"mode\":\"reviews\",\"appInputs\":[\"com.spotify.music\"],\"rating\":1,\"dateFrom\":\"2026-01-01T00:00:00Z\",\"dateTo\":\"2026-12-31T23:59:59Z\",\"maxReviews\":5000,\"country\":\"us\",\"language\":\"en\"}\n```\n\nDate boundaries are inclusive. Dates without a timezone use UTC; a date without a time means midnight, so specify the day's ending time if you want the whole day. The date filter is applied locally to returned reviews. A narrow filter can require scanning many pages and may reach the time budget before enough matching rows appear. Review timestamps are Google-provided; this Actor does not infer a missing date.\n\n## App details and app keyword search\n\n```json\n{\"mode\":\"apps\",\"appInputs\":[\"https://play.google.com/store/apps/details?id=com.whatsapp\",\"com.spotify.music\"],\"country\":\"gb\",\"language\":\"en\"}\n```\n\n```json\n{\"mode\":\"search\",\"searchTerms\":[\"budget planner\",\"habit tracker\"],\"maxSearchResults\":20,\"country\":\"us\",\"language\":\"en\"}\n```\n\nApp detail fields include public developer email and website where Google supplies them. Missing fields remain null. Detail mode also preserves source screenshots, header image, video links, developer address and ads flag when supplied. Install labels are public thresholds, and any source-provided install counters are not audited download measurements. This Actor does not estimate revenue.\n\n## Output fields\n\n| Field | Meaning |\n|---|---|\n| `recordType`, `appId`, `url` | Result type and Android package identity |\n| `reviewId`, `content`, `score`, `at` | Public review ID, text, 1–5 stars and review timestamp |\n| `userName`, `userImage`, `thumbsUpCount` | Public display name, avatar URL and helpful votes |\n| `appTitle`, `developer` | App context on review rows when enabled and available |\n| `reviewCreatedVersion`, `appVersion` | App versions reported by the source, if available |\n| `replyContent`, `repliedAt` | Developer response and response timestamp, if present |\n| `title`, `developer`, `description`, `genre` | App detail metadata; detail mode only |\n| `ratings`, `reviews`, `score`, `histogram` | App aggregates in detail mode; not a count of rows available to scrape |\n| `searchTerm`, `searchRank` | Query and observed listing position in search mode |\n| `country`, `language`, `scrapedAt` | Requested storefront/locale and collection time |\n\n`country` is the requested storefront, not the author's location. `language` selects the source locale and does not translate text or guarantee every review's language. Fields vary by mode; absent source values are not filled with invented values.\n\n### Illustrative review row\n\nThis is a schema illustration, not captured customer feedback. Missing reply/version fields remain null.\n\n```javascript\n{\n  recordType: \"review\",\n  appId: \"com.example.app\",\n  reviewId: \"illustrative-review-id\",\n  content: \"Illustrative review text.\",\n  score: 2,\n  at: \"2026-10-01T12:00:00Z\",\n  appVersion: null,\n  replyContent: null,\n  country: \"us\",\n  language: \"en\"\n}\n```\n\n## App context and sample insights — no extra result events\n\nIn reviews mode, `includeAppDetails` defaults to true. App title and developer are attached to delivered reviews when lookup succeeds, and `APPS` stores the source-provided app context and aggregate ratings. Context lookup adds a source request and platform usage, but no additional result event. Its failure records a warning and review collection continues. Disable it for a lighter export.\n\n`INSIGHTS` contains, per app, the delivered sample's star histogram, average rating, developer-reply percentage, observed low-star reviews without replies, helpful-vote total and timestamp range. It describes only delivered reviews that passed your filters, across the continuation chain. It does not infer text sentiment or represent all users. INSIGHTS, APPS, SUMMARY and CHECKPOINT are key-value records without Dataset result charges.\n\nCheckpoint state is compressed to reduce transfer and storage costs. Checkpoints from the previous candidate format cannot be resumed with this build; use the original build for those runs or start a new collection. Controlled-stop continuation remains supported. A hard crash can happen between Dataset delivery and checkpoint persistence; automatic crash recovery and exactly-once delivery are not promised.\n\n## Continue a large or budget-limited run\n\n`SUMMARY` stores delivered counts, fetched review pages, filtered/invalid/duplicate counts, target errors and the final collection status. `CHECKPOINT` stores progress and an `input` object for continuing. After the run has stopped, copy `CHECKPOINT.input` into a new run. It includes `resumeCheckpointStoreId`; retain the same app list, mode, locale, filters and per-app target. You may adjust the per-run `maxResults` and time budget.\n\nThe prior checkpoint must belong to this Actor and be accessible to your account. Select its key-value store; only read permission for that selected storage is requested. The Actor reads its own stored checkpoint; inline, user-written row payloads are not accepted. Continuation keeps known delivered IDs and a partially delivered page in a compressed checkpoint, preventing repeats during a normal, controlled limit or budget stop. Do not start multiple continuations from the same checkpoint. Google reviews can change between requests; this is not a frozen snapshot. Only controlled stops produce a resumable checkpoint. Sudden process termination leaves the checkpoint marked running and cannot be resumed automatically; check IDs before retrying and combining interrupted exports. Errors skip the affected target and are recorded unpaid; retry those targets separately.\n\n## Pricing and complete run costs\n\n**$0.02 per 1,000 useful delivered rows** for reviews, app details and search listings, on all plans. **Apify compute, storage and transfer usage is additional and paid by the user.** There is no Actor-start event. Errors, diagnostics, filtered/invalid rows and removed duplicates have no result event. APPS, INSIGHTS, SUMMARY and CHECKPOINT are separate key-value records without result events.\n\n| Useful delivered rows | Result-event cost |\n|---:|---:|\n| 100 | $0.002 |\n| 1,000 | $0.02 |\n| 10,000 | $0.20 |\n| 100,000 | $2.00 |\n\nThe verified 100,000-review export had $2.00 in result fees and about $0.565 in reported platform usage: approximately **$2.565 total, or $0.02565/1,000 rows**. A 5,000-review run was about $0.128 including events and reported usage. These are measured examples and event arithmetic, not an invoice, fixed package price or guarantee. Small or narrowly filtered runs can have higher platform cost per delivered row. Later exports/storage reads and external integrations can add account-level charges.\n\nCheck the Pricing tab and set a spending limit before a large export. Apify's automatic Dataset billing controls the result-event budget; do not treat it as a guarantee that every possible platform charge is included in that cap. No blanket claim of cheapest service or superiority over every scraper is made.\n\n## Limits and diagnostics\n\n| Setting | Default | Maximum |\n|---|---:|---:|\n| `maxReviews` per app | 1,000 | 100,000 |\n| `maxResults` per run | 100,000 | 100,000 |\n| Input apps / search terms | 1 | 1,000 |\n| `maxSearchResults` per keyword | 50 | 250 |\n| `maxRunSeconds` | 3,600 | 7,200 |\n\nSet the Apify run timeout at least 60 seconds higher than the collection budget. A source request has a bounded network timeout; the time budget is checked between requests and deliveries. `PARTIAL_LIMIT`, `PARTIAL_TIME` and `PARTIAL_BUDGET` mean rows were preserved but the requested work is unfinished. `PARTIAL_ERRORS` identifies failed targets or skipped unusable source rows; inspect the counts and error list. A platform-level SUCCEEDED status alone does not prove complete source coverage. An empty valid search or a review feed with no matching reviews can finish with zero rows. Invalid input or all targets failing produces a failed run with no fabricated Dataset row.\n\nGoogle can restrict or change its public endpoints, return fewer records, reorder feedback, or make an app unavailable in a storefront. Review pagination stops on exhaustion, a repeated token, a configured ceiling or a time/spending limit. An endpoint or parser failure is not represented as a successful complete review history. No proxy is required by this candidate; source availability from your selected region may vary.\n\n## API, Python and workflow integrations\n\nUse exact Actor ID **`OfCoojvD9eGIdwxuz`** with the [Apify API](https://docs.apify.com/api/v2/), [official Python client](https://docs.apify.com/api/client/python/) or [official JavaScript client](https://docs.apify.com/api/client/js/).\n\n```python\nimport os\nfrom apify_client import ApifyClient\n\nclient = ApifyClient(os.environ[\"APIFY_TOKEN\"])\nrun = client.actor(\"OfCoojvD9eGIdwxuz\").call(\n    run_input={\n        \"mode\": \"reviews\",\n        \"appInputs\": [\"com.whatsapp\"],\n        \"country\": \"us\",\n        \"language\": \"en\",\n        \"maxReviews\": 100,\n    },\n    build=\"latest\",\n    memory_mbytes=512,\n    timeout_secs=3660,\n    max_total_charge_usd=0.01,\n)\nif run is None:\n    raise RuntimeError(\"The run did not return metadata\")\nfor review in client.dataset(run[\"defaultDatasetId\"]).iterate_items():\n    print(review[\"reviewId\"], review[\"score\"], review[\"content\"])\n```\n\nKeep your token in an environment variable. The example selects the current production build. Use your Apify account token and review the run spending limit before starting.\n\nThe Dataset supports JSON, CSV and Excel exports through the console/API. n8n, Make or your own workflow can call the standard Apify API. No dedicated API Vault Google Play n8n node or Python package is advertised: the historical App Store integration points to a different product. No dedicated marketplace package is required to use the standard Apify API.\n\n## FAQ\n\n**Does it return every review counted on the app page?** No. Star ratings include ratings without text, and Google's public review feed has its own locale, relevance and availability limits. A configured ceiling is not a completeness guarantee.\n\n**Can it collect hundreds or thousands at once?** Yes, it follows review pagination and writes individual records. Start with a small sample and raise both the review limit and run budget for a larger export. A 100,000-row export has been verified on this runtime; source coverage and timing can differ for another app or locale.\n\n**Can I collect developer replies?** Yes, when Google includes reply text and timestamps for that review. Missing replies stay null.\n\n**Does search paginate through all Android apps?** No. Search reads the public keyword results exposed by Google, up to your listing limit. Only review collection promises continuation-token pagination.\n\n**Are diagnostics billed?** No. Only useful Dataset rows trigger the single automatic result event. The key-value summary, errors and checkpoint do not produce result events.\n\n**Can I resume a stopped export?** Yes, after a controlled collection limit, time or spending stop. Use CHECKPOINT.input after the earlier run stops. Keep the same collection inputs; do not resume one checkpoint concurrently. Sudden termination has the checkpoint caveat described above.\n\n**Can I schedule daily monitoring?** You can schedule runs through Apify and use dates/IDs in your workflow. A new independent run does not automatically deduplicate against every prior run. Controlled continuation is a separate feature. This Actor does not send external alerts.\n\n**Is this an official Google product?** No. API Vault collects public Google Play data independently and is not affiliated with Google. The generated cover/avatar are illustrative artwork, not platform logos or screenshots of captured customer data.\n\n<!-- new-actor-funnels-20261023:start -->\n## Python client and n8n workflow\n\nUse the thin [Python client](https://github.com/apivault-labs/apivault-labs/tree/main/packages/apivault-google-play-reviews-scraper) or install it from [PyPI](https://pypi.org/project/apivault-google-play-reviews-scraper/):\n\n```bash\npip install apivault-google-play-reviews-scraper==0.1.0\n```\n\nThe client starts this hosted Actor through the Apify API and reads its dataset. An Apify account and your own API token are required. Actor result charges and infrastructure usage follow the current pricing. The client package has no subscription of its own. Set both Actor collection limits and run charge caps; the dataset download limit does not limit paid collection.\n\n[n8n node source and manual workflow](https://github.com/apivault-labs/apivault-labs/tree/main/community-nodes/n8n-nodes-apivault-google-play-reviews-scraper) are available on GitHub. The workflow is inactive and has no embedded credentials. Its Run operation starts a paid Actor run; Read Existing Run reads a previous run without starting another. The [npm package](https://www.npmjs.com/package/n8n-nodes-apivault-google-play-reviews-scraper) is published as version0.1.0. Install `n8n-nodes-apivault-google-play-reviews-scraper@0.1.0` on a self-hosted n8n instance that allows community nodes. npm publication, when approved, does not establish n8n verification or availability in n8n Cloud.\n<!-- new-actor-funnels-20261023:end -->\n",
      "changelog": "# Changelog\n\n## 0.1 candidate — 2026-10-22\n\nReal paginated Google Play reviews, app details, keyword search, useful-row billing, filters, deduplication and account-scoped continuation. Separate product from the historical Apple App Store prototype. Awaiting owner review before publication.\n\n## Private upgrade — 2026-10-22\n\nBatched Dataset writes, 1000-row source pages, compressed checkpoints, free app context and sample insights, multiple-star/reply/keyword/version/helpful-vote filters, richer detail images, direct review links and $0.02/1000 private candidate pricing. Explicit owner prohibition on publication retained.\n\n## Private artwork and README — 2026-10-22\n\nGenerated matching avatar/cover saved privately. Complete product README restructured with measured capacity/costs, filters, examples and Python integration. Apify text edition omits the repository-relative cover until public image hosting is separately authorized. Runtime, schemas and pricing unchanged. No publication.\n\n## Public-ready packaging candidate — 2026-10-22\n\nPinned public README cover, production/latest SDK example and public-ready text. Runtime, schema, price and owner-installed avatar preserved. Awaiting exact final review; not yet public.\n",
      "storages": {
        "dataset": {
          "actorSpecification": 1,
          "fields": {},
          "views": {
            "overview": {
              "title": "Reviews and apps",
              "transformation": {
                "fields": [
                  "recordType",
                  "appId",
                  "title",
                  "appTitle",
                  "developer",
                  "reviewId",
                  "content",
                  "score",
                  "at",
                  "replyContent",
                  "repliedAt",
                  "reviewCreatedVersion",
                  "searchTerm",
                  "searchRank",
                  "country",
                  "language",
                  "url",
                  "scrapedAt"
                ]
              },
              "display": {
                "component": "table",
                "properties": {
                  "recordType": {
                    "label": "recordType",
                    "format": "text"
                  },
                  "appId": {
                    "label": "appId",
                    "format": "text"
                  },
                  "title": {
                    "label": "title",
                    "format": "text"
                  },
                  "reviewId": {
                    "label": "reviewId",
                    "format": "text"
                  },
                  "content": {
                    "label": "content",
                    "format": "text"
                  },
                  "score": {
                    "label": "score",
                    "format": "text"
                  },
                  "at": {
                    "label": "at",
                    "format": "text"
                  },
                  "replyContent": {
                    "label": "replyContent",
                    "format": "text"
                  },
                  "repliedAt": {
                    "label": "repliedAt",
                    "format": "text"
                  },
                  "reviewCreatedVersion": {
                    "label": "reviewCreatedVersion",
                    "format": "text"
                  },
                  "developer": {
                    "label": "developer",
                    "format": "text"
                  },
                  "searchTerm": {
                    "label": "searchTerm",
                    "format": "text"
                  },
                  "searchRank": {
                    "label": "searchRank",
                    "format": "text"
                  },
                  "country": {
                    "label": "country",
                    "format": "text"
                  },
                  "language": {
                    "label": "language",
                    "format": "text"
                  },
                  "url": {
                    "label": "url",
                    "format": "link"
                  },
                  "scrapedAt": {
                    "label": "scrapedAt",
                    "format": "text"
                  },
                  "appTitle": {
                    "label": "appTitle",
                    "format": "text"
                  }
                }
              }
            }
          }
        }
      },
      "output": {
        "actorOutputSchemaVersion": 1,
        "title": "Google Play results and progress",
        "properties": {
          "results": {
            "type": "string",
            "title": "Useful results",
            "template": "{{links.apiDefaultDatasetUrl}}/items"
          },
          "summary": {
            "type": "string",
            "title": "Unpaid diagnostics and counts",
            "template": "{{links.apiDefaultKeyValueStoreUrl}}/records/SUMMARY"
          },
          "checkpoint": {
            "type": "string",
            "title": "Continuation checkpoint",
            "template": "{{links.apiDefaultKeyValueStoreUrl}}/records/CHECKPOINT"
          },
          "insights": {
            "type": "string",
            "title": "Unpaid delivered-sample analysis",
            "template": "{{links.apiDefaultKeyValueStoreUrl}}/records/INSIGHTS"
          },
          "apps": {
            "type": "string",
            "title": "Unpaid review-app context",
            "template": "{{links.apiDefaultKeyValueStoreUrl}}/records/APPS"
          }
        }
      },
      "seoTitle": "Google Play Scraper — Reviews, Replies & App Search",
      "seoDescription": "Export Google Play reviews with ratings, dates, app versions and developer replies. Country/language selection, keyword app search, app details and resumable JSON/CSV exports."
    },
    "buildNumber": "0.3.1",
    "imageDigest": "bcfa99ec1008357fce6eb86ced22544ac9b08f300e57da3fb7a1dd27270b4176",
    "actVersion": {
      "sourceType": "SOURCE_FILES",
      "buildTag": "funnel-ready-20261023",
      "versionNumber": "0.3"
    },
    "usage": {
      "ACTOR_COMPUTE_UNITS": 0.005772222222222222
    }
  }
}