Keyword Gap & Opportunity Report - Competitor Keyword Gap avatar

Keyword Gap & Opportunity Report - Competitor Keyword Gap

Pricing

$9,000.00 / 1,000 keyword gap reports

Go to Apify Store
Keyword Gap & Opportunity Report - Competitor Keyword Gap

Keyword Gap & Opportunity Report - Competitor Keyword Gap

Keywords up to 3 competitors rank for on Google and your client's domain doesn't: volume, difficulty, intent, competing URLs and why each was picked. Top 20 re-checked on the live Google top 10. CSV-ready dataset + HTML report. One flat price per report.

Pricing

$9,000.00 / 1,000 keyword gap reports

Rating

0.0

(0)

Developer

Wrenfield Data

Wrenfield Data

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

Keyword Gap & Opportunity Report: keywords your competitors rank for and you don't

$9 per completed report. The Store price box may show this as "$9,000 / 1,000 reports": it is $9 per report. Up to 3 competitors, up to 300 gap keywords, the top 20 re-checked on live Google. Not charged if a competitor fails or nothing matches your filters.

Enter one domain (yours or a client's) and up to 3 competitors. You get the Google keywords those competitors rank for and your domain doesn't, deduplicated and filtered, each with search volume, keyword difficulty, intent, the competing URLs and a plain-language reason it was picked. The best 20 are then re-checked on the live Google top 10, so you know which gaps are still open today, not just in a months-old database snapshot.

  • 🎯 Real gaps, not noise: competitor brand searches, login/navigational queries and hosted subdomains (for example customer help centers on *.zendesk.com) are removed by default. Add your own exclusions and topic terms.
  • 🧭 Topic fit: every keyword is scored against the words on your own homepage, so "customer service training" outranks "margin calculator" for a help desk company.
  • ✅ Live check of the top 20: open gap, client already ranks, or the database ranking is out of date. Includes whether an AI Overview shows and whether it cites you.
  • 🕒 Honest timestamps: when the provider observed each ranking vs when this run retrieved it, and when Google was checked live. Zero search volume and unavailable are never mixed up.
  • 📄 CSV-ready dataset + compact HTML report (REPORT.html, printable, no third-party branding; add your agency name).

What a report looks like

Real rows from a run on Oct 22, 2026: helpscout.com against zendesk.com, freshworks.com and intercom.com (United States, English). It found 235 gap keywords after filters, took 29 seconds, and re-checked the top 20 on live Google.

KeywordVolume / moKDCompetitor in databaseLive Google, Oct 22
ticketing system1,90015zendesk.com #1open gap: zendesk.com #8
customer service training8,10018zendesk.com #4open gap: zendesk.com #2
ai powered customer platform1,30033freshworks.com #1open gap: intercom.com #4
customer service desk4808freshworks.com #1open gap: freshworks.com #1
email thread6,6003intercom.com #4competitors not in top 10 now

The last row is why the live check exists: the database said Intercom ranked #4, but on Oct 22 no competitor was in the Google top 10. Of the 20 keywords checked live, 8 were open gaps and 12 had moved.

How to use it

  1. Enter the domain you want new keywords for (for example helpscout.com).
  2. Add 1 to 3 competitors that actually outrank you in Google (search competitors, not only business rivals).
  3. Optional: topic terms (keep only keywords about, for example, help desk, support), exclusions (jobs, product names), minimum volume, maximum difficulty.
  4. Click Start. A report takes about 30 seconds. Open REPORT.html in the Output tab, or export the dataset as CSV or Excel.

Input example

{
"clientDomain": "helpscout.com",
"competitors": ["zendesk.com", "freshworks.com", "intercom.com"],
"location": "United States",
"language": "English",
"excludeTerms": ["freshdesk", "freshservice", "fin ai"],
"minSearchVolume": 30,
"maxCompetitorPosition": 20,
"liveSerpChecks": 20,
"preparedBy": "Northwind Digital"
}

Output example

One row per gap keyword (real row from a run on Oct 22, 2026; trimmed):

{
"rank": 5,
"keyword": "customer service training",
"opportunity_score": 74.9,
"search_volume": 8100,
"search_volume_status": "measured",
"search_volume_month": "2026-08",
"cpc_usd": 14.64,
"keyword_difficulty": 18,
"search_intent": "informational",
"topic_fit": 1,
"competitors_ranking": 1,
"competitor_positions": "zendesk.com #4",
"best_competitor_url": "https://www.zendesk.com/blog/customer-service/support/what-is-customer-service/customer-service-training/",
"selection_reasons": "1 of 3 competitors ranks for it: zendesk.com #4; 8,100 Google searches a month in United States; keyword difficulty 18 (easy); informational intent; matches the client's homepage wording (customer, train); ...; live Google check 2026-10-22: helpscout.com not in the top 10; zendesk.com #2; AI Overview shown",
"live_verdict": "open gap",
"competitor_positions_live": "zendesk.com #2",
"top10_domains_live": "www.dalecarnegie.com, www.zendesk.com, www.amanet.org, www.reddit.com, ...",
"ai_overview_live": true,
"ai_overview_cites_client": false,
"labs_serp_observed_at": "2026-07-30T12:58:52Z",
"labs_retrieved_at": "2026-10-22T23:45:12Z",
"serp_checked_at": "2026-10-22T23:45:22Z"
}

That run found 235 gap keywords after filters. Of the 20 re-checked live, 8 were open gaps with a competitor in today's top 10, and 12 had a competitor that was no longer in the top 10 (the database snapshot was from July to October). That is why the live check exists.

Key-value store: REPORT.html (the report), REPORT (JSON summary: filters, per-competitor counts, top picks, observation date range, the homepage words used for topic fit).

Columns

ColumnMeaning
opportunity_score0-100: 25% demand, 20% ease (100 - KD), 20% topic fit, 15% how many competitors rank, 10% intent, 10% best competitor position
search_volume, search_volume_statusMonthly Google searches (Google Ads data); status measured, zero or unavailable (no value, not the same as zero)
keyword_difficulty, search_intentKD 0-100 and main intent, each with a _status column
topic_fitShare of the keyword's words found on your homepage (null if the site could not be read)
competitor_positions, competing_urlsWhich competitors rank, where, and with which page (database)
selection_reasonsWhy the keyword is in the report, in plain language
live_verdictopen gap, client already ranks, competitors not in top 10 now, check failed or not checked
labs_serp_observed_at / labs_retrieved_atWhen the provider observed the rankings / when this run queried them
serp_checked_atWhen the live Google top 10 was observed

Pricing

$9 per completed report, all-inclusive: up to 3 competitors, up to 100 candidates each (up to 300 keywords after merging), filtering, scoring, 20 live Google checks and the HTML report. No per-keyword or per-request fees. Apify platform usage for a run is a fraction of a cent.

Not charged: a run where any competitor's data request fails (the partial report is still saved), a run where nothing matches your filters, or a run whose maximum cost is below $9 (it stops before collecting anything).

Free Apify plan: up to 3 free previews a week (1 competitor, 25 candidates, 5 live checks), not charged.

Method and limits

  • Candidates come from a licensed SEO database (DataForSEO Labs, Google results): keywords where a competitor ranks and your domain has no top-100 ranking, ordered by the competitor's estimated traffic. Rankings in the database are refreshed on the provider's schedule, typically every few weeks to months, which is why every row carries the observation date.
  • Live checks are real Google desktop results (top 10) for the chosen country and language at run time.
  • Traffic estimates are modeled by the provider, not analytics data.
  • Topic fit reads your homepage only (title, headings, links, descriptions). If the site blocks automated requests, fit is marked unavailable and scored neutral.

Keyword Gap Report: REST, Python, JavaScript, n8n and MCP

Actor ID: wrenfield-data/keyword-gap-report. Authenticate with your Apify API token in an Authorization: Bearer header. One run is one report, so set maxTotalChargeUsd to at least 10 (the report is $9). A lower cap makes the run stop before collecting anything, free of charge.

curl -X POST "https://api.apify.com/v2/acts/wrenfield-data~keyword-gap-report/run-sync-get-dataset-items?maxTotalChargeUsd=10" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"clientDomain": "yourdomain.com", "competitors": ["competitor1.com", "competitor2.com"]}'

