# SaaS Competitor Pricing Monitor (`congism/competitor-pricing-monitor`) Actor

Monitor competitor SaaS pricing pages for changes. Get Slack alerts the moment a price changes, a plan disappears, or a free trial is killed.

- **URL**: https://apify.com/congism/competitor-pricing-monitor.md
- **Developed by:** [Cong](https://apify.com/congism) (community)
- **Categories:** Marketing, AI, Automation
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $450.00 / 1,000 competitor checkeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## PriceSentinel — SaaS Competitor Pricing Monitor

**Know the moment a competitor changes their pricing — before your sales team finds out on a lost deal.**

PriceSentinel monitors your SaaS competitors' pricing pages on a schedule, extracts structured plan data using Claude AI, and fires a Slack alert the moment anything meaningful changes — price increase, plan removed, free trial killed, new tier added.

***

### What it detects

| Change type | Severity | Example |
|-------------|----------|---------|
| Price increase / decrease | 🔴 High | Pro plan: $29/mo → $49/mo (↑ 69%) |
| Plan added | 🔴 High | New "Growth" plan added at $99/mo |
| Plan removed | 🔴 High | "Starter" plan ($19/mo) was removed |
| Plan renamed | 🟡 Medium | "Business" plan renamed to "Enterprise" |
| Free trial changed | 🟡 Medium | Trial reduced from 14 days to 7 days |
| Annual discount changed | 🟡 Medium | Annual discount changed from 20% to 15% |
| Feature removed from plan | 🟡 Medium | Feature removed from Pro: "Unlimited exports" |
| Feature added to plan | 🟢 Low | Feature added to Starter: "Basic analytics" |
| CTA text changed | 🟢 Low | Pro CTA: "Get started" → "Start free trial" |

***

### Quickstart (10 minutes to first Slack alert)

#### 1. Configure competitors

In the **Input** tab, paste your competitor list:

```json
[
  { "name": "Notion", "pricingUrl": "https://www.notion.so/pricing" },
  { "name": "Coda",   "pricingUrl": "https://coda.io/pricing" },
  { "name": "Linear", "pricingUrl": "https://linear.app/pricing" }
]
```

#### 2. Add your Anthropic API key

Get one at [console.anthropic.com](https://console.anthropic.com) → API Keys → Create key.

Paste it into the **Anthropic API Key** field. It's stored as a secret.

#### 3. Connect Slack (optional but recommended)

1. Go to [api.slack.com/apps](https://api.slack.com/apps) → Create New App → From scratch
2. Enable **Incoming Webhooks**
3. Add webhook to your chosen channel, copy the URL
4. Paste into the **Slack Webhook URL** field

#### 4. Run it once to capture baselines

Click **Start**. The first run captures a baseline snapshot for each competitor — no Slack alert fires yet (there's nothing to compare to).

#### 5. Set up a daily schedule

In your actor's **Schedules** tab → **Add schedule** → set to run daily at 8am. From now on, if anything changes, Slack fires automatically.

***

### Output

Each run produces a Dataset record per competitor:

```json
{
  "competitor": "Notion",
  "pricingUrl": "https://www.notion.so/pricing",
  "runDate": "2026-07-24T08:00:00.000Z",
  "scrapeSuccess": true,
  "extractionSuccess": true,
  "changeDetected": true,
  "isFirstRun": false,
  "changes": [
    {
      "type": "price_change",
      "severity": "high",
      "planName": "Plus",
      "summary": "\"Plus\" monthly price increased from $10 to $12 (20% ↑)",
      "before": "$10",
      "after": "$12"
    }
  ],
  "currentSnapshot": {
    "plans": [
      {
        "name": "Plus",
        "monthlyPrice": "$12",
        "annualPrice": "$8",
        "currency": "USD",
        "isFree": false,
        "isContactSales": false,
        "highlighted": true,
        "features": ["Unlimited blocks", "Unlimited file uploads", "30-day history"],
        "ctaText": "Get started"
      }
    ],
    "freeTrialMentioned": false,
    "annualDiscountMentioned": true,
    "annualDiscountPercent": "save 20%"
  }
}
```

***

### Integrations (via Zapier — no extra setup needed)

The Dataset output is a live integration bus. Connect it to anything:

**Email digest (Zapier)**
Trigger: "New item in Apify Dataset" → Filter: `changeDetected = true` → Action: "Send email"

**Google Sheets log**
Trigger: "New item in Apify Dataset" → Action: "Append row to spreadsheet"

**Notion database**
Trigger: "New item in Apify Dataset" → Filter: `changeDetected = true` → Action: "Create Notion page"

**Linear / Jira ticket**
Trigger: "New item in Apify Dataset" → Filter: `severity = high` → Action: "Create issue"

***

### Proxy configuration

Most SaaS pricing pages load fine without a proxy. For protected pages (HubSpot, Intercom, Salesforce), use **Apify Residential Proxies** in the Proxy Configuration field — this dramatically improves success rates on bot-protected pages.

***

### Known limitations

- **Login-gated pricing pages**: Pages that require authentication cannot be scraped. If a competitor hides pricing behind a demo request, PriceSentinel cannot access it.
- **Image-based pricing tables**: If pricing is embedded in an image rather than HTML text, extraction will fail gracefully (the actor logs a warning, does not crash).
- **URL changes**: If a competitor moves their pricing page from `/pricing` to `/plans`, the actor will return a 404 alert so you can update the URL.

***

### Pricing

Billed per competitor URL processed per run.

| Frequency | Competitors | Estimated monthly cost |
|-----------|-------------|----------------------|
| Weekly | 5 | ~$10/mo |
| Daily | 10 | ~$150/mo |
| Daily | 20 | ~$300/mo |

Apify's free plan covers initial testing. No credit card required for first 10 events.

***

### Architecture

```
Playwright (headless Chrome) → page text
  → Claude Haiku (structured extraction)
  → Apify KV Store (snapshot comparison)
  → Diff engine (semantic change detection)
  → Slack Block Kit notification
  → Apify Dataset (full run archive)
```

The extraction uses Claude AI rather than regex, so it works across any pricing page layout regardless of CSS class names or HTML structure. The diff engine does semantic matching — it detects plan renames (not just deletions + additions) and calculates percent-change on prices.

# Actor input Schema

## `competitors` (type: `array`):

List of competitor companies and their pricing page URLs. Each item must have a 'name' and 'pricingUrl'.

## `anthropicApiKey` (type: `string`):

Your Anthropic API key for Claude-powered pricing extraction. Get one at console.anthropic.com.

## `slackWebhookUrl` (type: `string`):

Slack Incoming Webhook URL for change alerts. Leave empty to skip Slack notifications. Create one at api.slack.com/apps.

## `alertOnlyOnChange` (type: `boolean`):

When enabled, Slack notifications fire only when a change is detected. Disable to receive a summary on every run.

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

Proxy settings. Apify Residential proxies are recommended for pricing pages with bot protection (HubSpot, Intercom, etc.).

## `ourProductName` (type: `string`):

Your SaaS product name. Required to enable the Sales Response Brief feature — e.g. 'Acme', 'Superblocks', 'Stackwise'.

## `ourProductDescription` (type: `string`):

1–2 sentences describing what your product does and who it's for. The more specific, the better the sales brief. E.g. 'Acme is a no-code workflow builder for operations teams at mid-market SaaS companies.'

## `enableSalesBrief` (type: `boolean`):

When enabled and Your Product Name is set, each change alert includes 3 AI-generated talking points your sales team can use on prospect calls.

## Actor input object example

```json
{
  "competitors": [
    {
      "name": "Notion",
      "pricingUrl": "https://www.notion.so/pricing"
    },
    {
      "name": "Coda",
      "pricingUrl": "https://coda.io/pricing"
    },
    {
      "name": "Linear",
      "pricingUrl": "https://linear.app/pricing"
    }
  ],
  "alertOnlyOnChange": true,
  "enableSalesBrief": true
}
```

# 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 = {
    "competitors": [
        {
            "name": "Notion",
            "pricingUrl": "https://www.notion.so/pricing"
        },
        {
            "name": "Coda",
            "pricingUrl": "https://coda.io/pricing"
        },
        {
            "name": "Linear",
            "pricingUrl": "https://linear.app/pricing"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("congism/competitor-pricing-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 = { "competitors": [
        {
            "name": "Notion",
            "pricingUrl": "https://www.notion.so/pricing",
        },
        {
            "name": "Coda",
            "pricingUrl": "https://coda.io/pricing",
        },
        {
            "name": "Linear",
            "pricingUrl": "https://linear.app/pricing",
        },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("congism/competitor-pricing-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 '{
  "competitors": [
    {
      "name": "Notion",
      "pricingUrl": "https://www.notion.so/pricing"
    },
    {
      "name": "Coda",
      "pricingUrl": "https://coda.io/pricing"
    },
    {
      "name": "Linear",
      "pricingUrl": "https://linear.app/pricing"
    }
  ]
}' |
apify call congism/competitor-pricing-monitor --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/s7dHirYSk96DmtiMm/builds/8V5n1ksox0QQMxYya/openapi.json
