# Shopify App Store Scraper (`smorgi_apps/shopify-app-store-scraper`) Actor

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

## Pricing

from $1.00 / 1,000 shopify app store 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/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 — Pay Per Result

Scrape **Shopify App Store app listings and public merchant reviews** via lightweight HTTP requests. Discover apps by **category** or **search**, or pass direct **app URLs/handles** — aggregate ratings, pricing hints, and optional review rows in one run.

**Store search keywords:** Shopify App Store scraper · Shopify apps · app reviews · Shopify app ratings · ecommerce app directory

***

### Why this Actor

| Need | What you get |
|------|----------------|
| App intelligence | Name, handle, rating, review count, pricing hint, icon, short description |
| Review monitoring | Review text, stars, reviewer, date, country, usage duration |
| Directory discovery | Paginate category browse pages or Store search results |
| Failures that shouldn't bill | 404 / empty / unparseable → **not charged** |
| Low cost | HTTP-only (no Playwright); PPE priced from measured unit economics |

Public listing pages only. No Shopify Partner API key required.

***

### Endpoints (public HTTP)

There is **no official public REST API** for browsing the App Store catalog. This Actor uses the same HTML pages your browser loads:

| Purpose | URL | Notes |
|---------|-----|-------|
| Category browse | `GET https://apps.shopify.com/categories/{slug}?page=N` | SSR app cards with `data-app-card-*` attributes (~12–40 apps/page depending on layout) |
| Store search | `GET https://apps.shopify.com/search?q={query}&page=N` | Requires `Turbo-Frame: search_page` header — main search shell is JS-deferred (~24 apps/page) |
| App detail | `GET https://apps.shopify.com/{handle}` | JSON-LD `SoftwareApplication` + Open Graph meta (aggregate rating, pricing hint) |
| Public reviews | `GET https://apps.shopify.com/{handle}/reviews?page=N` | ~10 merchant reviews per page in SSR HTML |

Legacy or shortened category slugs may 301-redirect to canonical paths (handled automatically).

***

### Input

```json
{
  "categories": ["marketing-and-conversion-marketing-email-marketing"],
  "searchQueries": ["email marketing"],
  "appUrls": ["https://apps.shopify.com/klaviyo-email-marketing"],
  "mode": "both",
  "maxItems": 100,
  "maxReviewsPerApp": 20,
  "requestDelayMs": 400
}
```

Accepted app URL / handle forms:

- Handle: `klaviyo-email-marketing`
- Detail URL: `https://apps.shopify.com/klaviyo-email-marketing`
- Reviews URL: `https://apps.shopify.com/klaviyo-email-marketing/reviews`

***

### Output fields

#### `recordType: "app"` (one row per app)

| Field | Description |
|-------|-------------|
| `handle` | App URL slug |
| `name` | App title |
| `shortDescription` | Listing blurb or JSON-LD description |
| `developerName` | Brand from JSON-LD (detail pages) |
| `iconUrl` | App icon URL |
| `storeUrl` | Canonical detail URL (tracking params stripped) |
| `ratingValue` / `ratingCount` | Aggregate star rating and total review count |
| `pricingHint` | e.g. "Free to install", "Free plan available" |
| `source` | `listing` (category/search card) or `detail` (detail page JSON-LD) |

#### `recordType: "review"` (one row per review)

| Field | Description |
|-------|-------------|
| `reviewId` | Numeric review identifier |
| `reviewerName` | Merchant / store name |
| `rating` | 1–5 stars |
| `reviewText` | Review body (paragraphs joined) |
| `reviewDate` | Human-readable date from page |
| `country` | Reviewer country when listed |
| `usageDuration` | e.g. "2 months using the app" |

***

### Pricing

Pay-per-event for each **delivered** dataset row (`apify-default-dataset-item`).

- Empty pages, 404 apps, and parse failures → **not charged**
- Apps-only runs bill one row per app; review runs bill one row per review

**~$1 / 1,000 results** on the Store pricing tab (HTTP-only; empty/404 free).

***

### Limitations (honest)

- **Search requires turbo-frame:** The search results shell at `/search?q=…` is empty without the `Turbo-Frame: search_page` header. This Actor sets it automatically; plain curl without the header returns a skeleton page.
- **Reviews pagination:** Each `/reviews` HTTP response embeds **~10 reviews**. Deep history requires paginating `?page=N` — implemented, but very large review counts mean many HTTP calls.
- **Category layout drift:** Listing cards use Stimulus `data-app-card-*` attributes and Tailwind classes. Shopify redesigns can break parsing.
- **Detail vs listing metadata:** Category/search discovery emits lighter listing-card rows (`source: listing`) unless you also pass the app in `appUrls` or set `mode` to include reviews (which fetches detail/review pages).
- **No Partner API:** Cannot access install counts, revenue, or private Partner dashboard data — public pages only.
- **Rate limits:** High volume may trigger HTTP 429/503; use `requestDelayMs` and optional Apify Proxy.
- **Removed apps:** Return HTTP 404 and are skipped (not charged).

***

Issues / feature requests: use the Actor **Issues** tab.

# Actor input Schema

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

Browse apps in a Store category. Slug (marketing-and-conversion-marketing-email-marketing) or full https://apps.shopify.com/categories/… URL. Paginates with ?page=N.

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

Search the public App Store. Uses the search turbo-frame SSR endpoint (~24 apps/page).

## `appUrls` (type: `array`):

Direct app detail URLs or handles (e.g. klaviyo-email-marketing). Always fetches the detail page for richer metadata.

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

apps = one row per app (aggregate rating); reviews = one row per review; both = app rows + reviews.

## `maxItems` (type: `integer`):

Cap total dataset rows across all apps (apps + reviews combined).

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

When mode includes reviews, cap review rows per app (~10 reviews per /reviews HTTP page).

## `requestDelayMs` (type: `integer`):

Throttle between category/search/detail/reviews HTTP calls.

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

Optional. Direct requests usually work; enable Apify Proxy for high volume.

## Actor input object example

```json
{
  "categories": [
    "marketing-and-conversion-marketing-email-marketing"
  ],
  "searchQueries": [
    "email marketing"
  ],
  "appUrls": [
    "https://apps.shopify.com/klaviyo-email-marketing"
  ],
  "mode": "apps",
  "maxItems": 100,
  "maxReviewsPerApp": 20,
  "requestDelayMs": 500,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `items` (type: `string`):

No description

# 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 = {
    "categories": [
        "marketing-and-conversion-marketing-email-marketing"
    ],
    "searchQueries": [
        "email marketing"
    ],
    "appUrls": [
        "https://apps.shopify.com/klaviyo-email-marketing"
    ],
    "mode": "apps",
    "maxItems": 100,
    "maxReviewsPerApp": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("smorgi_apps/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 = {
    "categories": ["marketing-and-conversion-marketing-email-marketing"],
    "searchQueries": ["email marketing"],
    "appUrls": ["https://apps.shopify.com/klaviyo-email-marketing"],
    "mode": "apps",
    "maxItems": 100,
    "maxReviewsPerApp": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("smorgi_apps/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 '{
  "categories": [
    "marketing-and-conversion-marketing-email-marketing"
  ],
  "searchQueries": [
    "email marketing"
  ],
  "appUrls": [
    "https://apps.shopify.com/klaviyo-email-marketing"
  ],
  "mode": "apps",
  "maxItems": 100,
  "maxReviewsPerApp": 20
}' |
apify call smorgi_apps/shopify-app-store-scraper --silent --output-dataset

```

## MCP server setup

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