SEO TOOLSAI

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.

Try on Apify Store
$0.25per event
0
Users (30d)
30
Runs (30d)
90
Actively maintained
Maintenance Pulse
$0.25
Per event

Maintenance Pulse

90/100
Last Build
Today
Last Version
1d ago
Builds (30d)
8
Issue Response
N/A

Cost Estimate

How many results do you need?

competitor-analyzeds
Estimated cost:$25.00

Pricing

Pay Per Event model. You only pay for what you use.

EventDescriptionPrice
competitor-analyzedCharged 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

  1. Enter one or more competitor website URLs (e.g., https://notion.so, https://slack.com, https://linear.app)
  2. Choose which intelligence to gather: pricing, careers, team info, or all three
  3. Click Start and wait for the run to finish (typically under 2 minutes for 5 competitors)
  4. Download results from the Dataset tab in JSON, CSV, or Excel format

Input Parameters

ParameterTypeRequiredDefaultDescription
competitorUrlsString[]YesList of competitor website URLs (e.g., https://notion.so). Domains without https:// are normalized automatically.
checkPricingBooleanNotrueFind and extract pricing page data including plan names, prices, billing periods, and features.
checkCareersBooleanNotrueFind and extract career page data including job listings, total openings, and hiring velocity.
checkTeamBooleanNofalseFind and extract team/about page data including estimated team size and company description.
maxPagesPerSiteIntegerNo10Maximum pages to crawl per competitor website (1–50). Most useful data comes from 3–4 pages.
maxResultsIntegerNo50Maximum 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 maxPagesPerSite low (3–5) for faster runs. Most useful data comes from homepage + pricing + careers + about.
  • URLs without https:// are normalized automatically — notion.so works just as well as https://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

FieldTypeDescription
urlStringThe competitor URL that was analyzed
domainStringNormalized domain (without www.)
companyNameStringDetected company name (from og:site_name or <title>)
scrapedAtStringISO 8601 timestamp of the scrape
homepage.titleStringWebsite <title> tag content
homepage.descriptionStringMeta description or og:description
homepage.ogImageString / nullOpen Graph image URL
homepage.socialLinksObjectSocial media URLs found in page links (twitter, linkedin, facebook, instagram, youtube, github, tiktok)
pricing.foundBooleanWhether a pricing page was found and extracted
pricing.pricingUrlString / nullURL of the pricing page
pricing.plans[]ArrayExtracted pricing plans, each with name, price, period, features[]
pricing.rawPricingTextString / nullRaw text from the pricing page (up to 3,000 chars)
careers.foundBooleanWhether a careers page was found
careers.careersUrlString / nullURL of the careers page
careers.totalOpeningsIntegerNumber of open positions detected
careers.jobTitlesString[]Up to 50 unique job titles found
careers.hiringVelocityStringnone (0), minimal (1–5), moderate (6–20), or aggressive (21+)
team.foundBooleanWhether a team/about page was found
team.teamUrlString / nullURL of the team/about page
team.teamSizeInteger / nullEstimated team size (from member cards or text patterns)
team.companyDescriptionString / nullCompany description from meta tags or first paragraph
techStackString[]Detected technologies, sorted alphabetically
metadata.pagesScrapedIntegerNumber of pages crawled for this competitor
metadata.scrapeDurationMsIntegerTotal 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 TypeURL PatternsAnchor Text Keywords
Pricing/pricing, /plans, /packagespricing, plans, packages
Careers/careers, /jobs, /hiring, /open-rolescareers, jobs, hiring, work-with-us, join-us, openings
Team/about, /team, /company, /peopleabout, 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:

CategoryTechnologies Detected
AnalyticsGoogle Analytics, Google Tag Manager, Segment, Mixpanel, Amplitude, Heap, Hotjar, FullStory
MarketingHubSpot, Marketo, Pardot, Clearbit
SupportIntercom, Drift, Zendesk, Crisp, Freshdesk
PaymentsStripe
Error TrackingSentry, Datadog
FrameworksReact, Vue.js, Angular, Next.js, Nuxt.js
CMS/PlatformsWordPress, Webflow, Shopify
InfrastructureCloudflare, Salesforce
Feature FlagsLaunchDarkly, Optimizely

Hiring Velocity Classification

VelocityOpen PositionsSignal
none0Not actively hiring
minimal1–5Selective hiring or backfills
moderate6–20Steady growth phase
aggressive21+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.

ScenarioCompetitorsEstimated Cost
Quick comparison3 competitors~$0.005
Weekly monitoring10 competitors~$0.02
Market landscape25 competitors~$0.05
Large-scale audit50 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 rawPricingText field 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.XX patterns 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_name or <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 maxPagesPerSite at 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

ActorWhat it doesUse with SaaS Competitive Intel
Website Tech Stack DetectorDeep technology analysisMore thorough tech stack fingerprinting
Website Contact ScraperExtract contact detailsGet emails and phone numbers from competitor sites
Brand Protection MonitorBrand threat monitoringCheck if competitors are typosquatting your brand
E-Commerce Price MonitorProduct price trackingTrack e-commerce product prices alongside SaaS pricing
Company Deep Research AgentComprehensive company researchGet Wikipedia, SEC, GitHub, and DNS data on competitors
SERP Rank TrackerKeyword ranking trackingSee how competitors rank for shared keywords
WHOIS Domain LookupDomain registration detailsGet registration dates and hosting info for competitor domains

How it works

01

Configure

Set your parameters in the Apify Console or pass them via API.

02

Run

Click Start, trigger via API, webhook, or set up a schedule.

03

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.

Ready to try SaaS Competitive Intelligence?

Start for free on Apify. No credit card required.

Open on Apify Store