SaaS Pricing Watcher
Pricing
Pay per event
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
Maintained by CommunityActor 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
urlsarray 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
- Fetches the pricing page (Playwright by default for modern React SPAs; HTTP mode available for server-rendered pages at lower cost).
- 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. - LLM extraction (default path) — uses Defuddle to extract clean content, then
gpt-4.1-minipopulates a strict zod schema with each tier's name, monthly/annual prices, currency, features list, CTA, and "Most popular" flag. - 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), andignoreText(regex for noise like view counters).
Inputs
| Field | Type | Required | Description |
|---|---|---|---|
urls | string[] | one of urls/url | Preferred for batch monitoring. Each URL produces its own dataset row. |
url | string | one of urls/url | Single-URL convenience field. Ignored when urls is set. |
currencyHint | string | no (default USD) | ISO 4217 code — USD, EUR, GBP, BRL, etc. |
fetchMode | http | playwright | no (default playwright) | http is cheaper but doesn't render JS |
extractTrackingFilters | bool | no (default true) | Return CSS/regex filters for ongoing change detection |
screenshot | bool | no (default false) | Save a full-page PNG (Playwright mode only) |
useEasyList | bool | no (default true) | Strip ads + cookie banners before analysis |
userAgent | string | no | Override 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+subtractiveSelectorsinto the watch's filter fields. - n8n / Zapier / Make.com — pass the regex patterns to your scheduled scraper step.
- Your own code — match
triggerTextregex against future fetches to detect pricing changes. - Any MCP-compatible AI agent — agents can read
trackingFiltersand set up monitoring autonomously.
Pricing
Pay-per-event. Configured in the Apify Console:
| Event | Price | When it fires |
|---|---|---|
init | $0.01 | Once per run |
page-fetched | $0.01 | When the pricing page loads successfully |
ai-call | $0.05 | When the LLM extracts plan tiers (skipped on JSON-LD short-circuit) |
screenshot | $0.005 | When screenshot: true |
result-pushed | $0.005 | Once 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-miniunder 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
currencyHintto 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:
- JSON-LD fast path — deterministic parse of
Product.offers[]when available. Free, no LLM call. Empirically rare on modern React-rendered pricing pages. - LLM fallback — Defuddle-cleaned markdown +
gpt-4.1-miniwith 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.