# Shopify App Store Scraper - Keyword Ranks & Watchlist (`crawloop/shopify-app-store-rank-tracker`) Actor

Scrape the Shopify App Store: keyword and category ranks, app details (ratings, pricing tiers, Built for Shopify badge), and watchlist deltas for rating, reviews, price, and badge changes. Built for daily runs. No Partner login.

- **URL**: https://apify.com/crawloop/shopify-app-store-rank-tracker.md
- **Developed by:** [Andrej Kiva](https://apify.com/crawloop) (community)
- **Categories:** E-commerce, Developer tools, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 app / rank rows

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 — Keyword Ranks, Category Ranks & Watchlist

> Unofficial tool for publicly accessible Shopify App Store listing data. Shopify and related trademarks belong to their respective owners. Not affiliated with, sponsored by, or endorsed by Shopify Inc. Provided for informational use only; users must comply with applicable terms and laws.

| Actor | Platform |
| :--- | :--- |
| Shopify App Store Scraper / Rank Tracker ◄── you are here | Shopify App Store |
| [Apple App Store Scraper](https://apify.com/crawloop/apple-app-store-scraper) | iOS / App Store |
| [Google Play Store Scraper](https://apify.com/crawloop/google-play-scraper) | Android / Google Play |
| [App Stores Scraper — Apple & Google Play ASO](https://apify.com/crawloop/app-stores-scraper) | Apple + Google Play (combo) |

**Shopify App Store scraper** for Apify — track **keyword SERP ranks**, **category positions**, and scrape **app details** (rating, review count, pricing tiers, Built for Shopify badge). Run a **watchlist** that emits deltas when competitors move. Export structured **JSON** for Python, Node.js, or AI agents via **MCP**. Designed for **daily scheduled runs** with KV history. No Shopify Partner login — a practical Shopify App Store API alternative for public listing data.

Use it for Shopify app competitor research, ASO-style keyword monitoring on App Store search, and cron alerts when a rival gains reviews or wins the Built for Shopify badge. For mobile store ASO, chain to [Apple App Store Scraper](https://apify.com/crawloop/apple-app-store-scraper) or [Google Play Store Scraper](https://apify.com/crawloop/google-play-scraper).

### When to use this Actor

- Daily keyword rank tracking for your app vs competitors (`email marketing`, `product reviews`, …)
- Category position snapshots on curated category pages
- Watchlist alerts: rating / review count / pricing / Built for Shopify badge
- Reliable app detail export via schema.org JSON-LD (not fragile CSS-only scraping)
- Canary mode for pipeline health checks before production schedules

#### When not to use

- You need install counts or revenue (not published on public listings)
- You only want a one-off dump of the entire 16k+ catalog with no rank history (use a full-catalog sitemap Actor instead)

### Modes

| Mode | What it does |
| :--- | :--- |
| `keyword_ranks` | Search SERP position of tracked handles × keywords + KV history + optional `RANK_CHANGE` |
| `category_ranks` | Position on a category page × tracked handles + KV history |
| `watchlist` | Fingerprint deltas: rating, review count, pricing, Built for Shopify badge |
| `app_details` | Full listing parse (JSON-LD + pricing plans + badge + developer) |
| `search` | Dump search result rows for a keyword (discovery) |
| `canary` | Fixed public probes — fails the run loudly if parsers break |

### Key features

- **Turbo-Frame search** — real SERP HTML (organic vs `search_ad` sponsored cards)
- **Organic-first ranks** — ads excluded by default (`includeAds` to count them)
- **JSON-LD details** — `ratingValue` / `ratingCount` from structured data
- **True BFS badge** — detects `built-for-shopify-badge`, not navbar guide links
- **KV history** — named store for rank snapshots and watchlist fingerprints
- **Canary** — deterministic health check for scheduled pipelines
- **Typed dataset** — `keyword_rank`, `category_rank`, `app`, `search_result`, `monitor_event`

### Input parameters

| Parameter | Description |
|-----------|-------------|
| `mode` | See modes table above |
| `appHandles` | App slugs to track (`klaviyo-email-marketing`, `judgeme`, …) |
| `startUrls` | App / category / search URLs (handles and queries parsed automatically) |
| `searchTerm` / `searchTerms` | Keywords for `search` / `keyword_ranks` |
| `categoryUrls` | Category paths or URLs (`marketing-and-conversion`) |
| `maxSearchPages` | Pages per keyword (default 3) |
| `includeAds` | Count sponsored cards in SERP ranks (default false) |
| `concurrency` | Parallel workers (default 4) |
| `rankHistoryLimit` | KV snapshots per target |
| `emitRankChanges` | Emit `RANK_CHANGE` monitor events |
| `maxItems` | Dataset row cap (`0` = unlimited) |
| `monitorStoreName` | KV store for ranks + watchlist state |
| `monitorBaselineOnly` | Seed state without change events |
| `resetMonitorState` | Clear KV state before run |
| `proxyConfiguration` | Optional Apify Proxy |

#### Example — keyword ranks (daily)

```json
{
  "mode": "keyword_ranks",
  "appHandles": ["klaviyo-email-marketing", "omnisend", "mailchimp"],
  "searchTerms": ["email marketing", "sms marketing"],
  "maxSearchPages": 3,
  "includeAds": false,
  "emitRankChanges": true,
  "maxItems": 50
}
```

#### Example — watchlist deltas

```json
{
  "mode": "watchlist",
  "appHandles": ["judgeme", "loox", "klaviyo-email-marketing"],
  "monitorBaselineOnly": false,
  "maxItems": 100
}
```

#### Example — category ranks

```json
{
  "mode": "category_ranks",
  "appHandles": ["judgeme", "loox", "instafeed"],
  "categoryUrls": ["marketing-and-conversion"],
  "emitRankChanges": true,
  "maxItems": 50
}
```

#### Example — app details

```json
{
  "mode": "app_details",
  "appHandles": ["klaviyo-email-marketing", "judgeme", "omnisend"],
  "maxItems": 10
}
```

### Output

Typed dataset rows via `itemType` — export as JSON, CSV, or Excel from the Apify dataset.

| itemType | Main fields |
| :--- | :--- |
| `keyword_rank` | `keyword`, `handle`, `rank`, `previousRank`, `rankDelta`, `found`, `history` |
| `category_rank` | `category`, `handle`, `rank`, `previousRank`, `found` |
| `app` | `title`, `rating`, `reviewCount`, `pricingSummary`, `pricingPlans`, `builtForShopify`, `developerName` |
| `search_result` | `keyword`, `handle`, `rank`, `isAd`, `page` |
| `monitor_event` | `eventType`, `changes`, `handle` (`RATING_CHANGE`, `REVIEW_COUNT_CHANGE`, `PRICE_CHANGE`, `BADGE_CHANGE`, `RANK_CHANGE`, `NEW_APP`) |
| `canary` | `ok`, `checks`, `failures` |

#### Example — keyword\_rank

```json
{
  "itemType": "keyword_rank",
  "keyword": "email marketing",
  "handle": "klaviyo-email-marketing",
  "title": "Klaviyo: Email Marketing & SMS",
  "rank": 1,
  "previousRank": 2,
  "rankDelta": 1,
  "found": true,
  "isAd": false,
  "url": "https://apps.shopify.com/klaviyo-email-marketing",
  "scrapedAt": "2026-08-03T16:00:00Z"
}
```

#### Example — app details

```json
{
  "itemType": "app",
  "handle": "judgeme",
  "title": "Judge.me Product Reviews App",
  "rating": 5.0,
  "reviewCount": 42771,
  "pricingSummary": "Free plan available",
  "pricingPlans": [{"name": "Free", "price": "Free"}, {"name": "$15/month", "price": "$15/month"}],
  "builtForShopify": true,
  "developerName": "Judge.me",
  "url": "https://apps.shopify.com/judgeme",
  "scrapedAt": "2026-08-03T16:00:00Z"
}
```

### Use cases

- Shopify app founders tracking SERP vs Klaviyo / Omnisend / Judge.me
- Agencies monitoring client apps for review-count velocity and badge wins
- Market researchers exporting category grids and competitor pricing tiers
- SaaS / VC screening of a niche (email, reviews, loyalty) via keyword discovery
- Pipelines that need a failing canary when Shopify markup changes

### Integration examples

#### Node.js

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('crawloop/shopify-app-store-rank-tracker').call({
  mode: 'keyword_ranks',
  appHandles: ['klaviyo-email-marketing', 'omnisend'],
  searchTerms: ['email marketing'],
  maxSearchPages: 2,
  maxItems: 20,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.slice(0, 5));
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient()
run = client.actor("crawloop/shopify-app-store-rank-tracker").call(run_input={
    "mode": "watchlist",
    "appHandles": ["judgeme", "loox"],
    "maxItems": 50,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item.get("eventType") or item.get("itemType"), item.get("handle"))
```

#### cURL

```bash
curl -s -X POST "https://api.apify.com/v2/acts/crawloop~shopify-app-store-rank-tracker/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode":"app_details","appHandles":["klaviyo-email-marketing"],"maxItems":5}'
```

### MCP and AI assistants

Use this Actor from AI tools via [Apify MCP](https://docs.apify.com/platform/integrations/mcp).
Connect your Apify account, then call this Actor by its Store ID / name (`crawloop/shopify-app-store-rank-tracker`).

Example prompts:

- "Run Shopify App Store Scraper for keyword email marketing tracking klaviyo-email-marketing and omnisend, return ranks as JSON"
- "Watchlist judgeme and loox for rating, review count, and Built for Shopify badge changes"
- "Scrape Shopify App Store app details for judgeme with Python, then compare Apple App Store ranks via Apple App Store Scraper"

### Suite next step

After Shopify App Store ranks, enrich mobile ASO with [Apple App Store Scraper](https://apify.com/crawloop/apple-app-store-scraper) or [Google Play Store Scraper](https://apify.com/crawloop/google-play-scraper), or run both via [App Stores Scraper](https://apify.com/crawloop/app-stores-scraper).

### FAQ

**Is this a Shopify App Store API?**\
Shopify does not offer a public App Store listing API for third parties. This Actor scrapes the same public pages merchants see and returns structured JSON — a practical API alternative for ranks, ratings, and pricing.

**Can I scrape with Python or Node.js?**\
Yes — use the Apify client examples above, or call the Actor from MCP / AI assistants.

**Do I get install counts or revenue?**\
No — Shopify does not publish those on public listings. Use `rating`, `reviewCount`, and SERP/category `rank` as popularity proxies.

**Are search ads included in ranks?**\
By default no. Set `includeAds: true` to count sponsored `search_ad` cards.

**Why is category rank coverage limited?**\
Category landing pages are curated (section grids), not infinite paginated catalogs. Rank is position among unique handles on that page.

**How do I schedule daily runs?**\
Use Apify Schedules with `keyword_ranks` or `watchlist`. First run with `monitorBaselineOnly: true` to seed KV state quietly.

### Related Actors

- [Apple App Store Scraper](https://apify.com/crawloop/apple-app-store-scraper)
- [Google Play Store Scraper](https://apify.com/crawloop/google-play-scraper)
- [App Stores Scraper — Apple & Google Play ASO](https://apify.com/crawloop/app-stores-scraper)

# Actor input Schema

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

What to scrape from the public Shopify App Store.

## `startUrls` (type: `array`):

App, category, or search URLs. Handles and category paths are parsed automatically.

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

App Store handles to track (slug after apps.shopify.com/), e.g. klaviyo-email-marketing, judgeme.

## `searchTerm` (type: `string`):

Single keyword for search / keyword\_ranks.

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

Keywords for search or keyword\_ranks. Merged with Search term.

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

Category paths or full URLs, e.g. marketing-and-conversion or https://apps.shopify.com/categories/marketing-and-conversion

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

Pages to crawl per keyword (≈24–28 apps/page). Used by search and keyword\_ranks.

## `includeAds` (type: `boolean`):

If true, sponsored search\_ad cards count toward SERP position. Default false = organic-only ranks.

## `concurrency` (type: `integer`):

Parallel HTTP workers (1–16).

## `rankHistoryLimit` (type: `integer`):

KV snapshots kept per app×keyword/category.

## `emitRankChanges` (type: `boolean`):

In keyword\_ranks / category\_ranks, also push RANK\_CHANGE monitor events when position moves.

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

Maximum dataset rows to push (0 = unlimited).

## `maxRequestsPerSecond` (type: `number`):

Client-side rate limit.

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

Named Apify key-value store for rank history and watchlist fingerprints.

## `monitorBaselineOnly` (type: `boolean`):

Seed KV state without emitting change events (watchlist) or optionally skip dataset pushes for ranks.

## `resetMonitorState` (type: `boolean`):

Clear fingerprints / rank history in the state store before this run.

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

Optional Apify Proxy. Usually not required for public App Store pages.

## Actor input object example

```json
{
  "mode": "keyword_ranks",
  "startUrls": [
    {
      "url": "https://apps.shopify.com/klaviyo-email-marketing"
    }
  ],
  "appHandles": [
    "klaviyo-email-marketing",
    "omnisend",
    "judgeme"
  ],
  "searchTerm": "",
  "searchTerms": [
    "email marketing",
    "product reviews"
  ],
  "categoryUrls": [
    "marketing-and-conversion"
  ],
  "maxSearchPages": 3,
  "includeAds": false,
  "concurrency": 4,
  "rankHistoryLimit": 30,
  "emitRankChanges": true,
  "maxItems": 100,
  "maxRequestsPerSecond": 4,
  "monitorStoreName": "shopify-app-store-rank-tracker-state",
  "monitorBaselineOnly": false,
  "resetMonitorState": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Default dataset items.

# 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 = {
    "startUrls": [
        {
            "url": "https://apps.shopify.com/klaviyo-email-marketing"
        }
    ],
    "appHandles": [
        "klaviyo-email-marketing",
        "omnisend",
        "judgeme"
    ],
    "searchTerms": [
        "email marketing",
        "product reviews"
    ],
    "categoryUrls": [
        "marketing-and-conversion"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawloop/shopify-app-store-rank-tracker").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 = {
    "startUrls": [{ "url": "https://apps.shopify.com/klaviyo-email-marketing" }],
    "appHandles": [
        "klaviyo-email-marketing",
        "omnisend",
        "judgeme",
    ],
    "searchTerms": [
        "email marketing",
        "product reviews",
    ],
    "categoryUrls": ["marketing-and-conversion"],
}

# Run the Actor and wait for it to finish
run = client.actor("crawloop/shopify-app-store-rank-tracker").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 '{
  "startUrls": [
    {
      "url": "https://apps.shopify.com/klaviyo-email-marketing"
    }
  ],
  "appHandles": [
    "klaviyo-email-marketing",
    "omnisend",
    "judgeme"
  ],
  "searchTerms": [
    "email marketing",
    "product reviews"
  ],
  "categoryUrls": [
    "marketing-and-conversion"
  ]
}' |
apify call crawloop/shopify-app-store-rank-tracker --silent --output-dataset

```

## MCP server setup

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

```

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/dZOM3IUQl6ehf2mxM/builds/vgspWWSceSjVGOXAG/openapi.json
