# Shopify App Store Scraper - Apps, Pricing & Reviews (`s-r/shopify-app-store`) Actor

Collect Shopify App Store apps and merchant reviews by keyword, category or app handle. Get pricing plans with free trials, developer website and country, ratings, Built for Shopify badge and developer replies.

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

## Pricing

from $2.00 / 1,000 app listings

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

Shopify App Store Scraper exports app listings, pricing plans and merchant reviews from the public Shopify App Store, so app makers, Shopify Partners, agencies and market researchers can compare apps without copying pages by hand. Search by keyword, explore a category, or provide app handles and app URLs directly.

### What Shopify App Store Scraper collects

Use the actor to compare competing apps, build a partner research dataset, track published subscription plans, or study feedback from Shopify merchants. Every search or category result is expanded into a complete app listing. You receive the developer, categories, supported languages, integrations, launch date and public pricing information together with the app name and rating.

Pricing plans have numeric base amounts, billing periods, free trial durations and plan features. Where Shopify publishes structured usage tiers, the actor preserves those tiers separately from the base subscription amount. This helps distinguish an app advertised as free to install from one that charges for usage. Shopify displays up to four plan cards; an external pricing link is included when available, so the dataset does not imply that those cards cover every enterprise arrangement.

Reviews are optional and delivered as separate dataset rows. Each review links back to its app through `listing_id`. The actor includes the rating, merchant's store name, country, reported usage duration, review date, review text and any developer response. A rating-only review remains a valid row with `text: null`.

### Use cases for Shopify App Store data

- **Competitor research for app makers.** Track how rival apps in your category price their plans, which free trials they offer, how their ratings move and which integrations they list.
- **Shopify app pricing benchmarks.** Collect the published plans of every app in a category to see the going rate for a feature, the share of apps with a free plan and typical trial lengths.
- **Review mining.** Pull one-star and two-star Shopify app reviews of a competitor to find the complaints merchants repeat, or read developer replies to learn how support is handled.
- **Partner and agency prospecting.** Build lists of app developers per category with their website and country, plus the apps that carry the Built for Shopify badge.
- **Market sizing.** Count apps, ratings and reviews per category or keyword to judge how crowded a niche of the Shopify App Store is before you build.

### Input

At least one source list must contain a valid value: `app_handles`, `search_queries`, or `category_urls`. You can combine them in one run. An app handle is the first part of its Shopify App Store URL, such as `loox` or `klaviyo-email-marketing`. Full app URLs are also accepted, including a URL ending in `/reviews`. Repeated direct handles are collected once.

This input collects two apps and up to twenty reviews for each:

```json
{
  "app_handles": ["loox", "klaviyo-email-marketing"],
  "include_reviews": true,
  "max_reviews": 20,
  "review_sort": "newest"
}
```

For discovery, use `search_queries: ["email marketing"]` or `category_urls: ["marketing-and-conversion-marketing-email-marketing"]`. Category URLs beginning with `https://apps.shopify.com/categories/` also work. `max_results` defaults to twenty and accepts values from one to one thousand. The limit applies separately to each search query or category, and does not trim the list of direct handles.

`include_reviews` defaults to false. When enabled, `max_reviews` defaults to one hundred and accepts values up to five thousand per app. Set `review_ratings` to one or more integers between one and five to restrict reviews by rating. For example, `[1, 2]` requests one-star and two-star feedback together. `review_sort` accepts `newest` or `relevance`, with `newest` as the actor default. The dataset follows Shopify's returned ordering; combined rating filters may not produce a strictly chronological sequence.

Sponsored results are excluded by default. Set `include_ads` to true to include them. Sponsored listings have `is_sponsored: true` and no organic position. Large jobs continue automatically during an Apify run. If you use the API output to resume a collection manually, pass the returned `cursor` together with the same input options.

### Output

The default dataset contains two row types. `record_type` and `_type` identify each row as `software_listing` or `software_review`. All rows include `source`, `platform`, `fetched_at` and `listing_id`. The platform is `shopify_app_store`, and the listing identifier is the app handle. These fields make it straightforward to join app details and merchant feedback without parsing a nested object.

