Apple App Store Reviews Scraper | iOS & Mac avatar

Apple App Store Reviews Scraper | iOS & Mac

Pricing

from $0.05 / 1,000 review delivereds

Go to Apify Store
Apple App Store Reviews Scraper | iOS & Mac

Apple App Store Reviews Scraper | iOS & Mac

Collect iOS and Mac App Store reviews across countries. Export ratings, review text, dates and developer replies where available. Filter by date, deduplicate results and schedule product-feedback monitoring.

Pricing

from $0.05 / 1,000 review delivereds

Rating

0.0

(0)

Developer

tingyou333 zhuang

tingyou333 zhuang

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

16 hours ago

Last modified

Categories

Share

Collect iOS and Mac App Store reviews for product feedback, ASO and release monitoring. Export review text, ratings, dates, reviewed versions and source context across multiple storefronts.

Quick start · Workflows · Pricing · Input reference · Output reference · API and automation · FAQ · Technical reference

What you can do

  • One app or a portfolio — Use app IDs, store URLs or the app-name compatibility input.
  • iOS and Mac coverage — Choose the source and platform explicitly; archive mode supports deeper pagination where available.
  • Useful review context — Retain ratings, text, dates, reviewed versions and helpfulness data exposed by Apple.
  • Budget and quality controls — Set global and per-storefront limits; inspect source metadata instead of assuming the requested history was complete.

Who uses it

  • Product teams: organize complaints and requests by app version.
  • ASO and research teams: compare ratings and written feedback across country storefronts.
  • Data teams: feed scheduled review exports into a warehouse or an external sentiment-analysis workflow.

Quick start

  1. Open Input, enter your target and a small result limit.
  2. Click Start and inspect the dataset and run log.
  3. Export JSON/CSV, or save the input as a Task for recurring runs.
{
"appIds": [
"389801252"
],
"country": "us",
"sourceMode": "archive",
"maxItems": 20
}

Form prefills, schema defaults and empty API input can differ. Use explicit targets and limits; see the technical reference for source and default behavior.

Countries and storefront coverage

us is a default, not the only supported storefront. Use country for one storefront, or countries for multiple storefronts. A nonempty countries list takes precedence.

Archive and Mac routing now includes 175 storefronts, using Apple's public storefront selector. The Input form lists country names and codes, with multi-selection through countries. Examples include us, gb, cn, jp, sg, nl and za.

A September 9, 2026 source check retrieved one iOS archive review from each of the 175 storefronts for app 389801252, with distinct review IDs. This is a small-sample routing check, not a guarantee of every app, full history, every metadata field or every Mac storefront. App availability and source responses still determine results.

Country selects the review storefront, not a translation language. RSS retains its ceiling of 500 recent reviews per app/storefront. Archive scans use their configured caps and may have incomplete history.

Import an existing configuration

Choose wolvesInput for The Wolves inputs or johnvcInput for the Apple App Store Reviews API inputs. Paste the original JSON object inside the selected field. Keep all overrides inside that object; do not mix it with outer native settings. This preserves the selected reference's defaults without interference from the form's native defaults. Existing top-level inputs remain supported.

{"wolvesInput": {"appIds": ["389801252"], "country": "sg", "maxItems": 20}}

Import compatibility covers documented input contracts, not a promise of identical source availability or output metadata. Select the documented output schema separately when needed.

Common workflows

Compare two storefronts

{
"appIds": [
"389801252"
],
"countries": [
"us",
"gb"
],
"sourceMode": "archive",
"maxItems": 40
}

Collect Mac app reviews

{
"appIds": [
"497799835"
],
"platform": "mac",
"sourceMode": "archive",
"maxItems": 20
}

Filter critical feedback

{
"appIds": [
"389801252"
],
"country": "us",
"ratings": [
"1",
"2"
],
"maxItems": 20
}

Output at a glance

Illustrative field subset below; these are example values, not a captured customer review or a claim about source coverage. Native and compatibility output profiles can differ.

