# Shopify App Store Scraper (apps, pricing, reviews) (`steadyrows/shopify-apps`) Actor

Scrape Shopify App Store apps by search, category or URL: pricing plans, features, integrations, rating histogram, developer email and address, launch date, plus reviews with developer replies.

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

## Pricing

from $3.00 / 1,000 app with full 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: apps, pricing plans and reviews

Get structured data on any app in the [Shopify App Store](https://apps.shopify.com): find apps by **keyword search**, by **category**, or by **URL**, and get every field of the listing plus the **reviews** with the developer's replies.

Built for lead lists, competitor monitoring and market research on the Shopify ecosystem: who makes the apps in a niche, what they charge, how they are rated, how long they have been around, and what merchants say about them.

### What you get

**One row per app** (all fields present on every row, `null` when the store has no value):

| Field | Example |
|---|---|
| `handle`, `name`, `url`, `id` | `klaviyo-email-marketing`, Klaviyo: Email Marketing & SMS |
| `rating`, `reviewCount`, `ratingHistogram` | 4.7, 3336, `{ "5": 2924, "4": 83, ... }` |
| `pricingHint`, `plans[]` | "Free to install"; each plan has `name`, `price`, `priceUsd`, `period`, `note`, `features[]` |
| `externalCharges` | true when the developer bills outside Shopify |
| `tagline`, `description`, `highlights[]` | the listing text |
| `categories[]`, `features[]` | category names and slugs; feature tags with group names (e.g. "Campaign types / Abandoned cart") |
| `languages[]`, `worksWith[]` | supported languages; integrations (Checkout, Shopify Flow, Gorgias, ...) |
| `developer`, `developerUrl`, `developerWebsite`, `developerAddress`, `supportEmail` | Klaviyo, partner page, website, postal address, support@klaviyo.com |
| `privacyPolicyUrl`, `faqUrl`, `tutorialUrl`, `documentationUrl`, `changelogUrl` | resource links |
| `launchedAt` | `2012-09-20` |
| `builtForShopify`, `isAd` | Built for Shopify badge; paid search placement |
| `screenshots[]`, `videoUrl`, `similarApps[]` | media and the store's "more apps like this" |
| `query`, `category`, `position` | where the app was found and its rank there |

**One row per review** (when `maxReviewsPerApp` > 0):

`id`, `appHandle`, `appName`, `appUrl`, `url`, `rating`, `date`, `text`, `store`, `country`, `usage` ("About 4 years using the app"), `reply`, `replyDate`.

The dataset has two views, **Apps** and **Reviews**, so each type can be exported on its own.

### Input

```json
{
  "searchQueries": ["email marketing", "upsell"],
  "categories": ["https://apps.shopify.com/categories/store-design-site-optimization-seo"],
  "apps": ["https://apps.shopify.com/klaviyo-email-marketing"],
  "maxApps": 50,
  "includeDetails": true,
  "maxReviewsPerApp": 100,
  "reviewsSort": "newest",
  "reviewRatings": ["1", "2"]
}
```

- **searchQueries** return apps in the store's own ranking, 24 organic results per page plus ads (marked `isAd: true`).
- **categories** accept the category URL or slug and list the whole category.
- **apps** accept the app page URL or the handle.
- **maxApps** applies per query and per category; apps named in `apps` are always delivered. An app that shows up under several queries is delivered once.
- **includeDetails** off: only the card fields (name, rating, review count, pricing hint, tagline), about 3× faster and cheaper.
- **reviewRatings** filters reviews by stars, e.g. `["1", "2"]` for complaints only.

### Pricing

Pay per result, no subscription:

| Event | Price |
|---|---|
| App with full listing | $3.00 per 1,000 |
| App, search row only (`includeDetails: false`) | $1.00 per 1,000 |
| Review | $0.30 per 1,000 |
| Run start | $0.002 |

A full listing is one page per app, so 1,000 apps with details take about 5 minutes. Reviews come 10 per page.

### Reliability

- Uses only public pages, no login, no proxy. Requests are spaced out to stay under the store's rate limit, and 429/5xx answers are retried with backoff.
- An app that does not exist (404) is skipped with a warning; the rest of the run continues.
- If app pages stop answering, the run falls back to search rows (charged at the lower price) instead of failing.
- Rows are pushed as they are collected, so a run stopped early still delivers what it has.

### Limits

- Search results are what the store shows a logged-out visitor in English (the `Based in …` personalisation is not included).
- The store caps search pagination; use categories to list a whole segment.
- Reviews pages do not expose the reviewer's store URL, only its name and country.

### Related

- [App Store & Google Play Apps](https://apify.com/steadyrows/app-store-google-play-apps): charts, search and details for mobile apps.
- [App Store & Google Play Reviews](https://apify.com/steadyrows/app-store-google-play-reviews): full review history with developer replies.

# Actor input Schema

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

Keywords to search the Shopify App Store for, e.g. `email marketing`, `upsell`, `dropshipping`. Each query returns apps in the store's own ranking; paid ads are included and marked with `isAd`.

## `categories` (type: `array`):

Category page URLs or slugs, e.g. `https://apps.shopify.com/categories/marketing-and-conversion-marketing-email-marketing` or `store-design-site-optimization-seo`. All apps in the category are listed, 24 per page.

## `apps` (type: `array`):

Specific apps, as app page URLs (`https://apps.shopify.com/klaviyo-email-marketing`) or handles (`klaviyo-email-marketing`).

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

Upper limit of apps delivered for each search query and each category. Apps named in "App URLs" are always delivered. Duplicates across queries are delivered once.

## `includeDetails` (type: `boolean`):

On: every app row has the full listing (description, pricing plans, features, languages, integrations, rating histogram, developer contact, launch date, screenshots). Off: only the search-card fields (name, rating, review count, pricing hint, tagline), which is faster and cheaper.

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

Reviews to deliver for each app (0 = no reviews). Review rows carry the app handle and name; each has rating, date, text, store name, country, time using the app, and the developer's reply.

## `reviewsSort` (type: `string`):

Order in which reviews are collected.

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

Keep only reviews with these ratings, e.g. `1` and `2` for complaints. Empty = all ratings.

## Actor input object example

```json
{
  "searchQueries": [
    "email marketing"
  ],
  "categories": [],
  "apps": [],
  "maxApps": 20,
  "includeDetails": true,
  "maxReviewsPerApp": 0,
  "reviewsSort": "newest",
  "reviewRatings": []
}
```

# Actor output Schema

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

All rows the run collected, one per item, in the default dataset.

# 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 = {
    "searchQueries": [
        "email marketing"
    ],
    "categories": [],
    "apps": [],
    "maxApps": 20,
    "reviewRatings": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("steadyrows/shopify-apps").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 = {
    "searchQueries": ["email marketing"],
    "categories": [],
    "apps": [],
    "maxApps": 20,
    "reviewRatings": [],
}

# Run the Actor and wait for it to finish
run = client.actor("steadyrows/shopify-apps").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 '{
  "searchQueries": [
    "email marketing"
  ],
  "categories": [],
  "apps": [],
  "maxApps": 20,
  "reviewRatings": []
}' |
apify call steadyrows/shopify-apps --silent --output-dataset

```

## MCP server setup

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

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/NNAfopVa9SgAODShk/builds/fmbDbHgok6PlAo0Ze/openapi.json
