# Shopify New Arrivals and Removed Products Delta Watch (`practical_ai_lab_jp/pal-shopify-new-arrivals-delta-watch`) Actor

Give one public Shopify store URL. The first run saves a baseline; each later run reports new and removed product handles with dated JSON and CSV evidence.

- **URL**: https://apify.com/practical_ai_lab_jp/pal-shopify-new-arrivals-delta-watch.md
- **Developed by:** [Practical AI Lab](https://apify.com/practical_ai_lab_jp) (community)
- **Categories:** E-commerce, Developer tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 delta reports

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 New Arrivals and Removed Products Delta Watch

**See which products a Shopify store added or removed since your last check.** Enter one public store URL, run once to save a baseline, then repeat or schedule it to receive dated JSON/CSV evidence. No Shopify login or uploaded CSV needed.

**Verified first-run example:** An Apify run on November 4, 2026 successfully created a `BASELINE_CREATED` report using `https://www.allbirds.com`. This establishes that one bounded initial scan worked; it does **not** prove future site access, changes, or paying demand.

**Billing:** The published pay-per-event configuration charges $0.02 per `delta-report` for a successful repeat run with detected new/removed products. Baselines and unchanged runs do not trigger that event, but Apify Actor-start and usage fees may still apply. Check the live Pricing tab before running.

**Need price drops or restocks instead?** Use [Shopify Price & Restock Monitor](https://apify.com/practical_ai_lab_jp/pal-shopify-storefront-price-restock-watch), which watches a different change type and has its own charges.

Give this Actor **one public Shopify storefront URL**. It reads the store's public product feed (`/products.json`) within strict limits and remembers a small baseline of product handles. On every later run it tells you which published product handles are **new** and which have **disappeared**, and saves dated JSON and CSV evidence.

You do not upload CSV or JSON files and you do not provide two snapshots. The Actor keeps the baseline itself.

### Quick start (one URL)

1. Open the Actor and paste a store you are allowed to monitor:

```json
{
    "storeUrl": "https://www.allbirds.com",
    "maxPages": 3,
    "maxChangedRecords": 200,
    "sampleSize": 5,
    "requestDelaySeconds": 1
}
```

The URL above is only an example of a public storefront format. Replace it with your own target. Only `storeUrl` is required; the other fields show the defaults.

2. **First run:** the dataset contains one `BASELINE_CREATED` row plus a few `SAMPLE_PRODUCT` rows so you can confirm the feed was read correctly. No changes are reported yet, because there is nothing to compare against.
3. **Second and later runs:** the dataset contains a `DELTA_SUMMARY` row, then `NEW_PRODUCT` and `REMOVED_PRODUCT` rows, plus samples.

### How to schedule later runs

Changes are only detected when the Actor runs. Create a schedule in Apify Console (**Schedules**) that runs this Actor with the same input, for example once per day. Use the **same Apify account and the same Actor** every time so the saved baseline is found. The Actor does not send alerts by itself; connect the dataset or run result to your own integration or webhook if you want notifications. Without a schedule, nothing runs on its own.

### Output

Dataset rows (flat records, see the dataset view in Console):

| Field | Meaning |
| --- | --- |
| `recordType` | `BASELINE_CREATED`, `DELTA_SUMMARY`, `NEW_PRODUCT`, `REMOVED_PRODUCT`, `SAMPLE_PRODUCT` |
| `status` | `BASELINE_CREATED`, `CHANGES_FOUND` or `NO_CHANGES` (summary rows) |
| `storeDomain`, `runDate`, `observedAt` | Store host and UTC date/time of the read |
| `handle`, `title`, `productUrl` | Product identity (`https://<store>/products/<handle>`) |
| `newCount`, `removedCount`, `catalogSize`, `previousCatalogSize`, `pagesRead` | Counts in summary rows |
| `catalogComplete`, `comparisonScope` | Whether the whole feed was read; `baseline`, `complete_catalog` or `partial_window` |
| `baselineObservedAt` | When the compared baseline was taken |
| `notes` | Plain-language caveats for that run |

Key-value store records:

- `OUTPUT`: summary of the run, or `{"status": "FAILED", "errorCode": ..., "message": ...}` on failure.
- `EVIDENCE-<UTC date>-<store domain>.json` and `.csv`: every new and removed handle for that run. A second run on the same UTC day overwrites that day's evidence files.
- `BASELINE-<store domain>`: the saved baseline (handle and title per product, at most 2,500 products).

### What the Actor does for safety

- Accepts only `https://` URLs on the default port, without credentials; IP addresses, `localhost` and internal-looking host names are refused.
- Resolves the host name and refuses to connect if any address is private, loopback, link-local or otherwise non-public (checked before `robots.txt` and before every page).
- Fetches `robots.txt` first and checks it for the `PALShopifyDeltaWatch` user agent before every feed request. A `Crawl-delay` is respected (capped at 10 seconds). A missing robots file (404/410) is treated as no restrictions; 401/403 or any other error is treated as denied or unknown and the run stops.
- Does not follow redirects, limits response size, uses a 15 second timeout and reads at most `maxPages` (1 to 10) pages of 250 products.
- Reads only the public product feed. No login, no proxies, no customer data, no checkout or cart pages.

### Pricing event

The code calls `delta-report` once per **successful repeat run with a new or removed product**. The observed Apify Store price is $0.02 per such report; the live Pricing tab is authoritative. Baseline, no-change and failed runs do not trigger `delta-report`, but Actor-start and platform usage charges may still apply.

### Limitations and sample-size caveats

- **Only what the public feed shows.** Stores can disable or restrict `/products.json`, in which case the run fails with a clear error. Products hidden from the online storefront do not appear, so "removed" can also mean "unpublished" or "hidden from this sales channel", not necessarily deleted.
- **Handle-based.** A renamed handle appears as one removed and one new product. Price, stock and variant changes are not tracked.
- **Large catalogs.** At most 10 pages (2,500 products) are read. If the cap is reached, the run is marked `catalogComplete: false` and `comparisonScope: partial_window`: removed products are **not** reported, and "new" items may simply have moved into the read window. Raise `maxPages` for bigger stores, up to 10.
- **Between-run blind spot.** Products added and removed between two runs are never seen. Results reflect two points in time only.
- **Small samples.** One store with a few changes says little about its overall launch cadence; judge trends over many scheduled runs.
- **First run is not a delta.** The first run only stores the baseline.
- **Feed ordering** is controlled by the store and may change, which matters only for partial windows.
- **Network checks** validate DNS before connecting, but cannot fully rule out DNS changes between the check and the connection.
- One first-run baseline on a permitted public storefront was successfully verified, but repeat-run change detection has not been proven on that store. Verify your own target and respect each store's terms and applicable law.

# Actor input Schema

## `storeUrl` (type: `string`):

One public HTTPS storefront URL of a Shopify store you are allowed to monitor, for example https://www.allbirds.com. Only the domain is used. IP addresses, ports, credentials and non-HTTPS URLs are rejected.

## `maxPages` (type: `integer`):

Maximum product feed pages to read (250 products per page). Larger catalogs are only partly compared when the cap is reached.

## `maxChangedRecords` (type: `integer`):

Cap on NEW_PRODUCT and REMOVED_PRODUCT dataset rows. The evidence file always lists every detected handle.

## `sampleSize` (type: `integer`):

Number of current products echoed as SAMPLE_PRODUCT rows so you can check the feed was read correctly.

## `requestDelaySeconds` (type: `integer`):

Pause between feed pages. A larger Crawl-delay in robots.txt takes precedence (capped at 10 seconds).

## Actor input object example

```json
{
  "storeUrl": "https://www.allbirds.com",
  "maxPages": 3,
  "maxChangedRecords": 200,
  "sampleSize": 5,
  "requestDelaySeconds": 1
}
```

# 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 = {
    "storeUrl": "https://www.allbirds.com"
};

// Run the Actor and wait for it to finish
const run = await client.actor("practical_ai_lab_jp/pal-shopify-new-arrivals-delta-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 = { "storeUrl": "https://www.allbirds.com" }

# Run the Actor and wait for it to finish
run = client.actor("practical_ai_lab_jp/pal-shopify-new-arrivals-delta-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 '{
  "storeUrl": "https://www.allbirds.com"
}' |
apify call practical_ai_lab_jp/pal-shopify-new-arrivals-delta-watch --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,practical_ai_lab_jp/pal-shopify-new-arrivals-delta-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/v82l1fHFGl7CjjeOJ/builds/nkpogAOpvWTsi8LvJ/openapi.json
