SaaS Pricing Watcher avatar

SaaS Pricing Watcher

Pricing

Pay per event

Go to Apify Store
SaaS Pricing Watcher

SaaS Pricing Watcher

Track 10-30 competitor SaaS pricing pages in one batch run — Stripe, Notion, Linear, Vercel, OpenAI, Anthropic, or any URL in any language. Extract plans + features + billing cycles. Returns change-detection filters for ongoing monitoring. No API key needed. MCP-ready.

Pricing

Pay per event

Rating

0.0

(0)

Developer

Vitaly Kuprin

Vitaly Kuprin

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Share

Monitor competitor SaaS pricing pages — Stripe, Notion, Linear, Vercel, Cloudflare, OpenAI, Anthropic, or any other SaaS pricing page in any language. Extract plans, prices, features, billing cycles plus the CSS selectors + regex filters to wire ongoing change detection into your stack.

  • Batch mode — track 10-30 competitor pricing pages in a single run via the urls array input. Each URL gets its own dataset row.
  • Pricing + change-detection filters in one call. Most scrapers give you data. This Actor returns data and the filters to monitor the page going forward — feed them into changedetection.io, n8n, Zapier, your own code, or any MCP-compatible AI agent.
  • No OpenAI/Anthropic API key needed. AI cost is included in the per-call event price.
  • Works on any SaaS pricing page in any language (English, Russian, Spanish, Chinese, Arabic, …). Emits feature strings in the page's native language.
  • MCP-ready for Claude Desktop, Cursor, Codex, Gemini Code Assist, Cline, Continue, and every MCP-compatible client.
  • Typical cost: ~$0.075/URL. Tracking 20 competitors in one batch run ≈ $1.50.

Why this exists

Tracking competitor pricing is a recurring product-management headache. Existing tools either (a) give you a CSV export once and leave you to glue together your own monitoring, or (b) cost $200+/mo for a managed dashboard you outgrow quickly. This Actor is the cheaper, agentic version: ~$0.075/run, drop it into any workflow that knows how to call an Apify Actor.

The differentiator over generic pricing scrapers is the trackingFilters object — CSS selectors + regex patterns that tell a change-detection system exactly what to monitor on the page. Hand them to changedetection.io, set up an n8n flow, or call the Actor again next week — your choice.

What it does

  1. Fetches the pricing page (Playwright by default for modern React SPAs; HTTP mode available for server-rendered pages at lower cost).
  2. JSON-LD short-circuit — if the page exposes Product.offers[] schema.org data (rare on modern SaaS sites, common on older marketplaces), parses it deterministically. Zero LLM cost on this path.
  3. LLM extraction (default path) — uses Defuddle to extract clean content, then gpt-4.1-mini populates a strict zod schema with each tier's name, monthly/annual prices, currency, features list, CTA, and "Most popular" flag.
  4. Tracking filters (the wedge) — runs the same smart-config engine that powers production change-detection services. Returns includeFilters (where pricing lives), subtractiveSelectors (ads/cookies/nav to strip), triggerText (regex for price-change patterns), and ignoreText (regex for noise like view counters).

Inputs

FieldTypeRequiredDescription
urlsstring[]one of urls/urlPreferred for batch monitoring. Each URL produces its own dataset row.
urlstringone of urls/urlSingle-URL convenience field. Ignored when urls is set.
currencyHintstringno (default USD)ISO 4217 code — USD, EUR, GBP, BRL, etc.
fetchModehttp | playwrightno (default playwright)http is cheaper but doesn't render JS
extractTrackingFiltersboolno (default true)Return CSS/regex filters for ongoing change detection
screenshotboolno (default false)Save a full-page PNG (Playwright mode only)
useEasyListboolno (default true)Strip ads + cookie banners before analysis
userAgentstringnoOverride the default User-Agent

Output

One row per analyzed page:

{
"url": "https://stripe.com/pricing",
"fetchedAt": "2026-05-11T00:00:00.000Z",
"fetchMode": "playwright",
"source": "llm",
"plans": [
{
"name": "Standard",
"monthly_price": null,
"annual_price": null,
"currency": "USD",
"billing_period": "usage_based",
"features": ["Pay-as-you-go 2.9% + $0.30 per transaction", "Online + in-person", "24/7 support"],
"cta_text": "Start now",
"is_highlighted": false
},
{
"name": "Custom",
"monthly_price": null,
"annual_price": null,
"currency": "USD",
"billing_period": null,
"features": ["Volume discounts", "Country-specific rates", "Multi-product discounts"],
"cta_text": "Contact sales",
"is_highlighted": false
}
],
"hasFreeTier": false,
"hasUsageBased": true,
"explanation": "Stripe presents one usage-based standard tier plus a custom enterprise tier.",
"trackingFilters": {
"includeFilters": ["main"],
"subtractiveSelectors": [".cookie-banner", "nav"],
"triggerText": ["/(\\$|€|£)\\d+(\\.\\d+)?\\/(mo|month|yr|year)/i"],
"ignoreText": ["/\\d+\\s*(customers|companies)/i", "/©\\s*20\\d{2}/"]
},
"screenshotKey": null,
"aiTokens": { "input": 1840, "output": 380 }
}

