# SaaS Pricing Page & Changelog Monitor (`stellar_ballet_0bu/saas-pricing-page-monitor`) Actor

Monitor public SaaS pricing pages and changelog/release-notes pages for plan-level and release-entry deltas. Structured output for GTM, sales enablement, and competitive intelligence.

- **URL**: https://apify.com/stellar\_ballet\_0bu/saas-pricing-page-monitor.md
- **Developed by:** [Nikita S](https://apify.com/stellar_ballet_0bu) (community)
- **Categories:** Automation, AI, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## 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.md):

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

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.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/platform/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

## SaaS Pricing Page & Changelog Monitor

Apify Actor that watches **public SaaS pricing pages** and **changelog / release-notes pages**, emitting structured deltas: plan-level changes (new/removed plans, price, currency, billing, CTA, badge) AND release-entry changes (new/removed entries, title, body, version, date, category changes).

The differentiator: structured plan-row + release-entry output with stateful diffing, not a text or hash diff. Built for GTM teams, sales enablement, and competitive-intel workflows. One Actor, two jobs, one set of integrations.


<!-- store-visuals:start -->

### Visual demo: SaaS Pricing Page Monitor

<a href="https://api.apify.com/v2/key-value-stores/yjcSu1xOwpsFPXeto/records/saas-pricing-page-monitor-hero.svg" target="_blank"><img src="https://api.apify.com/v2/key-value-stores/yjcSu1xOwpsFPXeto/records/saas-pricing-page-monitor-hero.svg" alt="SaaS Pricing Page Monitor visual overview" width="780"></a>

<a href="https://api.apify.com/v2/key-value-stores/yjcSu1xOwpsFPXeto/records/saas-pricing-page-monitor-workflow.svg" target="_blank"><img src="https://api.apify.com/v2/key-value-stores/yjcSu1xOwpsFPXeto/records/saas-pricing-page-monitor-workflow.svg" alt="SaaS Pricing Page Monitor workflow diagram" width="780"></a>

<a href="https://api.apify.com/v2/key-value-stores/yjcSu1xOwpsFPXeto/records/saas-pricing-page-monitor-sample-output.svg" target="_blank"><img src="https://api.apify.com/v2/key-value-stores/yjcSu1xOwpsFPXeto/records/saas-pricing-page-monitor-sample-output.svg" alt="SaaS Pricing Page Monitor sample output dataset row" width="620"></a>

These images are hosted in a persistent Apify key-value store so the Store README has stable, clickable visual previews.

<!-- store-visuals:end -->

### What it does

- **Pricing pages** — crawls a list of public SaaS pricing page URLs and extracts a structured plan row per card: `planName`, `price`, `currency`, `billingPeriod`, `cta`, `badge`, `featuresCount`, `pricingPage`, `checkedAt`.
- **Changelog / release-notes pages** (v0.2) — crawls a list of public SaaS changelog URLs and extracts a release entry per item: `title`, `releaseDate`, `version`, `body`, `category`, `url`, `entryKey`, `changelogPage`, `checkedAt`.
- Diffs against the previous run (in-run input or persisted in a key-value store) and emits:
  - **Pricing deltas**: `new_plan`, `removed_plan`, `price_change`, `currency_change`, `billing_period_change`, `cta_change`, `badge_change`, `plan_renamed`
  - **Changelog deltas** (v0.2): `new_entry`, `removed_entry`, `title_change`, `body_change`, `version_change`, `category_change`, `date_change`
  - `currency_change` — currency code changed
  - `billing_period_change` — billing cadence changed
  - `cta_change` — call-to-action text changed
  - `badge_change` — "Most Popular" / "Recommended" toggle
  - `plan_renamed` — plan name changed
- Each row carries `event_severity` (`high` for price/currency/rename, `medium` for plan/badge/billing, `low` for CTA), `events[]`, and a structured `changes[]` array.
- Optional `persistState` keeps the latest snapshot in a key-value store, so back-to-back runs are real stateful deltas.

### What it does NOT do

- No login, no cookie-based scraping, no anti-bot bypass.
- No CAPTCHA solving, no proxy rotation, no Cloudflare bypass.
- No headless browser, no JS rendering — public HTML only.
- No personal-data scraping, no enrichment against private APIs.

### Input

```json
{
  "pricingPages": [
    "https://www.apify.com/pricing",
    "https://stripe.com/pricing",
    "https://www.notion.so/pricing"
  ],
  "previousItems": [],
  "onlyChanged": true,
  "persistState": true,
  "stateStoreName": "saas-pricing-page-monitor-state",
  "stateKey": "",
  "userAgent": "Mozilla/5.0 (compatible; SaaS-Pricing-Monitor/0.1; +https://apify.com)",
  "requestTimeoutMs": 30000
}
````

| Field | Required | Notes |
|---|---|---|
| `pricingPages` | yes (or `changelogPages`) | Public SaaS pricing page URLs (1..N) |
| `changelogPages` | yes (or `pricingPages`) | Public SaaS changelog / release-notes page URLs (1..N). v0.2. |
| `previousItems` | no | Pass an earlier dataset's pricing items array to diff against an arbitrary baseline |
| `previousChangelogItems` | no | Pass an earlier dataset's changelog items array to diff against an arbitrary baseline. v0.2. |
| `onlyChanged` | no | Default `true`. Set to `false` to emit unchanged rows too |
| `persistState` | no | Default `true`. Saves the latest snapshot to a key-value store |
| `stateStoreName` | no | Default `saas-pricing-page-monitor-state` |
| `stateKey` | no | Override snapshot key. Default derives from combined `pricingPages`+`changelogPages` hostnames |
| `userAgent` | no | Set a real browser UA if a target blocks generic bots |
| `requestTimeoutMs` | no | Per-request timeout, default 30s |

### Output

Each dataset item is one plan-row delta:

```json
{
  "pricingPage": "https://www.apify.com/pricing",
  "planName": "Starter",
  "planKey": "starter",
  "price": "$29",
  "currency": "USD",
  "billingPeriod": "month",
  "cta": "choose plan",
  "badge": null,
  "featuresCount": null,
  "checkedAt": "2026-07-07T11:30:00Z",
  "status": "changed",
  "event": "price_change",
  "events": ["price_change"],
  "event_severity": "high",
  "changes": [{ "field": "price", "before": "$25", "after": "$29" }]
}
```

A `SUMMARY` record on the key-value store contains: `pagesSeen`, `plansSeen`, `rowsEmitted`, `eventCounts`, `stateSaved`, `stateKey`, `pagePlanCounts`, `errors`, and (v0.2) `changelog.pagesSeen`, `changelog.entriesSeen`, `changelog.rowsEmitted`, `changelog.eventCounts`, `changelog.pageEntryCounts`, `changelog.errors`.

#### Changelog output (v0.2)

When `changelogPages` is set, each dataset item is one release-entry delta:

```json
{
  "changelogPage": "https://docs.retool.com/changelog",
  "title": "Restore changes from chat",
  "releaseDate": "2026-06-17",
  "version": null,
  "body": "This feature is available on cloud instances...",
  "category": null,
  "url": "https://docs.retool.com/changelog",
  "entryKey": "https://docs.retool.com/changelog::t:restore changes from chat",
  "checkedAt": "2026-07-07T17:30:00Z",
  "status": "new",
  "event": "new_entry",
  "events": ["new_entry"],
  "event_severity": "medium",
  "changes": []
}
```

If a changelog page yields no parseable entries, the Actor emits a single `no_entries_extracted` row with `event_severity: "low"` so the user knows the page was checked but matched no entries (the page may be JS-rendered or use a non-standard layout).

### Pricing

Pay Per Event:

| Event | Price | Trigger |
|---|---|---|
| `apify-actor-start` | $0.0005 | Once per run, on Actor init |
| `delta_result` | $0.002 | Each new / changed / removed plan row |

`price_drop_alert` and other price-event hooks are not enabled in v0.1 (no price-drop scoring yet); they are reserved in the billing model for v0.2 if we add severity-ranked price-drop alerts.

Pricing is currently scheduled to start at `2026-07-22T12:00:00Z` to satisfy the Apify 2-week pricing-change rule.

### Common use cases

- **Sales battlecard** — feed deltas into Google Sheets / n8n / Slack; reps get a ping when a competitor raises prices, changes plan names, adds a "Most Popular" badge, ships a new release, or removes a feature.
- **GTM signal** — "competitor X added an enterprise tier" or "competitor Y shipped an MCP integration" → drop into CRM, alert AE.
- **Pricing research** — long-run stateful dataset of every public pricing change in your category.
- **Founder comp set watch** — quick "is anyone in my space repricing or shipping features this month?" scan.
- **Release-note digests** — only-changed deltas for the last week, one row per release entry, dropped into a Slack channel or Notion page.

### Integrations

- **Google Sheets:** pipe the dataset items via Apify's Google Sheets integration, or run a webhook → Sheets function.
- **n8n / Make / Zapier:** use the Apify trigger node; route `event_severity=high` rows to a Slack/Discord channel.
- **Airtable:** same pattern; map `planName`, `price`, `currency`, `billingPeriod`, `changes[]` to Airtable fields.
- **Slack / Discord:** webhook URL field in the integration; send a one-line summary per row.

### Limitations

- No JS rendering. Pricing pages and changelog pages that load content via client-side JS without server-rendered fallback will return 0 entries.
- Currency detection uses simple regex + ISO code scan. Some pages use locale-formatted prices (e.g. `1.299,00 €`) that the current detector may misread.
- Plan name detection is heading-based. Pricing tables that render plans as a single long table row (no `<h2>`/`<h3>` per plan) are not currently supported.
- Changelog parsing is conservative. Pages that mix SEO/landing content with real release entries (Vercel-style) may under-extract.
- This Actor does not bypass anti-bot protection. If a target returns 403/503 to a default UA, set `userAgent` to a real browser UA or move to a paid SaaS pricing data provider.

### When NOT to use this

- You need **historic** pricing backfill. This Actor is for stateful delta detection going forward.
- You need **rich feature-level diffs** (e.g. "added SSO" or "removed 24/7 support"). This Actor detects price, currency, billing, CTA, and badge changes; per-feature diffing is not in scope.
- You need to scrape **paywalled / gated** pricing. This Actor uses public HTML only.

### Local development

```bash
npm install
npm test                                    # runs delta + pricing + changelog test suites (23 + 7 + N)
node -e "import('./src/changelog.js').then(({parseChangelogPage}) => fetch('https://docs.retool.com/changelog').then(r=>r.text()).then(h=>console.log(parseChangelogPage(h,'https://docs.retool.com/changelog'))))"
```

### Maintainer

Operated by **Nikita S** (DataFlow LV, Latvia-based data automation). Built and maintained as part of the Income Factory Apify portfolio.

Issues / feature requests: open via the Apify Actor page or contact the developer.

### Run it from Claude / Cursor / VS Code via MCP

The Actor is available through the Apify MCP server, so you can ask your AI assistant to "watch this competitor's pricing page and alert me to changes" without writing a custom scraper.

Add this to your MCP client config (for example `claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "apify": {
      "command": "npx",
      "args": ["-y", "@apify/mcp-server"],
      "env": {
        "APIFY_TOKEN": "your-apify-api-token"
      }
    }
  }
}
```

Once connected, the assistant can discover this Actor and trigger runs with a plain prompt like *"Run SaaS Pricing Page Monitor on https://linear.app/pricing and https://notion.so/pricing and summarize what changed this week."* The remote MCP server at `https://mcp.apify.com` works the same way without a local install.

