SaaS Competitive Intelligence
Pricing
from $250.00 / 1,000 competitor analyzeds
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.
Pricing
from $250.00 / 1,000 competitor analyzeds
Rating
0.0
(0)
Developer
Ryan Clinton
Maintained by CommunityActor stats
0
Bookmarked
6
Total users
2
Monthly active users
2 hours ago
Last modified
Share

Deterministic competitive decision infrastructure for SaaS teams. This actor continuously monitors competitor websites and converts weak public signals — pricing changes, enterprise expansion, AI adoption, hiring spikes, GTM shifts, and strategic drift — into structured operational decisions.
This is not a generic web scraper — it is a deterministic competitive signal router that turns competitor web changes into auditable GTM decisions: operational decisions, escalation recommendations, deterministic battlecard updates, and structured strategic signals. No dashboard, no analyst queue, no LLM. It functions as a programmable competitive-intelligence platform for SaaS teams that need deterministic monitoring, structured signals, and automation-native workflows without enterprise-dashboard overhead.
Most competitor-monitoring tools give you snapshots. This actor accumulates memory — pricing history, hiring history, AI-adoption history, strategic-drift history. Anyone can scrape a competitor's website today; no one can reconstruct the six months of strategic movement you've already observed. The moat is memory, not scraping.
Unlike generic web scrapers or AI research agents, the output is deterministic, explainable, schema-stable, automation-ready, longitudinally comparable, and designed for routing, escalation, and monitoring workflows. Every classification is auditable. Every score is reproducible. No LLM calls. No black-box scoring. No hallucinations.
Every run answers four questions:
- What changed? —
changeFlags/fieldDiffs/competitorMemory.history - Why does it matter? —
whyThisMatters/threatSurface/competitiveMateriality - What should we do? —
escalationRecommendation/battlecardDelta/nextBestAction - Where can we win? —
opportunityScore/attackTargets(which competitors are weakening, which accounts to target) — the revenue axis threat-only tools never compute
Everything else in the output is the evidence behind those four answers.
TL;DR
This actor:
- detects competitor strategic movement across pricing / hiring / enterprise / AI / GTM
- classifies pricing model, GTM motion, enterprise readiness, AI maturity, archetype, market position
- scores competitive threats deterministically via weighted signals + per-class confidence
- detects strategic drift between runs (PLG → sales-led, no-AI → AI-native, SMB → enterprise)
- suppresses noisy signals with documented reasons (alert-fatigue resistance)
- escalates meaningful changes via persona-shaped routing (sales-enablement / executive-monitoring / product-strategy / vc-monitoring / revops-routing)
- optionally folds in customer voice from public G2 reviews and cross-signals it against the website signals (competitor moved upmarket and customers are unhappy = a
switching_window) - emits a deterministic battlecard delta — which sections to revise, talk track, and CRM tags — without an LLM
- emits schema-stable enum outputs for Slack / Zapier / Make / n8n / Dify / agent tool calls
- requires no LLM — every score, event, and classification is reproducible from the same inputs
Pay-per-event: $0.25 per competitor analyzed. HTML-first extraction (a headless browser is used only for JS-rendered careers pages) — fast, cheap, deterministic.

