SaaS Competitive Intelligence
Automatically monitor and analyze competitor SaaS websites to extract pricing plans, job openings, team size, tech stack, and social media presence. Enter a list of competitor URLs and get structured competitive intelligence data back in JSON, CSV, or Excel format — no manual research required.
Maintenance Pulse
90/100Cost Estimate
How many results do you need?
Pricing
Pay Per Event model. You only pay for what you use.
| Event | Description | Price |
|---|---|---|
| competitor-analyzed | Charged per competitor analyzed. Scrapes homepage, pricing, careers, and team pages with tech stack detection, pricing extraction, and team size inference. | $0.25 |
Example: 100 events = $25.00 · 1,000 events = $250.00
Documentation
Automatically monitor and analyze competitor SaaS websites to extract pricing plans, job openings, team size, tech stack, and social media presence. Enter a list of competitor URLs and get structured competitive intelligence data back in JSON, CSV, or Excel format — no manual research required.
Why Use SaaS Competitive Intelligence?
Manual competitor research is tedious: visiting pricing pages, checking career listings, counting team members, and identifying tech stacks across dozens of sites. This actor does it all in under 2 minutes for 5 competitors, returning clean structured data you can feed into dashboards, spreadsheets, or alerting systems. Schedule it weekly to track changes over time.
Features
- Pricing extraction — automatically finds pricing pages and extracts plan names, prices, billing periods, and feature lists from competitor websites
- Career page analysis — detects job listings, counts open positions, and classifies hiring velocity (none, minimal, moderate, aggressive)
- Team and company intelligence — scrapes about/team pages for estimated team size and company descriptions
- Tech stack detection — identifies 30+ technologies including analytics (Google Analytics, Mixpanel, Amplitude), frameworks (React, Next.js, Vue.js, Angular), support (Intercom, Zendesk, Crisp), marketing (HubSpot, Marketo, Pardot), and infrastructure (Cloudflare, Stripe, Sentry)
- Social media link discovery — extracts links to Twitter/X, LinkedIn, Facebook, Instagram, YouTube, GitHub, and TikTok profiles
- Batch processing — analyze up to 50 competitor websites in a single run with configurable crawl depth per site
- Structured output — returns clean, normalized JSON data per competitor with homepage metadata, pricing details, career data, and detected technologies
How to Use
- Enter one or more competitor website URLs (e.g.,
https://notion.so,https://slack.com,https://linear.app) - Choose which intelligence to gather: pricing, careers, team info, or all three
- Click Start and wait for the run to finish (typically under 2 minutes for 5 competitors)
- Download results from the Dataset tab in JSON, CSV, or Excel format
Input Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
competitorUrls | String[] | Yes | — | List of competitor website URLs (e.g., https://notion.so). Domains without https:// are normalized automatically. |
checkPricing | Boolean | No | true | Find and extract pricing page data including plan names, prices, billing periods, and features. |
checkCareers | Boolean | No | true | Find and extract career page data including job listings, total openings, and hiring velocity. |
checkTeam | Boolean | No | false | Find and extract team/about page data including estimated team size and company description. |
maxPagesPerSite | Integer | No | 10 | Maximum pages to crawl per competitor website (1–50). Most useful data comes from 3–4 pages. |
maxResults | Integer | No | 50 | Maximum number of competitor websites to process per run (1–200). |
Input Examples
Quick competitor comparison — pricing and careers:
{
"competitorUrls": ["https://notion.so", "https://slack.com", "https://linear.app"],
"checkPricing": true,
"checkCareers": true,
"checkTeam": false
}
Full analysis — all modules enabled:
{
"competitorUrls": ["https://stripe.com", "https://square.com", "https://paypal.com"],
"checkPricing": true,
"checkCareers": true,
"checkTeam": true,
"maxPagesPerSite": 15
}
Tech stack audit only — homepage scan:
{
"competitorUrls": ["https://vercel.com", "https://netlify.com", "https://render.com"],
"checkPricing": false,
"checkCareers": false,
"checkTeam": false,
"maxPagesPerSite": 1
}
Input Tips
- Even without enabling pricing/careers/team, the homepage scan extracts company name, meta description, social media links, and full tech stack.
- Keep
maxPagesPerSitelow (3–5) for faster runs. Most useful data comes from homepage + pricing + careers + about. - URLs without
https://are normalized automatically —notion.soworks just as well ashttps://notion.so.
Output
The actor returns one result object per competitor website:
{
"url": "https://notion.so",
"domain": "notion.so",
"companyName": "Notion",
"scrapedAt": "2025-11-15T14:32:07.123Z",
"homepage": {
"title": "Notion - Your connected workspace for wiki, docs & projects",
"description": "A new tool that blends your everyday work apps into one.",
"ogImage": "https://www.notion.so/images/meta/default.png",
"socialLinks": {
"twitter": "https://x.com/NotionHQ",
"linkedin": "https://www.linkedin.com/company/notionhq/",
"youtube": "https://www.youtube.com/@NotionHQ"
}
},
"pricing": {
"found": true,
"pricingUrl": "https://www.notion.so/pricing",
"plans": [
{
"name": "Free",
"price": "$0",
"period": "/mo",
"features": ["Collaborative workspace", "7 day page history"]
},
{
"name": "Plus",
"price": "$10",
"period": "/mo",
"features": ["Unlimited blocks", "30 day page history"]
}
],
"rawPricingText": null
},
"careers": {
"found": true,
"careersUrl": "https://www.notion.so/careers",
"totalOpenings": 42,
"jobTitles": ["Senior Software Engineer", "Product Designer"],
"hiringVelocity": "aggressive"
},
"team": {
"found": true,
"teamUrl": "https://www.notion.so/about",
"teamSize": 500,
"companyDescription": "Notion is a connected workspace..."
},
"techStack": ["Cloudflare", "Google Analytics", "Intercom", "Next.js", "Stripe"],
"metadata": {
"pagesScraped": 4,
"scrapeDurationMs": 8432
}
}
Output Fields
| Field | Type | Description |
|---|---|---|
url | String | The competitor URL that was analyzed |
domain | String | Normalized domain (without www.) |
companyName | String | Detected company name (from og:site_name or <title>) |
scrapedAt | String | ISO 8601 timestamp of the scrape |
homepage.title | String | Website <title> tag content |
homepage.description | String | Meta description or og:description |
homepage.ogImage | String / null | Open Graph image URL |
homepage.socialLinks | Object | Social media URLs found in page links (twitter, linkedin, facebook, instagram, youtube, github, tiktok) |
pricing.found | Boolean | Whether a pricing page was found and extracted |
pricing.pricingUrl | String / null | URL of the pricing page |
pricing.plans[] | Array | Extracted pricing plans, each with name, price, period, features[] |
pricing.rawPricingText | String / null | Raw text from the pricing page (up to 3,000 chars) |
careers.found | Boolean | Whether a careers page was found |
careers.careersUrl | String / null | URL of the careers page |
careers.totalOpenings | Integer | Number of open positions detected |
careers.jobTitles | String[] | Up to 50 unique job titles found |
careers.hiringVelocity | String | none (0), minimal (1–5), moderate (6–20), or aggressive (21+) |
team.found | Boolean | Whether a team/about page was found |
team.teamUrl | String / null | URL of the team/about page |
team.teamSize | Integer / null | Estimated team size (from member cards or text patterns) |
team.companyDescription | String / null | Company description from meta tags or first paragraph |
techStack | String[] | Detected technologies, sorted alphabetically |
metadata.pagesScraped | Integer | Number of pages crawled for this competitor |
metadata.scrapeDurationMs | Integer | Total scrape time in milliseconds |
Use Cases
- Product managers — track how competitors change pricing tiers and feature bundles over time. Run weekly to spot pricing shifts early.
- Venture capital analysts — gauge growth signals by monitoring hiring velocity and team size across portfolio companies and competitors.
- Marketing teams — understand which analytics, CRM, and marketing tools competitors use to inform tooling decisions.
- Sales teams — prepare for competitive deals by knowing exactly what pricing plans and features rivals offer.
- Startup founders — benchmark pricing against the market and track when competitors expand engineering or sales teams.
- Market researchers — build comprehensive competitive landscape reports with structured data on dozens of SaaS companies.
How to Use the API
Python
import requests
import time
run = requests.post(
"https://api.apify.com/v2/acts/ryanclinton~saas-competitive-intel/runs",
params={"token": "YOUR_APIFY_TOKEN"},
json={
"competitorUrls": ["https://notion.so", "https://slack.com", "https://linear.app"],
"checkPricing": True,
"checkCareers": True,
"checkTeam": True
},
timeout=30,
).json()
run_id = run["data"]["id"]
while True:
status = requests.get(
f"https://api.apify.com/v2/actor-runs/{run_id}",
params={"token": "YOUR_APIFY_TOKEN"},
timeout=10,
).json()
if status["data"]["status"] in ("SUCCEEDED", "FAILED", "ABORTED"):
break
time.sleep(5)
dataset_id = status["data"]["defaultDatasetId"]
items = requests.get(
f"https://api.apify.com/v2/datasets/{dataset_id}/items",
params={"token": "YOUR_APIFY_TOKEN"},
timeout=30,
).json()
for item in items:
plans = ", ".join(f"{p['name']}: {p['price']}" for p in item["pricing"]["plans"])
print(f"{item['companyName']}: {plans or 'No pricing found'}")
print(f" Hiring: {item['careers']['hiringVelocity']} ({item['careers']['totalOpenings']} openings)")
print(f" Tech: {', '.join(item['techStack'][:5])}")
JavaScript
const response = await fetch(
"https://api.apify.com/v2/acts/ryanclinton~saas-competitive-intel/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
competitorUrls: ["https://notion.so", "https://slack.com"],
checkPricing: true,
checkCareers: true,
}),
}
);
const results = await response.json();
results.forEach((r) => {
console.log(`${r.companyName}: ${r.pricing.plans.length} plans, ${r.careers.totalOpenings} openings`);
});
cURL
curl -X POST "https://api.apify.com/v2/acts/ryanclinton~saas-competitive-intel/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"competitorUrls": ["https://notion.so", "https://slack.com"],
"checkPricing": true,
"checkCareers": true
}'
How It Works
Input (competitor URLs, module toggles)
│
▼
┌──────────────────────────────────────────────────┐
│ URL Normalization │
│ Add https:// if missing, extract domain │
│ Initialize result objects per domain │
└──────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ CheerioCrawler (concurrency: 5) │
│ │
│ ┌─ HOMEPAGE handler ─────────────────────────┐ │
│ │ • Extract <title>, og:*, meta description │ │
│ │ • Detect company name (og:site_name > title)│ │
│ │ • Extract social media links (7 platforms) │ │
│ │ • Detect tech stack (30+ regex patterns) │ │
│ │ • Discover pricing/careers/team page links │ │
│ │ via URL patterns + anchor text matching │ │
│ │ • Queue discovered subpages for crawling │ │
│ └────────────────────────────────────────────┘ │
│ │ │
│ ├── PRICING handler ───────────────────┐ │
│ │ Strategy 1: CSS class selectors │ │
│ │ [class*="price"], [class*="plan"] │ │
│ │ → extract plan name, $price, │ │
│ │ /period, feature lists │ │
│ │ │ │
│ │ Strategy 2: Fallback regex scan │ │
│ │ Scan all elements for $X.XX │ │
│ │ patterns + nearby headings │ │
│ │ Deduplicate by price+name │ │
│ └──────────────────────────────────────┘ │
│ │ │
│ ├── CAREERS handler ───────────────────┐ │
│ │ Strategy 1: Job CSS selectors │ │
│ │ [class*="job"], a[href*="/jobs/"] │ │
│ │ │ │
│ │ Strategy 2: Role keyword matching │ │
│ │ engineer, designer, manager, etc. │ │
│ │ │ │
│ │ Strategy 3: Count text patterns │ │
│ │ "42 open positions" │ │
│ │ │ │
│ │ Hiring velocity classification: │ │
│ │ 0=none, 1-5=minimal, │ │
│ │ 6-20=moderate, 21+=aggressive │ │
│ └──────────────────────────────────────┘ │
│ │ │
│ └── TEAM handler ──────────────────────┐ │
│ Count team member cards via CSS │ │
│ Fallback: "200+ employees" text │ │
│ Extract company description from │ │
│ meta tags or first paragraph │ │
│ └──────────────────────────────────┘ │
└──────────────────────────────────────────────────┘
│
▼
Dataset (one row per competitor)
Page Discovery
The actor finds subpages by scanning all internal links on the homepage for URL patterns and anchor text:
| Page Type | URL Patterns | Anchor Text Keywords |
|---|---|---|
| Pricing | /pricing, /plans, /packages | pricing, plans, packages |
| Careers | /careers, /jobs, /hiring, /open-roles | careers, jobs, hiring, work-with-us, join-us, openings |
| Team | /about, /team, /company, /people | about, team, company, people, our-team, about-us |
Only same-domain links are followed.
Tech Stack Detection
The actor identifies 30+ technologies by matching regex patterns against script sources, link hrefs, and raw HTML:
| Category | Technologies Detected |
|---|---|
| Analytics | Google Analytics, Google Tag Manager, Segment, Mixpanel, Amplitude, Heap, Hotjar, FullStory |
| Marketing | HubSpot, Marketo, Pardot, Clearbit |
| Support | Intercom, Drift, Zendesk, Crisp, Freshdesk |
| Payments | Stripe |
| Error Tracking | Sentry, Datadog |
| Frameworks | React, Vue.js, Angular, Next.js, Nuxt.js |
| CMS/Platforms | WordPress, Webflow, Shopify |
| Infrastructure | Cloudflare, Salesforce |
| Feature Flags | LaunchDarkly, Optimizely |
Hiring Velocity Classification
| Velocity | Open Positions | Signal |
|---|---|---|
none | 0 | Not actively hiring |
minimal | 1–5 | Selective hiring or backfills |
moderate | 6–20 | Steady growth phase |
aggressive | 21+ | Rapid expansion (often signals funding round or new product) |
How Much Does It Cost?
This actor uses CheerioCrawler (server-side HTML, no browser rendering), making it extremely lightweight.
| Scenario | Competitors | Estimated Cost |
|---|---|---|
| Quick comparison | 3 competitors | ~$0.005 |
| Weekly monitoring | 10 competitors | ~$0.02 |
| Market landscape | 25 competitors | ~$0.05 |
| Large-scale audit | 50 competitors | ~$0.10 |
The Apify Free plan ($5/month) covers daily monitoring of 10 competitors for an entire month.
Tips
- Start with homepages — even without enabling pricing/careers/team, the homepage scan extracts company name, description, social links, and full tech stack.
- Run on a schedule — set up a weekly or monthly schedule to track competitor changes over time. Connect to Google Sheets or a webhook to build a time-series dashboard.
- Keep maxPagesPerSite low — the default of 10 is generous. Most useful data comes from 3–4 pages. Lower values speed up execution.
- Watch hiring velocity — a competitor shifting from "minimal" to "aggressive" often signals a new product launch, funding round, or market expansion 3–6 months before it becomes public.
- Combine with WHOIS data — pair with domain lookup tools to get registration dates and hosting details alongside competitive intelligence.
- Use rawPricingText for custom parsing — if the auto-extracted pricing plans miss details, the
rawPricingTextfield contains up to 3,000 characters of raw pricing page text you can parse yourself.
Limitations
- Server-rendered HTML only — uses CheerioCrawler, which processes server-side HTML. If a competitor's pricing page relies heavily on client-side JavaScript rendering, pricing plans may not be fully extracted. Most SaaS companies serve pricing content in initial HTML for SEO.
- Pricing extraction is heuristic — the actor looks for
$X.XXpatterns and CSS classes containing "price", "plan", or "tier". Custom pricing structures, enterprise-only pricing, or heavily abstracted layouts may not be detected. - Job title quality varies — job listing extraction depends on consistent HTML structure. Some career pages use embedded iframes (Greenhouse, Lever) that CheerioCrawler cannot access.
- Team size is estimated — counted from team member cards or text patterns like "200+ employees". Companies that don't display team info on their website will return
null. - No login/authentication — the actor only accesses publicly visible pages. Gated content behind login walls is not accessible.
- Social media links are from anchor tags only — if social links are rendered via JavaScript or embedded in images, they may not be detected.
- 30+ tech stack patterns, not exhaustive — the detection covers major tools but may miss niche or recently launched technologies.
- One brand name per competitor — the company name is auto-detected from
og:site_nameor<title>. Multi-brand companies may show the parent brand only.
Responsible Use
- Only scrape publicly available pages — this actor accesses the same pages any visitor would see in a browser.
- Respect robots.txt — the CheerioCrawler respects robots.txt directives by default.
- Use reasonable crawl depths — keep
maxPagesPerSiteat 10 or below to avoid excessive requests to competitor servers. - Competitive intelligence, not harassment — use the data for legitimate business analysis, not to spam or attack competitors.
- Comply with applicable laws — for GDPR, CCPA, or jurisdiction-specific questions, consult legal counsel. See Apify's guide on web scraping legality.
FAQ
How does the actor find pricing, career, and team pages? It crawls the competitor's homepage and scans all internal links for URL patterns and anchor text matching keywords like "pricing", "plans", "careers", "jobs", "about", and "team".
Can it extract pricing from JavaScript-rendered pages? This actor uses CheerioCrawler (server-side HTML). If a competitor's pricing relies on client-side JavaScript, plans may not be fully extracted. Most SaaS companies serve pricing in initial HTML for SEO.
What tech stack tools does it detect? 30+ technologies across analytics, marketing, support, payments, error tracking, frameworks, CMS, and infrastructure. See the tech stack detection table above.
How accurate is the hiring velocity classification? Based on the number of open positions found: "none" (0), "minimal" (1–5), "moderate" (6–20), "aggressive" (21+). Reflects what is publicly listed at the time of the scrape.
Can I monitor competitors automatically on a schedule? Yes. Set up a cron schedule on Apify to run daily, weekly, or monthly. Combine with Zapier or webhooks for automated alerts.
Why is team size sometimes null? Team size is estimated from team member cards or text patterns. If the page uses a non-standard layout or doesn't disclose team size, the value will be null.
Can I track more than 50 competitors?
Yes, set maxResults up to 200. Larger batches take proportionally longer to complete.
Integrations
- Zapier — trigger alerts when competitors change pricing or post new jobs.
- Make (Integromat) — build multi-step competitive analysis workflows.
- Google Sheets — export competitor data into a tracking spreadsheet.
- Webhooks — receive results at any HTTP endpoint for custom processing.
- Apify API — call programmatically from any language for custom dashboards.
- Slack / Email — configure Apify notifications for run completion alerts.
Related Actors
| Actor | What it does | Use with SaaS Competitive Intel |
|---|---|---|
| Website Tech Stack Detector | Deep technology analysis | More thorough tech stack fingerprinting |
| Website Contact Scraper | Extract contact details | Get emails and phone numbers from competitor sites |
| Brand Protection Monitor | Brand threat monitoring | Check if competitors are typosquatting your brand |
| E-Commerce Price Monitor | Product price tracking | Track e-commerce product prices alongside SaaS pricing |
| Company Deep Research Agent | Comprehensive company research | Get Wikipedia, SEC, GitHub, and DNS data on competitors |
| SERP Rank Tracker | Keyword ranking tracking | See how competitors rank for shared keywords |
| WHOIS Domain Lookup | Domain registration details | Get registration dates and hosting info for competitor domains |
How it works
Configure
Set your parameters in the Apify Console or pass them via API.
Run
Click Start, trigger via API, webhook, or set up a schedule.
Get results
Download as JSON, CSV, or Excel. Integrate with 1,000+ apps.
Use cases
Sales Teams
Build targeted lead lists with verified contact data.
Marketing
Research competitors and identify outreach opportunities.
Data Teams
Automate data collection pipelines with scheduled runs.
Developers
Integrate via REST API or use as an MCP tool in AI workflows.
Related actors
Website Contact Scraper
Extract emails, phone numbers, team members, and social media links from any business website. Feed it URLs from Google Maps or your CRM and get structured contact data back. Fast HTTP requests, no browser — scrapes 1,000 sites for ~$0.50.
Email Pattern Finder
Discover the email format used by any company. Enter a domain like stripe.com and detect patterns like [email protected]. Then generate email addresses for any name. Combine with Website Contact Scraper to turn company websites into complete email lists.
Website Content to Markdown
Convert any website to clean Markdown for RAG pipelines, LLM training, and AI apps. Crawls pages, strips boilerplate, preserves headings, tables, and code blocks. GFM support.
Wayback Machine Search
Search Internet Archive for historical web snapshots. Find cached pages, track website changes over time, recover deleted content. Filter by date, status, content type. No API key needed.
Ready to try SaaS Competitive Intelligence?
Start for free on Apify. No credit card required.
Open on Apify Store