The synchronous endpoint waits up to 300 seconds, and a report usually takes about 30. It returns the dataset rows as a JSON array.

Python (pip install apify-client):

import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("wrenfield-data/keyword-gap-report").call(
run_input={"clientDomain": "yourdomain.com", "competitors": ["competitor1.com", "competitor2.com"]},
max_total_charge_usd=10,
)
for row in client.dataset(run.default_dataset_id).iterate_items(): # apify-client 1.x/2.x: run["defaultDatasetId"]
if row.get("type") == "notice":
print("NOTE:", row["note"]); continue
print(row["rank"], row["keyword"], row["search_volume"], row["keyword_difficulty"], row["live_verdict"])

JavaScript (npm install apify-client):

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('wrenfield-data/keyword-gap-report').call(
{ clientDomain: 'yourdomain.com', competitors: ['competitor1.com', 'competitor2.com'] },
{ maxTotalChargeUsd: 10 },
);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
const gaps = items.filter((r) => r.type !== 'notice');
console.log(gaps.slice(0, 5).map((r) => `${r.keyword} ${r.search_volume} KD${r.keyword_difficulty} ${r.live_verdict}`));

Async with a webhook: POST /v2/acts/wrenfield-data~keyword-gap-report/runs?maxTotalChargeUsd=10 returns immediately. Add a webhook for ACTOR.RUN.SUCCEEDED, then fetch GET /v2/datasets/{defaultDatasetId}/items?format=csv. REPORT.html is in the run's key-value store at GET /v2/key-value-stores/{defaultKeyValueStoreId}/records/REPORT.html.