### Quick start

1. Open this Actor in Apify Console.
2. Paste one or more SaaS pricing page URLs into the input.
3. Keep `persistState` enabled for scheduled monitoring.
4. Run once to create the baseline snapshot.
5. Run again on a schedule to receive only delta rows.
6. Export the dataset to CSV/JSON, or send it to Google Sheets, n8n, Make, Slack, Discord, or a webhook.

### Sample output

Use this sample dataset to see the output shape before running it yourself:

- Sample dataset: https://console.apify.com/storage/datasets/hx4UmMfqxfbYziAv2

The important fields for automation are `event`, `events`, `event_severity`, `status`, and `changes`. Filter for `event_severity = high` when you only want alerts that deserve immediate attention.

### Pricing and cost expectations

This Actor is designed for scheduled monitoring and delta-only outputs. It avoids charging or processing unchanged rows where possible. Pay-Per-Event pricing is scheduled/used for meaningful emitted deltas such as new items, removed items, price changes, stock changes, URL changes, or pricing-plan changes depending on the Actor.

Start with a small input list first. Once the baseline looks correct, schedule recurring runs and set a reasonable max charge limit in Apify.

### FAQ

#### Is this a one-time scraper or a monitor?

It is a monitor. The first run creates a baseline. Later runs compare the current data against the stored baseline and emit only the changes.

