Shopify App Store Scraper: Apps, Reviews & Monitoring
Pricing
$2.00 / 1,000 results
Shopify App Store Scraper: Apps, Reviews & Monitoring
Scrapes apps.shopify.com: app details, pricing plans, exact star counts, reviews past the 10,000 limit with developer replies, category and search rankings with ads, change monitoring between runs, a 0-100 score and an HTML report.
Pricing
$2.00 / 1,000 results
Rating
0.0
(0)
Developer
Sankov Vadim
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a month ago
Last modified
Categories
Security
Limited permissionsShare
Shopify App Store Scraper: Apps, Reviews, Pricing and Rank Monitoring
Shopify App Store Scraper reads apps.shopify.com and returns app details, pricing plans, exact star counts, merchant reviews with developer replies, and category or search rankings. It can also compare each run with the previous one and write an HTML report. One run can mix apps, categories, developers, keywords and the whole sitemap (about 27,600 apps in the catalog).
It is made for app developers, agencies and analysts who need more than a one-off export: who ranks where, what competitors charge, what merchants complain about, and what changed since last week.
Why people run it
Tracking the Shopify App Store by hand does not scale. A category has hundreds of apps. Pricing sits in plan cards. The review page stops at page 1000 when sorted by relevance, so a popular app's history is cut off at 10,000 reviews. Rank is visible only by scrolling and counting.
This Actor puts all of it in one dataset:
- Competitor monitoring: rating, review count, star distribution, pricing and Built for Shopify status, plus a
deltaagainst the previous run. - App market research: every app in a category with price, rating, ad share and a 0-100 score.
- Developer lead lists: support email, website, address and launch date of the developer behind each app.
- Review analysis: merchant reviews by star rating, country and time using the app, with the developer's reply.
Quick start
- Open the Input tab. The prefilled input (two apps, one category, 10 reviews each) is a cheap trial run.
- Click Start. A trial run takes seconds.
- Open the Output tab (views: Overview, Pricing, Reviews, Developer). If you set a Monitor ID, also open the
REPORTrecord in the Key-value store.
To scrape your own targets, paste handles or URLs into Apps, Categories, Developers or Search keywords. A handle is the last part of the URL: https://apps.shopify.com/judgeme becomes judgeme.
What you get
Every dataset row has a recordType: app, review or rank.
app: one row per app
- Core: name, tagline, handle, URL, app ID, icon, full description, feature bullets, screenshots, YouTube videos, demo store URL, languages, "works with" integrations.
- Pricing: pricing summary, every plan (name, price, billing period, free trial days, feature list, usage notes), free-plan and free-trial flags, lowest paid monthly price, currency, link to external pricing.
- Rating: rating, review count and the exact number of reviews per star (the page shows rounded values like "47K", this Actor reads the exact count).
- AI summary: the "What merchants think" summary when the app page has one.
- Status: Built for Shopify badge, awards, categories with their category features, "Featured in" guides, similar apps, the data access the app requests.
- Developer: name, handle, page URL, website, support email, address and launch date.
- Resources: privacy policy, FAQ, tutorial, docs and changelog links.
- Derived by this Actor:
score(0-100),scoreBreakdown,delta,isNewSinceLastRun, andranks(positions where the app was found in this run).
review: one row per merchant review
Review ID, app handle and name, star rating, date, text, store name, store country, "N months using the app" (plus usageMonths as a number), the developer's reply (text, date, author), source page and sort order.
More than 10,000 reviews. Sorted by relevance, the store stops at 10,000 reviews per app. This Actor switches to newest-first, which has no such cap, whenever you ask for all reviews (maxReviewsPerApp = 0) or set Reviews since. Set Only these star ratings to pull, for example, only 1 and 2 star reviews.
rank: one row per app per listing
The category or search keyword the app was found in, position, page, whether the card is a paid Ad placement, rating, review count, Built for Shopify flag, tagline and the total result count of that listing.
Why this Actor
| Capability | What it does |
|---|---|
| Combine modes in one run | Apps, categories, developers, keywords and the sitemap can be used together. An app found by three sources is saved once, with all its rank rows. |
| Change monitoring | Set a Monitor ID and schedule the run. Each app row gets a delta (rating, reviews, star counts, pricing, Built for Shopify, positions) and isNewSinceLastRun. Apps that left the results are listed in OUTPUT and the report. |
| Score 0-100 | A transparent score per app (formula below) to sort a category at a glance. |
| HTML report | A self-contained dashboard in the Key-value store (REPORT): rating vs. reviews map, app table, pricing, Built for Shopify and ad share, changes. |
| Filters before opening apps | Filters are applied to listing cards before an app is opened and again on the full app page, so you do not pay for apps you would discard. |
| Reliability | Automatic retries with backoff, Retry-After respected, concurrency lowered when the store rate-limits, rows saved as they are ready (a timeout keeps what was collected), resume after a migration, and a clean stop when the spending limit is reached. |
| No browser needed | Plain HTTP requests, so runs are fast and light on memory. |
How the score is calculated
score is deterministic and reproducible from the fields in the row (scoreBreakdown shows each part, 0 to 1):
| Component | Weight | Based on |
|---|---|---|
| Rating quality | 30 | rating above 3.0, damped for apps with few reviews |
| Review volume | 15 | log of the review count |
| Recent negatives | 15 | share of 1-2 star reviews in the last 90 days (from collected reviews, otherwise from the star distribution) |
| Developer replies | 10 | share of reviews with a developer reply |
| Built for Shopify | 10 | badge present |
| Activity | 10 | latest review within 30 days (full), within 180 days (half) |
| Price access | 5 | free plan (full), free trial (partial) |
| Ranking position | 5 | best organic position: top 10 (full), top 50 (half) |
A component that cannot be computed is dropped and the rest are re-weighted. If less than half of the total weight is available, score is null. The score is a quick sorting aid, not a verdict on app quality.
Input
All fields are optional, but you need at least one source (Apps, Categories, Developers, Search keywords, or Whole catalog).
| Parameter | Type | Default | Description |
|---|---|---|---|
appHandles | array | prefill: judgeme, klaviyo-email-marketing | App handles or full app URLs. Apps listed here are always opened. |
categoryHandles | array | prefill: one reviews category | Category handles or URLs. Saves one ranking row per app with position, page and Ad flag. |
developerHandles | array | empty | Developer (partner) handles or URLs. Collects all apps of the developer. |
searchQueries | array | empty | Keywords to search in the App Store; positions and ads are saved as ranking rows. Optional, see FAQ. |
allAppsFromSitemap | boolean | false | Take every app in the store sitemap (about 27,600). Combine with Max apps and filters to control cost. |
sitemapLastmodSince | string (date) | empty | With the sitemap source: only apps whose sitemap lastmod is on or after this date. Useful for incremental runs. |
scrapeAppDetails | boolean | true (prefill false) | On: every app found in a listing is opened and saved with full details. Off: only cheap ranking rows are saved. |
maxApps | integer | 100 | Maximum number of app rows per run. 0 = no limit. |
maxCategoryPages | integer | 5 (prefill 1) | Pages per category (about 20 apps plus ads per page). 0 = all pages. |
maxSearchPages | integer | 3 | Pages per keyword (about 24 apps plus ads per page). 0 = all pages. |
maxDeveloperPages | integer | 10 | Pages per developer. 0 = all pages. |
minRating | string | empty | Keep apps rated at least this (for example 4.5). |
minReviews | integer | empty | Keep apps with at least this many reviews. |
maxReviews | integer | empty | Keep apps with at most this many reviews. Finds small or new competitors. |
pricingFilter | string | any | any, free (completely free), freePlan, freeTrial, paidOnly (no free plan). |
builtForShopifyOnly | boolean | false | Keep only apps with the Built for Shopify badge. |
requireCategories | array | empty | Keep apps listed in at least one of these categories (handle or name, for example SEO). |
excludeAds | boolean | false | Ignore paid (Ad) placements in category and search results. |
includeReviews | boolean | false (prefill true) | Collect reviews for every app that passes the filters. |
maxReviewsPerApp | integer | 100 (prefill 10) | 0 = all reviews (switches to newest-first, past the 10,000 limit). |
reviewRatings | array | empty | Only these star ratings (1-5). Empty = all. |
reviewsSince | string (date) | empty | Only reviews on or after this date; collection stops at the first older review. |
reviewSort | string | newest | newest or relevance. Relevance stops at 10,000 reviews; newest is used automatically when you need more or set a date. |
reviewsOutput | string | rows | rows = one dataset row per review. embedded = up to 200 reviews inside the app row. |
monitorId | string | empty | Any name (letters, digits, dashes, up to 40). Use the same ID on every scheduled run to get delta. |
generateReport | boolean | true | Save the HTML report as REPORT in the Key-value store. |
maxConcurrency | integer | 10 | Parallel requests, 1-50. Lowered automatically when the store rate-limits. |
proxyConfiguration | object | no proxy | Not needed for small runs. For whole-catalog runs a datacenter proxy is enough. If the proxy fails, the run continues without it. |
locale | string | en | Language code of the store pages, for example en, de, fr, es, ja. |
Example input
{"categoryHandles": ["marketing-and-conversion-social-trust-product-reviews"],"maxCategoryPages": 2,"scrapeAppDetails": true,"builtForShopifyOnly": true,"includeReviews": true,"maxReviewsPerApp": 50,"reviewRatings": ["1", "2"],"monitorId": "reviews-category-weekly"}
Output fields
app
| Field | Type | Description |
|---|---|---|
recordType | string | app |
handle, url, appId | string | Handle, app page URL and the store's internal app ID. |
name, tagline, shortDescription, iconUrl | string | Title and texts as shown in the store. |
description, features | string / array | Full description and feature bullets. |
screenshots, videos, demoStoreUrl | array / string | Screenshot URLs, YouTube videos (youtubeId, url) and the demo store link. |
languages, worksWith | array | Supported languages and integrations. |
categories | array | Each with handle, name and features (handle, name, group). |
featuredIn, awards, dataAccess | array | Guides that feature the app, awards, and the data-access groups the app requests. |
builtForShopify | boolean | Built for Shopify badge. |
rating, reviewsCount | number | Overall rating and total reviews. |
ratingDistribution | object | Exact count per star: keys "5" to "1". |
aiReviewSummary | string / null | The store's "What merchants think" text. null when the page has none. |
latestReviews | array | The few recent reviews shown on the app page. |
pricingSummary, pricingNote | string | Summary line and the billing note from the pricing section. |
hasFreePlan, hasFreeTrial | boolean | Derived from the plans and the summary. |
lowestPaidPrice, currency | number / string | Lowest paid plan price per month, and its currency. |
externalPricingUrl | string / null | Link when full pricing lives on the developer's site. |
pricingPlans | array | Per plan: name, price, priceText, billingPeriod, yearlyPrice, trialDays, features, usageNote, isFree. |
developer | object | name, handle, url, website, supportEmail, address, launchedAt (ISO date), appsCount, otherApps. |
resources | object | privacyPolicy, faq, tutorial, docs, changelog (only the links the page has). |
similarApps | array | "More apps like this": handle, name, icon, rating, reviews, pricing summary, tagline, Built for Shopify. |
ranks | array | Where the app appeared in this run: source, key, position, page, isAd. |
reviews | array | Only with reviewsOutput = embedded: up to 200 reviews. |
locale, scrapedAt, isAvailable | string / boolean | Store language, extraction time (ISO 8601), availability. |
score, scoreBreakdown | number / object | Derived, see the formula above. |
delta | object / null | Derived. Changed fields as {old, new} among rating, reviews count, star distribution, pricing (a hash of the plans), lowest paid price, Built for Shopify, non-ad positions and availability, plus reviewsGained and ratingChange. null on the first run of a Monitor ID or when no Monitor ID is set. |
isNewSinceLastRun | boolean / null | Derived. true when the app was not in the previous snapshot. null without a baseline. |
review
| Field | Type | Description |
|---|---|---|
recordType | string | review |
reviewId, appHandle, appName | string | Review ID and the app it belongs to. |
rating | integer | 1-5 stars. |
date | string | ISO date of the review. |
text | string / null | Review text. Some reviews are star-only, and then this is null. |
storeName, storeCountry | string | Merchant's store and country. |
usageDuration, usageMonths | string / integer | Text such as "About 1 month using the app" and the same as a number of months. |
developerReply | object / null | text, date, author. |
page, sort, scrapedAt | mixed | Source page, sort order and extraction time. |
rank
| Field | Type | Description |
|---|---|---|
recordType | string | rank |
source, key | string | category or search, and the category handle or keyword. |
position | integer / null | Position among organic results. null for paid Ad placements. |
page, surfaceIntraPosition | integer | Page number and the position inside the listing page. |
isAd | boolean | Paid placement flag. |
handle, name, url, iconUrl, tagline | string | App identity from the card. |
rating, reviewsCount, pricingSummary, builtForShopify | mixed | Card data. Rating and reviews can be null for new apps. |
totalResults | integer | Total apps in that category or search. |
scrapedAt | string | Extraction time (ISO 8601). |
Deliberate omissions
- Empty means not on the page. A field the page does not show is
null(or an empty list). The Actor does not guess or fill gaps from other sources. - No currency conversion. Prices stay in the currency the store shows, with
currencynext to them. - No invented positions. Ad placements have
position: null, so ads never shift organic positions and the score ignores them. - No reviews for apps that did not pass your filters.
- Disappeared apps are not dataset rows. Apps that left the results since the last run are listed in
OUTPUTand the report, so you are not charged for an absence. - Developer
appsCountandotherAppsare filled only when the developer page was read in the same run (for example with Developers). Otherwise they stay empty.
Example rows
An app row from a trial run (long texts shortened, lists cut):
{"recordType": "app","handle": "klaviyo-email-marketing","url": "https://apps.shopify.com/klaviyo-email-marketing","name": "Klaviyo: Email Marketing & SMS","tagline": "Build email marketing, SMS, and WhatsApp campaigns powered by AI to grow ecommerce sales.","builtForShopify": false,"rating": 4.7,"reviewsCount": 3346,"ratingDistribution": { "5": 2933, "4": 83, "3": 31, "2": 37, "1": 262 },"pricingSummary": "Free to install","hasFreePlan": true,"hasFreeTrial": false,"lowestPaidPrice": 15.0,"currency": "USD","pricingPlans": [{ "name": "Free", "price": null, "priceText": "Free to install", "isFree": true, "trialDays": null },{ "name": "SMS", "price": 15.0, "priceText": "$15/month", "billingPeriod": "month", "isFree": false }],"developer": {"name": "Klaviyo","handle": "klaviyo","website": "https://developers.klaviyo.com/en","supportEmail": "support@klaviyo.com","address": "125 Summer St, Floor 7, Boston, MA, 02111, US","launchedAt": "2012-09-20"},"languages": ["English", "French", "Spanish", "German"],"scrapedAt": "2026-10-03T09:05:58+00:00","ranks": [],"score": 77,"scoreBreakdown": { "ratingQuality": 0.85, "volume": 0.881, "recentNegative": 0.8, "developerReplies": 0.7, "builtForShopify": 0.0, "activity": 1.0, "priceAccess": 1.0, "position": null, "weightUsed": 95 },"delta": null,"isNewSinceLastRun": null}
A review row with a developer reply:
{"recordType": "review","reviewId": "2381422","appHandle": "klaviyo-email-marketing","appName": "Klaviyo: Email Marketing & SMS","rating": 5,"date": "2026-10-01","text": null,"storeName": "CAAM.COM","storeCountry": "Chile","usageDuration": "About 1 month using the app","usageMonths": 1,"developerReply": { "text": "Thank you for the positive review!", "date": "2026-10-02", "author": "Klaviyo" },"sort": "newest"}
Monitoring and the HTML report
Give every scheduled run the same Monitor ID. The Actor keeps a snapshot in a named Key-value store (shopify-monitor-<id>) and merges into it on each run, so a partial run does not erase history.
- Each app row carries
deltaandisNewSinceLastRun. OUTPUTlistsdisappearedapps: ones that were in the snapshot for the same set of sources and are no longer found.OUTPUTalso holds run counts, listing totals, request and retry counts, andfieldCoverage(the share of app rows where each field was filled), so a layout change on the store shows up as a drop in coverage.
The REPORT record is one self-contained HTML file with the data embedded: rating vs. review-count map, app table, pricing overview, Built for Shopify and ad share, and changes since the previous run. Text taken from the store is escaped in the report.
Use cases
- App developer tracking competitors. Schedule your category weekly with a Monitor ID. Watch
deltafor price changes, new plans, Built for Shopify gains and rating drops. - Agency choosing apps for clients. Filter a category by
minRating,pricingFilterandbuiltForShopifyOnly, then sort byscore. - Founder doing market research. Use
maxReviewsto find small, new apps in a crowded category, and read their pricing plans. - Product team mining complaints. Collect 1 and 2 star reviews with
reviewRatings, then read the text, country and usage time next to the developer reply. - Partner or lead sourcing. Export developer name, website, support email, address and launch date for apps in a niche.
- Ad and placement analysis. Compare Ad and organic placements per category or keyword with
isAd, and track your own position week over week.
Pricing
Pay per event. See the Pricing tab of this Actor for the current price. Dataset rows (app, review and rank) are the billable results. Use Max apps and Max reviews per app to cap a run. The Actor stops cleanly when your spending limit is reached, and everything saved before that stays in the dataset.
Cost tips: scrapeAppDetails = false saves only the cheap ranking rows; listing filters are applied before an app is opened; reviewsOutput = embedded puts up to 200 reviews inside the app row.
FAQ
Is search by keyword on by default?
No, it is an optional extra. The store's robots.txt asks crawlers not to fetch search pages, so Search keywords is empty by default and you decide whether to use it. Apps, categories, developers and the sitemap work without it.
Do I need a proxy? Not for small and medium runs. For whole-catalog runs a datacenter proxy is enough. If the proxy fails, the run continues without it instead of failing.
How much does a run cost and how long does it take? It depends on the rows saved. The trial input finishes in a few seconds. An app page is one request and reviews come 10 per request, so collecting all reviews of a large app takes many requests. Use Max reviews per app to bound it.
Why is a field empty?
Empty means the app page does not show it. Examples: aiReviewSummary is null for apps without that block, rating can be empty for brand-new apps, and delta is null until the second run of a Monitor ID.
Why is position empty on some rank rows?
Those rows are paid Ad placements. They keep isAd: true and have no organic position.
Can I get all reviews of an app with more than 10,000 reviews?
Yes. Set maxReviewsPerApp to 0 (or set Reviews since). Newest-first order has no 10,000 cap.
Can I run it on a schedule? Yes. Use Apify Schedules with the same Monitor ID.
Which store language is used?
locale (default en).
Limits
- Very large volumes (the whole catalog, or all reviews of many large apps) may need a proxy. Behaviour on thousands of requests from a single IP has not been tested.
- The store changes its page layout from time to time. The parser relies on stable attributes and section labels, and a missing field returns
nullinstead of failing the run, but a redesign can reduce coverage until the Actor is updated. CheckfieldCoverageinOUTPUT. - The "What merchants think" summary exists only for some apps.
- How deep a category can be paged was not verified.
- Whether
localechanges the content itself and not only the interface labels was not verified. - The score is a heuristic. Use it to sort, not to decide.
Legal and responsible use
This Actor collects only publicly visible pages of the Shopify App Store. It does not log in and does not access merchant accounts. Developer contact details are those the developers publish on their app pages; you are responsible for using them in line with applicable law (including data protection and e-mail marketing rules) and with the store's terms. This is an independent tool and is not affiliated with or endorsed by Shopify.
Changelog
- 0.1 (2026-10-03): first release. Apps, reviews, rankings, sitemap source, filters, change monitoring, score and HTML report.
Support
Found a bug or a field that comes back empty? Open an issue from the Actor page in Apify Console and include the run link and the app handle.