n8n / Make / Zapier: use the Apify node or app and choose Run an Actor and Get Dataset (n8n) or Run an Actor followed by Get Dataset Items. Paste the JSON input above. Schedule it monthly per client to see new gaps, and send rows to Google Sheets.

MCP (Claude, Cursor, VS Code or any MCP client): https://mcp.apify.com?tools=wrenfield-data/keyword-gap-report

Notice rows: if a run stops early (maximum cost below $9, or the weekly free-preview limit was reached), the dataset holds a single row {"type": "notice", "note": "..."} that explains why. Filter on type in pipelines.

Stable fields: we add fields but don't rename or remove the ones documented above. Optional fields can be null or absent.

For agencies: run your whole client book

Reporting to clients every week? Agency AI Visibility Reports turns a client CSV into a white-label packet per client: AI visibility on ChatGPT, Perplexity, Gemini and Google AI Mode, competitor share of voice, Google rankings, quoted evidence and an action queue. $12 per client packet (the Store lists it as "$12,000 / 1,000 packets"; that is $12 each, less for 20+ clients).

FAQ

How is this different from a competitor keywords export? An export gives you everything a competitor ranks for. This keeps only what you don't rank for, removes brand and login searches, merges duplicates across competitors, scores fit with your site, explains every pick, and verifies the top 20 against today's Google.

Can I use page URLs? Domains only (paths are removed). Rankings count the whole domain.

Which countries? Every country the keyword database covers (90+). Use a country name, 2-letter code or location code.

What if my site is new and ranks for nothing? It works: every competitor keyword is then a gap. Use topic terms to stay on topic.

Feedback and support

Need more competitors, another market or a different scoring? Open an issue on the Issues tab with the run ID. We reply there, usually within a day.

Acceptable use

Independent tool, not affiliated with Google, DataForSEO or the companies in the examples. Brands appear only because their public Google rankings were analyzed.