#### Can I send alerts to Slack, Discord, Google Sheets, n8n, or Make?

Yes. Use Apify integrations, webhooks, dataset export, or API polling. The `event`, `events`, `event_severity`, and `changes` fields are meant for automation routing.

#### Does it bypass CAPTCHA, login walls, or anti-bot systems?

No. This portfolio is intentionally focused on public, low-risk sources such as public APIs, feeds, sitemaps, product pages, or storefront endpoints.

#### Which rows should trigger alerts?

Use `event_severity`. High-severity rows are the best candidates for Slack/Discord/email alerts. Low-severity rows are usually better for reports or spreadsheets.

### Support and custom monitoring

If a public source does not fit this Actor, check the related monitors below. Open an issue on the Actor page with a sample URL and the output you need.

### Which monitor should I use?

This Actor is part of a focused monitoring portfolio. Pick the narrowest Actor that matches your source:

| Source you have | Use this Actor | Best for |
|---|---|---|
| Shopify store | [Shopify Delta Monitor](https://apify.com/stellar_ballet_0bu/shopify-delta-monitor) | Shopify competitor price/stock/sale monitoring |
| WooCommerce store | [WooCommerce Delta Monitor](https://apify.com/stellar_ballet_0bu/woocommerce-delta-monitor) | WooCommerce Store API product deltas |
| Product page URLs with Schema.org JSON-LD | [Schema.org Product Delta Monitor](https://apify.com/stellar_ballet_0bu/schema-product-delta-monitor) | Magento, BigCommerce, custom stores, marketplaces |
| Product feeds / APIs / CSV / XML | [Product Feed Delta Monitor](https://apify.com/stellar_ballet_0bu/product-feed-delta-monitor) | Supplier feeds, affiliate feeds, Google Merchant exports |
| sitemap.xml | [Sitemap Delta Monitor](https://apify.com/stellar_ballet_0bu/sitemap-delta-monitor) | SEO, content ops, RAG indexing queues |
| SaaS pricing pages | SaaS Pricing Page Monitor | Plan/price/feature changes on public pricing pages |

All monitors are built for scheduled runs, stateful comparisons, delta-only outputs, and workflow automation via Google Sheets, n8n, Make, Slack, Discord, or webhooks.

# Actor input Schema

## `pricingPages` (type: `array`):

Public SaaS pricing page URLs to monitor (one entry per competitor/vendor).

## `changelogPages` (type: `array`):

Public SaaS changelog, release-notes, or product-updates URLs to monitor. The Actor extracts a release entry per item (title, releaseDate, version, body, category) and emits deltas (new\_entry, removed\_entry, title\_change, body\_change, version\_change, category\_change, date\_change).

## `previousItems` (type: `array`):

Optional previous pricing plan rows from an earlier run for stateful diffing.

## `previousChangelogItems` (type: `array`):

Optional previous changelog entry rows from an earlier run for stateful diffing.

## `onlyChanged` (type: `boolean`):

Skip unchanged plans/entries. New, changed, removed, and error rows are still emitted.

## `persistState` (type: `boolean`):

Store the latest pricing + changelog snapshot in a named key-value store.

## `stateStoreName` (type: `string`):

Named key-value store used for snapshots when persistState is enabled.

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

Optional snapshot key. Leave empty to derive from input page URLs.

## `userAgent` (type: `string`):

Custom user-agent string. Use a real browser UA if a target blocks generic bots.

## `requestTimeoutMs` (type: `integer`):

Per-request timeout in milliseconds.

## Actor input object example

```json
{
  "pricingPages": [
    "https://www.apify.com/pricing"
  ],
  "changelogPages": [
    "https://docs.retool.com/changelog"
  ],
  "previousItems": [],
  "previousChangelogItems": [],
  "onlyChanged": true,
  "persistState": true,
  "stateStoreName": "saas-pricing-page-monitor-state",
  "stateKey": "",
  "userAgent": "Mozilla/5.0 (compatible; SaaS-Pricing-Monitor/0.2; +https://apify.com)",
  "requestTimeoutMs": 30000
}
```

# Actor output Schema

## `deltaRows` (type: `string`):

Default dataset items with pricingPage, planKey, planName, price, currency, billingPeriod, status, event, events, event\_severity, and changes array.

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

Run summary with page count, plan count, emitted count, event counters, per-page plan counts, state key, and errors.

# 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 = {
    "pricingPages": [
        "https://www.apify.com/pricing"
    ],
    "changelogPages": [
        "https://docs.retool.com/changelog"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("stellar_ballet_0bu/saas-pricing-page-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 = {
    "pricingPages": ["https://www.apify.com/pricing"],
    "changelogPages": ["https://docs.retool.com/changelog"],
}

# Run the Actor and wait for it to finish
run = client.actor("stellar_ballet_0bu/saas-pricing-page-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 '{
  "pricingPages": [
    "https://www.apify.com/pricing"
  ],
  "changelogPages": [
    "https://docs.retool.com/changelog"
  ]
}' |
apify call stellar_ballet_0bu/saas-pricing-page-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=stellar_ballet_0bu/saas-pricing-page-monitor",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "SaaS Pricing Page & Changelog Monitor",
        "description": "Monitor public SaaS pricing pages and changelog/release-notes pages for plan-level and release-entry deltas. Structured output for GTM, sales enablement, and competitive intelligence.",
        "version": "0.2",
        "x-build-id": "wymkL5IC9ySG2DfyF"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/stellar_ballet_0bu~saas-pricing-page-monitor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-stellar_ballet_0bu-saas-pricing-page-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/stellar_ballet_0bu~saas-pricing-page-monitor/runs": {
            "post": {
                "operationId": "runs-sync-stellar_ballet_0bu-saas-pricing-page-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/stellar_ballet_0bu~saas-pricing-page-monitor/run-sync": {
            "post": {
                "operationId": "run-sync-stellar_ballet_0bu-saas-pricing-page-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",
                "properties": {
                    "pricingPages": {
                        "title": "Pricing page URLs",
                        "type": "array",
                        "description": "Public SaaS pricing page URLs to monitor (one entry per competitor/vendor).",
                        "items": {
                            "type": "string"
                        }
                    },
                    "changelogPages": {
                        "title": "Changelog / release-notes page URLs",
                        "type": "array",
                        "description": "Public SaaS changelog, release-notes, or product-updates URLs to monitor. The Actor extracts a release entry per item (title, releaseDate, version, body, category) and emits deltas (new_entry, removed_entry, title_change, body_change, version_change, category_change, date_change).",
                        "items": {
                            "type": "string"
                        }
                    },
                    "previousItems": {
                        "title": "Previous pricing items",
                        "type": "array",
                        "description": "Optional previous pricing plan rows from an earlier run for stateful diffing.",
                        "default": []
                    },
                    "previousChangelogItems": {
                        "title": "Previous changelog items",
                        "type": "array",
                        "description": "Optional previous changelog entry rows from an earlier run for stateful diffing.",
                        "default": []
                    },
                    "onlyChanged": {
                        "title": "Only output changed rows",
                        "type": "boolean",
                        "description": "Skip unchanged plans/entries. New, changed, removed, and error rows are still emitted.",
                        "default": true
                    },
                    "persistState": {
                        "title": "Persist state between runs",
                        "type": "boolean",
                        "description": "Store the latest pricing + changelog snapshot in a named key-value store.",
                        "default": true
                    },
                    "stateStoreName": {
                        "title": "State store name",
                        "type": "string",
                        "description": "Named key-value store used for snapshots when persistState is enabled.",
                        "default": "saas-pricing-page-monitor-state"
                    },
                    "stateKey": {
                        "title": "State key override",
                        "type": "string",
                        "description": "Optional snapshot key. Leave empty to derive from input page URLs.",
                        "default": ""
                    },
                    "userAgent": {
                        "title": "User agent",
                        "type": "string",
                        "description": "Custom user-agent string. Use a real browser UA if a target blocks generic bots.",
                        "default": "Mozilla/5.0 (compatible; SaaS-Pricing-Monitor/0.2; +https://apify.com)"
                    },
                    "requestTimeoutMs": {
                        "title": "Request timeout (ms)",
                        "minimum": 5000,
                        "maximum": 120000,
                        "type": "integer",
                        "description": "Per-request timeout in milliseconds.",
                        "default": 30000
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
