# Shopify Variant Price & Stock Watch (`isolovyev/shopify-variant-watch`) Actor

Track Shopify competitor prices, sale prices and variant availability. Keep repeat history and export a change digest. Мониторинг цен и наличия вариантов товаров Shopify с историей изменений.

- **URL**: https://apify.com/isolovyev/shopify-variant-watch.md
- **Developed by:** [Ivan Solovyev](https://apify.com/isolovyev) (community)
- **Categories:** E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.00 / 1,000 verified variant observations

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 Variant Price & Stock Watch

<table width="100%"><tr><td style="padding:24px 28px;background:#EEF2FF;border:1px solid #C7D2FE;border-top:4px solid #4F46E5;border-radius:12px"><span style="font-size:23px;font-weight:800;color:#1E1B4B">Turn competitor prices and availability into a daily decision</span><br><span style="font-size:15px;color:#4B5563">Stable variant IDs, repeat observations and a digest for your spreadsheet.</span></td></tr></table>

Monitor public Shopify product variants with product and variant IDs, price, compare-at price, currency, SKU and boolean availability. Each Dataset row represents one verified variant observation. A separate SUMMARY provides source coverage, change counts and errors, and CHANGES contains new variants, price changes and back-in-stock signals.

For Shopify store owners, pricing analysts and agencies that need a repeatable competitor-price review.

### Start with a buying decision

Watch the exact competitor products your team compares each morning. Keep the same `watchId` for repeat runs. Export Dataset observations to Google Sheets or use the Apify Make integration to fetch CHANGES after the run completes. Match competitor products using your own comparison table of product and variant IDs; SKU is descriptive data, not a cross-store match key.

```json
{"storeUrls":["https://colourpop.com/products/pencil-sharpener"],"watchId":"daily-competitor","mode":"monitor","maxProductsPerStore":2,"maxVariantsPerStore":100}
```

Store roots, locale roots, collection URLs and exact product URLs are supported. Product URLs provide the most focused repeat workflow. Requests use the storefront locale and the currency supplied by its public cart. Changing domain, locale or currency creates a separate comparison identity.

### Read the result

`new` establishes a baseline variant; `changed` identifies changed fields; `back_in_stock` means availability changed from false to true; `unchanged` keeps an auditable repeat observation. `available` describes public purchase availability, not a warehouse quantity. Prices include zero-priced products when the storefront exposes them. Compare-at price can be null.

SUMMARY reports `complete_requested_scope`, product/page limits, variant limits, source errors and the Shopify variant API cap. The public product endpoint returns at most 250 variants. An absent variant is retained in history; this Actor emits no removal events. A complete requested scope is an observation of the public endpoint at that time, not a promise of a static catalog.

Monitor history is isolated by Apify actor, user and `watchId` in a named store. Run the same watch sequentially; separate watches can run independently. The latest 30 runs and 2000 recently observed variants are retained. An evicted variant establishes a new baseline when observed again. Snapshot mode produces a fresh baseline without updating monitor state. A run delivers at most 2000 variant observations. Requests, redirects, response size, products, variants, concurrency and runtime have explicit limits. State advances only for rows confirmed in the Dataset after delivery, including spending-limit handling.

### Russian

Отслеживайте цены и наличие вариантов товаров конкурентов в публичных Shopify-магазинах. В Dataset есть стабильные product/variant ID, цена, цена до скидки, валюта и булево наличие. SUMMARY показывает полноту выбранной области, ошибки источников и счётчики изменений; CHANGES содержит новые варианты, изменения и возвращение в наличие.

Для ежедневного контроля используйте точные ссылки на товары и постоянный `watchId`. История разделяется по актору, пользователю и наблюдению. Повторные запуски одного наблюдения выполняйте последовательно. Для сравнения конкурентов заведите свою таблицу соответствий product/variant ID: одинаковый SKU между магазинами не гарантирован.

`available` означает возможность покупки по публичным данным магазина. Количество на складе не вычисляется. Валюта берётся из публичной корзины того же магазина и локали. Лимит Product API составляет 250 вариантов; границы обхода отражаются в SUMMARY. Пропавшие из ограниченной выборки варианты сохраняются в истории, события удаления не создаются.

Актуальная цена указана в разделе Pricing на странице актора.

The Actor uses fixed 256 MB memory. Each run allows up to 60 seconds of source collection, 100 HTTP requests, and 8 MiB each of encoded and decoded HTTP bodies (4 MiB by default). The complete run, including storage, has a 90-second deadline. Budget-limited targets appear in SUMMARY. Output is bounded to 2 MiB and 2,000 observations; compact watch state to 512 KiB and 2,000 variants. Oldest observations may be evicted when either state limit is reached. Product metadata is shared across variant state records. Titles, SKUs, IDs and rows have size limits.

Актор работает с фиксированной памятью 256 МБ. Сбор ограничен 60 секундами, 100 HTTP-запросами и 8 MiB для encoded и decoded тел отдельно (по умолчанию 4 MiB). Полный запуск с записью данных ограничен 90 секундами. Источники, остановленные бюджетом, отмечаются в SUMMARY. Выход: до 2000 наблюдений и 2 MiB; компактное состояние: до 2000 вариантов и 512 KiB. При достижении любого предела состояния старые наблюдения могут вытесняться. Product metadata хранится один раз для вариантов товара. Для названий, SKU, ID и строк действуют ограничения размера.

# Actor input Schema

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

Public Shopify URLs. Use exact product URLs for focused competitor checks. Публичные ссылки Shopify, точные товары для узкого контроля.

## `watchId` (type: `string`):

Reuse this ID and run the same watch sequentially. Повторяйте этот ID, запускайте одно наблюдение последовательно.

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

Monitor stores repeat history; snapshot makes a fresh baseline. Мониторинг хранит историю, срез создаёт новую базу.

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

Bound the collection workload. Ограничение объёма обхода.

## `maxVariantsPerStore` (type: `integer`):

Bound the collection workload. Ограничение объёма обхода.

## `maxPagesPerStore` (type: `integer`):

Bound the collection workload. Ограничение объёма обхода.

## `maxRequests` (type: `integer`):

Bound the collection workload. Ограничение объёма обхода.

## `deadlineSeconds` (type: `integer`):

Bound the collection workload. Ограничение объёма обхода.

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

Bound the collection workload. Ограничение объёма обхода.

## `maxTransferMiB` (type: `integer`):

Total encoded and decoded HTTP bodies are independently bounded. Общий объём encoded и decoded HTTP тел ограничен отдельно.

## Actor input object example

```json
{
  "storeUrls": [
    "https://colourpop.com/products/pencil-sharpener"
  ],
  "watchId": "prefill-shopify",
  "mode": "monitor",
  "maxProductsPerStore": 1,
  "maxVariantsPerStore": 5,
  "maxPagesPerStore": 1,
  "maxRequests": 6,
  "deadlineSeconds": 45,
  "concurrency": 1,
  "maxTransferMiB": 4
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

## `summary` (type: `string`):

No description

## `changes` (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 = {
    "storeUrls": [
        "https://colourpop.com/products/pencil-sharpener"
    ],
    "watchId": "prefill-shopify",
    "mode": "monitor",
    "maxProductsPerStore": 1,
    "maxVariantsPerStore": 5,
    "maxPagesPerStore": 1,
    "maxRequests": 6,
    "deadlineSeconds": 45,
    "concurrency": 1,
    "maxTransferMiB": 4
};

// Run the Actor and wait for it to finish
const run = await client.actor("isolovyev/shopify-variant-watch").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": ["https://colourpop.com/products/pencil-sharpener"],
    "watchId": "prefill-shopify",
    "mode": "monitor",
    "maxProductsPerStore": 1,
    "maxVariantsPerStore": 5,
    "maxPagesPerStore": 1,
    "maxRequests": 6,
    "deadlineSeconds": 45,
    "concurrency": 1,
    "maxTransferMiB": 4,
}

# Run the Actor and wait for it to finish
run = client.actor("isolovyev/shopify-variant-watch").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": [
    "https://colourpop.com/products/pencil-sharpener"
  ],
  "watchId": "prefill-shopify",
  "mode": "monitor",
  "maxProductsPerStore": 1,
  "maxVariantsPerStore": 5,
  "maxPagesPerStore": 1,
  "maxRequests": 6,
  "deadlineSeconds": 45,
  "concurrency": 1,
  "maxTransferMiB": 4
}' |
apify call isolovyev/shopify-variant-watch --silent --output-dataset

```

## MCP server setup

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

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/Md8OwYQgPeGX4eG1Y/builds/niTjeszP5B03vdhoq/openapi.json