App rows include `title`, `url`, `developer`, `description`, `rating` and `rating_count`. Additional fields include `plans`, `plans_currency`, `pricing_summary`, `has_free_plan`, `has_free_trial`, `built_for_shopify`, `rating_distribution`, `developer_website`, `developer_country`, `launched_at`, `languages`, `works_with` and `categories`. The rating distribution uses exact star counts rather than abbreviated labels. Apps without reviews have null rating fields and an empty distribution.

For context, search rows carry `search_query`, category rows carry `category_slug`, and organic discovery rows carry `position`. An app appearing under two different source requests produces a listing row for each context. Reviews for that app are collected once during the run.

Review rows include `review_id`, `review_url`, `rating`, `text`, `author_name`, `author_country`, `usage_duration`, `published_at`, `edited`, `reply_text` and `reply_published_at`. Dates use `YYYY-MM-DD` because the public page does not provide a time. For edited reviews, the published date is the displayed edit date. Missing replies and usage durations remain null. Reviews retain their original language, while listing interface labels are read in English.

#### Example output

A shortened app row for `loox`, taken from a real collection on 2026-10-05 (the full row also has the description, screenshots, feature bullets, every plan with its features and the rating distribution):

```json
{
  "record_type": "software_listing",
  "platform": "shopify_app_store",
  "listing_id": "loox",
  "url": "https://apps.shopify.com/loox",
  "title": "Loox ‑ Product Reviews App",
  "developer": "Loox",
  "developer_website": "https://loox.app/",
  "developer_country": "IL",
  "rating": 4.9,
  "rating_count": 9761,
  "built_for_shopify": true,
  "has_free_plan": true,
  "has_free_trial": true,
  "plans_currency": "USD",
  "launched_at": "2015-10-16",
  "categories": [
    {"slug": "marketing-and-conversion-social-trust-product-reviews", "name": "Product reviews"},
    {"slug": "marketing-and-conversion-social-trust-social-proof", "name": "Social proof"}
  ],
  "plans": [
    {
      "name": "Convert",
      "price_label": "$49.99/month",
      "price": 49.99,
      "billing_period": "month",
      "additional_charges": "300 orders included in base price + $50 per additional 300 orders",
      "trial_days": 14,
      "usage_charges": null
    }
  ]
}
```

A review row from the same collection, for `klaviyo-email-marketing`:

```json
{
  "record_type": "software_review",
  "platform": "shopify_app_store",
  "listing_id": "klaviyo-email-marketing",
  "review_id": "2383813",
  "review_url": "https://apps.shopify.com/reviews/2383813",
  "rating": 5,
  "published_at": "2026-10-04",
  "edited": false,
  "text": "Fácil de trabalhar",
  "author_name": "Missuna Home",
  "author_country": "Portugal",
  "usage_duration": "11 months",
  "reply_text": null,
  "reply_published_at": null
}
```

### How it compares

| | Shopify App Store Scraper | Copying pages by hand | Shopify Partner API |
|---|---|---|---|
| Apps from any developer | Yes | Yes | Only your own apps |
| Pricing plans as numbers, with trial days | Yes | Retyped manually | No |
| Merchant reviews with rating filter | Yes, up to 5,000 per app | Ten per page | No |
| Search, category and handle input in one run | Yes | No | No |
| Listing and reviews joinable by `listing_id` | Yes | No | Not applicable |

Most Shopify App Store scrapers return the app name, rating and a price label. This actor also splits every published plan into price, billing period, trial days, additional charges and usage tiers, so you can sort and compare Shopify app pricing directly in a spreadsheet.

### Pricing

Apps and reviews are separate result events. An app event corresponds to a delivered `software_listing` row; a review event corresponds to a delivered `software_review` row. Check the actor's current Pricing tab for the amount charged per event. Empty results produce no app or review charge, and the actor does not define a separate run-start event.

Users without a paid Apify plan receive up to ten dataset rows per run, counting apps and reviews together. The actor stops its continuation when that cap is filled. Paid users retain the requested collection limits. Result events reflect the rows delivered after the free-user cap, so reviews and app listings are counted separately.