{
"appId": "389801252",
"id": "example-review-id",
"score": 4,
"title": "Example review",
"text": "Example feedback used to illustrate the output format.",
"version": "1.2.0",
"country": "us",
"coverage": "complete"
}

RSS covers up to 500 recent reviews per app/storefront. Archive coverage is source-dependent and configured for 175 storefronts; a larger limit does not guarantee a complete historical archive. Some fields, including developer replies, may be absent. See the source reference below.

Pricing

Pay per delivered event, with automatic discounts based on your Apify subscription plan. These are result fees in USD, not separate subscriptions sold by this Actor. All tiers have the same Actor features. Apify compute, storage, transfers and any proxy usage are charged additionally.

Billable event (1,000 events)FreeStarterScaleBusiness
Review delivered$0.08$0.07$0.06$0.05

Platinum and Diamond currently use the Business rate. The Pricing tab is the source of truth for the active schedule and your applicable plan.

  • Review delivered: One delivered review after filtering and output mapping. Error rows have no result fee. Apify platform usage is additional.

Example on the Free plan: 10 / 1,000 / 10,000 events cost $0.0008 / $0.08 / $0.8 in result fees, plus platform usage.

There is no additional developer setup or monthly rental fee. A run with no billable results can still consume platform resources. Start small, cap results and review run costs before scheduling a larger workload. Requested counts are ceilings, not guaranteed deliveries.

Input reference

Fields below are grouped like the Input form. Optional fields need not be supplied. Compatibility input envelopes and transformations are explained in the technical reference.

Targets and collection

FieldTypeDefaultMeaning
appIdsarrayNot setNumeric Apple App Store IDs, without the id prefix.
product_idsarrayNot setCompatibility alias for callers using product_ids.
startUrlsarrayNot setApple App Store application URLs. The app ID and storefront country are parsed automatically.
app_namestringNot setOptional app name to resolve through Apple's public Search API when no exact ID is available.
countrystring"us"Select one of 175 Apple storefronts. us is only the default. Archive and Mac requests use the official Apple storefront ID for the selected country; actual reviews depend on app/source availability. Custom two-letter codes are accepted for RSS. A nonempty countries list overrides this field.
countriesarrayNot setSelect multiple storefronts in one run. Overrides country. All 175 listed storefronts have Apple source mappings; an app may have no reviews in a selected market. Custom codes remain accepted for RSS.
start_pageinteger1Page index/count. RSS ceiling 10; archive ceiling 2000, 25 reviews per page.
sincestringNot setOptional ISO date or timestamp. Useful for scheduled incremental monitoring.
deduplicateReviewsbooleantrueDeduplicate by app ID, country and Apple review ID.
requestDelayMillisinteger500Spacing between pages inside one app/country task. Defaults to 500 ms to reduce bursts on long archive scans; set 0 explicitly to disable.
sourceModestring"auto"RSS uses 50-row pages; iOS archive uses 25-row pages; Mac HTML uses native 10-row pages. Product IDs support automatic platform detection.
platformstring"auto"Automatically identify each product, or explicitly select iOS / Mac. Explicit selection takes precedence over detection.
includeSourceMetadatabooleantrueFor archive mode, make one extra metadata lookup per app/storefront for written-review and rating totals. Counts are unfiltered; derived page count is not an accessibility guarantee.
includeReviewVersionsbooleantrueFor archive pages, join public XML version metadata by review ID and matching text. Adds one public request per page; failures retain the review and an explicit warning.
include_macosbooleantrueDetect app platform and skip Mac apps when false. Explicit platform remains authoritative.
parse_helpfulnessbooleantrueInclude helpful_count and total_helpful_count when present in the public source.
output_filestringNot setLocal testing only: save a delivered-result JSON copy under storage/local_exports. Use a simple .json filename. Existing files are never overwritten. Ignored completely on Apify cloud; auto-generated locally if blank.

