# SaaS Pricing Changelog Battlecard Watch Scraper (`taroyamada/saas-pricing-changelog-battlecard-watch-scraper`) Actor

Unofficially watch public SaaS pricing and changelog pages, then emit source-linked pricing changes and battlecard report rows.

- **URL**: https://apify.com/taroyamada/saas-pricing-changelog-battlecard-watch-scraper.md
- **Developed by:** [太郎 山田](https://apify.com/taroyamada) (community)
- **Categories:** Business, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $30.00 / 1,000 saas pricing page snapshots

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/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.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 Changelog Battlecard Watch Scraper

Competitive intelligence, sales enablement, and product marketing teams use this actor to watch public SaaS pricing and changelog pages.
Provide competitor names, public pricing URLs, changelog URLs, and watched terms.
The actor returns source-linked pricing changes, changelog observations, battlecard reports, and export rows.

### Store Quickstart

Run with `dryRun=false` and public competitor URLs that do not require login or private access.

```json
{
  "competitorTargets": [
    {
      "name": "Example SaaS",
      "pricingUrl": "https://example.com/pricing",
      "changelogUrl": "https://example.com/changelog"
    }
  ],
  "trackedTerms": ["price", "plan", "seat", "usage", "enterprise"],
  "generateBattlecard": true,
  "emitUnchanged": false,
  "dryRun": false
}
````

### Input Examples

#### Pricing-page watch

```json
{
  "competitorTargets": [
    {
      "name": "Competitor A",
      "pricingUrl": "https://example.com/pricing"
    }
  ],
  "trackedTerms": ["annual", "seat", "enterprise"],
  "dryRun": false
}
```

#### Changelog watch

```json
{
  "competitorTargets": [
    {
      "name": "Competitor B",
      "changelogUrl": "https://example.com/changelog"
    }
  ],
  "trackedTerms": ["usage", "api", "enterprise"],
  "generateBattlecard": true,
  "dryRun": false
}
```

#### Multi-competitor export

```json
{
  "competitorTargets": [
    {
      "name": "Competitor A",
      "pricingUrl": "https://example.com/pricing"
    },
    {
      "name": "Competitor B",
      "changelogUrl": "https://example.org/changelog"
    }
  ],
  "emitExport": true,
  "dryRun": false
}
```

### Sample Output

```json
{
  "actorName": "saas-pricing-changelog-battlecard-watch-scraper",
  "rowType": "saas_pricing_change",
  "billingEventName": "saas-pricing-change-detected",
  "competitorName": "Example SaaS",
  "currentPriceSignals": ["$39/mo"],
  "sourceUrl": "https://example.com/pricing"
}
```

### Output Fields

- `rowType`: `saas_pricing_page_snapshot`, `saas_pricing_change`, `saas_changelog_entry`, `saas_battlecard_report`, or `saas_watch_export`.
- `competitorName`: competitor label supplied in the input.
- `sourceUrl`: public source URL supporting the row.
- `priceSignals`: public price text signals extracted from the page.
- `recommendedReviewQueue`: source-linked rows to review in the battlecard.

### Pricing And No-Change Runs

- `saas-pricing-page-snapshot`: $0.030 per optional public pricing page snapshot.
- `saas-pricing-change-detected`: $0.350 per source-linked pricing page change.
- `saas-changelog-entry-detected`: $0.150 per public changelog entry.
- `saas-battlecard-report`: $9.000 per generated battlecard report.
- `saas-watch-export-generated`: $7.000 per generated export.

When `emitUnchanged=false`, repeated unchanged runs emit zero dataset rows and zero charges after state is saved.

### Compliance Guardrails

- Public SaaS pages only.
- No login, paywall, CAPTCHA, private workspace, contract, account, or bypass behavior.
- This is an unofficial monitoring tool and is not affiliated with any watched company.
- No procurement, legal, investment, pricing, or compliance advice.

### Bundle Paths

- Competitive Intel: run a low-cost pricing/changelog watch first, then generate `saas-battlecard-report` or `saas-watch-export-generated` when a sales or PMM handoff is needed.
- Pair with [Shopify Public Catalog Map & Promo Watch](https://apify.com/taroyamada/shopify-public-catalog-map-promo-watch-scraper) for public storefront promo/catalog monitoring.
- Pair with [Ad Transparency Creative Change Watch Scraper](https://apify.com/taroyamada/ad-transparency-creative-change-watch-scraper) for public campaign change monitoring.

### See Also

- [Ad Transparency Creative Change Watch Scraper](https://apify.com/taroyamada/ad-transparency-creative-change-watch-scraper) for public ad creative change reports.
- [Shopify Public Catalog Map & Promo Watch](https://apify.com/taroyamada/shopify-public-catalog-map-promo-watch-scraper) for public storefront promo watch reports.

# Actor input Schema

## `competitorTargets` (type: `array`):

Public SaaS pricing and changelog page targets.

## `trackedTerms` (type: `array`):

Terms to flag in pricing pages and battlecard rows.

## `maxTargets` (type: `integer`):

Maximum competitor targets to check.

## `emitSnapshotRows` (type: `boolean`):

Emit optional public pricing page snapshot rows.

## `generateBattlecard` (type: `boolean`):

Generate a competitive battlecard report row when watched signals are emitted.

## `emitExport` (type: `boolean`):

Generate an export row for handoff workflows.

## `emitUnchanged` (type: `boolean`):

When false, repeated unchanged runs emit zero rows and zero charges.

## `dryRun` (type: `boolean`):

Emit local sample rows without charging.

## `initialRunMode` (type: `string`):

Deployment canary control used by automation; emit\_backfill allows first-run proof rows, baseline\_only is used for no-change proof.

## `snapshotKey` (type: `string`):

Optional state namespace for canary and recurring no-change proof runs.

## Actor input object example

```json
{
  "competitorTargets": [
    {
      "name": "Example SaaS",
      "pricingUrl": "https://example.com/pricing",
      "changelogUrl": "https://example.com/changelog"
    }
  ],
  "trackedTerms": [
    "price",
    "plan",
    "seat",
    "usage",
    "enterprise"
  ],
  "maxTargets": 10,
  "emitSnapshotRows": false,
  "generateBattlecard": true,
  "emitExport": false,
  "emitUnchanged": false,
  "dryRun": true,
  "initialRunMode": "emit_backfill",
  "snapshotKey": ""
}
```

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("taroyamada/saas-pricing-changelog-battlecard-watch-scraper").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("taroyamada/saas-pricing-changelog-battlecard-watch-scraper").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 '{}' |
apify call taroyamada/saas-pricing-changelog-battlecard-watch-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "SaaS Pricing Changelog Battlecard Watch Scraper",
        "description": "Unofficially watch public SaaS pricing and changelog pages, then emit source-linked pricing changes and battlecard report rows.",
        "version": "0.1",
        "x-build-id": "VW1o6nvfBShYUMCaz"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/taroyamada~saas-pricing-changelog-battlecard-watch-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-taroyamada-saas-pricing-changelog-battlecard-watch-scraper",
                "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/taroyamada~saas-pricing-changelog-battlecard-watch-scraper/runs": {
            "post": {
                "operationId": "runs-sync-taroyamada-saas-pricing-changelog-battlecard-watch-scraper",
                "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/taroyamada~saas-pricing-changelog-battlecard-watch-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-taroyamada-saas-pricing-changelog-battlecard-watch-scraper",
                "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": {
                    "competitorTargets": {
                        "title": "Competitor targets",
                        "type": "array",
                        "description": "Public SaaS pricing and changelog page targets.",
                        "default": [
                            {
                                "name": "Example SaaS",
                                "pricingUrl": "https://example.com/pricing",
                                "changelogUrl": "https://example.com/changelog"
                            }
                        ]
                    },
                    "trackedTerms": {
                        "title": "Tracked terms",
                        "type": "array",
                        "description": "Terms to flag in pricing pages and battlecard rows.",
                        "default": [
                            "price",
                            "plan",
                            "seat",
                            "usage",
                            "enterprise"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxTargets": {
                        "title": "Max targets",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Maximum competitor targets to check.",
                        "default": 10
                    },
                    "emitSnapshotRows": {
                        "title": "Emit snapshot rows",
                        "type": "boolean",
                        "description": "Emit optional public pricing page snapshot rows.",
                        "default": false
                    },
                    "generateBattlecard": {
                        "title": "Generate battlecard row",
                        "type": "boolean",
                        "description": "Generate a competitive battlecard report row when watched signals are emitted.",
                        "default": true
                    },
                    "emitExport": {
                        "title": "Generate export row",
                        "type": "boolean",
                        "description": "Generate an export row for handoff workflows.",
                        "default": false
                    },
                    "emitUnchanged": {
                        "title": "Emit unchanged rows",
                        "type": "boolean",
                        "description": "When false, repeated unchanged runs emit zero rows and zero charges.",
                        "default": false
                    },
                    "dryRun": {
                        "title": "Dry run",
                        "type": "boolean",
                        "description": "Emit local sample rows without charging.",
                        "default": true
                    },
                    "initialRunMode": {
                        "title": "Initial run mode",
                        "enum": [
                            "emit_backfill",
                            "baseline_only"
                        ],
                        "type": "string",
                        "description": "Deployment canary control used by automation; emit_backfill allows first-run proof rows, baseline_only is used for no-change proof.",
                        "default": "emit_backfill"
                    },
                    "snapshotKey": {
                        "title": "Snapshot key",
                        "type": "string",
                        "description": "Optional state namespace for canary and recurring no-change proof runs.",
                        "default": ""
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
