# Shopify Best Sellers Tracker | New Products, Prices, $3/1K (`aurelix/shopify-best-sellers-tracker`) Actor

Scrape Shopify best sellers and price changes with no platform usage on top and product rows at $3.00 per 1,000, cheaper than the leading tools, reporting stock-outs, restocks and per-variant old and new prices since your last run. No login. $0.015 per store.

- **URL**: https://apify.com/aurelix/shopify-best-sellers-tracker.md
- **Developed by:** [Aurelix](https://apify.com/aurelix) (community)
- **Categories:** E-commerce, Automation, Lead generation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.10 / 1,000 spy 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/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

### What is Shopify Best Sellers Tracker?

**Track Shopify stores' best sellers, new products, price changes, stock-outs and restocks since your last run for $3.00 per 1,000 rows, no login.**

For brands, resellers and agencies watching competitor stores. Each store checked costs $0.015 and includes a catalogue summary, with no platform usage billed on top. Your first run with the example input costs about $0.034 (11 rows in our test run).

[![Shopify Best Sellers Tracker: example output from a real run](https://api.apify.com/v2/key-value-stores/twkCCtTWzsi8fVbx5/records/shopify-best-sellers-tracker-card-v2.png)](https://console.apify.com/actors/6mjDKuBnEvdsxaPbF?addFromActorId=6mjDKuBnEvdsxaPbF)

| | |
|---|---|
| **Watch** | Shopify store domains or any URL on the store |
| **Row types** | Store summary, best-seller, new product, price change, stock-out, restock |
| **Output** | 34 fields per row; JSON, CSV, Excel, API |
| **Automate** | Schedules, webhooks, Zapier, Make, n8n, Google Sheets, MCP for AI agents |
| **Price** | $3.00 per 1,000 rows ($2.10 per 1,000 rows on paid Apify plans) |
| **Free to try** | Runs on Apify's free plan: the $5 monthly credit covers about 1,600 rows (plus $0.015 per store checked) |
| **Login needed** | No |

### Why Shopify Best Sellers Tracker users pick this one

- **All signals in one run.** Best sellers, new products, price moves, stock-outs and restocks.
- **Price moves in detail.** Old and new price, direction, percent and every variant that moved.
- **The store's own order.** Best sellers ranked as the store shows them, source named.
- **Cheaper per row.** $3.00 per 1,000 rows, cheaper than the leading tools.
- **Polite and resilient.** Respects robots.txt; a rate-limited store keeps what was read.

### Get started in 3 steps

1. Paste your competitors' Shopify store URLs into 'Competitor store URLs' (e.g. warmlydecor.com).
2. Optionally change how many best-sellers to return per store, or give the watch list a change-tracking name.
3. Click Start, then schedule it daily; each run reports what changed since the last one. Download JSON, CSV or Excel, or send rows to Google Sheets, Zapier, Make or n8n.

**[▶ Try it with the example input](https://console.apify.com/actors/6mjDKuBnEvdsxaPbF?addFromActorId=6mjDKuBnEvdsxaPbF)**

The form opens with an example input already filled in: that run costs about $0.034 on the free plan.

### How much does it cost to scrape Shopify best sellers?

Pay per event: you pay only for what the run returns, plus a small start fee. Bronze, Silver, Gold and higher Apify plans pay less per result.

| Rows | Free plan | Paid plans (Bronze, Silver, Gold) |
|---|---|---|
| 100 | $0.30 | $0.21 |
| 1,000 | $3.00 | $2.10 |
| 10,000 | $30.00 | $21.00 |

Totals include the $0.0005 start fee per run, rounded to the cent. Apify's free plan includes $5 of credit a month, enough for about 1,600 rows (plus $0.015 per store checked).

Each store read is charged once, as its store summary row ($0.015 per store checked on every plan), for catalogues up to 25,000 products. Best-seller, new product, price change, stock-out and restock rows are charged at the spy-result price per row. Skipped stores return no rows and cost nothing beyond the start fee.

#### Billing events

| Event | Free plan | Paid plans (Bronze, Silver, Gold) |
|---|---|---|
| `spy-result` | $3.00 per 1,000 rows | $2.10 per 1,000 rows |
| `store-summary` | $0.015 per store checked | $0.015 per store checked |
| `apify-actor-start` | $0.0005 per run | $0.0005 per run |

### Benchmarks: how we compare

| Test | Rows returned | Run time | Notes |
|---|---|---|---|
| Prefilled form: notebooktherapy.com, 10 best-sellers, 250 products | 11 (1 summary + 10 best-sellers) | not recorded | - |
| 3 small stores (1,281 products in all), first run | 43 (3 summaries + 40 best-sellers) | 4.0 s | best-sellers found on 2 of 3 stores; the third has no public best-seller list |
| Same 3 stores, run again | 43 | 4.1 s | 0 change rows repeated |
| 4 stores, first run, new products from the last 30 days | 82 (4 summaries, 60 best-sellers, 18 new products) | 7.4 s | - |
| Same 4 stores, run again | 64 (4 summaries + 60 best-sellers) | 8.7 s | 0 change rows repeated |
| Store at the 25,000-product limit, first run | 3 (summary + 2 new products) | 406 s | summary marked partial, cap named |
| Same store, run again | 1 (summary) | 432 s | peak memory 129-137 MB of 256 MB on this store |
| 4 bad inputs: 2 non-Shopify sites, a domain that does not exist, text that is not a URL | 0 | 8.7 s | each named in the run status; run succeeded |
| Field check: 10 random best-seller rows against the store's own product file | 10 of 10 matched | - | title, vendor, type, price range, stock flag |
| Best-seller order against the store's own collection page | 3 of 3 stores matched | - | - |

Each row is one run on the Apify cloud at 256 MB of memory, no proxy. Run time is the platform's run time, start-up included. The whole catalogue is read on every run, so run time grows with catalogue size, not with the number of rows returned. The field and order checks compared our rows with each store's public product files and collection pages.

### What data you get

**Shopify Best Sellers Tracker** compares each competitor Shopify store with your previous run and returns only what changed: new products, price changes with old and new price, stock-outs and restocks. It also returns the store's best-sellers in the store's own order and a catalogue summary (product count, price range and median, top vendors and product types). Paste store domains and schedule it daily; it reads only the public product feed and checks each store's robots.txt first.

- store_summary row per store: catalogue (product_count, variant_count, in/out of stock, on sale, price_low, price_high, price_median, top_vendors, top_product_types, newest_published_at), changes (counts), best_sellers_source, first_run, partial, note
- best_seller rows: rank, product id, title, vendor, type, price range, compare-at price, in-stock flag, product URL, image
- new_product rows: products added since your previous run (first run: created in the last 7 days)
- price_change rows: previous_price_min/max, price_min/max now, price_direction (up/down/mixed), price_change_pct, variant_changes with old and new price per variant
- stock_out and restock rows: products that sold out completely or came back in stock
- Every row: store domain, name and currency, created and published dates in ISO 8601 UTC, first_seen_at, source_url, scraped_at

| record_type | store_domain | rank | title | price_min | currency | available | best_sellers_source |
|---|---|---|---|---|---|---|---|
| store_summary | warmlydecor.com |  |  |  | USD |  | store's own Best Sellers collection: best-sellers |
| best_seller | warmlydecor.com | 1 | Motion Sensor LED Night Lights | 10.95 | USD | True | store's own Best Sellers collection: best-sellers |
| best_seller | warmlydecor.com | 2 | Brien - Solar Lawn Lights | 64.95 | USD | True | store's own Best Sellers collection: best-sellers |
| best_seller | notebooktherapy.com | 1 | Tsuki Bullet Journal Stencil Set ☾ | 34.08 | USD | True | store's own Best Sellers collection: best-sellers |

One full row record, exactly as a real run returned it (long text and lists shortened here). From a real run:

```json
{
  "record_type": "best_seller",
  "store_domain": "notebooktherapy.com",
  "store_name": "NotebookTherapy",
  "store_url": "https://notebooktherapy.com",
  "currency": "USD",
  "rank": 3,
  "product_key": "notebooktherapy.com:15474992775537",
  "product_id": 15474992775537,
  "title": "Tsuki ‘Matcha Bloom’ Travel Notebook Gift Set ☾",
  "handle": "tsuki-matcha-bloom-travel-notebook-gift-set",
  "vendor": "NotebookTherapy",
  "product_type": "Gift Sets",
  "product_url": "https://notebooktherapy.com/products/tsuki-matcha-bloom-travel-notebook-gift-set",
  "image_url": "https://cdn.shopify.com/s/files/1/2026/1775/files/01-matcha_bloom_set-carousel-2000.jpg?v=1774956451",
  "price_min": 74.78,
  "price_max": 82.13,
  "compare_at_price_max": 92.36,
  "available": true,
  "created_at": "2026-03-20T16:46:46Z",
  "published_at": "2026-03-31T12:02:35Z",
  "first_seen_at": "2026-11-04T04:50:32Z",
  "previous_price_min": null,
  "previous_price_max": null,
  "price_direction": null,
  "price_change_pct": null,
  "variant_changes": [],
  "best_sellers_source": "store's own Best Sellers collection: best-selling-products",
  "catalogue": null,
  "changes": null,
  "first_run": null,
  "partial": null,
  "note": null,
  "source_url": "https://notebooktherapy.com/products/tsuki-matcha-bloom-travel-notebook-gift-set",
  "scraped_at": "2026-11-04T11:20:24Z"
}
```

### Use cases

- Shopify store owners checking competitors' new products and price moves every day
- Brands spotting when a competitor sells out or restocks a product
- Dropshippers seeing which products competing stores list as best-sellers
- Agencies sending clients a daily competitor report in Google Sheets

### Use-case recipes

#### Daily competitor report in Google Sheets

For agencies and store owners. List the rival stores, give the list a change-tracking name and schedule it daily. Send rows to Google Sheets: `store_summary` rows give the counts per store, `price_change` rows give `previous_price_min`, `price_min` and `price_change_pct`, and `new_product` rows link to the new items by `product_url`.

```json
{
  "storeUrls": [
    "warmlydecor.com",
    "notebooktherapy.com",
    "meowingtons.com"
  ],
  "maxBestSellers": 10,
  "stateKey": "daily-report"
}
```

#### Stock-out and restock alerts

For brands watching when a rival sells out. Set best-sellers to 0 so a quiet day returns only the summary rows. Filter on `record_type` = stock_out or restock and send those rows to Slack or email through Zapier, Make or n8n; `product_url` and `title` say which product moved.

```json
{
  "storeUrls": [
    "warmlydecor.com",
    "meowingtons.com"
  ],
  "maxBestSellers": 0,
  "stateKey": "stock-alerts"
}
```

#### Best-seller rank tracking for product research

For dropshippers looking for proven products. Return 20 best-sellers per store on a weekly schedule. Key the `best_seller` rows on `product_id` and compare `rank` across runs; `first_seen_at` shows how long a product has been in your watch, and `best_sellers_source` says which store list the rank came from.

```json
{
  "storeUrls": [
    "notebooktherapy.com",
    "warmlydecor.com"
  ],
  "maxBestSellers": 20,
  "stateKey": "bestseller-weekly"
}
```

#### Launch watch: what did a store add recently?

For buyers and marketers tracking a rival's launches. On the first run, 'new products from the last N days' returns what the store created in that window; later runs return everything added since the previous run. Use `created_at` and `published_at` on the `new_product` rows to date each launch.

```json
{
  "storeUrls": [
    "notebooktherapy.com"
  ],
  "maxBestSellers": 0,
  "newWithinDays": 30,
  "stateKey": "launch-watch"
}
```

### Input

| Field | Type | What it does | Default |
|---|---|---|---|
| `storeUrls` (Competitor store URLs) | array | Shopify stores to watch, as a domain or any URL on the store, e.g. 'kith.com', 'https://www.allbirds.com'. |  |
| `maxBestSellers` (Best-sellers per store) | integer | How many best-sellers to return per store, in rank order, e.g. 20. 0 = skip best-sellers. | 20 |
| `maxProductsPerStore` (Max products per store) | integer | Upper limit of products read per store for the summary and change tracking, e.g. 1000. 0 = the whole catalogue... | 0 |
| `newWithinDays` (First run: new products from the last N days) | integer | On the first run for a store there is no previous run to compare with, so 'new products' are those... | 7 |
| `proxyConfiguration` (Proxy) | object | Optional proxy. | {"useApifyProxy": false} |

All 6 fields, with examples: see the **Input** tab.

### Use with AI agents (MCP)

MCP (Model Context Protocol) is the open standard that lets AI assistants such as Claude, ChatGPT and Cursor call outside tools. Apify's hosted MCP server at `https://mcp.apify.com/?tools=aurelix/shopify-best-sellers-tracker` gives your assistant this Actor only: it fills in the input from your request, runs it and reads the rows back, at the same per-result price as a run started by hand.

#### Example prompts

- "Show me the top 10 best-sellers of notebooktherapy.com in the store's own order with their prices"
- "Watch warmlydecor.com and meowingtons.com every day and tell me which products sold out or came back in stock since the last run"
- "Give me a catalogue summary of these two Shopify stores: product count, price range, median price and top vendors"

#### Claude Desktop and claude.ai

**Settings > Connectors > Add custom connector**, name it Apify, paste `https://mcp.apify.com/?tools=aurelix/shopify-best-sellers-tracker`, keep the detected OAuth settings, select **Add** and sign in to Apify.

#### Claude Code

```bash
claude mcp add --transport http apify "https://mcp.apify.com/?tools=aurelix/shopify-best-sellers-tracker"
```

#### Cursor and VS Code

Add this to `~/.cursor/mcp.json` (Cursor); in VS Code's `.vscode/mcp.json` put the same entry under `"servers"` with `"type": "http"`. Sign in to Apify when asked.

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com/?tools=aurelix/shopify-best-sellers-tracker"
    }
  }
}
```

#### ChatGPT

Turn on **Developer mode**, open **Settings > Apps & Connectors > Create**, paste the URL above as the MCP server URL, choose **OAuth** and authorize Apify.

Clients without sign-in send `Authorization: Bearer <YOUR_APIFY_TOKEN>` instead. No Apify account? This Actor supports Apify's agentic payments: an agent can pay per run with a prepaid, spend-capped token, bought with x402 stablecoin payments.

#### n8n AI agent

Give an **AI Agent** node an **MCP Client Tool** with the endpoint `https://mcp.apify.com/?tools=aurelix/shopify-best-sellers-tracker` and a Bearer credential holding your Apify token.

### Use it from AI agents (MCP), the API or no-code

#### Copy this to your AI assistant

```text
Use the Apify Actor aurelix/shopify-best-sellers-tracker (Shopify Best Sellers Tracker) through Apify's MCP server or API. Main input: storeUrls (Competitor store URLs). Example input: {"storeUrls": ["warmlydecor.com", "notebooktherapy.com"], "maxBestSellers": 20, "stateKey": "competitors-daily"}. Each result is one row with fields such as record_type, store_domain, store_name, store_url, currency, rank, product_key, product_id. It costs $3.00 per 1,000 rows on Apify's free plan plus a $0.0005 start fee per run, and needs no login.
```

MCP server URL for this Actor: `https://mcp.apify.com/?tools=aurelix/shopify-best-sellers-tracker` (setup for each client in the section above).

#### API

Start a run and read the dataset with Apify's REST API or the Python and JavaScript clients:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("aurelix/shopify-best-sellers-tracker").call(run_input={'storeUrls': ['warmlydecor.com', 'notebooktherapy.com'], 'maxBestSellers': 20, 'stateKey': 'competitors-daily'})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

#### No-code: schedule it in 3 clicks

Send the results to Google Sheets, Zapier, Make, n8n, Slack or any webhook URL.

1. Fill in the input, then click **Save as a new task**.
2. In the task, click **Schedule** and pick daily or weekly (Apify Schedules).
3. Open the task's **Integrations** tab to send every run's results to Slack, Google Sheets, email or any webhook.

Prefer n8n or Make? Ask in the **Issues** tab and we will share a ready-made workflow for it.

### FAQ

#### Can I scrape Shopify best sellers without login?

Yes. It never logs in, so you need no Shopify account, password or cookies; only a free Apify account to run it.

#### Is there a Shopify best sellers API?

You can use this Actor as one. Start it with Apify's REST API or the Python and JavaScript clients and read the results as JSON (see the code above), or call it from an AI agent through MCP.

#### How much does it cost to scrape Shopify best sellers?

About $3.00 for 1,000 rows on Apify's free plan and $2.10 on paid plans, start fee included. The free $5 monthly credit covers about 1,600 rows (plus $0.015 per store checked).

#### Can I export Shopify best sellers data to Excel or Google Sheets?

Yes. Download the results as Excel, CSV, JSON, XML or HTML from the run's **Storage** tab, or send them to Google Sheets with Apify's Google Sheets integration or the API.

#### Is it legal to scrape Shopify best sellers?

It reads only public data any logged-out visitor can see: the product feed each Shopify store serves to every visitor. It goes at a polite pace, respects robots.txt, never logs in and never solves CAPTCHAs. It returns product fields (title, price, variants, images, links); no customer or order data. To have a record removed, open an issue on this Actor's Issues tab; if a store formally asks us to stop, this Actor will stop. You are responsible for using the data lawfully, incl. anti-spam and privacy laws; this is not legal advice.

#### Where do the best-sellers come from?

From Shopify's public best-selling sort where the store's robots.txt allows it. Most stores disallow sorted pages, so the Actor then uses the store's own best-seller collection (e.g. 'Best Sellers'), in the order the store shows it. If neither is allowed or exists, no best-sellers are returned and best_sellers_source says why. Every best-seller row names its source in best_sellers_source, and rank is the store's own order, not sales figures.

#### What does the first run return?

The catalogue summary, the best-sellers, and products the store created in the last 7 days (adjustable). Price changes, stock-outs and restocks start from the second run, because they need a previous run to compare with.

#### How are price changes measured?

Per variant, against the variant's price at your previous run on that store. One row per product lists every variant that moved, with old and new price, and says whether prices went up, down or both.

#### What counts as a stock-out?

A product whose variants were in stock at the previous run and are all out of stock now. A restock is the reverse. Shopify's public feed has an in-stock flag, not quantities.

#### What if a store blocks access?

Stores whose robots.txt disallows the product feed, that hide the feed, or that are not on Shopify are skipped and named in the run status, as are store addresses that do not exist or do not answer ('store not reachable'). Other stores in the run still deliver.

#### Can I track the same stores for different purposes?

Yes. Give each watch list its own 'Change-tracking name', and each keeps its own memory of the previous run.

#### What does a quiet day cost?

One store summary per store read, at the per-store price, plus the best-seller rows you asked for. Change rows are only returned, and charged, when something changed. Set 'Best-sellers per store' to 0 to pay for the summaries only. Stores that are skipped return no rows and cost nothing beyond the start fee.

#### Why do best-sellers come back on every run?

Best-seller rows show the store's current order, so they are returned every run, not only when they change. Compare `rank` by `product_id` between runs to see products move up or down.

#### Can the same change be reported twice?

No. The change memory is saved before rows are returned. If the run's Max total charge stops output, the changes not returned are held back and come in the next run. In our reruns, 0 change rows repeated.

#### What happens when a store is only partly read?

If a store stops answering midway, its summary and change rows cover the products read so far, and the summary row has partial = true with a note. Best-sellers are skipped for that store on that run. The next run measures new products from your last complete run, so nothing added in between is missed.

#### How long is the change memory kept?

Per store and per change-tracking name. A product not seen for 90 days is forgotten. If a store is not checked for 90 days, its next run counts as a first run again.

#### What do price_direction and price_change_pct mean?

price_direction is up when every variant that moved went up, down when every one went down, and mixed otherwise. price_change_pct is the change of the product's lowest price against the lowest price at your previous run. variant_changes lists each moved variant with its old and new price.

#### How long does a run take?

The whole catalogue is read every run, 250 products per request. In our test runs three stores with 1,281 products took 4 s, and a store at the 25,000-product limit took about 7 minutes.

### Limits (stated honestly)

- Shopify stores only, and only stores that leave the public products.json feed on and allow it in robots.txt.
- Catalogues are read up to Shopify's public limit of 25,000 products per store; larger stores are summarised and tracked on those 25,000, and the summary row and run status say the cap was reached (partial: true).
- Best-sellers depend on what the store makes public: most stores disallow the best-selling sort in robots.txt, so the store's own best-seller collection is used, and some stores have none.
- Stock is an in-stock flag per variant, not a quantity.
- Prices are the ones the store serves to the Actor's server. Stores that price by visitor country can show other visitors converted prices: in our checks, two stores showed a Canadian address prices converted at a fixed rate.
- Changes are measured between your runs; anything that changed and changed back between two runs is not seen.
- If a store rate-limits midway, its report covers only the products read before that and is marked partial.
- Products removed from a store are not reported.

### Works great with

- **Before this: [Tech Stack API](https://apify.com/aurelix/tech-stack-detector)**: find out which domains are Shopify stores first; those go into `storeUrls`
- **Then: [Shopify Product Export Scraper](https://apify.com/aurelix/shopify-products-scraper)**: the same `storeUrls` for one full catalogue export

### Related Aurelix tools

Public Aurelix Actors, grouped by the data they collect. All are pay-per-result and need no login.

#### E-commerce and product data

- **[AliExpress Scraper API](https://apify.com/aurelix/aliexpress-product-search)**: AliExpress search results by keyword: price, discount, rating, units sold, ship-from country and sponsored flag.
- **[Amazon Best Sellers & Amazon New Releases](https://apify.com/aurelix/amazon-best-sellers)**: Amazon Best Sellers and New Releases top 100 on 10 marketplaces: rank, ASIN, price, rating, rank change.
- **[Shopify Product Export Scraper](https://apify.com/aurelix/shopify-products-scraper)**: Every public product of any Shopify store with variants, SKUs, prices, barcodes, stock counts and collections.

#### Jobs and hiring data

- **[Job Bank Canada Scraper API](https://apify.com/aurelix/job-bank-canada-scraper)**: Official Job Bank Canada postings by month: NOC and NAICS codes, wages, hours and location.
- **[Greenhouse Jobs Scraper](https://apify.com/aurelix/greenhouse-jobs-scraper)**: Live jobs from a company's Greenhouse, Lever, Ashby or SmartRecruiters board, with salary and Canadian province tags.
- **[LinkedIn Jobs Country Filter Scraper](https://apify.com/aurelix/linkedin-jobs)**: Public LinkedIn job postings by keyword and country: title, company, location, seniority, job type, salary text, description.
- **[Multiple Job Boards Scraper](https://apify.com/aurelix/multi-job-board-scraper)**: LinkedIn, about 50 company career sites, Remote OK and We Work Remotely jobs in one deduplicated list.
- **[Remote Job Board Scraper API](https://apify.com/aurelix/remote-jobs-scraper)**: Remote OK and We Work Remotely jobs in one deduplicated list with salary, regions and tags.

#### Leads and company data

- **[Contact Page Scraper](https://apify.com/aurelix/contact-details-scraper)**: Published company emails, phones, addresses, social pages and team members from a list of company websites.
- **[Decision Maker Finder](https://apify.com/aurelix/decision-maker-finder)**: Founders, CEOs, VPs and department heads from company team pages, with title, seniority and function.
- **[Newly Funded Companies Hiring](https://apify.com/aurelix/funded-companies-hiring)**: Companies that just raised money (SEC Form D), with their open roles and business contacts, as a new-only monitor.
- **[Google Maps Phone Scraper](https://apify.com/aurelix/google-maps-scraper)**: Local business lists from Google Maps: phones, websites, ratings, hours, coordinates; optional website emails and socials.
- **[Recently Funded Companies API](https://apify.com/aurelix/recently-funded-companies)**: US companies that just filed an SEC Form D: amount raised, industry, state, executives, confirmed website.
- **[Tech Stack API](https://apify.com/aurelix/tech-stack-detector)**: CMS, e-commerce platform, analytics, ad pixels, chat, CDN and email provider for each domain you enter.

#### Ad intelligence

- **[Competitor Watch](https://apify.com/aurelix/competitor-watch)**: One report per competitor with only what is new: Meta and TikTok ads, page changes, Shopify products and prices, jobs.
- **[Facebook Ad Library Search & API](https://apify.com/aurelix/facebook-ad-library-scraper)**: Facebook and Instagram business ads from the Meta Ad Library: copy, creatives, landing pages, dates, optional EU reach.
- **[TikTok Ads Library API](https://apify.com/aurelix/tiktok-ads-library-scraper)**: TikTok Ads Library ads for Europe, UK, Switzerland and Turkey with targeting, reach, ad text and landing pages.

#### Canada and government data

- **[Canada Building Permits](https://apify.com/aurelix/canada-building-permits-scraper)**: Building permits and development applications from 7 Canadian cities: address, type, status, dates, value, applicant, contractor and Toronto planner contact.
- **[Government Tenders Scraper](https://apify.com/aurelix/government-tenders-scraper)**: Open tenders from SAM.gov, CanadaBuys and EU TED in one table: buyer, codes, value, deadline, contact and link.
- **[USPTO Trademark API](https://apify.com/aurelix/uspto-trademark-search)**: US trademark search and watch from USPTO: mark, owner or number lookups, new filings, owner, attorney, goods.

#### AI, content and SEO

- **[Google Trends by Region](https://apify.com/aurelix/google-trends-scraper)**: Google Trends interest over time, by region and rising queries for any number of keywords, plus trending searches.
- **[Google Autocomplete API](https://apify.com/aurelix/google-autocomplete-scraper)**: Expands seed keywords into hundreds of real Google and YouTube autocomplete phrases, tagged by search intent.
- **[PDF Table Extraction & PDF to Markdown OCR](https://apify.com/aurelix/pdf-to-markdown)**: Turns linked PDF and Word files into Markdown per page, with tables as JSON rows, RAG chunks and OCR.
- **[Broken Link Crawler & SEO Audit](https://apify.com/aurelix/seo-audit-crawler)**: Audits a whole site: one row per page with SEO checks and broken links, plus a ranked issues summary.
- **[Website to Markdown API](https://apify.com/aurelix/website-to-markdown)**: Crawls a site and returns one row of clean main-content Markdown per page, with title, headings and links.
- **[YouTube Transcript Scraper](https://apify.com/aurelix/youtube-transcript-scraper)**: Returns YouTube video transcripts as text, timed segments and AI chunks, from videos, channels, playlists or searches.

#### More data tools

- **[Agoda API (Unofficial)](https://apify.com/aurelix/agoda-reviews-scraper)**: Scrape Agoda guest reviews at $0.50 per 1,000 with this unofficial Agoda API, cheaper than the leading tools: Agoda and...
- **[Tennis Betting Odds Scraper](https://apify.com/aurelix/tennis-odds-scraper)**: Tennis results and upcoming matches with opening and closing odds per bookmaker and implied probabilities.

### Recent changes

- **0.1**: The form starts with 10 best-sellers and 250 products per store, so a first test run finishes quickly.

The full history is on the **Changelog** tab.

### Tested daily

An automated health check runs this Actor every day on a fixed input and checks that at least 9 rows come back with `record_type`, `store_domain`, `store_url`, `source_url`, `scraped_at` filled in; a failed check alerts the maintainer straight away.

### Your feedback

Missing a field, found a bug or need another filter? Open an issue on the **Issues** tab; we aim to answer within a day. If this Actor saved you time, a short review helps other people find it.

# Changelog

This Actor's version history is a separate document: https://apify.com/aurelix/shopify-best-sellers-tracker/changelog.md

# Actor input Schema

## `storeUrls` (type: `array`):

Shopify stores to watch, as a domain or any URL on the store, e.g. 'kith.com', 'https://www.allbirds.com'. Only the domain is used. Stores whose robots.txt blocks the product feed, or that hide it, are skipped and named in the run status.

## `maxBestSellers` (type: `integer`):

How many best-sellers to return per store, in rank order, e.g. 20. 0 = skip best-sellers.

## `newWithinDays` (type: `integer`):

On the first run for a store there is no previous run to compare with, so 'new products' are those the store created in the last N days, e.g. 7. Later runs report everything added since the previous run.

## `maxProductsPerStore` (type: `integer`):

Upper limit of products read per store for the summary and change tracking, e.g. 1000. 0 = the whole catalogue (recommended, so changes and the summary are complete).

## `stateKey` (type: `string`):

Name for the 'previous run' memory used for new products, price changes and stock changes, e.g. 'competitors-daily'. Leave empty to share one memory per store across all your runs.

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

Optional proxy. Shopify stores are public and usually work without one; turn on Apify Proxy if a store answers with rate limits (HTTP 429).

## Actor input object example

```json
{
  "storeUrls": [
    "notebooktherapy.com"
  ],
  "maxBestSellers": 10,
  "newWithinDays": 7,
  "maxProductsPerStore": 250,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `report` (type: `string`):

One store_summary row per store, then its best_seller, new_product, price_change, stock_out and restock rows.

# 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 = {
    "storeUrls": [
        "notebooktherapy.com"
    ],
    "maxBestSellers": 10,
    "maxProductsPerStore": 250
};

// Run the Actor and wait for it to finish
const run = await client.actor("aurelix/shopify-best-sellers-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 = {
    "storeUrls": ["notebooktherapy.com"],
    "maxBestSellers": 10,
    "maxProductsPerStore": 250,
}

# Run the Actor and wait for it to finish
run = client.actor("aurelix/shopify-best-sellers-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 '{
  "storeUrls": [
    "notebooktherapy.com"
  ],
  "maxBestSellers": 10,
  "maxProductsPerStore": 250
}' |
apify call aurelix/shopify-best-sellers-tracker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,aurelix/shopify-best-sellers-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/6mjDKuBnEvdsxaPbF/builds/eLEJZuvlVRYMPjHcl/openapi.json
