# Price & Stock Delta Monitor (Shopify + Schema.org) (`yushi3/price-delta-monitor`) Actor

Hourly price and stock checks for Shopify and Schema.org product pages. Returns compact JSON with PRICE_DROP, PRICE_INCREASE, OUT_OF_STOCK and BACK_IN_STOCK deltas and optional webhook alerts. Pay per product checked.

- **URL**: https://apify.com/yushi3/price-delta-monitor.md
- **Developed by:** [Yushi Homma](https://apify.com/yushi3) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 product checkeds

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

## Price & Stock Delta Monitor

Track price and stock changes on product pages. Give it product URLs; on every run it returns each variant's current price and stock status, **what changed since the previous run**, and can POST each change to your webhook.

- **Shopify stores**: any `/products/<handle>` URL, read from Shopify's public product endpoint (every variant, SKU, price and stock status).
- **Any other store with Schema.org data**: product pages that embed `Product` or `ProductGroup` JSON-LD (most large e-commerce platforms do).
- **Change detection built in**: `PRICE_DROP`, `PRICE_INCREASE`, `OUT_OF_STOCK`, `BACK_IN_STOCK`, `UNCHANGED`, `FIRST_SEEN`, with the previous price and the delta.
- **API and AI agent tool**: check a URL in one API call, or let an AI agent call it as a tool through the Apify MCP server.
- **No browser, low cost**: plain HTTP requests, 256 MB memory, a few seconds per run.

### Use cases

- Watch competitors' prices and get a webhook (to Slack, email or a spreadsheet via Zapier, Make or n8n) the moment they change.
- Get alerted when a sold-out size or color comes back in stock.
- Feed a repricing tool or a price-history dashboard with clean, typed deltas.
- Give an AI agent a reliable "what does this product cost right now?" tool.

### How to use it

1. Add product URLs, for example `https://www.allbirds.com/products/mens-wool-runners`.
2. Optionally set **Alert webhook URL**. Each price or stock change is POSTed there as JSON.
3. Run it on a [schedule](https://docs.apify.com/platform/schedules) (hourly or daily). The first run records a baseline (`FIRST_SEEN`); later runs report changes against the previous run.

Price history is kept per product URL and variant SKU in your account's key-value store `price-delta-monitor-state`, so it survives between scheduled runs.

### Tutorial: get a Slack message when a Shopify product's price drops

1. In [Zapier](https://zapier.com), [Make](https://www.make.com) or [n8n](https://n8n.io), create a scenario that starts with a **webhook trigger** ("Catch Hook" in Zapier, "Custom webhook" in Make, "Webhook" node in n8n) and copy its URL.
2. Add a **Filter** step that continues only when `item.changeType` is `PRICE_DROP` (or also `BACK_IN_STOCK`), then a **Slack → Send message** step with `item.title`, `item.previousPrice`, `item.currentPrice` and `item.url`.
3. In this Actor, paste the product links under **Product URLs** and the webhook URL into **Alert webhook URL**.
4. Run it once. That run records today's prices as the baseline (`FIRST_SEEN`).
5. Open **Schedules** in Apify Console and run the Actor hourly or daily. Every price or stock change is POSTed to your scenario, and the filter decides which ones reach Slack.

### Input

```json
{
  "urls": ["https://www.allbirds.com/products/mens-wool-runners"],
  "alertWebhookUrl": "https://hooks.example.com/price-alerts"
}
```

| Field | Required | Description |
| --- | --- | --- |
| `urls` | yes | 1 to 1,000 product page URLs. |
| `alertWebhookUrl` | no | Receives a POST for every price or stock change. |
| `proxyConfiguration` | no | Leave empty to connect directly and fall back to Apify datacenter, then residential proxies only for stores that block the run. Set a proxy to use it for every request. |

### Output

One dataset item per variant:

```json
{
  "url": "https://www.allbirds.com/products/mens-wool-runners",
  "sku": "WR3MNGL090",
  "title": "Men's Wool Runner - Natural Grey (Light Grey Sole) - 9",
  "currency": "USD",
  "currentPrice": 99,
  "inStock": true,
  "previousPrice": 110,
  "priceDelta": -11,
  "changeType": "PRICE_DROP",
  "checkedAt": "2026-10-25T04:00:00.000Z"
}
```

The webhook body is `{ "actor": "price-delta-monitor", "item": { ...same fields... }, "detectedAt": "<ISO time>" }`.

### API and AI agents

Run it and get the results in one call:

```bash
curl -X POST "https://api.apify.com/v2/acts/yushi3~price-delta-monitor/run-sync-get-dataset-items" \
  -H "Authorization: Bearer <APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"urls": ["https://www.allbirds.com/products/mens-wool-runners"]}'
```

It returns the dataset items as a JSON array. AI agents can call the Actor as a tool through the [Apify MCP server](https://mcp.apify.com).

### Pricing

You pay per product URL checked, not per variant, plus a small fee per alert actually delivered:

| Event | Price |
| --- | --- |
| Product checked | $0.002 |
| Change alert delivered to your webhook | $0.005 |

You are **not charged** when a page can't be read: if a store blocks the request or a page has no machine-readable price, the run fails loudly instead of returning empty or made-up data, and nothing is billed for that URL. Failed webhook deliveries are not billed either.

### Limitations

- Pages must expose prices to plain HTTP: either a Shopify store or Schema.org product JSON-LD. Sites that render prices only with JavaScript, or that block automated requests (for example eBay, Best Buy), are not supported.
- Prices are reported as the store displays them to an anonymous visitor in the store's default currency.
- Change detection compares against the previous run of your account; the first run for a URL is always `FIRST_SEEN`.
- Some stores block automated requests even for their public product data; those URLs are reported as unreachable and not billed.

### When a URL fails

One bad URL never costs you the rest of the run. Every URL is checked; failures are listed in the run's key-value store under `FAILED_TARGETS` with the reason, for example a discontinued product (`product no longer exists (redirects to …)`) or a store blocking the request. The run only fails outright when a store's page format changed in a way the Actor can no longer read, or when every URL failed.

### Questions and issues

Open an issue on the Actor's **Issues** tab. The Actor is re-tested against live stores every 12 hours, so breakages caused by store changes are caught quickly.

# Actor input Schema

## `urls` (type: `array`):

Shopify product URLs (/products/<handle>) or any product page with Schema.org Product JSON-LD.

## `alertWebhookUrl` (type: `string`):

Optional. Receives a POST with the item whenever a price or stock change is detected.

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

Optional. By default each store is fetched directly and only falls back to Apify datacenter, then residential proxies when it blocks the run; the proxy that worked is reused for a week. Set a proxy here to use it for every request instead.

## Actor input object example

```json
{
  "urls": [
    "https://www.allbirds.com/products/mens-wool-runners"
  ]
}
```

# Actor output Schema

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

One item per product variant: current price, stock status, previous price, delta and change type.

# 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 = {
    "urls": [
        "https://www.allbirds.com/products/mens-wool-runners"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("yushi3/price-delta-monitor").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 = { "urls": ["https://www.allbirds.com/products/mens-wool-runners"] }

# Run the Actor and wait for it to finish
run = client.actor("yushi3/price-delta-monitor").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 '{
  "urls": [
    "https://www.allbirds.com/products/mens-wool-runners"
  ]
}' |
apify call yushi3/price-delta-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,yushi3/price-delta-monitor"
        }
    }
}
```

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/guYALinrmDgkcvMbB/builds/EkX7pQSqT5hi8o8MX/openapi.json