Filters and ordering

FieldTypeDefaultMeaning
sortstring"mostrecent"Source-native Apple review sort. mostrecent and mosthelpful are verified public-feed modes.
ratingsarrayNot setOptional star ratings to keep after source retrieval, for example ["1","2"] for negative reviews.
sort_orderstringNot set1 helpful, 2 favorable, 3 critical, 4 recent.
normalize_datesbooleantrueInclude review_date_iso in johnvc-compatible output.

Result limits and cost

FieldTypeDefaultMeaning
maxItemsintegerNot setOptional global cap across all app/country combinations. Leave blank to derive the total budget from the per-app/storefront quota and task count for compatibility inputs (product_ids, app_name or max_reviews); native inputs default to 1000 at runtime. An explicitly supplied value takes precedence over the automatic budget.
maxReviewsPerAppCountryintegerNot setPer app/country cap. RSS source ceiling is 500; archive ceiling is 50000.
maxPagesintegerNot setMaximum native pages per app and country. Omit to derive the Mac/automatic budget from the requested review count; explicit limits take precedence.
maxRequestRetriesinteger2Retries for transient Apple HTTP failures.
max_reviewsintegerNot setAlias per app/country cap; zero uses selected source ceiling. maxItems remains the global cap.

Compatibility and transformations

FieldTypeDefaultMeaning
customMapFunctionstringNot setJavaScript function applied after output formatting to each review. Must return one JSON object. Isolated runtime with no network, file system or Python access; 50ms CPU and 16MB per row, 10s total. Not a filter.
outputSchemastring"extended"Explicit migration format. Missing source values stay null; extended preserves diagnostics.

Connection and advanced settings

FieldTypeDefaultMeaning
maxConcurrencyinteger8Maximum app/country combinations fetched concurrently.

Additional compatibility options

FieldTypeDefaultMeaning
wolvesInputobjectNot setPaste the complete competitor input JSON here to preserve its field types and defaults. Put all options inside this object. This is optional; normal native inputs remain available.
johnvcInputobjectNot setPaste the complete competitor input JSON here to preserve its field types and defaults. Put all options inside this object. This is optional; normal native inputs remain available.

Output reference

The table describes native fields; fields can be absent or null when the source does not provide them. Error rows and selected compatibility profiles have different shapes. Nested objects remain structured in JSON; CSV exports may serialize them.

FieldTypeMeaning
parentIdstringCompatibility field; Apple review identifier when no separate parent is exposed.
idstringUnique Apple review identifier.
date['string', 'null']Review publication timestamp from Apple.
userName['string', 'null']Reviewer display name.
userUrl['string', 'null']Public iTunes reviewer URL when exposed.
version['string', 'null']App version reviewed.
scoreintegerStar rating from 1 to 5.
title['string', 'null']Review headline.
textstringFull review body.
url['string', 'null']Public iTunes review URL.
countrystringReview storefront code, e.g. sg; not a translation language.
appIdstringNumeric App Store application ID.
voteCount['integer', 'null']Apple im:voteCount value.
voteSum['integer', 'null']Apple im:voteSum value.
sourcePageintegerPage number within the selected source: RSS has 50 rows/page, archive has 25.
sortOrderstringApple source sort used for retrieval.
retrievalMethodstringPublic Apple source path.
coveragestringCompleteness classification for the review row.
scrapedAtstringUTC extraction timestamp.
sourcePosition['integer', 'null']sourcePosition
sourceReviewCount['integer', 'null']sourceReviewCount
sourceRatingCount['integer', 'null']sourceRatingCount
sourceTotalPages['integer', 'null']sourceTotalPages
sourceMetadataStatus['string', 'null']sourceMetadataStatus
sourceTotalPagesBasis['string', 'null']sourceTotalPagesBasis
sourceMetadataUrl['string', 'null']sourceMetadataUrl
sourceMetadataCountry['string', 'null']sourceMetadataCountry
sourceMetadataFetchedAt['string', 'null']sourceMetadataFetchedAt
sourceMetadataWarning['string', 'null']sourceMetadataWarning
sourceMetadataError['string', 'null']sourceMetadataError