The trackingFilters object plugs directly into:

  • changedetection.io — paste includeFilters + subtractiveSelectors into the watch's filter fields.
  • n8n / Zapier / Make.com — pass the regex patterns to your scheduled scraper step.
  • Your own code — match triggerText regex against future fetches to detect pricing changes.
  • Any MCP-compatible AI agent — agents can read trackingFilters and set up monitoring autonomously.

Pricing

Pay-per-event. Configured in the Apify Console:

EventPriceWhen it fires
init$0.01Once per run
page-fetched$0.01When the pricing page loads successfully
ai-call$0.05When the LLM extracts plan tiers (skipped on JSON-LD short-circuit)
screenshot$0.005When screenshot: true
result-pushed$0.005Once per dataset row

Typical run (Playwright + LLM extraction + tracking filters, no screenshot): ~$0.075. Best case (JSON-LD short-circuit, no LLM): ~$0.025. Rare on modern SaaS pages — don't count on it. 20 pricing pages monthly: ~$1.50/mo. 100 pricing pages monthly (large competitor coverage): ~$7.50/mo.

MCP usage (any MCP client)

Apify exposes Store Actors as MCP tools natively. Add the Apify MCP server to your client and this Actor appears as a callable tool with the inputs above. Works in:

  • Claude Desktop~/Library/Application Support/Claude/claude_desktop_config.json
  • Cursor~/.cursor/mcp.json
  • OpenAI Codex / Codex CLI (with MCP enabled)
  • Google Gemini Code Assist (when MCP is enabled)
  • Cline (VS Code extension)
  • Continue.dev
  • Any custom MCP client
{
"mcpServers": {
"apify": {
"command": "npx",
"args": ["-y", "@apify/actors-mcp-server"],
"env": { "APIFY_TOKEN": "<your-apify-token>" }
}
}
}

Then ask your agent:

"Track Stripe and Notion's pricing pages weekly. Alert me if any plan's monthly price changes by more than 10%."

The agent calls this Actor for both pages, captures the trackingFilters for ongoing monitoring, and uses the structured plans data to detect price deltas across runs.

Examples

// Batch — track your top 5 competitors in one run (PREFERRED for monitoring)
{
"urls": [
"https://stripe.com/pricing",
"https://www.notion.so/pricing",
"https://linear.app/pricing",
"https://vercel.com/pricing",
"https://www.cloudflare.com/plans/"
],
"currencyHint": "USD",
"fetchMode": "playwright",
"extractTrackingFilters": true
}
// Single URL — one-off scrape
{ "url": "https://www.anthropic.com/pricing", "currencyHint": "USD" }
// Cheap one-off scrape — HTTP mode, no filters, no screenshot
{
"url": "https://www.example-saas.com/pricing",
"fetchMode": "http",
"extractTrackingFilters": false
}
// Non-USD pricing page
{
"url": "https://www.example-saas.de/preise",
"currencyHint": "EUR"
}

Limits

  • Single URL per run. For multi-page workflows, run the Actor once per URL or use Apify's Task scheduler.
  • Modern SaaS pricing pages are JS-rendered React apps — use fetchMode: "playwright" (the default). HTTP mode works for server-rendered pages and is cheaper.
  • LLM uses gpt-4.1-mini under the hood. The Actor handles cost; no API key for you to manage.
  • Currency detection works best when the page consistently displays a single currency. For multi-region pricing pages, set currencyHint to disambiguate.
  • "Custom" / "Contact us" / "Enterprise" tiers return monthly_price: null — that's correct, not a bug.

Source & methodology

Engine: @site-spy/smart-config-core — the same module used in production by a change-detection service. Tested on 1,066 real production pages with 99.4% configure-success — works on sites that break generic scrapers (A/B-tested layouts, hashed CSS classes, JS-heavy SPAs, non-English content).

Two-stage extraction architecture:

  1. JSON-LD fast path — deterministic parse of Product.offers[] when available. Free, no LLM call. Empirically rare on modern React-rendered pricing pages.
  2. LLM fallback — Defuddle-cleaned markdown + gpt-4.1-mini with a zod-validated extraction schema. Handles "Custom" pricing, multi-region pages, non-English content, missing annual/monthly disambiguation.

Source is bundled into the Actor image at publish time.