# Price & Availability Drift Monitor (`checksmithcats/price-availability-drift-monitor`) Actor

Tracks detectable price and stock drift between a public product feed, live product pages, and the previous run. Reads only public URLs.

- **URL**: https://apify.com/checksmithcats/price-availability-drift-monitor.md
- **Developed by:** [Checksmith Cats](https://apify.com/checksmithcats) (community)
- **Categories:** Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.60 / drift report generated

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use 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

## Price & Availability Drift Monitor

### Summary

Track detectable product feed health, price, and stock drift across scheduled runs.

### Description

Run it on an Apify Schedule when you need a lightweight record of how feed availability, parsed row count, feed price, page price, and stock signals changed since the previous run. It reuses the Merchant Feed Preflight feed-vs-page checks, then stores a redacted state snapshot and reports drift findings on the next run.

The first run saves a baseline and returns the normal feed-vs-page report. Later runs add drift findings for feed fetch/parse/count changes, price changes, availability flips, newly mismatched products, resolved mismatches, new products, and removed products.

### Good fit

- ecommerce operators monitoring price or stock sync after feed automation changes
- agencies watching a small scheduled product sample
- developers who need dataset rows showing drift detected in the current run
- feed operators checking fetch status, parse status, and parsed product-count drops
- QA workflows that already use Apify Schedule and max cost/run controls

### Not a fit

- failure notification service
- threshold alerting
- guaranteed detection of every feed or page change
- account recovery
- appeal writing
- policy/legal review
- managed feed repair
- login/CAPTCHA/proxy bypass

### Input

- `feedUrl`: public product feed URL. State keys store only a hash of this URL.
- `storeUrl`: optional storefront URL
- `sampleLimit`: 1-200 products
- `country`: report context
- `currency`: default comparison currency
- `recordRobots`: record robots.txt status
- `stateStoreName`: named Apify Key-Value Store for previous snapshots

### Output

- dataset rows, one per finding
- JSON report
- HTML report
- Markdown report
- drift Evidence Pack with redacted URLs, state feed hash, state keys, and checked item metadata

### Drift Findings

- `drift.price_changed`
- `drift.availability_flipped`
- `drift.feed_unreachable`
- `drift.feed_parse_failed`
- `drift.feed_count_dropped`
- `drift.newly_mismatched`
- `drift.resolved`
- `drift.new_product`
- `drift.removed_product`
- `drift.baseline_saved` on first run

### Billing note

Pay-per-event billing is based on reachable product pages only.

Monitoring runs can happen daily or weekly, so users should set Apify max cost/run before enabling a frequent Schedule. Monthly exposure should be estimated as:

`scheduled runs per month x max cost/run`

Choose a `sampleLimit` that matches the desired maximum reachable products per run, then set max cost/run so a repeated Schedule cannot create an unexpected bill.

### Boundaries

This is an informational diagnostic record of detectable drift in the current run. It does not promise failure notifications, threshold alerts, guaranteed detection of every feed or page change, account recovery, policy repair, ad performance, or platform approval.

Feed-health drift is separate from price and availability value drift. It records whether the feed could be fetched, whether product rows could be parsed, and whether the parsed product count dropped sharply. It does not store raw feed bodies.

### Related tools

- Merchant Feed Preflight - Use when you need a one-off feed/page preflight before setting up drift monitoring.
- Meta Catalog Feed Preflight - Use when Meta catalog records are the source of the feed risk.
- Apify Dataset Drift Monitor - Use when the changing source is an Apify dataset instead of a product feed.

# Actor input Schema

## `feedUrl` (type: `string`):

Public HTTPS URL of a Google-style product feed in CSV, TSV, RSS/XML, or Atom/XML format. The state key stores only a hash of this URL.
## `storeUrl` (type: `string`):

Optional public store homepage URL. If omitted, the Actor infers the store from product links in the feed.
## `sampleLimit` (type: `integer`):

Maximum number of products to sample from the feed on each scheduled run. This is the main per-run cost control.
## `country` (type: `string`):

Optional country label shown in the report header. Does not change the checks.
## `currency` (type: `string`):

Optional default ISO currency (e.g. USD) applied when a feed or page price omits one, so amounts compare correctly.
## `recordRobots` (type: `boolean`):

When enabled, the report records robots.txt availability. This MVP does not parse robots.txt rules or bypass blocks/login walls.
## `stateStoreName` (type: `string`):

Named Apify Key-Value Store used to keep previous snapshots across runs. Do not put secrets in this name.

## Actor input object example

```json
{
  "feedUrl": "https://example.com/products.xml",
  "sampleLimit": 25,
  "country": "US",
  "currency": "USD",
  "recordRobots": true,
  "stateStoreName": "price-availability-drift-state"
}
````

# Actor output Schema

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

No description

## `report` (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 = {
    "feedUrl": "https://example.com/products.xml"
};

// Run the Actor and wait for it to finish
const run = await client.actor("checksmithcats/price-availability-drift-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 = { "feedUrl": "https://example.com/products.xml" }

# Run the Actor and wait for it to finish
run = client.actor("checksmithcats/price-availability-drift-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "feedUrl": "https://example.com/products.xml"
}' |
apify call checksmithcats/price-availability-drift-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=checksmithcats/price-availability-drift-monitor",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Price & Availability Drift Monitor",
        "description": "Tracks detectable price and stock drift between a public product feed, live product pages, and the previous run. Reads only public URLs.",
        "version": "0.1",
        "x-build-id": "6CHxsMGzvPZUbcHYq"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/checksmithcats~price-availability-drift-monitor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-checksmithcats-price-availability-drift-monitor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/checksmithcats~price-availability-drift-monitor/runs": {
            "post": {
                "operationId": "runs-sync-checksmithcats-price-availability-drift-monitor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/checksmithcats~price-availability-drift-monitor/run-sync": {
            "post": {
                "operationId": "run-sync-checksmithcats-price-availability-drift-monitor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "feedUrl"
                ],
                "properties": {
                    "feedUrl": {
                        "title": "Product feed URL",
                        "pattern": "^https?:\\/\\/.+",
                        "type": "string",
                        "description": "Public HTTPS URL of a Google-style product feed in CSV, TSV, RSS/XML, or Atom/XML format. The state key stores only a hash of this URL."
                    },
                    "storeUrl": {
                        "title": "Store URL",
                        "pattern": "^https?:\\/\\/.+",
                        "type": "string",
                        "description": "Optional public store homepage URL. If omitted, the Actor infers the store from product links in the feed."
                    },
                    "sampleLimit": {
                        "title": "Sample limit",
                        "minimum": 1,
                        "maximum": 200,
                        "type": "integer",
                        "description": "Maximum number of products to sample from the feed on each scheduled run. This is the main per-run cost control.",
                        "default": 25
                    },
                    "country": {
                        "title": "Target country",
                        "type": "string",
                        "description": "Optional country label shown in the report header. Does not change the checks.",
                        "default": "US"
                    },
                    "currency": {
                        "title": "Expected currency",
                        "type": "string",
                        "description": "Optional default ISO currency (e.g. USD) applied when a feed or page price omits one, so amounts compare correctly.",
                        "default": "USD"
                    },
                    "recordRobots": {
                        "title": "Record robots.txt status",
                        "type": "boolean",
                        "description": "When enabled, the report records robots.txt availability. This MVP does not parse robots.txt rules or bypass blocks/login walls.",
                        "default": true
                    },
                    "stateStoreName": {
                        "title": "State store name",
                        "maxLength": 128,
                        "type": "string",
                        "description": "Named Apify Key-Value Store used to keep previous snapshots across runs. Do not put secrets in this name.",
                        "default": "price-availability-drift-state"
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
