
Apify Easy Competitive Intelligence
- 233 installs
- 239 repo stars
- Updated June 29, 2026
- apify/awesome-skills
Automate competitor site, pricing, and feature scraping with Apify to benchmark rivals early when scoping positioning, roadmap, and differentiation strategy.
About
Delivers an easy Apify-based competitive intelligence workflow that scrapes rival sites, pricing, and feature signals so teams can benchmark competitors early and sharpen positioning before committing to build and launch plans.
- Automated competitor scraping
- Pricing and feature benchmarking
- Rival page change tracking
- Positioning comparison snapshots
- Low-friction Apify workflows
Apify Easy Competitive Intelligence by the numbers
- 233 all-time installs (skills.sh)
- Ranked #553 of 2,715 Automation & Workflows skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/apify/awesome-skills --skill apify-easy-competitive-intelligenceAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 233 |
|---|---|
| repo stars | ★ 239 |
| Last updated | June 29, 2026 |
| Repository | apify/awesome-skills ↗ |
What it does
Automate competitor site, pricing, and feature scraping with Apify to benchmark rivals early when scoping positioning, roadmap, and differentiation strategy.
Files
Competitive Intelligence
Real-time competitive intelligence powered by live web data via Apify actors. Never answer competitive questions from training knowledge alone. Always gather live data first, then analyze.
Prerequisites
- Apify CLI v1.5.0+ (
npm install -g apify-cli), or Apify MCP server - Authenticated session (
apify loginorAPIFY_TOKENenv var)
CLI rules: Always pass --json, --user-agent apify-awesome-skills/apify-easy-competitive-intelligence, and 2>/dev/null.
- Run actor:
apify actors call "ACTOR_ID" -i 'INPUT' --json 2>/dev/null→ returns run metadata withdefaultDatasetId - Fetch results:
apify datasets get-items DATASET_ID --format json > /tmp/results.json 2>/dev/null— save locally, parse from file: - Quick extraction:
jq '.[] | "\(.field1) | \(.field2)"' /tmp/results.json - Aggregation:
python3 -c "import json; d=json.load(open('/tmp/results.json')); ..." - Tabular:
--format csv > /tmp/results.csv+python3withcsv.DictReader - Flags:
--limit N,--offset N,--format json|jsonl|csv|xlsx|xml - Output fields:
apify datasets info DATASET_ID --json | jq .fields - Fetch schema:
apify actors info "ACTOR_ID" --input --json 2>/dev/null
If CLI is unavailable and Apify MCP server is connected, use MCP call-actor / fetch-actor-details / get-actor-output directly.
Authentication
If a CLI command fails with an auth error, authenticate using one of these methods:
1. OAuth (interactive): apify login (opens browser) 2. Environment variable: export APIFY_TOKEN=your_token_here 3. From .env file: source .env (if the file contains APIFY_TOKEN=...)
Generate token: https://console.apify.com/settings/integrations
Actor Registry
Every actor call follows three steps: 1. Read — find the actor's section in reference/actor-schemas.md. Use the exact verified input and follow the "How to find" instructions for URLs/slugs. 2. Discover — verify platform URLs and slugs (e.g. via SERP) as described in the actor's schema section. Do not guess — wrong slugs silently return empty or wrong data. 3. Run — call the actor with verified input.
Alternatively, fetch the live schema: apify actors info "ACTOR_ID" --user-agent apify-awesome-skills/apify-easy-competitive-intelligence --input --json 2>/dev/null
| Data Need | Actor | Notes |
|---|---|---|
| Google SERP | apify/google-search-scraper | Supports country/language. SERP snippets contain ratings & review counts |
| Page scrape | apify/website-content-crawler | proxyConfiguration REQUIRED. Returns markdown |
| RAG browse | apify/rag-web-browser | Search + scrape in one call. Good fallback |
| LinkedIn company | dev_fusion/Linkedin-Company-Scraper | Output in KV store, not dataset |
| LinkedIn jobs | curious_coder/linkedin-jobs-scraper | Requires LinkedIn search URL, NOT keywords |
| Crunchbase | pratikdani/crunchbase-companies-scraper | Single company URL per call |
| Amazon product | junglee/Amazon-crawler | Product or category URLs |
| Amazon reviews | web_wanderer/amazon-reviews-extractor | May return 0 for some products |
| Walmart product | e-commerce/walmart-product-detail-scraper | May return empty |
| Google Maps reviews | compass/Google-Maps-Reviews-Scraper | Use full Google Maps place URL |
| G2 reviews | automation-lab/g2-scraper | NPS, ratings, switching data. $0.04/run |
| Capterra reviews | zen-studio/capterra-reviews-scraper | $1.99/1K |
| Gartner Peer Insights | — | No working actor. Use SERP snippet mining as fallback |
| Glassdoor | memo23/glassdoor-scraper-ppr | Reviews, salaries, culture, ratings |
harshmaur/reddit-scraper | Posts + full comment threads | |
| Google Play reviews | neatrat/google-play-store-reviews-scraper | App ID or Play Store URL |
| App Store | jdtpnjtp/apple-app-store-scraper | Requires SHADER proxy — may not be available on all plans |
| SimilarWeb | pro100chok/similarweb-scraper | Minimum 10 domains per call |
| Google News | data_xplorer/google-news-scraper-fast | No boolean operators in keywords |
| Wayback Machine | andok/wayback-machine-scraper | Full URL including path |
Core Workflow
Step 0: Understand the User (once, at start)
Clarify before gathering data:
- Role — Analyzed company, competitor, investor, consultant?
- Decision — Entering market, defending position, choosing vendor, building battlecard?
- Autonomy — Checkpoints after initial findings, or autopilot?
Steps 1–7
1. Clarify scope — Identify competitors. Select module(s). Default geography: US. 2. Read module reference — Load reference/modules/<module>.md for gathering + analysis instructions. 3. Gather live data — For each actor call, follow the three-step pattern: Read (actor-schemas.md) → Discover (SERP for URLs) → Run (call actor). Use PRIMARILY actors from the Actor Registry above. 4. Checkpoint (if not autopilot) — Present first findings, confirm direction. 5. Analyze — Select framework, lead with narrative, support with tables. 6. Verify — Run pre-delivery verification (reference/verification-checklist.md). Check: every claim has a source URL, every major finding has a confidence label, inferences are labeled as such. Remove any ungrounded claims. 7. Deliver — End with strategic recommendations framed for the user's role.
Framework Selection
| Situation | Framework |
|---|---|
| Profile one competitor | SWOT |
| Market dynamics & forces | Porter's Five Forces |
| Visual position comparison | Strategy Canvas (Blue Ocean) |
| Why customers switch | Jobs-to-be-Done |
| Find white space | Positioning Matrix (2x2) |
| Predict competitor reaction | Competitive Response Matrix |
Data Collection Rules
- Prefer structured actors over
website-content-crawlerwhen a dedicated actor exists. - Cost budget — 3-8 actor calls per snapshot. Track total, warn at 15+.
- Parallelize independent
call-actorcalls in a single response. - Failures — Report every failure explicitly (actor, input, error). Retry with corrected input if the cause is obvious. If retry fails, try
rag-web-browseras fallback. Never silently skip a failed data source. - Cite everything — Include source URLs for every data point.
- Async for long runs — Set
async: truefor actors >30s, poll withget-actor-run. - Protected platforms — Do NOT use
website-content-crawlerorrag-web-browserfor: g2.com, capterra.com, gartner.com, glassdoor.com, reddit.com, linkedin.com. Use dedicated actors.
Apify vs. WebSearch
Apify required: review sites (G2, Capterra, Gartner, Glassdoor), LinkedIn, Reddit, Amazon, Walmart, app stores, SimilarWeb, Crunchbase, Wayback Machine, Google Maps reviews, news (Google News actor).
WebSearch/WebFetch sufficient (Claude Code built-in tools): competitor discovery, general company info, blog posts, publicly accessible pricing pages.
Data Validation & Grounding
- Every factual claim needs a source URL. No link = not a fact.
- Confidence labels are mandatory. Mark every major finding: High (primary source), Medium (2+ third-party sources), Low (single third-party source). Format:
[Confidence | Source]. No report without labels. - Data tiers: Verified (primary source) → Reported (third-party, attribute) → Inferred (label as "this suggests...") → Ungrounded (omit).
- Numbers are dangerous — employee counts, revenue, funding change fast. Always cite source and date.
- Empty results ARE intelligence — 0 jobs = not hiring, 0 SimilarWeb = small site, 12 reviews = low adoption.
- Cross-reference — Single-source claims are unverified. Multi-source (G2 + Capterra + Reddit) = pattern.
Module Selection
| User says... | Module | Reference |
|---|---|---|
| "Analyze [competitor]", "Tell me about [company]" | Competitor Snapshot | reference/modules/competitor-snapshot.md |
| "Compare pricing", "How much does [X] cost" | Pricing Intelligence | reference/modules/pricing-intelligence.md |
| "Pricing details", "per-use-case costs", "tiers", "add-ons" | Pricing Deep Dive | reference/modules/pricing-deep-dive.md |
| "What do customers think", "Reviews", "Pain points" | Review Intelligence | reference/modules/review-intelligence.md |
| "What are they hiring for", "Job postings" | Hiring Signals | reference/modules/hiring-signals.md |
| "How do they rank", "Content strategy", "SEO" | Content & SEO | reference/modules/content-seo.md |
| "Who are the players", "Market landscape" | Market Landscape | reference/modules/market-landscape.md |
| "Full battlecard", "Deep analysis", "Board prep" | Multi-Module | reference/multi-module-playbook.md |
Actor Input & Output Schemas
Verified inputs and output fields from real test runs. Last tested: 2026-05-06.
---
apify/google-search-scraper
Input:
{ "queries": "\"Company Name\" keyword", "maxPagesPerQuery": 1 }Optional: countryCode ("us"), languageCode ("en"), maxPagesPerQuery (1-10).
Output keys: searchQuery, url, organicResults[], paidResults[], peopleAlsoAsk[], relatedQueries[], aiOverview, resultsTotal
Each organicResult: title, url, description, position, date, emphasizedKeywords[], siteLinks[], productInfo (may contain rating, numberOfReviews).
---
apify/website-content-crawler
Input:
{
"startUrls": [{"url": "https://example.com/pricing"}],
"maxCrawlPages": 1,
"maxCrawlDepth": 0,
"proxyConfiguration": {"useApifyProxy": true}
}⚠️ proxyConfiguration is required. Optional: crawlerType ("playwright:adaptive").
Output keys: url, markdown, text, html, metadata, crawl, screenshotUrl
metadata: title, description, author, keywords, languageCode, openGraph, jsonLd. crawl: loadedUrl, loadedTime, httpStatusCode, depth, contentType.
---
apify/rag-web-browser
Input:
{ "query": "Company Name pricing plans" }Output keys: query, markdown, metadata, searchResult, crawl
searchResult: title, description, url, resultType, rank. metadata: title, description, languageCode, url. markdown: full page content in markdown.
---
dev_fusion/Linkedin-Company-Scraper
⚠️ Before calling: LinkedIn slugs often differ from company names (e.g., Oxylabs → oxylabs-io, not oxylabs). Wrong slug silently returns 0 results. Discover via SERP first: "[company] site:linkedin.com/company"
Input:
{ "profileUrls": ["https://www.linkedin.com/company/VERIFIED-SLUG/"] }⚠️ Field is profileUrls, NOT urls.
Output: Data stored in key-value store, not dataset. Check KV store keys after run.
---
curious_coder/linkedin-jobs-scraper
⚠️ Before calling: Verify the company's exact name on LinkedIn via SERP: "[company] site:linkedin.com/jobs". Multi-word names need URL-encoding (Bright Data → Bright%20Data). Wrong name returns 0 or unrelated jobs silently.
Input:
{
"urls": ["https://www.linkedin.com/jobs/search/?keywords=VERIFIED-COMPANY-NAME&position=1&pageNum=0"],
"count": 10,
"scrapeCompany": true
}⚠️ count minimum is 10. Requires LinkedIn search URL, NOT keyword string.
Output keys: id, title, companyName, companyLinkedinUrl, companyLogo, companyWebsite, companyDescription, companyEmployeesCount, companySlogan, location, country, postedAt, postedAtTimestamp, expireAt, salary, salaryInsights, seniorityLevel, employmentType, jobFunction, industries, descriptionText, descriptionHtml, applicantsCount, applyUrl, applyMethod, workplaceTypes, workRemoteAllowed, standardizedTitle, link, inputUrl
---
pratikdani/crunchbase-companies-scraper
⚠️ Before calling: Verify the org slug via SERP: "[company] site:crunchbase.com/organization". Slug is typically lowercased with hyphens.
Input:
{ "url": "https://www.crunchbase.com/organization/VERIFIED-SLUG" }⚠️ Field is url (singular string), NOT urls (array).
Output: May return {"error": "Issue in running the url."} for wrong slugs. When successful: company profile data (funding, investors, financials).
---
junglee/Amazon-crawler
Input:
{ "categoryOrProductUrls": [{"url": "https://www.amazon.com/dp/ASIN"}] }⚠️ Field is categoryOrProductUrls, NOT productUrls.
How to find the URL: Any Amazon product page works. The canonical form is amazon.com/dp/ASIN where ASIN is the 10-character product identifier (e.g., B0D1XD1ZV3). ASIN is visible in the URL or in the product details section of any Amazon listing.
Output keys: title, url, asin, price, listPrice, brand, stars, reviewsCount, inStock, features[], attributes[], productOverview[], description, thumbnailImage, highResolutionImages[], bestsellerRanks, seller, delivery, aiReviewsSummary, productPageReviews[], monthlyPurchaseVolume, variantAsins[]
---
web_wanderer/amazon-reviews-extractor
Input:
{ "products": ["https://www.amazon.com/dp/ASIN"] }⚠️ Field is products, NOT productUrls. Use the same amazon.com/dp/ASIN format as Amazon-crawler.
May return 0 items for some products — try the full product URL with title slug if the short form fails.
---
e-commerce/walmart-product-detail-scraper
Input:
{ "productUrls": ["https://www.walmart.com/ip/Product-Name/ID"] }How to find the URL: Use the full URL from Walmart product page. The numeric ID at the end is required (e.g., /1752657021).
⚠️ May return 0 items. Verify product URL is accessible (some products are region-locked).
---
compass/Google-Maps-Reviews-Scraper
Input:
{ "startUrls": [{"url": "https://www.google.com/maps/place/Place+Name/@lat,lng,17z"}], "maxReviews": 30 }How to find the URL: Search Google Maps for the business → copy full URL from browser address bar. Must include the @lat,lng,zoom part. Alternatively use a place ID URL: https://www.google.com/maps/place/?q=place_id:ChIJ....
Output: Status object with isFinished, enqueued, placeIdsEnqueued. Review data in separate dataset items.
---
automation-lab/g2-scraper
Replaces zhorex/g2-reviews-scraper (broken).
⚠️ Before calling: Discover the G2 slug via SERP: "[product] site:g2.com/products". Extract slug from URL pattern g2.com/products/[slug]/reviews. Wrong slug silently returns reviews for a different product (e.g., Slack). Always verify productName in output matches your target.
Input:
{ "mode": "product_reviews", "productUrls": ["VERIFIED-SLUG"], "maxReviews": 25, "sortReviews": "newest" }⚠️ Field is productUrls (array of slugs), NOT startUrls. mode is required.
Output keys: reviewId, title, starRating, nps, reviewText, publishedAt, submittedAt, reviewerName, country, region, easeOfUse, easeOfSetup, easeOfAdmin, qualityOfSupport, meetsRequirements, loveTheme, hateTheme, switchedFromOtherProduct, switchedReason, companySegment, industry, productName, productSlug, url, helpfulVotes, sourceType
---
zen-studio/capterra-reviews-scraper
⚠️ Before calling: Discover the Capterra URL via SERP: "[product] site:capterra.com/p/". URL pattern is capterra.com/p/[numeric-id]/[Product-Name]/reviews/. The numeric ID is required — do not guess it.
Input:
{ "productUrl": "https://www.capterra.com/p/NUMERIC-ID/Product-Name/reviews/", "maxReviews": 10 }⚠️ Field is productUrl (singular string), NOT startUrls.
Output keys: url, reviewId, title, writtenOn, overallRating, easeOfUseRating, customerSupportRating, functionalityRating, valueForMoneyRating, recommendationRating, prosText, consText, generalComments, adviceToOthers, incentivized, reviewer, vendorResponse, scrapedAt
reviewer: fullName, jobTitle, companySize, industry, timeUsedProduct, isValidated.
---
Gartner Peer Insights
⚠️ No working actor available (tested 2026-05-06 with Databricks — major vendor with thousands of reviews). All actors on Apify Store (zen-studio, hello.datawizards, memo23) return empty or fail. Gartner blocks all scrapers. Use SERP snippet mining as fallback:
call-actor: apify/google-search-scraper
input: { "queries": "[product] review site:gartner.com" }---
memo23/glassdoor-scraper-ppr
⚠️ Before calling: Discover the Glassdoor URL via SERP: "[company] site:glassdoor.com/Overview". The URL contains an employer ID (EI_IE[number]) — the numeric ID is what matters, not the company name part.
Input:
{ "startUrls": [{"url": "https://www.glassdoor.com/Overview/Working-at-COMPANY-EI_IEVERIFIED-ID.htm"}], "command": "reviews" }command values: reviews, jobs, interviews, salaries, overview. Default to reviews for CI.
Output keys: reviewId, summary, pros, cons, advice, ratingOverall, ratingWorkLifeBalance, ratingCultureAndValues, ratingCompensationAndBenefits, ratingCareerOpportunities, ratingSeniorLeadership, ratingDiversityAndInclusion, ratingCeo, ratingBusinessOutlook, ratingRecommendToFriend, jobTitle, location, reviewDateTime, isCurrentJob, lengthOfEmployment, employer
employer: id, shortName, squareLogoUrl. jobTitle: text.
---
harshmaur/reddit-scraper
Input:
{ "startUrls": [{"url": "https://www.reddit.com/search/?q=company+keyword"}], "maxItems": 10 }Alternatively, scrape a specific subreddit: https://www.reddit.com/r/subreddit/search/?q=keyword.
Output keys: id, title, body, authorName, communityName, upVotes, commentsCount, dataType ("post"/"comment"), postUrl, contentUrl, createdAt, crawledAt, flair, postType
---
neatrat/google-play-store-reviews-scraper
Input:
{ "appIdOrUrl": "com.company.app" }⚠️ Field is appIdOrUrl, NOT appId.
How to find the app ID: Open the app on Google Play → the URL is play.google.com/store/apps/details?id=com.company.app. The id parameter is the app ID (e.g., com.slack, com.spotify.music). Both the ID string and the full Play Store URL work as input.
---
jdtpnjtp/apple-app-store-scraper
⚠️ Requires SHADER proxy group which may not be available on all Apify plans. Verify access before use.
Input (when proxy available): App Store URL, e.g., https://apps.apple.com/us/app/app-name/idNUMBER.
How to find the URL: Search App Store or use SERP: "[app] site:apps.apple.com". The numeric ID at the end (id618783545) identifies the app.
---
pro100chok/similarweb-scraper
Input:
{ "searchType": "similarweb", "domains": ["apify.com", "oxylabs.io", "brightdata.com", "zyte.com", "scraperapi.com", "smartproxy.com", "scrapingbee.com", "nimbleway.com", "diffbot.com", "octoparse.com"] }⚠️ searchType is required. Minimum 10 domains required — actor rejects fewer with "Minimum 10 domains required for analysis." Always batch all competitors into one call. Use bare domain without protocol (e.g., apify.com, not https://apify.com).
---
data_xplorer/google-news-scraper-fast
Input:
{
"keywords": ["\"Company Name\""],
"maxArticles": 10,
"timeframe": "7d",
"region_language": "US:en",
"decodeUrls": true,
"extractDescriptions": true,
"extractImages": false
}timeframe values: 1h, 1d, 7d, 1y, all. Multi-keyword via array. Use quotes for exact phrase match (e.g., "\"Bright Data\"" to find articles mentioning "Bright Data" as a phrase, not "bright" and "data" separately). ⚠️ Boolean operators (OR, AND) produce unreliable results — use separate keywords array entries instead of boolean syntax.
Output keys: title, url, source, publishedAt (ISO), publishedTimestamp (unix), image, description (full text when extractDescriptions: true), metadata
metadata: scrapeTimestamp, keyword, sourceType, timeframe.
---
andok/wayback-machine-scraper
Input:
{ "url": "https://example.com/pricing" }No maxSnapshots parameter exists. Use full URL including path to specific page (e.g., pricing page, homepage).
Output keys: inputUrl, snapshotCount, snapshots[], latestSnapshot, latestHtml, checkedAt, error
Each snapshot contains URL + timestamp of archived version. May return "error": "Wayback CDX HTTP 503" when the Wayback Machine API is overloaded — retry later.
Competitor Snapshot
When to use: Analyze, profile, or understand a specific competitor.
Data Gathering
# 1: Discover website + news
call-actor: apify/google-search-scraper # "[competitor name]" branded query
# 2: Scrape key pages (parallel)
call-actor: apify/website-content-crawler # homepage, /pricing, /about
# 3: Structured enrichment (parallel, if URLs available)
call-actor: dev_fusion/Linkedin-Company-Scraper
call-actor: pratikdani/crunchbase-companies-scraper
# 4: Temporal context — what changed?
call-actor: andok/wayback-machine-scraper # homepage + pricing ~1 year ago
# 5: Recent news — last 7 days
call-actor: data_xplorer/google-news-scraper-fastAnalysis
Synthesize into: positioning, target audience, key claims, strengths, vulnerabilities. Compare to user's product if context available. Highlight changes over time (Wayback) and recent momentum (news).
Content & SEO Battle
When to use: Understand competitors' content strategy or search positioning.
Data Gathering
# 1: SERP rankings for category keywords (parallel, 4-6 buyer keywords, NOT brand terms)
call-actor: apify/google-search-scraper
input: { "queries": "[category] tools comparison [current-year]\nbest [category] platform\n[category] alternatives\n[use case] software", "maxPagesPerQuery": 1 }
# 2: Indexed content volume
call-actor: apify/google-search-scraper
input: { "queries": "site:[competitor.com]\nsite:[competitor-2.com]" }
# 3: Traffic data (may be empty for small sites)
call-actor: pro100chok/similarweb-scraper # minimum 10 domains — batch all competitors in one call
# 4: Blog/content strategy
call-actor: apify/website-content-crawler # [competitor-url]/blog, crawl 10 pagesThe most valuable SEO finding is often absence — not ranking for category keywords is a critical gap.
Analysis
Map competitors to keywords. Estimate content volume and frequency. Identify topic clusters. Find content gaps — topics nobody covers well that user could own.
Hiring Signal Analysis
When to use: Infer competitor's strategic direction from hiring patterns.
Data Gathering
# 1: LinkedIn job listings
call-actor: curious_coder/linkedin-jobs-scraper
# 2: Fallback — careers page
call-actor: apify/website-content-crawler # [competitor-url]/careers
# 3: Glassdoor — culture, salaries, internal signals
call-actor: memo23/glassdoor-scraper-ppr
# 4: Recent hiring news
call-actor: apify/google-search-scraper
input: { "queries": "[competitor] hiring jobs careers [current-year]\n[competitor] layoffs OR expansion [previous-year] [current-year]" }0 LinkedIn results = signal (not hiring aggressively). Glassdoor compensates — reviews reveal culture/strategy even without active hiring.
Analysis
Categorize roles by department. Hiring velocity (scaling/stable/contracting). Technology signals from JDs. Geographic expansion. Seniority mix: hiring leaders = new initiative, hiring ICs = scaling existing.
Market Landscape Map
When to use: Understand all players, find white space, or map the competitive landscape.
Data Gathering
# 1: Discover players (parallel)
call-actor: apify/google-search-scraper
input: { "queries": "[industry] companies\nbest [category] tools\n[category] alternatives" }
# 2: Category/comparison pages
call-actor: apify/rag-web-browser
input: { "query": "best [category] comparison" }
# 3: Quick snapshot of each discovered competitor
call-actor: apify/website-content-crawler # homepage of each discovered competitor
# 4: Funding/size enrichment
call-actor: pratikdani/crunchbase-companies-scraper
# 5: Traffic comparison
call-actor: pro100chok/similarweb-scraper # minimum 10 domains — batch all competitors in one callAnalysis
Categorize by tier (enterprise, mid-market, SMB, open-source). Build positioning map (e.g., price vs. feature breadth). Identify white space — underserved segments or unowned positioning. Note trends, recent entrants, consolidation signals.
Pricing Deep Dive
When basic Pricing Intelligence isn't enough — complex pricing models, multiple products/SKUs, or per-use-case/per-tier comparison needed.
When to Use
- Basic pricing scrape revealed non-trivial structure (usage-based, credit multipliers, tiered)
- User wants deeper comparison than headline price
- Multiple products/SKUs from one vendor with different pricing
Pricing Decomposition (Nagle)
For each vendor, decompose pricing into 4 components (ref: Thomas Nagle, The Strategy and Tactics of Pricing):
1. Price metric — unit of purchase (seat, API call, record, GB, credit, transaction) 2. Price structure — how price varies (flat, tiered, volume, usage-based, credit × multiplier, commitment terms) 3. Offering design — how features are bundled (all-inclusive, modular, add-on, freemium, good/better/best) 4. Price fences — what separates segments (feature gates, support tiers, SLA, SSO, compliance, API access)
This decomposition reveals hidden costs and comparison dimensions.
Normalization
Based on the decomposition:
1. Identify common price metric — what unit makes sense for this category? 2. Propose comparison dimensions — which axes matter? (per tier, per use case, per product line) 3. ⚠️ Confirm with user — always, even in autopilot mode, unless normalization was specified by the user in the prompt. Explain and confirm the decomposition principles and proposed comparison dimensions to the user. 4. Normalize — convert each vendor to common unit 5. Flag incomparables — where and why the comparison breaks down
Confidence
- V (Verified) — directly from pricing page / docs
- C (Calculated) — derived from documented values (base × multiplier)
- E (Estimated) — indirect estimate from plan names, third parties
- ? (Contact sales) — vendor doesn't publish
Pricing Intelligence
When to use: Compare pricing, understand pricing models, or find positioning opportunities.
Data Gathering
# Scrape pricing pages (parallel)
call-actor: apify/website-content-crawler # [competitor]/pricing for each vendor
# E-commerce products (if applicable)
call-actor: junglee/Amazon-crawler
call-actor: e-commerce/walmart-product-detail-scraper
# Third-party pricing breakdowns
call-actor: apify/google-search-scraper
input: { "queries": "[competitor] pricing review" }Analysis
Extract plan names, prices, feature lists, limits. Normalize into comparison matrix. Identify pricing model types (per-seat, usage-based, freemium, enterprise-only). Flag positioning signals — gaps, undercut potential, differentiation opportunities.
Review Intelligence
When to use: Understand customer sentiment, competitor pain points, or exploitable gaps.
SERP Snippet Mining (Always Start Here)
SERP results for review sites contain averageRating, numberOfReviews, and pros/cons snippets — fast triage before full scraping.
call-actor: apify/google-search-scraper
input: { "queries": "[company] review pros cons site:g2.com\n[company] review site:capterra.com\n[company] vs [rival] review", "maxPagesPerQuery": 1 }Full Review Scraping
Use dedicated actors only — review sites block generic scrapers.
# Structured reviews (if applicable)
call-actor: automation-lab/g2-scraper
call-actor: zen-studio/capterra-reviews-scraper
# Gartner: no working actor — use SERP snippet mining above as fallback
# Unfiltered community sentiment (if applicable)
call-actor: harshmaur/reddit-scraper
# Product/location reviews (if applicable)
call-actor: compass/Google-Maps-Reviews-Scraper
call-actor: web_wanderer/amazon-reviews-extractor
call-actor: neatrat/google-play-store-reviews-scraper
call-actor: jdtpnjtp/apple-app-store-scraperAnalysis
Categorize sentiment. Extract top praised features, top complaints, feature requests. Identify switching signals ("switched from X", "better than Y"). Complaints = positioning opportunity.
Multi-Module Playbook
For comprehensive analysis (battlecard, deep dive, board prep). Uses subagent architecture — each module runs as independent agent.
Module Sequence
Each step builds on prior findings (read definitions in modules/):
1. Market Landscape → competitor list + URLs + positioning signals 2. Competitor Snapshots → profiles using URLs from step 1 3. Pricing Intelligence → gathered alongside snapshots (pricing pages) 4. Review Intelligence → uses company names from step 1 for SERP queries 5. Hiring Signals → uses company names + career URLs from steps 1-2 6. Content & SEO → uses category keywords + domains from step 1
Data Carry-Forward
- URLs from Market Landscape → reuse everywhere (avoid re-searching)
- Company names → Review SERP queries + Hiring LinkedIn URLs
- Positioning insights from Snapshots → inform SEO keywords
- Review complaints → validate/contradict Snapshot claims
Subagent Architecture
Run discovery SERP directly (small, fast), then spawn parallel subagents:
- Competitor Profiler (Snapshots + Pricing) — URLs, pricing pages
- Review Analyst — company names, main rivals
- Hiring & Culture Analyst — company names, career URLs
- SEO & Content Analyst — domains, category keywords
Each subagent brief must include: user context (Step 0), competitor list + URLs, module reference path, output format (summary under 500 words: headline finding, key data table, 3 insights with source URLs).
Synthesis
1. Executive narrative — 1 paragraph connecting biggest cross-module finding 2. Top 5 cross-module insights (e.g., "G2 reviews confirm pricing vulnerability from snapshot") 3. Competitive comparison matrix 4. Strategic recommendations — prioritized, framed for user's role 5. Data gaps and confidence levels
Pre-delivery Verification Checklist
Run this audit on every claim before presenting the final report.
Audit Steps
1. Source audit — Every factual statement has a source URL? If not, find it in scraped data or remove the claim. 2. Data-back check — Every insight traces to specific data points. "Weak SEO" must be backed by "absent from top 10 for [keyword] — [URL]". Insight without data = opinion — trace back or remove. 3. Contradiction scan — Claims across modules contradict? (e.g., snapshot says "strong support" but G2 shows complaints). Flag and explain, don't hide.
Confidence Labeling
Mark each major finding:
| Level | Definition |
|---|---|
| High | Scraped from primary source (company website, official docs). Marketing claims — treat critically but data point is authoritative |
| Medium | Confirmed by 2+ independent third-party sources (G2 + Capterra + Reddit = pattern) |
| Low | Single third-party source. Signal, not fact |
| Source Type | Examples |
|---|---|
| Primary | Company's own domain, official docs, press releases |
| Verified third-party | G2, Capterra, Gartner (verified users) |
| Unverified third-party | Blogs, analyst posts, news, Reddit |
| Aggregator | SimilarWeb, Crunchbase, LinkedIn (modeled data — directional, not exact) |
Label format: [Confidence | Source] — e.g., "500+ connectors [High | Primary — fivetran.com/connectors]"
No inferences in reports. Untraceable claims must be removed.