๐Ÿ“ฃ SERP Share of Voice - Keyword Visibility Tracker avatar

๐Ÿ“ฃ SERP Share of Voice - Keyword Visibility Tracker

Pricing

Pay per event

Go to Apify Store
๐Ÿ“ฃ SERP Share of Voice - Keyword Visibility Tracker

๐Ÿ“ฃ SERP Share of Voice - Keyword Visibility Tracker

๐Ÿ“ฃ Track your and competitors' position-weighted share of search visibility across a keyword set, over time. Works from SERP results you supply โ€” the reliable path, since Google returns a JS shell to server-side requests. Optional Bing/DuckDuckGo live fetch.

Pricing

Pay per event

Rating

0.0

(0)

Developer

mohamed alaya

mohamed alaya

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

19 hours ago

Last modified

Categories

Share

SERP Share of Voice

What this actor can and cannot fetch โ€” read this first

Google cannot be scraped server-side. When a plain HTTP request (no real browser, no JS execution) hits Google Search, Google returns a JavaScript shell โ€” no organic results, no AI Overview, nothing usable. Any actor claiming to scrape Google's HTML directly is either running a full browser at real cost and real fragility, or lying about what it returns. This actor does neither.

Primary path (recommended, always works): bring your own SERP results. Pass an array of {"keyword": "...", "rank": 1, "url": "https://...", "title": "..."} rows โ€” from whatever SERP source or Apify actor you already use (Google, Bing, a rank tracker, a manual export, anything). This actor is then a pure analytics engine: it maps results to brands, applies position-weighting, computes share of voice, diffs against history, and reports movement. Nothing here depends on a scraper staying alive, so nothing here breaks when Google changes its markup.

Secondary path (optional, opt-in): live Bing / DuckDuckGo fetch. Both serve parseable HTML to plain server-side requests (unlike Google), so fetchMode: "bing", "duckduckgo", or "bing+duckduckgo" will fetch and parse live results for you. This is provided for convenience, guarded so a parsing failure is recorded in fetchErrors and skipped rather than crashing the run โ€” but their markup can and does change, so treat it as best-effort, not a guarantee.

What it computes

  • Position-weighted share of voice โ€” a documented CTR-style decay curve (rank 1 worth roughly 10-15x rank 10 by default; override with ctrCurve) instead of flat "count of rankings", which is what makes most SoV tools useless: being #1 for one keyword should count for far more than being #10 for the same keyword.
  • Optional keyword-volume weighting โ€” supply keywordVolumes and a high-volume keyword's rankings count proportionally more than a rarely-searched one's.
  • Brand mapping with subdomain handling โ€” brandMap: {"Brand": ["domain.com"]} automatically matches shop.domain.com, blog.domain.com, etc. to that brand; list a subdomain explicitly only when it belongs to a different brand than its parent.
  • Per-brand SoV%, per-keyword breakdown, and head-to-head gaps against yourBrand.
  • State across runs in a named key-value store (stateStoreName): rolling SoV history per brand, movement (delta + trend) since the last run, biggest keyword-level gains/losses, and new entrants/dropouts. First run is always a baseline โ€” no movement, no false "everything is new" noise.

Output rows

type: "brand" (one per brand, incl. dropouts), type: "keyword" (per-keyword breakdown), type: "head-to-head" (you vs. each competitor, worst gap first), type: "mover" (biggest keyword-level gains/losses). SUMMARY in the key-value store carries the leader, your SoV, winners, losers, new entrants and dropouts.

Typical uses

Weekly/monthly SoV tracking for a keyword set you already rank-track elsewhere ยท competitive intelligence โ€” see which competitor is quietly gaining on a specific keyword before it shows up anywhere else ยท reporting a defensible, position-weighted number to stakeholders instead of a flat "we rank for N keywords" count.

Schedule it

Weekly or monthly, matching whatever cadence you already pull SERP data at. Every run is diffed against the previous one automatically โ€” there is nothing else to configure for the history to build up correctly.