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

Scrape Shopify App Store search, 87-field app details, pricing plans, reviews, categories, developer portfolios, and localized full catalogs.

- **URL**: https://apify.com/scrapingmonkey/shopify-app-store-scraper.md
- **Developed by:** [ScrapingMonkey](https://apify.com/scrapingmonkey) (community)
- **Categories:** E-commerce, Developer tools, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.35 / 1,000 search results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Shopify App Store Scraper - Apps, Reviews, Pricing, Categories and Full Catalogs

Turn public Shopify App Store search, app pages, reviews, categories, collections, developer portfolios, and localized catalogs into structured datasets for market research and monitoring.

- Eight focused modes in one Actor: search, details, reviews, category, collection, app group, developer, and catalog
- Complete 87-field rich app rows with descriptions, pricing plans, permissions, developer contacts, ratings, media, and discovery context
- Shopify-native search, category, Built for Shopify, multi-rating, date, keyword, country, usage, and developer-reply filters
- Full localized sitemap discovery across apps, partners, categories, features, collections, stories, extensions, and built-in features
- Optional full-details enrichment for every discovered app and persistent change monitoring for scheduled runs
- Concurrent batch processing, deduplication, retries with proxy rotation, and useful partial results when individual inputs fail
- No Shopify login, API key, browser, or proxy setup required; production traffic uses the built-in Apify Proxy
- Export to JSON, CSV, Excel, XML, or consume results through the Apify API

### What can you do with this Actor?

| Mode | Input | Dataset output | Best for |
| --- | --- | --- | --- |
| `search` | Keywords | Ranked 27-field app cards, or 87-field enriched app rows | Keyword rankings and competitor discovery |
| `details` | App handles or URLs | One complete 87-field app profile per app | Pricing, permissions, media, and developer research |
| `reviews` | App handles or URLs | One 25-field row per merchant review | Sentiment, churn signals, and support analysis |
| `category` | Category handles or URLs | Paginated 33-field discovery rows | Category coverage and Built for Shopify research |
| `collection` | Collection handles or URLs | Paginated 33-field discovery rows | Curated-market and editorial tracking |
| `appGroup` | App-group handles or URLs | Paginated 33-field discovery rows | Shopify-defined app groups |
| `developer` | Partner handles or URLs | Paginated 33-field app rows | Developer portfolio intelligence |
| `catalog` | One or more catalog types | 13-field sitemap rows, optionally enriched for apps | Full-store discovery and recurring inventory snapshots |

One mode runs at a time. Discovery rows can be upgraded to the same complete 87-field shape as Details by enabling `enrichResults`; the source rank and URL remain attached. Every output shape and every nested object key is shown below without ellipses or hidden fields.

### Quick start

1. Open the Actor and choose **Try for free**.
2. Select a mode.
3. Enter keywords, app IDs, developer IDs, or listing URLs for that mode.
4. Set the per-input result limit and optional filters.
5. Start the run, then preview or download the dataset.

The default input runs a working search for `email marketing`.

### Input examples

#### Search for Shopify apps

```json
{
  "mode": "search",
  "searchTerms": ["email marketing", "product reviews"],
  "maxResults": 20,
  "language": "en",
  "builtForShopifyOnly": true,
  "searchFeatures": ["checkout"]
}
```

`maxResults` applies independently to every search term. Each row contains its originating `searchTerm`, global `searchRank`, source page, and source-page position.

#### Get complete app details

```json
{
  "mode": "details",
  "appIds": [
    "judge-me",
    "https://apps.shopify.com/klaviyo-email-marketing-sms",
    "https://apps.shopify.com/livemeup/reviews"
  ],
  "language": "en"
}
```

Full Details and Reviews URLs are normalized automatically. Duplicate handles are removed before requests are made.

#### Get app details with embedded reviews

```json
{
  "mode": "details",
  "appIds": ["judge-me"],
  "includeReviews": true,
  "maxResults": 50,
  "reviewSort": "newest",
  "reviewScores": ["4", "5"],
  "reviewKeywords": ["support"],
  "language": "en"
}
```

#### Collect newest low-rating reviews

```json
{
  "mode": "reviews",
  "appIds": ["judge-me", "https://apps.shopify.com/klaviyo-email-marketing-sms"],
  "maxResults": 100,
  "reviewSort": "newest",
  "reviewScores": ["1", "2"],
  "reviewHasDeveloperReply": false,
  "reviewsSince": "2026-01-01",
  "language": "en"
}
```

#### Browse a category and enrich every app

```json
{
  "mode": "category",
  "categoryUrls": ["sales-channels-selling-online"],
  "maxResults": 100,
  "builtForShopifyOnly": true,
  "enrichResults": true,
  "maxConcurrency": 8,
  "language": "en"
}
```

Use `collectionUrls` with `collection`, `appGroupUrls` with `appGroup`, or `developerIds` with `developer`. Each list accepts handles or full matching Shopify App Store URLs.

#### Export a localized full catalog

```json
{
  "mode": "catalog",
  "catalogTypes": ["apps", "partners", "categories", "collections"],
  "maxResults": 5000,
  "language": "de"
}
```

`maxResults` applies independently to every term, app, listing URL, developer, or catalog type. Omit `reviewScores` to collect every rating.

### Complete output examples

Live titles, ratings, prices, review counts, plan features, and URLs change over time. The values below are representative, while the field sets are complete.

#### Complete search output - 27 top-level fields

```json
{
  "recordType": "search",
  "searchTerm": "product reviews",
  "searchRank": 1,
  "appId": "judge-me",
  "title": "Judge.me Product Reviews App",
  "url": "https://apps.shopify.com/judge-me",
  "icon": "https://cdn.shopify.com/app-store/listing_images/example/icon.png",
  "summary": "Collect and display product reviews and ratings.",
  "score": 5.0,
  "scoreText": "5.0",
  "reviewsCount": 42815,
  "pricingText": "Free plan available",
  "pricingModel": "free_plan_available",
  "free": false,
  "freeToInstall": false,
  "freePlanAvailable": true,
  "freeTrialAvailable": false,
  "builtForShopify": true,
  "isSponsored": false,
  "searchPosition": 5,
  "searchPage": 1,
  "language": "en",
  "scrapedAt": "2026-08-10T03:00:00Z",
  "monitorStatus": null,
  "monitorKey": null,
  "previousScrapedAt": null,
  "changedFields": []
}
```

#### Complete app details or enriched app output - 87 top-level fields

`reviewsPreview` contains reviews displayed directly on the app page. `includedReviews` is always present and is populated only when `includeReviews` is enabled. Every nested pricing, permission, editorial, similar-app, and review field is visible below.

```json
{
  "recordType": "details",
  "appId": "livemeup",
  "apiKey": "3e0c7c88e4417401ab5e50d9f5c2c7f4",
  "title": "LiveMeUp Live Shopping",
  "url": "https://apps.shopify.com/livemeup",
  "reviewUrl": "https://apps.shopify.com/livemeup/reviews",
  "icon": "https://cdn.shopify.com/app-store/listing_images/example/icon.png",
  "summary": "Grow sales with live selling and shoppable videos.",
  "description": "An all-in-one platform for live selling on your storefront and social channels.",
  "descriptionHtml": "An all-in-one platform for <strong>live selling</strong> on your storefront and social channels.",
  "keyBenefits": [
    "Create live shopping events and shoppable replays",
    "Display video widgets on product and home pages"
  ],
  "metaDescription": "Video commerce platform for live shopping sessions and shoppable videos.",
  "brand": "Live Me Up SAS",
  "operatingSystem": "Shopify",
  "appStoreCategory": "DeveloperApplication",
  "language": "en",
  "developer": "Live Me Up SAS",
  "developerId": "live-me-up",
  "developerUrl": "https://apps.shopify.com/partners/live-me-up",
  "developerWebsite": "https://www.livemeup.io/",
  "developerLocation": "8 Allée des Charmes, Mouvaux, 59420, FR",
  "developerSupportEmail": "hello@livemeup.io",
  "supportText": "App support provided by Live Me Up SAS.",
  "resources": [
    {
      "name": "Privacy policy",
      "url": "https://www.livemeup.io/privacy-policy"
    },
    {
      "name": "FAQ",
      "url": "https://help.livemeup.io/"
    }
  ],
  "privacyPolicyUrl": "https://www.livemeup.io/privacy-policy",
  "faqUrl": "https://help.livemeup.io/",
  "launched": "August 1, 2022",
  "launchedDate": "2022-08-01",
  "languages": ["English"],
  "worksWith": ["Shopify Admin", "Facebook", "Instagram", "Klaviyo"],
  "categories": [
    {
      "name": "Video and livestream",
      "id": "store-design-images-and-media-video-and-livestream",
      "url": "https://apps.shopify.com/categories/store-design-images-and-media-video-and-livestream"
    }
  ],
  "categoryNames": ["Video and livestream"],
  "categoryFeatures": [
    {
      "name": "Shoppable videos",
      "handle": "cf.video_and_livestream.video_management.shoppable_videos",
      "url": "https://apps.shopify.com/categories/store-design-images-and-media-video-and-livestream/all?feature_handles%5B%5D=cf.video_and_livestream.video_management.shoppable_videos"
    }
  ],
  "categoryCount": 1,
  "featureCount": 1,
  "builtForShopify": true,
  "pricingText": "Free to install. Free trial available.",
  "pricingModel": "free_to_install",
  "currency": "USD",
  "free": false,
  "freeToInstall": true,
  "freePlanAvailable": true,
  "freeTrialAvailable": true,
  "hasPaidPlans": true,
  "pricingPlans": [
    {
      "name": "100% FREE FOREVER",
      "priceText": "Free to install",
      "priceAmount": null,
      "currency": null,
      "billingPeriod": null,
      "yearlyPriceText": null,
      "additionalChargesText": "30 Minutes of Streaming Included",
      "trialDays": null,
      "trialText": null,
      "features": ["Custom Branding", "Shoppable Replays", "Widget Mini-Player"]
    },
    {
      "name": "GROW",
      "priceText": "$89/month",
      "priceAmount": 89.0,
      "currency": "USD",
      "billingPeriod": "month",
      "yearlyPriceText": null,
      "additionalChargesText": "4 Hours of Streaming Included - Unlimited Impressions and Views",
      "trialDays": 14,
      "trialText": "14-day free trial",
      "features": ["Flash Live Sales", "Product Widget Carousel", "Built-in SMS Notifications"]
    }
  ],
  "pricingPlanCount": 4,
  "pricingDisclaimer": "All charges are billed in USD. Recurring and usage-based charges are billed every 30 days.",
  "score": 5.0,
  "scoreText": "5.0",
  "reviewsCount": 89,
  "ratingDistribution": {
    "1": {"count": 0, "percentage": 0.0},
    "2": {"count": 0, "percentage": 0.0},
    "3": {"count": 1, "percentage": 1.12},
    "4": {"count": 2, "percentage": 2.25},
    "5": {"count": 86, "percentage": 96.63}
  },
  "screenshots": [
    "https://cdn.shopify.com/app-store/listing_images/example/promotional_image/hero.png",
    "https://cdn.shopify.com/app-store/listing_images/example/desktop_screenshot/dashboard.png"
  ],
  "screenshotCount": 11,
  "promotionalImage": "https://cdn.shopify.com/app-store/listing_images/example/promotional_image/hero.png",
  "videos": [],
  "dataAccess": [
    {
      "category": "View and edit store data",
      "summary": "Products, Online Store",
      "details": [
        {
          "name": "Edit products",
          "data": "Products, collections"
        },
        {
          "name": "Edit Online Store",
          "data": "Theme and Online Store pages"
        }
      ]
    }
  ],
  "dataAccessSummary": [
    "View and edit store data: Products, Online Store"
  ],
  "featuredIn": [
    {
      "title": "Video commerce",
      "description": "Turn storefront video into a sales channel.",
      "url": "https://apps.shopify.com/stories/video-commerce",
      "image": "https://apps.shopify.com/cdn/example-story.webp"
    }
  ],
  "featuredInCount": 1,
  "reviewsPreview": [
    {
      "appId": "livemeup",
      "reviewId": "2291886",
      "url": "https://apps.shopify.com/reviews/2291886",
      "score": 5,
      "scoreText": "5",
      "date": "2026-07-31",
      "dateText": "July 31, 2026",
      "text": "The live shopping tools are easy to use and the support team is responsive.",
      "userName": "Example Store",
      "userCountry": "United States",
      "timeUsingApp": "About 2 months using the app",
      "developerReplyId": "528309",
      "developerReplyBy": "Live Me Up SAS",
      "developerReplyDate": "2026-08-01",
      "developerReplyDateText": "August 1, 2026",
      "developerReplyText": "Thank you for sharing your experience.",
      "reviewSort": null,
      "reviewScore": null,
      "language": "en"
    }
  ],
  "similarApps": [
    {
      "appId": "example-video-app",
      "title": "Example Video Shopping App",
      "url": "https://apps.shopify.com/example-video-app",
      "icon": "https://cdn.shopify.com/app-store/listing_images/example-video-app/icon.png",
      "summary": "Add shoppable video to your storefront.",
      "score": 4.9,
      "reviewsCount": 240,
      "pricingText": "Free plan available",
      "pricingModel": "free_plan_available",
      "builtForShopify": true
    }
  ],
  "similarAppCount": 3,
  "includedReviews": [
    {
      "appId": "livemeup",
      "reviewId": "2291886",
      "url": "https://apps.shopify.com/reviews/2291886",
      "score": 5,
      "scoreText": "5",
      "date": "2026-07-31",
      "dateText": "July 31, 2026",
      "text": "The live shopping tools are easy to use and the support team is responsive.",
      "userName": "Example Store",
      "userCountry": "United States",
      "timeUsingApp": "About 2 months using the app",
      "developerReplyId": "528309",
      "developerReplyBy": "Live Me Up SAS",
      "developerReplyDate": "2026-08-01",
      "developerReplyDateText": "August 1, 2026",
      "developerReplyText": "Thank you for sharing your experience.",
      "reviewSort": "newest",
      "reviewScore": null,
      "language": "en"
    }
  ],
  "includedReviewCount": 1,
  "available": true,
  "searchTerm": null,
  "searchRank": null,
  "searchPosition": null,
  "searchPage": null,
  "isSponsored": null,
  "sourceType": null,
  "sourceHandle": null,
  "sourceTitle": null,
  "sourceUrl": null,
  "sourceRank": null,
  "sourcePosition": null,
  "sourcePage": null,
  "sourceResultCount": null,
  "catalogType": null,
  "catalogUrl": null,
  "catalogSlug": null,
  "lastModified": null,
  "scrapedAt": "2026-08-10T03:00:00Z",
  "monitorStatus": null,
  "monitorKey": null,
  "previousScrapedAt": null,
  "changedFields": []
}
```

The example contains two representative pricing plans, two screenshots, one category, one category feature, one permission group, one editorial placement, one preview review, one similar app, and one included review. The Actor returns every item published in each array. All top-level fields and every nested object field are shown.

#### Complete review output - 25 top-level fields

Shopify displays the review date as a calendar day rather than an exact timestamp. `date` and `developerReplyDate` therefore use ISO `YYYY-MM-DD`; the original storefront strings remain available in `dateText` and `developerReplyDateText`.

```json
{
  "recordType": "review",
  "appId": "judge-me",
  "reviewId": "2191323",
  "url": "https://apps.shopify.com/reviews/2191323",
  "score": 5,
  "scoreText": "5",
  "date": "2026-05-05",
  "dateText": "May 5, 2026",
  "text": "Great app with useful customization and responsive support.",
  "userName": "Example Store",
  "userCountry": "Israel",
  "timeUsingApp": "29 days using the app",
  "developerReplyId": "528308",
  "developerReplyBy": "Judge.me",
  "developerReplyDate": "2026-07-29",
  "developerReplyDateText": "July 29, 2026",
  "developerReplyText": "Thank you for the great rating and thoughtful feedback.",
  "reviewSort": "newest",
  "reviewScore": null,
  "language": "en",
  "scrapedAt": "2026-08-10T03:00:00Z",
  "monitorStatus": null,
  "monitorKey": null,
  "previousScrapedAt": null,
  "changedFields": []
}
```

When Shopify does not publish a developer reply, all five `developerReply*` fields remain present with `null` values.

#### Complete category, collection, app-group, or developer output - 33 top-level fields

These four modes share one predictable discovery shape. `recordType` and `sourceType` identify the chosen source; the example below shows a category row.

```json
{
  "recordType": "category",
  "appId": "judge-me",
  "title": "Judge.me Product Reviews App",
  "url": "https://apps.shopify.com/judge-me",
  "icon": "https://cdn.shopify.com/app-store/listing_images/example/icon.png",
  "summary": "Collect and display product reviews and ratings.",
  "score": 5.0,
  "scoreText": "5.0",
  "reviewsCount": 42815,
  "pricingText": "Free plan available",
  "pricingModel": "free_plan_available",
  "free": false,
  "freeToInstall": false,
  "freePlanAvailable": true,
  "freeTrialAvailable": false,
  "builtForShopify": true,
  "isSponsored": false,
  "searchPosition": 1,
  "searchPage": 1,
  "language": "en",
  "sourceType": "category",
  "sourceHandle": "store-design-product-reviews",
  "sourceTitle": "Product review apps",
  "sourceUrl": "https://apps.shopify.com/categories/store-design-product-reviews",
  "sourceRank": 1,
  "sourcePosition": 1,
  "sourcePage": 1,
  "sourceResultCount": 126,
  "scrapedAt": "2026-08-10T03:00:00Z",
  "monitorStatus": null,
  "monitorKey": null,
  "previousScrapedAt": null,
  "changedFields": []
}
```

#### Complete catalog output - 13 top-level fields

One catalog row represents one URL published in the selected localized Shopify sitemap.

```json
{
  "recordType": "catalog",
  "catalogType": "apps",
  "catalogUrl": "https://apps.shopify.com/judge-me",
  "catalogSlug": "judge-me",
  "appId": "judge-me",
  "developerId": null,
  "lastModified": "2026-08-09T12:30:00+00:00",
  "language": "en",
  "scrapedAt": "2026-08-10T03:00:00Z",
  "monitorStatus": null,
  "monitorKey": null,
  "previousScrapedAt": null,
  "changedFields": []
}
```

Missing, removed, or invalid inputs are written to the run log and skipped; the Actor never mixes operational error objects into the user dataset. Other valid inputs continue processing.

### What data can you extract?

#### Complete Details field reference

| Category | Fields |
| --- | --- |
| Record and identity | `recordType`, `appId`, `apiKey`, `title`, `url`, `reviewUrl`, `available`, `language`, `scrapedAt` |
| Content | `summary`, `description`, `descriptionHtml`, `keyBenefits`, `metaDescription`, `brand`, `operatingSystem`, `appStoreCategory` |
| Developer and support | `developer`, `developerId`, `developerUrl`, `developerWebsite`, `developerLocation`, `developerSupportEmail`, `supportText`, `resources`, `privacyPolicyUrl`, `faqUrl`, `launched`, `launchedDate` |
| Discovery and compatibility | `languages`, `worksWith`, `categories`, `categoryNames`, `categoryFeatures`, `categoryCount`, `featureCount`, `builtForShopify` |
| Pricing | `pricingText`, `pricingModel`, `currency`, `free`, `freeToInstall`, `freePlanAvailable`, `freeTrialAvailable`, `hasPaidPlans`, `pricingPlans`, `pricingPlanCount`, `pricingDisclaimer` |
| Ratings and reviews | `score`, `scoreText`, `reviewsCount`, `ratingDistribution`, `reviewsPreview`, `includedReviews`, `includedReviewCount` |
| Media | `icon`, `screenshots`, `screenshotCount`, `promotionalImage`, `videos` |
| Data access | `dataAccess`, `dataAccessSummary` |
| Discovery modules | `featuredIn`, `featuredInCount`, `similarApps`, `similarAppCount` |
| Preserved enrichment context | `searchTerm`, `searchRank`, `searchPosition`, `searchPage`, `isSponsored`, `sourceType`, `sourceHandle`, `sourceTitle`, `sourceUrl`, `sourceRank`, `sourcePosition`, `sourcePage`, `sourceResultCount`, `catalogType`, `catalogUrl`, `catalogSlug`, `lastModified` |
| Monitoring | `monitorStatus`, `monitorKey`, `previousScrapedAt`, `changedFields` |

#### Complete Search field reference

Search rows contain `recordType`, `searchTerm`, `searchRank`, `appId`, `title`, `url`, `icon`, `summary`, `score`, `scoreText`, `reviewsCount`, `pricingText`, `pricingModel`, `free`, `freeToInstall`, `freePlanAvailable`, `freeTrialAvailable`, `builtForShopify`, `isSponsored`, `searchPosition`, `searchPage`, `language`, `scrapedAt`, `monitorStatus`, `monitorKey`, `previousScrapedAt`, and `changedFields`.

Sponsored and organic appearances of the same app are deduplicated by `appId`. `isSponsored` tells you whether the retained appearance was a paid placement.

#### Complete Review field reference

| Field | Description |
| --- | --- |
| `recordType` | Always `review` for standalone review rows |
| `appId` | Shopify app handle |
| `reviewId` | Stable review identifier published in the page markup |
| `url` | Direct public review URL |
| `score`, `scoreText` | Star rating from 1 to 5 in numeric and text form |
| `date`, `dateText` | Normalized calendar date and original displayed date |
| `text` | Full public review body |
| `userName` | Merchant display name |
| `userCountry` | Merchant country when published |
| `timeUsingApp` | Displayed time the merchant has used the app |
| `developerReplyId` | Stable developer reply identifier when available |
| `developerReplyBy` | Replying developer name |
| `developerReplyDate`, `developerReplyDateText` | Normalized and displayed reply dates |
| `developerReplyText` | Full developer response |
| `reviewSort` | Requested `newest` or `relevant` ordering |
| `reviewScore` | Requested star filter, or `null` for all ratings |
| `language` | Requested Shopify App Store locale |
| `scrapedAt` | ISO timestamp when the row was collected |
| `monitorStatus` | `new`, `changed`, `unchanged`, or `null` when monitoring is disabled |
| `monitorKey` | Stable change-monitoring storage key |
| `previousScrapedAt` | Previous snapshot timestamp |
| `changedFields` | Exact top-level fields changed since the previous monitored run |

#### Complete discovery and catalog field reference

Category, collection, app-group, and developer rows contain every base app-card field listed under Search except `searchTerm` and `searchRank`, plus `sourceType`, `sourceHandle`, `sourceTitle`, `sourceUrl`, `sourceRank`, `sourcePosition`, `sourcePage`, and `sourceResultCount`. Their complete 33-field shape is shown above.

Catalog rows contain `recordType`, `catalogType`, `catalogUrl`, `catalogSlug`, `appId`, `developerId`, `lastModified`, `language`, `scrapedAt`, `monitorStatus`, `monitorKey`, `previousScrapedAt`, and `changedFields`.

Shopify's current public review pages do not expose reviewer profile images, app-version numbers, review headlines, or reliable helpful-vote totals. The Actor does not invent these values.

#### Pricing model meanings

| `pricingModel` | Meaning |
| --- | --- |
| `free` | Shopify labels the app as completely free |
| `free_plan_available` | At least one free plan is advertised alongside optional paid plans |
| `free_to_install` | Installation has no upfront subscription charge; usage or external charges may still apply |
| `paid_with_free_trial` | The search/details summary advertises a trial but not a permanent free plan |
| `paid` | A paid recurring price is displayed |
| `other` | Shopify publishes a pricing label outside the recognized models |

The original storefront wording is always preserved in `pricingText`. Individual plan labels, prices, billing periods, yearly-price text, additional-charge notes, trial days, trial text, and complete feature lists are preserved in `pricingPlans`.

### Input parameters

| Parameter | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `mode` | string | Yes | `search` | `search`, `details`, `reviews`, `category`, `collection`, `appGroup`, `developer`, or `catalog` |
| `searchTerms` | string\[] | Search | `email marketing` | Search keywords; each receives its own limit |
| `appIds` | string\[] | Details/reviews | - | App handles or full Details/Reviews URLs |
| `categoryUrls` | string\[] | Category | - | Category handles or `/categories/` URLs |
| `collectionUrls` | string\[] | Collection | - | Collection handles or `/collections/` URLs |
| `appGroupUrls` | string\[] | App group | - | App-group handles or `/app-groups/` URLs |
| `developerIds` | string\[] | Developer | - | Partner handles or `/partners/` URLs |
| `catalogTypes` | string\[] | Catalog | `apps` | Any of `apps`, `partners`, `categories`, `category_features`, `collections`, `stories`, `extensions`, `built_in_features` |
| `maxResults` | integer | No | `50` | Rows per term, app, listing URL, developer, or catalog type; 1-50,000 |
| `maxConcurrency` | integer | No | `8` | Simultaneous requests; 1-50 |
| `language` | string | No | `en` | One of Shopify's 23 sitemap locales: `ar`, `cs`, `da`, `de`, `en`, `es`, `fi`, `fr`, `he`, `it`, `ja`, `ko`, `nb`, `nl`, `pl`, `pt-BR`, `pt-PT`, `sv`, `th`, `tr`, `ur`, `zh-CN`, `zh-TW` |
| `enrichResults` | boolean | No | `false` | Replace discovery cards with complete app details while preserving source context |
| `includeReviews` | boolean | No | `false` | Populate `includedReviews` whenever full details are fetched |
| `builtForShopifyOnly` | boolean | No | `false` | Apply Shopify's Built for Shopify filter to search and discovery listings |
| `searchFeatures` | string\[] | No | Empty | `checkout`, `customer-account`, or `point-of-sale` |
| `searchCategories` | string\[] | No | Empty | Shopify top-level category handles accepted by search |
| `reviewSort` | string | No | `newest` | `newest`, `relevant`, `highest`, or `lowest` |
| `reviewScores` | string\[] | No | All ratings | Any combination of `1`, `2`, `3`, `4`, `5` |
| `reviewKeywords` | string\[] | No | Empty | Text terms matched after page extraction |
| `reviewKeywordMatch` | string | No | `any` | Require `any` or `all` keywords |
| `reviewCountries` | string\[] | No | Empty | Exact country labels displayed by Shopify |
| `reviewUsage` | string\[] | No | Empty | Exact time-using-app labels displayed by Shopify |
| `reviewHasDeveloperReply` | boolean/null | No | Unset | Keep only reviews with or without a reply |
| `reviewsSince` | string | No | Unset | Inclusive `YYYY-MM-DD` lower date bound |
| `reviewsUntil` | string | No | Unset | Inclusive `YYYY-MM-DD` upper date bound |
| `monitoring` | boolean | No | `false` | Compare each row with its previous persistent snapshot |
| `monitoringOnlyChanges` | boolean | No | `false` | Save only new or changed rows while monitoring |
| `monitorStoreName` | string | No | `shopify-app-store-monitor` | Named key-value store used for monitoring snapshots |

`maxResults` does not limit plain Details rows because each input app produces at most one profile. It limits embedded reviews when `includeReviews` is enabled. Client-side review filters are applied before the result limit, so the Actor can continue through additional pages to find enough matching rows.

### Use cases

#### Shopify app market research

- Discover apps ranking for target search terms
- Compare ratings, review volume, Built for Shopify status, and pricing models
- Build recurring category and competitor-monitoring workflows

#### Pricing intelligence

- Compare free plans, paid tiers, trials, yearly discounts, and usage-charge notes
- Track changes to plan names, prices, and included features
- Separate genuinely free apps from free-to-install listings

#### Review and sentiment analysis

- Collect newest negative reviews for issue discovery
- Filter one-to-five-star feedback
- Analyze review text by date, country, time using the app, or developer response

#### Developer and risk research

- Collect public developer websites, support emails, locations, and policies
- Review requested customer, staff, product, order, and storefront data access
- Compare support coverage and developer-response behavior

### Performance and cost

The Actor is ready for pay-per-event pricing. Search, app details, reviews, category rows, collection rows, app-group rows, developer apps, and catalog rows use separate chargeable events, so rates can reflect the work required by each output type. Check the Actor's **Pricing** tab for the current plan and rates before a large run. Enrichment is charged as app details, and each embedded review is charged as a review.

The Actor uses lightweight HTML requests instead of launching a browser, which keeps resource usage focused on the pages required by the selected mode.

#### Retries and reliability

All Shopify traffic is routed through Apify Proxy automatically; no proxy field is exposed in the input and direct Shopify traffic is disabled in the runtime client.

HTTP 403, 408, 425, 429, server errors, timeouts, connection failures, and structurally invalid HTML are retried with exponential backoff and randomized delay. Confirmed 404/410 pages and Shopify's explicit “page doesn't exist” template are terminal and are not retried.

Search apps and reviews are deduplicated by their stable IDs. If one app fails in a batch, the Actor logs the categorized failure and continues with the remaining handles. Empty search pages and apps with `No reviews yet` are successful zero-result cases, not errors.

### API usage

Replace `YOUR_USERNAME` and `APIFY_TOKEN`:

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/YOUR_USERNAME~shopify-app-store-scraper/runs?token=APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "details",
    "appIds": ["judge-me", "klaviyo-email-marketing-sms"],
    "includeReviews": false,
    "language": "en"
  }'