Ready-to-run examples
Pre-configured runs you can launch or clone in one click — each is tuned for a specific competitive-intelligence job:
- SaaS Competitor Intelligence Monitor — track a cohort's pricing, hiring, AI adoption, and enterprise moves as automation-ready JSON.
- Find Competitor Switching Windows — fuse website signals with G2 review sentiment to surface live sales openings.
- Competitor Product & AI Strategy Tracker — follow competitors' AI adoption, GTM motion, and strategic drift over time.
- VC Market Scan for SaaS Competitors — scan a cohort for growth, AI, and upmarket signals.
- RevOps Competitor Alert Router — route every material competitor change into Slack, Zapier, or your CRM.
- Audit Competitor Enterprise Readiness — grade competitors on SSO, SCIM, SOC 2, and compliance read from their security and trust pages.
See all ready-to-run examples →
Common tasks
One engine, many competitive-intelligence jobs — each maps to a stable output field your workflow branches on:
| Job | Output |
|---|---|
| Monitor competitor pricing changes | changeFlags, pricingClassification |
| Detect GTM / strategy shifts | strategicDrift |
| Find sales-displacement opportunities | attackTargets |
| Track weakening competitors | opportunityScore |
| Detect switching windows | reviewVoice + attackTargets |
| Route urgent competitor changes | escalationRecommendation |
| Generate battlecard updates | battlecardDelta |
| Monitor enterprise expansion | enterpriseSignals |
| Track AI-feature adoption | aiSignals |
| Watch competitor product momentum | threatVelocity |
| Detect aggressive hiring | careers (classified hiring velocity) |
| Build a weekly competitor watchlist | watchlist mode + competitorMemory |
A switching window is the signature signal: a competitor raises prices while its G2 satisfaction drops and support complaints rise — a live opening to win their accounts, surfaced automatically at a high opportunityScore with the segment and the playbook to act on.
Flagship capabilities
Strategic drift detection
Detects when competitors change direction across watchlist runs:
- PLG → sales-led
- SMB → enterprise
- non-AI → AI-native
- pricing-transparent → pricing-opaque
Competitive event detection
Identifies operationally significant inferred events:
- enterprise expansion
- pricing restructuring
- AI-product launches
- sales-team buildouts
- aggressive growth phase
- pricing-transparency loss
Decision infrastructure
Prioritises human attention through deterministic rules:
escalationRecommendation— single field downstream automation branches oncompetitiveMateriality— persona-shaped weightingalertQuality— novelty + urgency + noiseRisksuppressedSignals— flagged-as-likely-noise with reasonsoperationalConfidence.safeToAutomate— production-automation gatedecisionBundles— events grouped under unifying themes
Longitudinal monitoring
Watchlist mode tracks per-competitor:
threatVelocity(numeric rate of change)focusShift(what they're emphasising right now)temporalSignals(trend / momentum / volatility / re-escalation)changeFlags(14 stable enums for routing)changeDensity(cohort activity pulse)

Fully auditable output
Every score, event, and classification ships with:
evidenceobjects (type+value+source+confidence)provenanceGraph(derived classifications → source evidence)scoringTrace(per-rule weights + contributions)perClassConfidence(per-signal-class 0-1 score)- deterministic reasoning — same inputs always produce the same output
Core concepts — the 5-layer architecture
This actor is built around five deterministic layers:
| Layer | Purpose |
|---|---|
| Extraction | Collect structured competitor data from public pages |
| Intelligence | Classify pricing, GTM motion, enterprise maturity, AI adoption, archetype, market position |
| Operational | Detect changes, strategic drift, pressure zones, competitive events, counter-moves |
| Decision infrastructure | Prioritise human attention via escalation, suppression, materiality, persona routing |
| Temporal | Compare competitors longitudinally across watchlist runs |
Every layer is independently consumable — sales teams branch on materiality + persona; ops teams branch on actionability + escalation; analysts read the full decision trace.


What makes this different?
| Tool type | What you get |
|---|---|
| Generic scraper | Raw HTML — analysis is your problem |
| AI research agent | Narrative summaries, low reproducibility, hallucination risk |
| Enterprise CI platform (Crayon / Klue / Kompyte / Contify) | Expensive dashboards + manual analyst workflows + per-seat licensing |
| This actor | Deterministic competitive decision infrastructure — auditable, explainable, schema-stable, automation-ready, pay-per-event |
The fields behind the memory moat: competitorMemory.history, milestones, and cohortShifts — accumulated cross-run state a same-day clone cannot backfill.
Crayon / Klue vs this actor
| Crayon / Klue | This actor |
|---|---|
| Dashboard you log into | Schema-stable JSON that routes itself |
| Analyst curation workflow | Deterministic automation, no humans in the loop |
| Per-seat licensing | Pay-per-event ($0.25 / competitor analysed) |
| Snapshots of "now" | Accumulated historical memory |
| Manual review queues | escalationRecommendation + attackTargets routing |
| AI-filtered alerts | No LLM — reproducible, auditable signals |
Website signals × customer voice = switching windows. A website scraper sees a competitor raise prices; a review scraper sees their customers complain. Only this actor sees both at once — when a competitor moves upmarket and its G2 reviews show a satisfaction drop, it emits a switching_window: a live sales opening, routed to your sales team with a playbook. That cross-signal is the wedge neither a website scraper nor a review scraper produces alone (opt in with includeReviews: "g2").
How it forms, end to end: (1) a competitor raises prices → website changeFlags: PRICING_CHANGED; (2) their G2 reviews show satisfaction_drop + support_gap; (3) the actor emits a switching_window cross-signal at a high opportunityScore; (4) it lands in attackTargets with a playbook and routes to a sales Slack channel via a webhook — no analyst, no dashboard, no LLM in the path.

Lightweight alternative to Crayon, Klue, Kompyte, and Contify
Compared to enterprise CI platforms like Crayon or Klue, this actor is lightweight, programmable, and automation-native — no per-seat license, no implementation services, no dashboard to maintain. Pay-per-event scales with what you monitor ($0.25 per competitor analysed).
For startups, RevOps, and sales-enablement teams that want a Crayon alternative or Klue alternative without the dashboard overhead, it delivers the same monitoring outcomes — pricing changes, hiring spikes, AI adoption, enterprise expansion, GTM shifts — as schema-stable JSON that drops straight into Slack, Zapier, Make, n8n, Dify, and agent tool calls. It's the data-supply layer underneath your battlecard process, not a replacement for the battlecard tool.

Which score should I use?
The actor emits several scores because they answer different questions. You rarely need all of them — pick the one that matches your question:
| Your question | Field |
|---|---|
| How dangerous is this competitor? | threatScore |
| Does it matter to me / my role? | competitiveMateriality |
| Should I act on it now? | actionabilityScore |
| Can automation trust this without a human? | operationalConfidence |
| Where can we win? | opportunityScore |
Everything else (alertQuality, surpriseIndex, riskHorizon, threatVelocity) is supporting detail for the analyst who wants the full trace — start with the five above.
Key definitions
- Threat score — weighted competitive signal intensity, 0-100. Sum of weighted contributions from detected signals.
- Threat level — categorical band derived from threat score:
critical(≥60),alert(≥40),monitor(≥20),watch(<20). - Competitive materiality — how much a signal matters to a specific persona. 0-100, persona-shaped weights.
- Actionability score — how worth your time is acting NOW. Composite of evidence strength + magnitude + freshness + strategic importance.
- Strategic drift — directional competitor identity change between watchlist runs (PLG → sales-led, no-AI → AI-native, SMB → enterprise).
- Pressure zones — areas where a competitor is actively investing (
enterprise-readiness / ai-products / developer-platform / pricing-aggression / sales-buildout / product-velocity / international-expansion). - Operational confidence — boolean gate: whether downstream automation can safely act without human review.
- Decision infrastructure — deterministic routing + escalation + suppression logic built on competitive signals.
- Evidence object — every signal ships with
{ type, value, source, confidence }so any classification can be traced back to the source page and detection method. - Provenance graph — explicit map from each derived classification to the source-evidence strings that produced it.
- Suppressed signal — a signal that fired but the actor flagged as likely noise, with a documented reason.
- Watchlist — named, isolated cross-run state. Each watchlist has its own history; same name = same comparison baseline.
- Persona — analyst-role preset that shapes escalation thresholds, audience tags, suppressed event types, and materiality weights. Different from
mode(scan depth) andoutputProfile(verbosity). - Schema-stable enums — output enum values are additive across minor versions; never renamed or repurposed within a major version.
Designed for
This actor is designed for sales, RevOps, product-strategy, competitive-intelligence, and investor teams who need continuous competitor monitoring at SaaS-cohort scale (3–200 competitors per run) as deterministic, hallucination-free output — routed into Slack / CRM / agent tool-calls, not a dashboard. It is built for workflows that branch on stable enums and compare competitors longitudinally across watchlist runs.
Who this is NOT for
- Teams that want a dashboard to log into — this returns JSON for automation, not a UI.
- Anyone who needs AI-written narrative or recommendations — every output is deterministic and rule-based, by design.
- One-off, single-competitor lookups where history doesn't matter — the value compounds with watchlist runs over time.
- Buyers who need shipment-level, licensed, or behind-login data (Bloomberg / Panjiva / paid CI feeds) — this reads public web + public G2 reviews only.
Design principles
This actor is intentionally:
- deterministic over probabilistic — same inputs always produce the same output; no LLM, no randomness, no hidden tuning.
- auditable over opaque — every score, classification, and event ships with structured evidence + provenance + scoring trace.
- composable over monolithic — five independent layers (extraction / intelligence / operational / decision-infrastructure / temporal); pick the layers your workflow needs.
- schema-stable over narrative-heavy — additive enum vocabulary, documented contract, every record carries
schemaVersion. - operational over presentational — output is built for routing, escalation, and automation pipelines; not for dashboards alone.
- longitudinal over snapshot-only — watchlist mode is a first-class capability, not an afterthought.
- suppression-aware over noise-blind — the actor flags signals as likely noise with documented reasons rather than dumping every change into the alert queue.
- honest about scope — see "What this actor does NOT do" — sibling actors handle the work that's deliberately out of scope here.
The goal is reliable competitive monitoring infrastructure — not AI-generated prose, not a dashboard, not a research report. Infrastructure means deterministic, recurring, automation-native, schema-contracted output that downstream systems can trust.
The actor behaves more like reliability-focused infrastructure than an AI assistant: explicit contracts, stable enums, deterministic outputs, auditable state transitions, bounded failure modes, and reproducible scoring. Same inputs always produce the same output. Watchlists isolate state per name. Schema versions are pinned per record. Every signal carries evidence and confidence. Every classification carries provenance.
What it detects
- Pricing & monetisation — extracts plan names, prices, billing periods, feature lists; classifies billing model (
free-only / freemium / flat-tier / seat-based / usage-based / enterprise-only / custom-quote); detects PLG vs sales-led vs hybrid GTM motion from CTA copy + pricing structure. - Hiring intelligence — open positions, classified hiring velocity (
none / minimal / moderate / aggressive / unknown), AI / ML / sales-team hiring detection, per-role categorisation (engineering / sales / customerSuccess / marketing / design / product / data / operations / people / finance / legal / executive) withengineeringToSalesRatio. Reads ATS-hosted careers via Greenhouse / Lever / Ashby / SmartRecruiters public APIs; detects and tags Workday / Phenom / iCIMS / Jobvite / Eightfold tenants asatsHostedUnsupported(their authoritative counts live behind tenant-scoped auth — surfaced ashiringVelocity: 'unknown'rather than misleading zeros). For JS-rendered careers SPAs (jobs.* subdomains, Workday/Phenom shells, React/Next/Gatsby careers pages) extraction escalates to a headless-browser render so the settled DOM, not the empty SPA shell, is what gets read. - Enterprise readiness — deterministic scoring of SSO, SCIM, SOC 2, HIPAA, ISO 27001, GDPR, audit logs, RBAC, admin APIs, uptime SLA, security / trust / compliance pages into one tier (
none / developing / serious / enterprise-grade). - AI adoption — detects integrated AI vendors (OpenAI, Anthropic, Cohere, Mistral, Pinecone, Weaviate, LangChain, LlamaIndex, etc.), AI-product keywords, AI-engineering hiring; classifies maturity (
none / experimenting / integrated / advanced). - Tech stack — fingerprints 30+ technologies across analytics, marketing, support, payments, error tracking, frameworks, CMS, and infrastructure.
- Team & social footprint — team size estimation, company description, links to Twitter / LinkedIn / Facebook / Instagram / YouTube / GitHub / TikTok.
- Change tracking — when run with a
watchlistName, every record carrieschangeFlags(PRICING_CHANGED,HIRING_INCREASED,TECH_STACK_ADDED,THREAT_LEVEL_RAISED, etc.) andtemporalSignals(trend, momentum, volatility, re-escalation) against the prior run.
Signal taxonomy
Every competitor record is scored against four signal classes. Each class is composable into the top-level threatScore and weighted into the threatLevel enum.
| Class | What it captures | Stable enums emitted |
|---|---|---|
| Hiring intelligence | Open positions, per-role category counts, eng-to-sales ratio, hiring velocity, ATS-hosted board detection (Greenhouse / Lever / Ashby / SmartRecruiters / Workday / Phenom / iCIMS / Jobvite / Eightfold), AI / ML / sales-team hiring | careers.hiringVelocity: none / minimal / moderate / aggressive / unknown; careers.atsProvider: greenhouse / lever / ashby / smartrecruiters / workday / phenom / icims / jobvite / eightfold |
| Pricing transparency | Public plan structure, plan count, free-tier / contact-sales presence, billing period | derived competitiveSignals[] codes: PUBLIC_PRICING, OPAQUE_PRICING |
| Pricing classification | Billing model + complexity + price ceiling/floor | pricingClassification.billingModel: free-only / freemium / flat-tier / seat-based / usage-based / enterprise-only / custom-quote / unknown |
| Feature matrix | Inverted plans[].features[] — which plans include each feature, which features are universal, which are enterprise-only | featureMatrix.features[].universal / enterpriseOnly booleans |
| Enterprise readiness | SSO, SCIM, SOC 2, HIPAA, ISO 27001, GDPR, audit logs, RBAC, admin API, SLA, security/trust/compliance pages | enterpriseSignals.tier: none / developing / serious / enterprise-grade |
| AI adoption | Integrated LLM vendors, AI keywords, AI-engineering hiring | aiSignals.maturity: none / experimenting / integrated / advanced |
| GTM motion | Self-serve vs sales-led CTAs, sales-team hiring, pricing structure | gtmSignals.motion: plg / sales-led / hybrid / unknown |
| Tech-stack maturity | 30+ technologies across analytics, support, payments, frameworks, infrastructure | derived signal codes: MATURE_TECH_STACK, GROWTH_TECH_STACK, DEEP_ANALYTICS, PERFORMANCE_TOOLING, SUPPORT_INVESTMENT |
| Team & social footprint | Team-size estimate, company description, social platforms | derived signal codes: LARGE_TEAM, GROWING_TEAM, SOCIAL_FOOTPRINT_BROAD, DEV_BRAND_PRESENCE |
Stable-enum tokens are documented and additive across minor versions — automation pipelines can branch on them without parsing prose.
Scoring framework
Per competitor:
threatScore(0–100) — sum of weighted signal contributions, capped at 100. Weights live insrc/decision-engine.tsso reviewers can audit them.threatLevelenum —critical(≥60),alert(≥40),monitor(≥20),watch(<20). This is the routing primitive downstream automation should branch on.confidence— block withscore(0–1),level(high / medium / low / very-low), and acomponents[]breakdown (pages-scraped,signal-coverage,data-completeness,rendering-clarity).scoringTrace[]— per-rule{ rule, weight, contribution }so the score is reproducible.summary,whyThisMatters,nextBestAction— plain-English fields paste-ready into Slack, exec emails, or AI-agent prompts. No LLM rewriting required.
Run-level summary record carries oneLine (paste-ready takeaway), decisionCards[] (top-threat / re-escalation / pricing-change / hiring-spike), trustSummary (level + reason for non-technical readers), portfolio rollup, marketBenchmarks (cross-competitor aggregation), and marketNarrative[] (deterministic plain-English observations like "AI capability adoption is widespread — 60% of competitors are integrated or advanced."). Benchmarks and narrative fire only when sample size ≥ 2.
Why you can trust this output
The actor is engineered for auditability. Every output field is reproducible:
- No LLM calls anywhere. All scoring, classification, signal detection, archetype assignment, market-position inference, narrative generation, and trajectory analysis are deterministic threshold logic over extracted data.
- Every signal carries an evidence object. Each
competitiveSignals[].evidenceshows{ type, value, source, confidence }— what fired, what page it came from, how confidently the match held. - Scoring trace is exposed.
scoringTrace[]lists every rule that contributed tothreatScore, with weights and contributions. Reviewers can recompute the score by hand from the trace. - Signal weights live in source.
src/decision-engine.ts:SIGNAL_WEIGHTSandsrc/signals.ts:ENTERPRISE_WEIGHTSare plain constants — no hidden tuning, no opaque models. - Confidence is decomposed. Top-level
confidencecarries 4 components (pages-scraped, signal-coverage, data-completeness, rendering-clarity).perClassConfidencefurther splits enterprise / AI / GTM / pricing so you can trust one block independently of the others. - Failure surfaces are first-class. Partial scrapes get
scrapeError+failureType. Bot-protection gets a named vendor. JS-rendering gates producefailureType: 'js-required'instead of empty fields. - No silent drops. Records that hit failure modes still appear in the dataset with a structured failure record (sorted last, ranked at the bottom).
- Cross-run state is named-KV scoped. Watchlist history lives in
saas-competitive-intel-history-<watchlistName>, isolated from the default KV store and other watchlists. Same input + same prior state = same output. - Stable enums are additive across minor versions.
threatLevel,archetype,gtmSignals.motion,pricingClassification.billingModel,failureType,changeFlags,competitiveSignals[].code,recordType, etc. — values never get renamed or repurposed within a major version. New values may be added.
Schema contract
schemaVersionis on every record (currently2.0.0).- Stable fields (additive-only across minor versions):
recordType,eventId,threatLevel,threatScore,archetype,gtmSignals.motion,pricingClassification.billingModel,enterpriseSignals.tier,aiSignals.maturity,failureType,changeFlags,competitiveSignals[].code,marketPosition.segment,marketPosition.estimatedAcvBand. - Stable enum vocabulary — values can be added in minor versions, never renamed or repurposed. Major-version bumps document any breaking changes in CHANGELOG.md.
- Decision-mode-friendly fields for downstream automation:
threatLevel,threatReasons[],decision-equivalent enum (actionRequiredderivable fromthreatLevel+changeFlags),failureType,changeCategories.*.
Intelligence layer
Beyond raw signals, every record carries derived intelligence — pure synthesis from data already extracted, computed deterministically, no LLM calls:
archetype(stable enum) —developer-first-plg / plg-saas / mid-market-sales-led / enterprise-sales-led / hybrid-plg-and-enterprise / ai-native / community-led / unclassifiedmarketPosition—segment(smb / mid-market / enterprise / consumer-developer / unknown),estimatedAcvBand(sub-1k / 1k-5k / 5k-25k / 25k-100k / 100k-plus / unknown),buyerPersonas[], plus areasoningstring showing the inputs.competitiveEvents[]— inferred business events from signal + change combination:upmarket-expansion,ai-product-launch-likely,pricing-restructure,enterprise-tier-introduced,sales-team-buildout,aggressive-growth-phase,pricing-transparency-loss. Each event carriesseverity,confidence, andevidence[].trajectory— movement direction (accelerating / rising / stable / unchanged / declining / new / unknown) acrossthreatScore / hiring / enterpriseMotion / aiAdoption. Requires at least one prior watchlist run.emergingCompetitor—detected+confidence+reasons[]. Fires on the small-team + aggressive-hiring + AI-positioning + developer-PLG combination that often precedes a breakout product launch.peerBenchmarks— within-cohort percentiles forthreatScore / enterpriseTier / aiMaturity / techStackSize / hiringVolume. Emits only when cohort size ≥ 3.gtmNumericScores—plgScore+salesLedScore(each 0-100, independent axes) alongside thegtmSignals.motionenum. Useful when a competitor sits midway between PLG and sales-led.perClassConfidence— per-signal-class confidence (enterprise / ai / gtm / pricing, each 0-1). Different from the globalconfidence— lets you trust one block while distrusting another.threatReasons[]— flat array of stable signal codes (AGGRESSIVE_HIRING / MATURE_TECH_STACK / DEEP_ANALYTICS / …). Automation-friendly subset ofcompetitiveSignals[].codefor downstream routing.changeCategories(watchlist mode only) — boolean rollup ofchangeFlagsintopricing / hiring / enterprise / ai / tech / team / threatLevelfor one-glance routing.
Operational layer (v3)
The intelligence layer tells you what a competitor looks like. The operational layer tells you what's changing, why it matters, how urgent it is, and what to do next — without an analyst, without an LLM.
strategicDrift— detects archetype change between watchlist runs. Kinds:plg-to-sales-led / plg-to-hybrid / smb-to-enterprise / no-ai-to-ai-integrated / no-ai-to-ai-native / consumer-to-business / archetype-change / none. Carriesfrom,to,confidence, andreasoning[]. Requires at least one prior watchlist snapshot — first-run records carrydetected: false.pressureZones[]— where the competitor is investing:enterprise-readiness / ai-products / developer-platform / pricing-aggression / sales-buildout / product-velocity / international-expansion. Stable enum array; downstream automation routes by zone.counterMoves[]— deterministic recommended responses keyed off detectedcompetitiveEvents+strategicDrift. Each:trigger,action,owner(product / sales / marketing / engineering / exec),urgency. Static playbook lookup, no LLM.threatVelocity—direction(accelerating / rising / stable / declining / unknown) +rate(0-1) +runsObserved. Numeric speed of change inthreatScore.surpriseSignals[]— within-cohort deviation:unusually-high-threat / cohort-pricing-outlier-low / sole-ai-leader / sole-enterprise-grade / aggressive-vs-cohort-stability. Requires cohort ≥ 3.executiveSignals[]— top-5 compressed observations per record, plain-English, paste-ready into Slack / exec emails.competitiveDna[]— persistent multi-tag identity fingerprint:developer-first / enterprise-ready / ai-native / plg-saas / sales-led / open-source-presence / fast-moving / mature / community-led / pricing-transparent / pricing-opaque. Stable enum.confidenceConflicts[]— flags where a high-confidence claim is undersupported by evidence (enterpriseSignals.tier=enterprise-gradewithperClassConfidence.enterprise=0.3, etc.). Distinct from low confidence — these are internal inconsistencies the actor flags against itself.provenanceGraph— maps each derived classification back to the source evidence that produced it.archetype:ai-native → ['gtm=plg', 'ai=advanced', 'github presence', ...]. Auditors can trace any conclusion to its inputs.actionabilityScore— 0-100 + components (evidenceStrength / magnitude / freshness / strategicImportance) + reasoning. Distinct axis fromthreatScore: threat is "how strong is the signal," actionability is "how worth your time is acting NOW."
Run-level narrativeCollisions[] (summary record) detects when ≥2 competitors converge on the same positioning theme — AI-native positioning, Enterprise-grade compliance race, Developer-first PLG GTM — with the cohort members named.
Decision-infrastructure layer (v4)
The v3 operational layer answers "what's happening?". The v4 decision-infrastructure layer answers the harder question: "what deserves a human's time RIGHT NOW vs what should be silently filtered?" — without an analyst, without an LLM.
Persona-shaped routing
Set persona to one of sales-enablement / executive-monitoring / product-strategy / vc-monitoring / revops-routing / generic (default generic). Each persona changes:
- which event types auto-escalate to immediate-review
- which event types get suppressed (downweighted in materiality)
- materiality weight pack (drift / events / threat / cohortSurprise)
- audience tags routed to (sales / marketing / exec / product / engineering / revops / investor)
- the actionability threshold below which records get
ignoreRecommendation: true
Different from mode (which controls scan depth). persona controls attention shaping on the resulting data.
Per-record fields
escalationRecommendation—level(immediate-review / weekly-review / monthly-review / archive / ignore) +sla(24h / 48h / 7d / 30d / no-action) +reason+audience[]+ignoreRecommendation. The single field downstream automation should branch on.competitiveMateriality— 0-100 + per-component breakdown (drift / events / threat / cohortSurprise) + reasoning. Different fromthreatScore— threat is "how strong is the signal", materiality is "how much does this matter to ME, given my persona's weight pack".alertQuality—novelty+urgency+noiseRisk(each 0-1). For alert-fatigue-resistant downstream pipelines.suppressedSignals[]— signals that fired but the actor flags as likely noise: within-volatility hiring change, mature-stack tech churn, social-link discovery artefact. Each entry:signal+reason. Surfaces what was filtered AND why.riskHorizon—window(immediate / 30-90d / 90-180d / 180d+ / unknown) + confidence + reasoning. Pricing changes hit deal economics now; AI-product launches hit narrative within 1-3 months; upmarket expansion builds over 3-6 months.detectionStability— per-signal-classstable / unstable / unknownrating. Unstable inferences should NOT auto-trigger destructive automation.operationalConfidence—safeToAutomateboolean + numeric confidence + blockers[]. Distinct from per-class confidence — this is the production-automation gate.decisionBundles[]— events grouped under unifying themes (Enterprise expansion,AI capability shift,Pricing strategy shift,Growth phase). Each:theme+priority+events[]+recommendedAction. Reduces analyst load from per-event to per-theme review.focusShift— what the competitor is emphasizing RIGHT NOW (vs strategic identity drift). Watchlist diff overpressureZones—from / to / reasoning.surpriseIndex(0-100) — single scalar combining cohort surprises + drift + velocity. Quick-filter primitive.
Run-level (summary record)
changeDensity—totalChanges+competitorsWithChanges+topChangedDomains[]. Cohort activity pulse.immediateReviewQueue— pre-filtered list of competitors whoseescalationRecommendation.level === 'immediate-review'. Drop straight into a Slack alert / pipeline review without filtering.
How the layers compose
| Layer | Per-record question | Field |
|---|---|---|
| Extraction | What does the site say? | pricing / careers / team / techStack / homepage |
| Intelligence | What kind of competitor is this? | archetype / marketPosition / threatLevel / threatScore / competitiveSignals |
| Operational (v3) | What's happening + why does it matter? | competitiveEvents / strategicDrift / pressureZones / counterMoves / actionabilityScore |
| Decision-infrastructure (v4) | Should a human look at this RIGHT NOW? | escalationRecommendation / competitiveMateriality / alertQuality / suppressedSignals / decisionBundles |
| Temporal | What changed since last run? | changeFlags / temporalSignals / focusShift / threatVelocity |
Evidence objects
Every competitiveSignals[].evidence is now a structured object, not a plain string:
{"code": "AGGRESSIVE_HIRING","weight": 25,"evidence": {"type": "count-threshold","value": "42 open positions — aggressive expansion phase.","source": "careers-page","confidence": 0.9}}
This means every signal is auditable end-to-end: what fired, what page it came from, how confidently the detector matched, and the human-readable line that explains it. No black-box scoring, no opaque heuristics.
Subpage discovery
Subpages (pricing / careers / about) are discovered in two stages:
- Anchor-text + URL-pattern matching on the homepage HTML (~80% hit rate on SaaS sites).
sitemap.xmlfallback when anchor matching missed a requested page — fetches/sitemap.xml,/sitemap_index.xml,/sitemap-index.xmlwith an 8s timeout, parses<loc>entries, and filters by URL pattern. Sitemap-index files are followed one level deep (top 3 child sitemaps).
Each record carries discoverySources: { homepage: [...], sitemap: [...] } so you can see which path found which page.
Execution modes
Pick a mode by user job, not by feature toggle. Explicit field overrides (checkPricing, checkCareers, etc.) always win over the preset.
| Mode | Job | What it scans | Auto-enables watchlist |
|---|---|---|---|
quick | One-off snapshot | Homepage + tech stack only (~10s/competitor) | no |
standard (default) | Default sweep | Homepage + pricing + careers | no |
deep | Full intelligence dive | Homepage + pricing + careers + team | no |
monitoring | Weekly competitor tracking | Homepage + pricing + careers, watchlist on | yes |
raw | Power-user — no opinionated routing | All scans, no preset overrides | no |
Output profile
Filter the output shape per record:
minimal— only the routing primitives (threatLevel,threatScore,summary,changeFlags, identifiers). Fastest for if/else automation.standard(default) — full record including signal blocks and reasoning fields.full— alias forstandard.llm— minimal core +whyThisMatters/competitiveSignals/temporalSignals/pipelineState/actorGraph/improvementSuggestions/coverage/dataGaps. Designed for AI-agent consumers.
Typical weekly workflow
- Schedule the actor weekly with
mode: "monitoring", awatchlistName, your competitor list, and (optionally)includeReviews: "g2"+reviewProducts. - Run 1 captures a baseline (
baselineRun: true) — no change detection yet, by design. - Every later run emits what changed (
changeFlags/fieldDiffs), the trajectory (competitorMemory.history,cohortShifts), and where to win (attackTargets). - Route
escalationRecommendation.level == "immediate-review"into Slack/PagerDuty, feedattackTargetsto sales, and let the rest accumulate as memory.

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. |
useCasePreset | Select | No | — | One-pick setup that resolves mode + persona + outputProfile: exec_weekly_digest, sales_enablement_monitoring, product_strategy_watchlist, vc_market_scan, revops_alert_router, raw_data_export. Any explicit mode/persona/outputProfile you set still wins. |
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. |
checkReleaseNotes | Boolean | No | false | Scan the competitor's changelog / release-notes page (probes /changelog, /releases, /release-notes, /updates, /whats-new) and emit productVelocity (releases in the last 30 days + a band) + capabilityThemes. Product movement is what PMs and founders track. |
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). |
includeReviews | Select | No | off | Add a customer-voice layer from public G2 reviews: off (website signals only, default) or g2. When g2, each competitor's record gains a reviewVoice block + review signals, and the website signals are cross-signalled against the reviews. |
reviewProducts | String[] | No | — | G2 product slugs or full g2.com/products/<slug> URLs to pull reviews for (e.g. slack, notion). Best-effort paired to competitorUrls by brand; explicit slugs are authoritative. Only used when includeReviews is not off. |
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}
Weekly monitoring with persona-shaped escalation (the operational shape):
{"competitorUrls": ["https://notion.so", "https://slack.com", "https://linear.app", "https://airtable.com", "https://clickup.com"],"mode": "monitoring","watchlistName": "productivity-saas-weekly","persona": "executive-monitoring","outputProfile": "minimal"}
This is the recommended shape for scheduled runs. monitoring mode auto-enables watchlist + change tracking. persona: "executive-monitoring" collapses output to drift / AI launches / upmarket expansion only — exec dashboards stay quiet on routine churn. outputProfile: "minimal" keeps Slack alerts compact.
Tech stack audit only — homepage scan:
{"competitorUrls": ["https://vercel.com", "https://netlify.com", "https://render.com"],"mode": "quick","maxPagesPerSite": 1}
Website signals + customer-voice cross-signals (the review layer):
{"competitorUrls": ["https://slack.com", "https://notion.so"],"includeReviews": "g2","reviewProducts": ["slack", "notion"],"watchlistName": "collab-suite-weekly","persona": "sales-enablement"}
This pulls public G2 reviews for the listed products and folds voice-of-customer signals into each record. When a competitor's website shows an upmarket / pricing move and its reviews show a satisfaction drop or support gap, the actor emits a switching_window cross-signal routed to the sales-enablement persona — the live displacement opening neither a website scraper nor a raw review scraper produces alone.
Input Tips
- Even without enabling pricing/careers/team, the homepage scan extracts company name, meta description, social media links, full tech stack, enterprise signals, AI signals, and GTM motion.
- 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. - For weekly monitoring at scale, set
mode: "monitoring"+watchlistName: "<list-name>". Each watchlist has its own isolated history. - Pair
personawithoutputProfile: "minimal"to drop Slack-routable records straight into automation pipelines without per-team filtering.
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"],"enterpriseSignals": {"score": 67,"tier": "enterprise-grade","detected": ["SSO / SAML", "SCIM provisioning", "SOC 2", "audit logs", "role-based access control", "enterprise plan / contact-sales tier"],"capabilities": ["sso", "scim", "soc2", "audit-logs", "rbac", "enterprise-page"]},"aiSignals": {"detected": true,"maturity": "integrated","vendors": ["OpenAI"],"keywords": ["ai", "assistant"],"aiHiringDetected": true},"gtmSignals": {"motion": "hybrid","confidence": 0.7,"plgIndicators": ["free signup CTA", "self-serve language"],"salesLedIndicators": ["contact-sales / demo-request CTA", "enterprise sales roles"],"reasoning": "Both PLG (2 signals) and sales-led (2 signals) indicators present."},"threatLevel": "alert","threatScore": 47,"summary": "Notion — ALERT. 42 open positions — aggressive expansion phase; 8 pricing plans published — transparent pricing strategy.","whyThisMatters": "Several growth signals detected — worth a closer review or weekly tracking.","nextBestAction": "Add to weekly watchlist; pair with company-deep-research for funding/SEC context.","metadata": {"pagesScraped": 4,"scrapeDurationMs": 8432}}
Operational output (the high-value shape)
Beyond raw extraction, the actor returns deterministic operational decisions. This is the shape downstream automation should consume:
{"domain": "notion.so","threatLevel": "alert","threatScore": 47,"archetype": "hybrid-plg-and-enterprise","marketPosition": {"segment": "enterprise","estimatedAcvBand": "25k-100k"},"strategicDrift": {"detected": true,"kind": "plg-to-hybrid","from": "plg-saas","to": "hybrid-plg-and-enterprise","confidence": 0.8,"reasoning": ["Archetype shift: plg-saas → hybrid-plg-and-enterprise."]},"competitiveEvents": [{ "type": "enterprise-tier-introduced", "severity": "high", "confidence": 0.7 },{ "type": "sales-team-buildout", "severity": "medium", "confidence": 0.65 }],"pressureZones": ["enterprise-readiness", "sales-buildout"],"escalationRecommendation": {"level": "immediate-review","sla": "48h","reason": "Strategic drift detected (plg-to-hybrid, conf 0.8).","audience": ["exec", "product"],"ignoreRecommendation": false},"competitiveMateriality": {"score": 72,"reasoning": ["Strategic drift detected (plg-to-hybrid, conf 0.8).", "2 high/critical events."]},"alertQuality": { "novelty": 0.65, "urgency": 0.78, "noiseRisk": 0.12 },"operationalConfidence": { "safeToAutomate": true, "confidence": 0.81, "blockers": [] },"actionabilityScore": { "score": 78, "reasoning": "High actionability — strong evidence (0.82), magnitude 47, accelerating." }}
This is the shape that drops into Slack alerts, Zapier rules, n8n flows, Dify if/else nodes, and agent tool calls without an LLM rewriting layer. Branch on escalationRecommendation.level, operationalConfidence.safeToAutomate, archetype, strategicDrift.kind, or pressureZones[].
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 |
When includeReviews: "g2" and a G2 product pairs to the competitor, these additional fields appear:
| Field | Type | Description |
|---|---|---|
reviewVoice | Object / null | Customer-voice block: aggregateRating, reviewVelocity, sentiment (positive/negative split), topComplaints[] / topPraise[] (theme + share), segmentSplit (enterprise vs SMB mean rating), switchingSignalCount, painAcceleration (per-theme complaint growth in share-points vs the last run — which complaints are accelerating), and reviewConfidence (score + band + reason). Recent-window only; status reports ok / blocked / not-found / empty / error. |
reviewSignals | Array | Typed review-voice signals, each { code, severity, evidence }. Codes: review_sentiment_shift, complaint_theme_surge, support_gap, feature_gap, satisfaction_drop, switching_signal, segment_divergence, review_velocity_shift. Trajectory signals require a prior watchlist run. |
decisionBundles[] (cross-signals) | Array | Review × website cross-signals appear here with kind: "cross-signal": Switching window (sales-enablement), Positioning gap (product-strategy), Weakening competitor (executive-monitoring), each with a routed audience and recommendedAction. |
reviewIntelligence | Object / null | On the summary record: competitorsWithReviews, avgAggregateRating, reviewSignalCounts, and the switchingWindows / positioningGaps / weakeningCompetitors competitor lists. |
Decision-router fields (always emitted; deterministic projections of the signals above):
| Field | Type | Description |
|---|---|---|
fieldDiffs | Object | Watchlist mode — per-field { previous, current } for every changed field (e.g. pricing.planCount, careers.totalOpenings, aiSignals.maturity). The first-class change contract for Slack / Zapier / Make / n8n routing. |
battlecardDelta | Object | Deterministic battlecard update (no LLM): changed, sectionsToUpdate[] (pricing / enterprise-readiness / product-capabilities / objection-handling / company-momentum), salesTalkTrack[], crmTags[]. Competes with Crayon/Klue workflows without becoming a dashboard. |
operationalConfidence | Object | safeToAutomate + numeric confidence + blockers[], plus strongEvidence[] / weakEvidence[] (which signal classes are well- vs thinly-supported) and recommendedHumanReview. The automation-trust ledger. |
watchlistHealth | Object / null | Summary record — meta-monitoring: coverage, staleCompetitors[], blockedDomains[], needsSlugMapping[] (review mode), and recommendations[] to cut failed runs. |
baselineRun / monitoringReady / nextRunWillDetect | Boolean / Boolean / String[] | Summary record — honest first-run expectation management: a baseline run captures state; the next run starts detecting change. |
competitorMemory | Object / null | Watchlist mode — consolidated history: firstSeen, daysTracked, runsSeen, dated majorEvents[] (archetype-shift / enterprise-tier-introduced / ai-maturity-jump / hiring-spike), strategicJourney[] (the archetype sequence over time), milestones[] (named firsts — first_enterprise_motion / first_ai_integrated / first_sales_led_transition / first_aggressive_hiring), and history{} — per-dimension time series (pricing / hiring / archetype / enterprise / ai). The competitive historical database: you provide history, everyone else provides snapshots. |
confidenceTrend / coverageTrend | String | Watchlist mode — improving / declining / stable for this competitor's confidence and scrape coverage vs the last run. Lets you tell "the competitor changed" apart from "our visibility dropped." |
cohortShifts | Array | Summary record — longitudinal observation of the whole cohort vs the last run (enterprise_adoption_rising, pricing_opacity_increasing, …). Observation, not prediction. |
mostSimilarCompetitors | Array | Top-3 cohort peers by deterministic similarity (GTM / billing / archetype / AI maturity / enterprise tier / hiring / tech-stack overlap). Answers "show me competitors behaving like Notion" with no LLM. |
threatSurface | Object | Decomposition of threatScore by dimension — pricing / product / enterprise / sales / brand — so "threat from what?" is answerable. Contributions sum to threatScore. |
evidenceTrail | Array | Per signal class: field, sourceUrl, capturedAt, matchedText, pageHash (tamper-evidence hash of the captured HTML). The "how do I know this is true?" audit surface. |
productVelocity / capabilityThemes / releaseNotesUrl | Object / String[] / String | Changelog mode (checkReleaseNotes) — releases shipped in the last 30 days + a velocity band, and the themes those releases touch (ai / enterprise / automation / …). Tracks actual product movement, not just pricing and hiring. |
opportunityScore | Object | The "where can WE win?" axis, distinct from threatScore: score 0-100 + level + reasons[] + drivers[] (per-driver code + weight + evidence — provenance for why the opening exists). Weights customer dissatisfaction, switching windows, weakening, and underserved segments. Deterministic, not a forecast. |
genome | Object | Structured 5-axis competitor fingerprint: growthStyle / gtm / productVelocity / innovation / pricing. Stable for longitudinal genome-shift tracking. |
attackTargets | Array | Summary record — ranked sales worklist: each competitor with a live opening, its reason (pricing move + dissatisfaction / support gap), target segment, and a playbook enum (enterprise_displacement / support_displacement / pricing_displacement / mid_market_displacement). The thing a sales team acts on, not a threat score. |
Use Cases
- Product managers — track how competitors change pricing tiers and feature bundles over time; spot strategic drift early via watchlist mode.
- Venture capital analysts — gauge growth signals by monitoring hiring velocity, team size, and AI adoption across portfolio companies and competitors. Persona
vc-monitoringfilters to growth + AI + upmarket signals only. - Marketing teams — understand which analytics, CRM, marketing, and AI tools competitors use to inform tooling decisions and competitive positioning.
- Sales / sales-enablement teams — prepare for competitive deals with structured pricing + feature-matrix + GTM-motion intelligence. Persona
sales-enablementprioritises pricing changes and enterprise-tier additions. - RevOps teams — route competitive alerts into Slack / Zapier / Make automation pipelines using
persona: "revops-routing"+outputProfile: "minimal". Branch onescalationRecommendation.levelandchangeFlags. - Executive monitoring —
persona: "executive-monitoring"filters output to only material strategic drift, AI-product launches, and upmarket expansion. Quiet on routine churn. - Startup founders — benchmark pricing against the market with
marketBenchmarksandpeerBenchmarks(within-cohort percentiles); track when competitors expand engineering or sales teams. - Competitive-intelligence teams — replace manual analyst workflows with deterministic competitive intelligence; pair with Slack alerts for
immediate-reviewqueue. - AI-agent tool calls —
outputProfile: "llm"returns minimal core + reasoning fields. Schema-stable enums for branching without prose-parsing.
Automation patterns
This actor is built automation-native. Output is schema-stable, enum-rich, and decision-ready — drop into:
- Slack alerts —
summary.immediateReviewQueue[]is a pre-filtered list of competitors needing review.escalationRecommendation.audience[]names the team to route to. - Zapier / Make scenarios — branch on
threatLevel,escalationRecommendation.level,operationalConfidence.safeToAutomate,changeFlags,archetype,strategicDrift.kind. No prose parsing. - n8n flows — multi-step routing on
decisionBundles[].theme+pressureZones[]. Each bundle carries a deterministicrecommendedAction. - Dify if/else nodes — branch on stable enums (
threatLevel,recordType,failureType,changeFlags). See the dedicated Dify section below. - Agent tool calls (OpenAI / Anthropic / LangChain / LlamaIndex) —
outputProfile: "llm"returns the reasoning fields agents need without bloating the context. - PagerDuty / OpsGenie incident routing — branch on
escalationRecommendation.sla(24h / 48h / 7d / 30d / no-action). - Jira / Linear / GitHub Issues backlog —
decisionBundles[]map cleanly to ticket themes;counterMoves[].ownernames the team and urgency. - Webhooks —
Actor.addWebhookintegration; receive each completed run at any HTTP endpoint. - Google Sheets / Airtable — flat
outputProfile: "minimal"rows drop straight into spreadsheets. - CRM (HubSpot / Salesforce / Pipedrive) — pair with
ryanclinton/hubspot-lead-pusherorryanclinton/salesforce-lead-pusherto write competitive context onto account records.
The actor is automation-ready out of the box. Schema-stable enums, deterministic outputs, and the provenance graph mean every routing rule you write today still works after the actor's next update.
How to Use the API
Python
import requestsimport timerun = 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"):breaktime.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
You supply competitor URLs and choose which modules to run. For each competitor the actor reads the public homepage, automatically locates the relevant subpages, and assembles a structured profile — company identity, social presence, tech stack, pricing model, hiring posture, and team size. That profile then feeds the full intelligence layer — classification, deterministic threat and opportunity scoring, change detection against prior runs, signal suppression, and persona-shaped routing — and the actor emits one decision-shaped row per competitor.
Pricing, careers, and team pages are located automatically from the homepage, and only same-domain pages are read. Pricing and team data come from each competitor's public HTML; a careers page escalates to a headless browser only when its listings are rendered client-side.
Tech Stack Detection
The actor fingerprints 30+ technologies a competitor runs, across these categories:
| 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 reads server-rendered HTML on the fast common path, and escalates a careers page to a headless browser only when its job listings are JavaScript-rendered — fast and cheap on the common path, accurate on SPA careers pages.
| 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
- Pricing/team data is read from server-rendered HTML — homepage, pricing, and team pages are read without a browser. If a competitor's pricing page relies heavily on client-side JavaScript, pricing plans may not be fully extracted. Most SaaS companies serve pricing content in initial HTML for SEO. (Careers pages are the exception: they escalate to a headless browser when the listings are JS-rendered.)
- Pricing extraction is heuristic — custom pricing structures, enterprise-only "contact us" pricing, or heavily abstracted layouts may not be fully detected.
- Job-listing quality varies — extraction depends on a consistent page structure. Some career pages embed their listings from third-party hosts (e.g. Greenhouse, Lever) in a way that isn't readable from the page itself.
- Team size is estimated — inferred from the team/about page and may be approximate. Companies that don't display team info on their website 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. - Review layer reads the recent G2 window —
includeReviews: "g2"reads the public G2 reviews feed, which carries the latest reviews only (no lifetime aggregate). Satisfaction trajectory and the trajectory signals build up across runs via the watchlist store, so on the first run those signals stay quiet. Supply G2 product slugs inreviewProducts; the actor does not auto-discover them. - Review fetches use a residential proxy — G2 restricts automated access from shared IPs, so the review layer routes through a residential proxy and degrades gracefully (a typed
reviewVoice.statusofblocked/empty, never a failed run) when a product can't be read.
Responsible Use
- Only scrape publicly available pages — this actor accesses the same pages any visitor would see in a browser.
- Respect robots.txt — the actor 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 reads the competitor's homepage and automatically locates the pricing, careers, and team pages from there. Only same-domain pages are read.
Can it extract pricing from JavaScript-rendered pages? Pricing and team data are read from server-rendered HTML, which most SaaS companies serve for SEO. If a competitor's pricing is delivered entirely client-side, plans may not be fully extracted. Careers pages are the exception — when the listings are JavaScript-rendered, the actor escalates that page to a headless browser and re-reads it.
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.
What does the customer-review layer add?
Set includeReviews: "g2" and list G2 product slugs in reviewProducts. Each paired competitor gains a reviewVoice block (sentiment, complaint/praise themes, enterprise-vs-SMB split, satisfaction trajectory, switching-language count) plus typed review signals. The differentiator is the cross-signals: when a competitor's website shows a pricing or upmarket move and its reviews show a satisfaction drop or support gap, the actor emits a switching_window — a live sales opening. The review engine is deterministic (no LLM), reads only public reviews, and never builds a reviewer-identity record.
Use in Dify
Drop this actor into Dify workflows via the Apify plugin's Run Actor node. Each competitor returns scored, classified, and recommended as structured JSON — critical / alert / monitor / watch plus the changeFlag enums (PRICING_CHANGED, HIRING_INCREASED, TECH_STACK_ADDED, THREAT_LEVEL_RAISED) your downstream if/else node branches on. Generic web scrapers pointed at the same competitor sites return raw HTML; this returns decisions.
- Actor ID:
ryanclinton/saas-competitive-intel - Sample input (weekly competitor monitoring with watchlist diff):
{"competitorUrls": ["https://notion.so", "https://slack.com", "https://linear.app"],"mode": "monitoring","watchlistName": "productivity-saas-weekly"}
Dify branching example
A Dify if/else node can route per competitor on the threatLevel enum:
| Branch condition | Action |
|---|---|
threatLevel == "critical" | Notify product team in Slack with summary + whyThisMatters |
threatLevel == "alert" | Add to weekly review queue |
changeFlags contains "PRICING_CHANGED" | Diff fieldDiffs.pricing.planCount and post to #pricing channel |
changeFlags contains "HIRING_INCREASED" | Trigger company-deep-research for funding/SEC context |
temporalSignals.reEscalated == true | Auto-page on-call competitive analyst |
decisionBundles contains a kind == "cross-signal" with theme == "Switching window" | Route the competitor's dissatisfied accounts to the sales team |
decisionBundles cross-signal theme == "Positioning gap" | Send to product strategy — exploitable messaging wedge |
failureType != null | Route to "needs human review" queue |
The nextBestAction, whyThisMatters, and summary fields are usable verbatim in Slack messages, exec emails, or LLM agent prompts — no LLM rewriting required. Decision-mode profile (outputProfile: "minimal") drops everything except the routing primitives, which is the fastest shape for if/else evaluation.
Opt-in modes that pair well with Dify:
mode: "monitoring"auto-enables watchlist + emitstemporalSignalsandchangeFlagsper record.outputProfile: "llm"keeps reasoning fields (whyThisMatters,improvementSuggestions) for AI-agent consumers.includeReviews: "g2"adds thereviewVoiceblock + review signals, and routes review × website cross-signals intodecisionBundles(persona-tagged) for one-field branching.
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.
What this actor does NOT do
Honest scope-fence — for needs in this column, use the sibling actor instead.
| Need | Use this instead |
|---|---|
| Deep multi-page tech stack fingerprinting (50+ technologies, version detection) | Website Tech Stack Detector |
| Wikipedia, SEC filings, GitHub org data, DNS/WHOIS, funding context | Company Deep Research |
| Decision-makers, verified emails, buying committees | Website Lead Intelligence |
| Real-time stock-ticker / market data / Bloomberg-grade financial feeds | not in scope — this is public-web SaaS intelligence, not financial data |
| Shipment-level commercial data (Panjiva / ImportGenius style) | not in scope |
| Brand-protection / typo-squatting detection | Brand Protection Monitor |
| Keyword / SERP-position tracking against competitors | SERP Rank Tracker |
| Domain registration / hosting / DNS history | WHOIS Domain Lookup |
| LLM-rewritten "competitive narrative" prose | not in scope — this is deterministic, no LLM calls |
JavaScript-rendered SPAs that gate pricing behind a __next shell | flagged in rendering.jsRenderingRequired + failureType: 'js-required'; out of scope for the HTML-extraction path |
| Product velocity / blog cadence / release-notes parsing | overlaps website-tech-stack-detector per the suite-cohesion contract — not in scope here |
| Cross-cohort market evolution (AI commoditisation, enterprise-feature saturation across many runs of different competitor sets) | requires multi-cohort fleet aggregation — out of scope for a per-run actor |
| Funding-likely / launch-likely event prediction | public-web signals can suggest a growth phase but cannot predict funding events — refusing to overpromise on this; use aggressive-growth-phase competitiveEvent + pressureZones as the deterministic stand-in |
| Per-field signal volatility (stability score over many runs) | meaningful only at watchlist run #3+; emit temporalSignals + threatVelocity for now and revisit when median user has 3+ runs of history |
| Signal entropy / noise-density scoring | requires ≥3 runs of history to be meaningful; emit alertQuality.noiseRisk instead for single/two-run cases |
| Competitive heatmaps as a separate field | use pressureZones[] + perClassConfidence + competitiveDna[] together — they cover the same analytical surface without duplicating data |
The actor stays lightweight — HTML-first extraction, with a headless browser invoked only for JS-rendered careers pages. The signal layer is composed deterministically from extracted data — no LLMs, no external APIs, no licensed feeds.
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 |