API and automation

The API tab provides snippets for this Actor. For scheduled or larger collections, start a run asynchronously and poll its status instead of holding a synchronous request open. Keep your API token in an environment variable.

import os, time, requests
base = "https://api.apify.com/v2"
headers = {"Authorization": "Bearer " + os.environ["APIFY_TOKEN"]}
actor_input = {'appIds': ['389801252'], 'country': 'us', 'sourceMode': 'archive', 'maxItems': 20}
response = requests.post(
base + "/acts/5eWGsOTxIbgRUYZS5/runs",
headers=headers, json=actor_input, timeout=30,
)
response.raise_for_status()
run = response.json()["data"]
for _ in range(720):
if run["status"] not in ("READY", "RUNNING", "TIMING-OUT", "ABORTING"):
break
time.sleep(5)
response = requests.get(base + "/actor-runs/" + run["id"], headers=headers, timeout=30)
response.raise_for_status()
run = response.json()["data"]
else:
raise TimeoutError("Polling ended; inspect the existing run before starting another.")
if run["status"] != "SUCCEEDED":
raise RuntimeError(run.get("statusMessage", run["status"]))
response = requests.get(
base + "/datasets/" + run["defaultDatasetId"] + "/items",
headers=headers, params={"format": "json", "limit": 1000, "offset": 0}, timeout=30,
)
response.raise_for_status()
rows = response.json()
print(rows) # Paginate with offset for larger datasets; inspect per-row coverage.

Scheduled monitoring and integrations

  1. Save a working input as an Apify Task.
  2. Attach a Schedule in your timezone; keep runs sharing an incremental state key sequential.
  3. Add a successful-run webhook or connect your downstream workflow to the dataset export/API.
  4. Inspect missing/partial data before sending alerts or treating absence as removal.

Use the platform Integrations/API options to connect external workflows such as Make, n8n or a data warehouse. An external sentiment or summarization step is separate from this Actor and may have its own charges. The platform also supports Actor tools through Apify MCP; availability and client setup depend on your integration.

FAQ

How do I find an app ID?

Use the digits after id in an App Store URL. For example, id389801252 becomes 389801252.

Can I retrieve every historical review?

No complete-history guarantee is made. Choose archive mode for supported deeper pages and inspect source coverage, limits and pagination stop reasons.

Are sentiment labels included?

Review text can be exported to an AI workflow. This Actor does not promise a built-in sentiment model.

Can I export without writing code?

Yes. Run from the Input form, open the dataset and use the export controls for JSON or CSV. Select your preferred output profile before running when migrating an integration.

Does a successful run guarantee every field?

No. Inspect coverage, warnings and source-specific status fields. Optional enrichment may be missing even when usable rows were delivered.

Troubleshooting

SymptomWhat to check
Empty datasetValidate the target, source availability and filters; try the small quick-start input.
Fewer rows than requestedCheck source limits, pagination and filtering. Increasing a cap cannot create unavailable source records.
Partial fieldsInspect coverage/warnings and the relevant source or enrichment status.
Access or throttling errorsCheck the run log and documented proxy configuration; retry at a lower request volume.
Migration mismatchCheck the explicit input/output profile and technical field mapping below.
Unexpected billSeparate result events from platform resources; inspect enrichment, result caps and the Pricing tab.

Technical reference

Migration-friendly inputs

Existing callers can continue using the common appIds, country, startUrls, and maxItems fields. The Actor also accepts product_ids and app_name for compatibility with another established App Store review API.

Exact targets from product_ids, appIds, or startUrls take precedence over app_name: name resolution runs only when there are no exact targets. A supplied name never adds another app to an explicit target list.

