SaaS Pricing Scraper avatar

SaaS Pricing Scraper

Pricing

from $0.50 / 1,000 results

Go to Apify Store
SaaS Pricing Scraper

SaaS Pricing Scraper

Extract structured pricing data from any SaaS company's public pricing page. The dedicated SaaS pricing intelligence tool on the Apify Store.

Pricing

from $0.50 / 1,000 results

Rating

0.0

(0)

Developer

Mick

Mick

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Extract structured pricing data from any SaaS company's public pricing page. Point it at a URL or domain and get back plan names, prices, features, billing models, and more as clean JSON. No API keys required. MCP-ready for AI agent integration.

What does it do?

SaaS Pricing Scraper renders pricing pages with Playwright (headless Chromium), then extracts structured plan data using multi-strategy HTML parsing. It handles JavaScript-rendered pages, cookie banners, billing toggles, and various pricing layouts -- cards, grids, rows, comparison tables.

Smart input -- no modes to think about. Provide URLs or domains in a single list:

  • Pricing page URLs (e.g. https://linear.app/pricing) -- scraped directly with Playwright
  • Bare domains (e.g. linear.app) -- the scraper auto-discovers the pricing page, then scrapes it

Mix and match in the same run. The scraper auto-detects which is which.

Use cases

  • Competitive intelligence -- track competitor pricing changes over time
  • Market research -- compare pricing across an entire SaaS category
  • Sales enablement -- feed pricing data into CRM workflows
  • Investment analysis -- evaluate SaaS business models at scale
  • AI agent tooling -- pipe structured pricing data into AI agents via MCP

What data does it extract?

Each record represents one pricing plan (tier) from a SaaS product:

FieldDescription
plan_nameName of the pricing tier (e.g. "Pro", "Enterprise")
plan_positionPosition on the page (1 = leftmost/first)
monthly_priceMonthly price in the detected currency
annual_priceAnnual price per month (if annual billing shown)
annual_savings_pctPercentage saved with annual billing
currencyDetected currency (default USD)
pricing_modelflat_rate, per_seat, usage_based, tiered, freemium, custom, hybrid
price_unite.g. "per user/month", "per seat"
has_free_tierWhether the plan is a free tier
has_trialWhether a free trial is offered
trial_daysTrial duration if detected
is_custom_pricingTrue if "Contact Sales" / custom pricing
featuresList of features included in this tier
highlighted_featureBadge text like "Most Popular", "Best Value"
cta_textCall-to-action button text
cta_urlCall-to-action link
extraction_confidencehigh, medium, or low
extraction_notesDetails on any extraction issues

Input

FieldTypeDefaultDescription
urlsarrayrequiredPricing page URLs or company domains (max 100)
maxResultsinteger100Max pricing records to return (1-500)
includeFeaturesPerPlanbooleantrueExtract feature lists per tier
includeRawHtmlbooleanfalseInclude raw pricing section HTML
requestIntervalSecsnumber2.0Min seconds between requests
timeoutSecsinteger30Page load timeout
maxRetriesinteger3Retry attempts per request

Example input

{
"urls": [
"https://linear.app/pricing",
"https://github.com/pricing",
"https://supabase.com/pricing",
"https://1password.com/pricing"
],
"maxResults": 50
}

Output

Example: Linear (4 plans extracted)

[
{
"schema_version": "1.0",
"type": "pricing_plan",
"company_name": "Linear",
"company_domain": "linear.app",
"pricing_page_url": "https://linear.app/pricing",
"plan_name": "Free",
"plan_position": 1,
"monthly_price": 0,
"annual_price": 0,
"currency": "USD",
"pricing_model": "freemium",
"has_free_tier": true,
"is_custom_pricing": false,
"features": ["Unlimited members", "2 teams", "250 issues", "Slack and GitHub", "AI agents"],
"cta_text": "Get started",
"extraction_confidence": "high"
},
{
"plan_name": "Basic",
"plan_position": 2,
"monthly_price": 10,
"pricing_model": "per_seat",
"price_unit": "per user/month",
"features": ["5 teams", "Unlimited issues", "Unlimited file uploads", "Admin roles"],
"extraction_confidence": "high"
},
{
"plan_name": "Business",
"plan_position": 3,
"monthly_price": 16,
"pricing_model": "per_seat",
"price_unit": "per user/month",
"features": ["Unlimited teams", "Private teams and guests", "Triage Intelligence", "Linear Insights", "Linear Asks", "Issue SLAs", "Zendesk and Intercom integrations"],
"extraction_confidence": "high"
},
{
"plan_name": "Enterprise",
"plan_position": 4,
"is_custom_pricing": true,
"pricing_model": "custom",
"features": ["Sub-initiatives", "Advanced Linear Asks", "Dashboards", "SAML and SCIM", "Advanced security", "Migration and onboarding support"],
"cta_text": "Contact sales",
"extraction_confidence": "high"
}
]

Output is trimmed for readability. Each record includes all fields from the schema -- see the full field list above.

What works well

The scraper performs best on standard SaaS pricing pages with clearly structured plan cards or grids:

SitePlansAccuracy
Linear4 (Free, Basic, Business, Enterprise)All prices and features correct
GitHub3 (Free, Team, Enterprise)All prices correct
1Password3 (Individual, Families, Business)All prices correct, monthly + annual
Supabase4 (Free, Pro, Team, Enterprise)All prices correct
Dropbox4 (Plus, Professional, Standard, Advanced)3/4 prices correct

Limitations

  • Bot-protected sites may fail. Sites using aggressive bot detection (Cloudflare, Akamai, or custom anti-bot) may not render pricing content for headless browsers. This includes some major tech companies like Notion, Slack, Figma, and Vercel. The scraper returns a low-confidence empty record when this happens.
  • Catalog pages are not supported. Pages that list dozens of products (like Azure's pricing overview) rather than showing plan tiers for a single product will produce poor results. Point the scraper at a specific product's pricing page instead.
  • Prices in non-standard locations. Some sites put prices outside of plan cards (e.g. only in FAQ sections or comparison table footnotes). The scraper extracts prices from plan containers and nearby DOM elements but may miss prices embedded in prose.
  • Heavy SPAs with long load times. Some single-page applications take over 45 seconds to render on Apify's infrastructure. These will time out.
  • USD assumed by default. The scraper detects currency symbols ($, €, £, ¥, ₹) but defaults to USD when ambiguous.

Cost

This actor uses pay-per-event (PPE) pricing. You pay only for the results you get.

  • $0.50 per 1,000 results ($0.0005 per result)
  • No proxy costs -- Playwright runs in the actor's Docker container
  • Free tier: 25 results per run (no subscription required)

Typical run: 5 URLs produces 15-20 plan records in about 30 seconds. Cost: ~$0.01.


MCP Integration

This actor works as an MCP tool through Apify's hosted MCP server. No custom server needed.

  • Endpoint: https://mcp.apify.com?tools=labrat011/saas-pricing-scraper
  • Auth: Authorization: Bearer <APIFY_TOKEN>
  • Transport: Streamable HTTP
  • Works with: Claude Desktop, Cursor, VS Code, Windsurf, Warp, Gemini CLI

Example MCP config (Claude Desktop / Cursor):

{
"mcpServers": {
"saas-pricing-scraper": {
"url": "https://mcp.apify.com?tools=labrat011/saas-pricing-scraper",
"headers": {
"Authorization": "Bearer <APIFY_TOKEN>"
}
}
}
}

Agent prompt example: "Compare the pricing of Linear, GitHub, and Supabase. Which offers the best value for a 10-person engineering team?"

The agent calls this tool, gets structured JSON for all tiers across all three products, and can compute total costs and compare features programmatically.


Technical details

  • Python 3.12, async architecture with asyncio.Semaphore concurrency control
  • Playwright (headless Chromium) for full JavaScript rendering
  • Stealth configuration: Chrome user agent, viewport 1920x1080, webdriver flag removal
  • Cookie banner auto-dismissal
  • Two-phase page wait: domcontentloaded + smart pricing wait, with full-load fallback for heavy SPAs
  • Multi-strategy extraction pipeline: plan headings, CSS card detection, sibling block analysis
  • Positional price correlation for row/grid layouts where prices live outside plan containers
  • BeautifulSoup4 for HTML parsing
  • SSRF prevention (blocks private IPs, cloud metadata endpoints)
  • Batch push (25 items) for memory efficiency
  • State persistence for resumable runs

FAQ

What kinds of pricing pages work best?

Pages with clearly structured plan cards or grids -- the typical SaaS pricing layout with 3-5 tiers shown side by side. The scraper handles both static HTML and JavaScript-rendered pages.

Why did a site return empty results?

Most likely the site uses aggressive bot detection that blocks headless browsers from rendering the pricing content. Check the extraction_notes field -- it will say "Playwright timeout" or "Could not extract any pricing plans" to help diagnose the issue.

Can I scrape non-English pricing pages?

The scraper detects prices by currency symbols and numeric patterns, so it can extract prices from pages in any language. Plan names and features will be in whatever language the page uses.

How do I get annual prices?

Many SaaS sites show both monthly and annual pricing via a billing toggle. The scraper detects billing toggles and extracts both prices when available. Annual prices appear in the annual_price field (normalized to per-month).

Can I use this with the Apify API?

Yes. Call the actor via the Apify API and retrieve results programmatically in JSON, CSV, or other formats. Works with the Apify Python and JavaScript clients.


Feedback

Found a bug or have a feature request? Open an issue on the actor's Issues tab in Apify Console.