```

After the run finishes, records are available in the default dataset. The Actor can also connect to Make, Zapier, n8n, Google Sheets, webhooks, schedules, or any application that can call a REST API.

`YOUR_USERNAME~shopify-app-store-scraper` is an example Actor identifier. Replace it with the identifier shown on the Actor's API page.

### Best for / not for

**Best for:** public Shopify App Store discovery, app catalogs, pricing comparisons, review analysis, developer research, and recurring monitoring.

**Not for:** installing or managing Shopify apps, accessing merchant stores, collecting account-protected information, or guaranteeing data that Shopify does not publish publicly.

### Limits and good to know

- One mode is executed per run.
- `maxResults` accepts 1-50,000 and applies independently to each input source; Shopify can expose fewer matching pages than requested.
- Search and discovery rows are lightweight unless `enrichResults` is enabled.
- Catalog mode reads Shopify's public localized sitemaps; supported catalogs and locale coverage remain controlled by Shopify.
- Review pages currently contain approximately 10 reviews per page, so larger limits require additional requests.
- Shopify localizes page text. Normalized dates are populated when the displayed format is recognized; the original text is always preserved.
- Apps without reviews return zero review rows and do not trigger retries.
- Missing or invalid source pages are logged and skipped while the rest of the batch continues; operational errors are never stored as result rows.
- Optional fields can be `null` or empty when an app does not publish the relevant data.
- `maxConcurrency` controls simultaneous work, while one logical pagination task keeps its proxy session until a retry rotates it.
- The Actor accesses public Shopify App Store information only. It does not install apps, access stores, or read account-protected data.

### Frequently asked questions

#### Do I need a Shopify account or API key?

No. The Actor uses public Shopify App Store pages and handles network routing automatically.

#### Can I pass full Shopify App Store URLs?

Yes. Handles, Details URLs, and Reviews URLs can be mixed in the same `appIds` array.

#### Can I search several keywords in one run?

Yes. Add multiple values to `searchTerms`. `maxResults` applies independently to each term.

#### Can I collect only negative reviews?

Yes. Set `reviewScores` to `["1", "2"]`. Leave it empty to collect all ratings.

#### What is the difference between `newest` and `relevant`?

- `newest` requests Shopify's newest-to-oldest ordering.
- `relevant` requests Shopify's relevance-ranked ordering.
- `highest` and `lowest` traverse selected star-rating groups in descending or ascending order.

#### Why is a zero-review run successful with an empty dataset?

Reviews mode stores one row per actual review. If Shopify says `No reviews yet`, there are no review rows to save. The Actor logs the successful zero-result outcome and stops without requesting another page.

#### Why is `score` null instead of zero for a new app?

Zero reviews means the app has not received a rating. `null` distinguishes “not yet rated” from a real numerical score.

#### Does `Free to install` mean the app is completely free?

No. It means there is no upfront installation subscription. Usage-based, transaction, or externally billed charges can still apply. Check `pricingPlans`, `additionalChargesText`, and `pricingDisclaimer`.

#### Can I schedule recurring runs?

Yes. Use Apify schedules and integrations to run searches, details checks, or review collection automatically and send the resulting dataset to your workflow.

### Responsible use

Use the Actor in accordance with applicable laws and Shopify's terms. Do not use merchant or developer information for spam, harassment, deceptive activity, or unlawful profiling.

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Shopify Inc. Shopify and related marks belong to their respective owners.

### Support

If you find a missing field, parsing problem, or unexpected empty result, create an issue in the Actor's **Issues** tab. Include the run ID, mode, locale, and a non-sensitive example input.

### Local development

Use Python 3.11 or newer:

```powershell
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
.\.venv\Scripts\python.exe -m unittest discover -s tests -v
```

The production image uses Python 3.13 and starts the Actor with `python -m my_actor`.

# Actor input Schema

## `mode` (type: `string`):

Choose the Shopify App Store data source to scrape.

## `searchTerms` (type: `array`):

Keywords to search for. Required in search mode; maxResults applies to every term.

## `appIds` (type: `array`):

Shopify app handles or full apps.shopify.com details/reviews URLs. Required in details and reviews modes.

## `categoryUrls` (type: `array`):

Category URLs or handles such as sales-channels-selling-online. Required in category mode.

## `collectionUrls` (type: `array`):

Curated Shopify collection URLs or handles. Required in collection mode.

## `appGroupUrls` (type: `array`):

Shopify app-group URLs or handles. Required in appGroup mode.

## `developerIds` (type: `array`):

Developer handles or /partners/ URLs. Required in developer mode.

## `catalogTypes` (type: `array`):

Localized sitemap catalogs to export in catalog mode.

## `maxResults` (type: `integer`):

Maximum rows per search term, app, listing URL, developer, or catalog type.

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

Maximum simultaneous Shopify requests. Lower this if a large run encounters throttling.

## `language` (type: `string`):

Localized Shopify App Store locale. Catalog mode supports all 23 published locales.

## `enrichResults` (type: `boolean`):

Fetch full app details for search, category, collection, app-group, developer, or apps-catalog rows. Enriched rows are billed as app details.

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

Store matching reviews in includedReviews when details are fetched directly or through enrichment.

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

Apply Shopify's Built for Shopify program filter to search and discovery listings.

## `searchFeatures` (type: `array`):

Optional compatibility filters used by Shopify search.

## `searchCategories` (type: `array`):

Optional top-level Shopify category filters used in search mode.

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

Newest and relevant use Shopify ordering; highest and lowest traverse ratings in score order.

## `reviewScores` (type: `array`):

Optional multi-score filter. Leave empty to collect every star rating.

## `reviewKeywords` (type: `array`):

Keep reviews containing any or all keywords in the review, reviewer, or developer reply text.

## `reviewKeywordMatch` (type: `string`):

Require any keyword or every keyword.

## `reviewCountries` (type: `array`):

Optional exact country names as displayed by Shopify, for example United States.

## `reviewUsage` (type: `array`):

Optional exact usage labels as displayed by Shopify.

## `reviewHasDeveloperReply` (type: `boolean`):

When set, keep only reviews with a developer reply (true) or without one (false). Leave unset for both.

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

Keep reviews on or after this YYYY-MM-DD date.

## `reviewsUntil` (type: `string`):

Keep reviews on or before this YYYY-MM-DD date.

## `monitoring` (type: `boolean`):

Compare rows with the previous run in a named key-value store and add change metadata.

## `monitoringOnlyChanges` (type: `boolean`):

When monitoring is enabled, omit unchanged rows from the dataset.

## `monitorStoreName` (type: `string`):

Persistent key-value store used for change snapshots.

## Actor input object example

```json
{
  "mode": "search",
  "searchTerms": [
    "email marketing"
  ],
  "appIds": [],
  "categoryUrls": [],
  "collectionUrls": [],
  "appGroupUrls": [],
  "developerIds": [],
  "catalogTypes": [
    "apps"
  ],
  "maxResults": 50,
  "maxConcurrency": 8,
  "language": "en",
  "enrichResults": false,
  "includeReviews": false,
  "builtForShopifyOnly": false,
  "searchFeatures": [],
  "searchCategories": [],
  "reviewSort": "newest",
  "reviewScores": [],
  "reviewKeywords": [],
  "reviewKeywordMatch": "any",
  "reviewCountries": [],
  "reviewUsage": [],
  "monitoring": false,
  "monitoringOnlyChanges": false,
  "monitorStoreName": "shopify-app-store-monitor"
}
```

# Actor output Schema

## `dataset` (type: `string`):

Search, app details, reviews, categories, collections, app groups, developer portfolios, and localized catalog rows in one complete Results table.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapingmonkey/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 = {}

# Run the Actor and wait for it to finish
run = client.actor("scrapingmonkey/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 '{}' |
apify call scrapingmonkey/shopify-app-store-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapingmonkey/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/cubORQ1dGC6ImpYo6/builds/nYCY6K9DG9O95wWTL/openapi.json