### Coverage and limitations

The actor collects public listings and public merchant reviews. It does not provide app installation counts, private merchant information, app revenue or historical prices that are no longer displayed. A developer's country comes from the published developer address. A merchant's country comes from the review, and the two fields describe different parties.

Some parent categories show sections rather than a fully paginated list. In that case the actor returns the visible apps and adds a warning naming relevant subcategories for broader coverage. Unknown apps or categories produce warnings when other results are available. A failed review page preserves earlier results and indicates that more work remains. Changes to app details or newly added reviews during a collection can affect the observed dataset.

### FAQ

#### Can I collect reviews without entering a search query?

Yes. Provide an app handle or its Shopify App Store URL and enable `include_reviews`. The actor returns the app listing first and then collects the requested merchant reviews.

#### Does the actor return every pricing option an app sells?

It returns the pricing cards published on the Shopify App Store page, including the base price, trial and additional-charge text. Shopify shows up to four cards. Custom enterprise contracts and unlisted options are outside that published coverage.

#### Why can an app appear more than once?

Separate search queries and category requests preserve their own discovery context. The same app can therefore appear in several listing rows. Repeated direct handles are deduplicated, and the actor collects that app's reviews only once.

#### Why is a review's text or usage duration null?

Some merchants leave only a rating, and some review sidebars omit usage duration. Null preserves those source omissions without discarding a valid review or guessing missing information.

#### Who uses a Shopify App Store scraper?

App developers watching competitors, Shopify Partners and agencies choosing apps for clients, investors and analysts sizing a niche, and sales teams looking for app developers to contact. The data is the same public information a merchant sees in the Shopify App Store.

#### Can I export the results to CSV or Excel?

Yes. The dataset can be downloaded from Apify as CSV, Excel, JSON or XML, or read through the Apify API. Nested fields such as `plans` and `categories` stay as JSON in a spreadsheet cell; filter on `record_type` to separate apps from reviews.

#### How many apps can one run collect?

`max_results` allows up to one thousand apps per search query or category, and a run can contain several queries and categories plus any number of direct handles. Free Apify users get up to ten rows per run.

# Actor input Schema

## `app_handles` (type: `array`):

App handles or apps.shopify.com app URLs; repeated handles are collected once.

## `search_queries` (type: `array`):

Search terms. Each query has its own max_results limit.

## `category_urls` (type: `array`):

Shopify category URLs or category slugs. Parent categories return their visible sections.

## `max_results` (type: `integer`):

Apps per search query or category; direct handles are not limited by this field.

## `include_ads` (type: `boolean`):

Include sponsored cards. Sponsored rows have no organic position.

## `include_reviews` (type: `boolean`):

Collect reviews for each distinct app. Reviews are separate rows.

## `max_reviews` (type: `integer`):

Maximum reviews per app, across all continuation requests.

## `review_ratings` (type: `array`):

Optional review ratings, 1 to 5; multiple ratings are passed together.

## `review_sort` (type: `string`):

Shopify source ordering. Combined rating filters may not be strictly chronological.

## `cursor` (type: `string`):

Opaque continuation returned by the previous response. Keep all other input fields unchanged.

## Actor input object example

```json
{
  "app_handles": [
    "loox"
  ],
  "max_results": 20,
  "include_ads": false,
  "include_reviews": false,
  "max_reviews": 100,
  "review_sort": "newest"
}
```

# Actor output Schema

## `results` (type: `string`):

One dataset row per app listing or merchant review.

# 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 = {
    "app_handles": [
        "loox"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("s-r/shopify-app-store").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 = { "app_handles": ["loox"] }

# Run the Actor and wait for it to finish
run = client.actor("s-r/shopify-app-store").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 '{
  "app_handles": [
    "loox"
  ]
}' |
apify call s-r/shopify-app-store --silent --output-dataset

```

## MCP server setup

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

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/HSFQgYikSK9sF1m6f/builds/1mF7a2NRPS8ZZhm2E/openapi.json