For compatibility inputs (product_ids, app_name, or max_reviews), omitting maxItems derives the total budget from the per-app/storefront quota and the number of app/storefront tasks. For example, two IDs with max_reviews: 600 receive a total budget of 1200, up to 600 each. Explicit maxItems retains the global cap. Native inputs without those compatibility fields retain the default global limit of 1000. Source/page limits still apply. The form leaves maxItems blank (no default or prefill), so automatic budgeting can apply. Remove a saved maxItems value from older inputs to use the derived budget; a value already present in the input is treated as explicit.

Extensions include:

  • countries: fetch several App Store storefronts in one run.
  • sort: Apple-native mostrecent or mosthelpful order.
  • ratings: keep selected star ratings, such as [1, 2] for complaint monitoring.
  • since: scheduled incremental collection by ISO date/time.
  • start_page and maxPages: resumable bounded pagination.
  • voteCount / voteSum, page number, retrieval method, and explicit coverage metadata on every row.

The RSS source exposes up to 50 reviews per page and 10 pages per app/storefront (500 reviews). Archive pagination has separate limits described below.

Example

{
"appIds": ["389801252"],
"countries": ["us", "gb", "ca"],
"sort": "mostrecent",
"ratings": ["1", "2"],
"since": "2026-09-01",
"maxItems": 1000
}

Each review preserves the familiar 12-field shape (parentId, id, date, userName, userUrl, version, score, title, text, url, country, appId) and adds source telemetry without breaking those fields.

Result limits and pagination

maxItems is a maximum, not a guaranteed count. Apple may return an empty page before that limit. SOURCE_DIAGNOSTICS records each task's stopReason, page count, and duplicatesSuppressed; OUTPUT.warnings reports early empty-page termination. Deduplication occurs before a page task counts unique rows toward its limit. No complete historical review archive is promised.

RSS fallback and compatibility

An empty explicit first RSS page is retried through the public default first-page endpoint. Later pages are never replaced with page one. max_reviews aliases the per-app/storefront limit; zero uses the selected source ceiling (RSS 500; archive bounded at 50,000). maxItems is the global cap. Select outputSchema=johnvc for that field layout. Archive mode supports deep pagination, Mac reviews and favorable/critical sorting.

Output profiles and custom JavaScript

The default outputSchema=extended preserves the existing output. Apple supports wolves and johnvc. These are explicit field projections, not a guarantee of identical source pagination or data availability. Missing source fields remain null.

customMapFunction runs after output projection and before delivery. Example: (row) => ({...row, exported: true}). It must synchronously return one JSON object per row. Async functions, filtering and non-object results fail the run before delivery. Each row has 50 ms CPU, 16 MB memory and 256 KB stack limits; total mapping budget is 10 seconds. The interpreter has no network, filesystem or host callbacks.

Archive source

sourceMode=archive uses 25-row iOS pages and 10-row Mac pages. iOS start_page=21 starts at offset 500. Archive traversal is bounded by 2,000 pages and 50,000 reviews per app/storefront, subject to source availability; Mac page size imposes a lower attainable page-bound total. sourceMode=auto selects archive for platform detection, Mac, a start page above 10, favorable/critical sorting, or a per-app quota above 500. Increasing only global maxItems does not force archive. RSS and archive page numbers differ.

Archive storefronts: the 175 named options in Input, sourced from Apple’s public country selector. Unconfigured storefronts fail explicitly. Archive rows may omit reviewed version and total page counts; these remain null. Source rows, identity, rating and review body are preserved; no complete-history guarantee.

Archive requests use each storefront's default language; they do not force US English onto other countries. The country code still selects the review storefront.

Archive totals and migration positions

Archive mode defaults to includeSourceMetadata=true, which performs an extra public storefront metadata lookup for each app/country task. It verifies app and platform identity. sourceReviewCount is written reviews; sourceRatingCount includes ratings and must not be used as the written-review count. sourceTotalPages uses the source written-review count and native page size (25 for iOS archive, 10 for Mac). It does not prove every page is accessible; configured page and result ceilings still apply. Counts are not adjusted for local date/rating filters. Disable the option to avoid the metadata lookup.

