# Shopify App Store Scraper: Apps, Reviews & Monitoring (`solalab_digital/shopify-app-store-scraper`) Actor

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.

- **URL**: https://apify.com/solalab_digital/shopify-app-store-scraper.md
- **Developed by:** [Sankov Vadim](https://apify.com/solalab_digital) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## 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 `delta` against 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

1. Open the **Input** tab. The prefilled input (two apps, one category, 10 reviews each) is a cheap trial run.
2. Click **Start**. A trial run takes seconds.
3. Open the **Output** tab (views: Overview, Pricing, Reviews, Developer). If you set a Monitor ID, also open the `REPORT` record 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`, and `ranks` (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

```json
{
  "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 `currency` next 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 `OUTPUT` and the report, so you are not charged for an absence.
- **Developer `appsCount` and `otherApps`** are 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):

```json
{
  "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:

```json
{
  "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 `delta` and `isNewSinceLastRun`.
- `OUTPUT` lists `disappeared` apps: ones that were in the snapshot for the same set of sources and are no longer found.
- `OUTPUT` also holds run counts, listing totals, request and retry counts, and `fieldCoverage` (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 `delta` for price changes, new plans, Built for Shopify gains and rating drops.
- **Agency choosing apps for clients.** Filter a category by `minRating`, `pricingFilter` and `builtForShopifyOnly`, then sort by `score`.
- **Founder doing market research.** Use `maxReviews` to 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 `null` instead of failing the run, but a redesign can reduce coverage until the Actor is updated. Check `fieldCoverage` in `OUTPUT`.
- The "What merchants think" summary exists only for some apps.
- How deep a category can be paged was not verified.
- Whether `locale` changes 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.

# Actor input Schema

## `appHandles` (type: `array`):

App handles ("judgeme") or full app URLs (https://apps.shopify.com/judgeme).

## `categoryHandles` (type: `array`):

Category handles or URLs (https://apps.shopify.com/categories/marketing-and-conversion-social-trust-product-reviews). Saves one ranking row per app with its position, page and Ad flag.

## `developerHandles` (type: `array`):

Developer (partner) handles or URLs (https://apps.shopify.com/partners/judge-me). Collects all apps of the developer.

## `searchQueries` (type: `array`):

Keywords searched in the App Store; positions and ads are saved as ranking rows. Note: the store's robots.txt asks crawlers not to fetch search pages, use at your own discretion.

## `allAppsFromSitemap` (type: `boolean`):

Take every app listed in the store sitemap (about 27,600). Combine with Max apps and the filters below to control cost.

## `sitemapLastmodSince` (type: `string`):

With the sitemap source: only apps whose sitemap lastmod is on or after this date. Handy for incremental runs.

## `scrapeAppDetails` (type: `boolean`):

On: every app found in a listing is opened and saved with full details. Off: only the cheap ranking rows are saved (apps from the Apps field are always opened).

## `maxApps` (type: `integer`):

Maximum number of app rows per run. 0 = no limit.

## `maxCategoryPages` (type: `integer`):

Pages per category (about 20 apps + ads per page). 0 = all pages.

## `maxSearchPages` (type: `integer`):

Pages per keyword (about 24 apps + ads per page). 0 = all pages.

## `maxDeveloperPages` (type: `integer`):

Pages per developer. 0 = all pages.

## `minRating` (type: `string`):

Keep apps rated at least this (for example 4.5). Leave empty for no limit.

## `minReviews` (type: `integer`):

Keep apps with at least this many reviews.

## `maxReviews` (type: `integer`):

Keep apps with at most this many reviews (find small or new competitors).

## `pricingFilter` (type: `string`):

Filter by pricing model.

## `builtForShopifyOnly` (type: `boolean`):

Keep only apps with the Built for Shopify badge.

## `requireCategories` (type: `array`):

Keep apps listed in at least one of these categories (category handle or name, for example "SEO").

## `excludeAds` (type: `boolean`):

Ignore paid (Ad) placements in category and search results.

## `includeReviews` (type: `boolean`):

Collect reviews for every app that passes the filters.

## `maxReviewsPerApp` (type: `integer`):

0 = all reviews (switches to newest-first, which goes past the store's 10,000-review limit).

## `reviewRatings` (type: `array`):

For example only 1 and 2 stars to study complaints. Empty = all ratings.

## `reviewsSince` (type: `string`):

Only reviews on or after this date; collection stops at the first older review (uses newest-first order).

## `reviewSort` (type: `string`):

Most relevant stops at 10,000 reviews; newest is used automatically when you need more or set a date.

## `reviewsOutput` (type: `string`):

Separate rows (one dataset row per review) or embedded (up to 200 reviews inside the app row, one row per app).

## `monitorId` (type: `string`):

Any name (letters, digits, dashes). Each app row gets a delta (rating, reviews, star counts, pricing, Built for Shopify, positions) and apps that left the results are listed in the report.

## `generateReport` (type: `boolean`):

Save an HTML report (REPORT in the key-value store): rating vs reviews map, app table, pricing, Built for Shopify and ad share, changes.

## `maxConcurrency` (type: `integer`):

Lowered automatically when the store starts rate limiting.

## `proxyConfiguration` (type: `object`):

Not needed for small runs. For whole-catalog runs datacenter proxy is enough. If the proxy fails, the run continues without it.

## `locale` (type: `string`):

Language code of the store pages, for example en, de, fr, es, ja.

## Actor input object example

```json
{
  "appHandles": [
    "judgeme",
    "klaviyo-email-marketing"
  ],
  "categoryHandles": [
    "marketing-and-conversion-social-trust-product-reviews"
  ],
  "allAppsFromSitemap": false,
  "scrapeAppDetails": false,
  "maxApps": 100,
  "maxCategoryPages": 1,
  "maxSearchPages": 3,
  "maxDeveloperPages": 10,
  "pricingFilter": "any",
  "builtForShopifyOnly": false,
  "excludeAds": false,
  "includeReviews": true,
  "maxReviewsPerApp": 10,
  "reviewSort": "newest",
  "reviewsOutput": "rows",
  "generateReport": true,
  "maxConcurrency": 10,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "locale": "en"
}
```

# Actor output Schema

## `report` (type: `string`):

Rating vs reviews map, sortable and filterable app table, Built for Shopify and ad share per listing, changes since the last run, new and disappeared apps.

## `apps` (type: `string`):

All dataset rows, Overview view.

## `summary` (type: `string`):

Counts, stop reason, field coverage, disappeared apps and the report link (OUTPUT record).

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "appHandles": [
        "judgeme",
        "klaviyo-email-marketing"
    ],
    "categoryHandles": [
        "marketing-and-conversion-social-trust-product-reviews"
    ],
    "scrapeAppDetails": false,
    "maxCategoryPages": 1,
    "includeReviews": true,
    "maxReviewsPerApp": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("solalab_digital/shopify-app-store-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "appHandles": [
        "judgeme",
        "klaviyo-email-marketing",
    ],
    "categoryHandles": ["marketing-and-conversion-social-trust-product-reviews"],
    "scrapeAppDetails": False,
    "maxCategoryPages": 1,
    "includeReviews": True,
    "maxReviewsPerApp": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("solalab_digital/shopify-app-store-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "appHandles": [
    "judgeme",
    "klaviyo-email-marketing"
  ],
  "categoryHandles": [
    "marketing-and-conversion-social-trust-product-reviews"
  ],
  "scrapeAppDetails": false,
  "maxCategoryPages": 1,
  "includeReviews": true,
  "maxReviewsPerApp": 10
}' |
apify call solalab_digital/shopify-app-store-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,solalab_digital/shopify-app-store-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/fxpExDJNWbbFDf6Ze/builds/dzGQm4JbDS1jajEjP/openapi.json