Metadata failure retains review rows and reports sourceMetadataStatus=failed in rows and source diagnostics. Historical reviewed versions and current-version review counts remain unknown unless provided by a reliable source.

For outputSchema=johnvc, position_on_page follows the reference's source-offset convention: iOS archive page 21 starts at 501. position_global remains the emitted row number. The extended format retains true within-page positionOnPage plus absolute sourcePosition. The display date is formatted in English from the source timestamp when no source display date is provided.

Historical review versions

Archive mode now enables includeReviewVersions by default. Each page joins Apple public XML metadata by review ID and matching text, recovering the actual reviewed version and current-version review count. Explicit pagination supports thousands separators (74,021 remains 74021). This adds one public request per page. Disable it to reduce requests. Unmatched or unavailable metadata stays unknown with a warning; application release dates are never used to guess a reviewed version. Source page counts do not guarantee all pages can be retrieved.

The johnvc compatibility output collapses whitespace in titles and review bodies to match that interface; extended preserves source line breaks. Verified XML locales: US, GB, CN, JP, DE, FR, CA, AU, IN, KR, TW, HK, IT, ES, BR and MX. Version labels and pagination are parsed in the source locale. Missing source counts (such as the Japanese current-version [?] placeholder) remain unknown. Mac reviews use their public HTML endpoint, with native 10-row pages and per-review versions. Product IDs are platform-detected; include_macos=false skips Mac applications.

Mac compatibility

Mac comments use native ten-row HTML pagination and per-review version metadata. johnvc outputs app_platform=macos and reviewed_version=v...; normalize_dates and parse_helpfulness are supported. Source day-only dates carry datePrecision=day in extended output. Mac sorting is sent to the source and returned sort/page are validated. Unavailable current-version totals remain null.

Automatic platform detection derives the native-page budget from the requested review count when maxPages is omitted; Mac pages contain ten reviews. An explicit maxPages still limits the scan. A per-app review quota above 500 selects archive in auto mode; global maxItems alone does not. actualRetrievalMethods and actualPlatforms in OUTPUT identify the sources that actually delivered rows. A Mac current-version review count is left unavailable unless independently established; it is not inferred from the app's overall rating count.

output_file is a local-only JSON export option for delivered rows. Blank names are generated automatically and existing files are never overwritten. Cloud runs ignore this option; retrieve cloud results from the run dataset.

Long scans default to 500 ms between pages within each app/country task (requestDelayMillis=0 explicitly disables spacing). Mac pagination follows the declared last page, including short intermediate pages. An isolated failed request is recorded in SOURCE_DIAGNOSTICS.tasks[].sourceMetadata.failedPages and later declared pages are still attempted; three consecutive failures stop the task. Any missing page makes the task report an error, and already collected reviews remain available. Use start_page to resume a known range. Retry counts include exhausted requests.

After a complete unfiltered Mac traversal from page 1 through the declared last page, with continuous positions, no missing pages, no duplicate IDs and all review versions available, the Actor can compute the observed written-review count for the current version returned by Apple lookup. currentVersionReviewCountBasis explicitly identifies this calculation. The johnvc profile adds reviews_for_current_version_basis and current_app_version when this count is computed. Partial/filtered scans never extrapolate totals, and rating counts are never substituted for written reviews. Lookup failure preserves all comments and the known traversed count but leaves the version-specific count unavailable.

Support

Open an issue from this Actor’s Issues tab with the run ID, expected result and a redacted input. Do not include tokens, cookies or private credentials. Include the output profile and affected field when reporting a migration mismatch.

Presentation update

The current listing adds workflow examples, grouped input documentation, output-field explanations and plan-based result discounts. Source-specific limitations above still apply. This is an independent tool and is not affiliated with the source platform.