# Keyword Gap Analysis: Competitor Keywords You Don't Rank For (`vncntlabs/keyword-gap-finder`) Actor

Compare your domain with up to 5 competitors and get the keywords they rank for on Google and you don't, with search volume, CPC, keyword difficulty, intent and each competitor's position and URL. Also finds keywords where they outrank you. No API key needed.

- **URL**: https://apify.com/vncntlabs/keyword-gap-finder.md
- **Developed by:** [VNCNT Labs](https://apify.com/vncntlabs) (community)
- **Categories:** SEO tools, Marketing, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 gap keywords

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Keyword Gap Analysis: Competitor Keywords You Don't Rank For

Put in your domain and up to 5 competitors and get **the Google keywords they rank for and you don't**. Every keyword comes back as one row with its **monthly search volume, CPC, keyword difficulty (0-100) and search intent**, how many of your competitors rank for it, **each competitor's position and ranking URL**, and the best one to copy. Two more modes show **keywords where a competitor outranks you** (usually the quickest wins) and **every keyword you share**.

It's the keyword gap report from the big SEO suites, without the monthly subscription. No API key, no login, $0.02 per competitor plus $1 per 1,000 keywords.

Built for:

- **SEO freelancers and agencies**: a content plan for a client in one run, backed by what their competitors already rank for.
- **Shopify, Etsy and print-on-demand store owners**: see which product and gift searches bring traffic to the bigger stores in your niche.
- **Bloggers and KDP authors with their own site**: find the topics similar sites rank for that you've never written about.
- **Developers and AI agents**: one call returns clean JSON you can sort, filter and feed into a content brief.

### What you get

| Row (`type`) | What's in it | Charged |
|---|---|---|
| `keyword` | `keyword`, `gapType`, `searchVolume`, `cpc`, `competition`, `keywordDifficulty`, `intent`, `searchVolumeTrendYearly`, `competitorsRanking`, `bestCompetitor`, `bestPosition`, `bestUrl`, `yourPosition`, `yourUrl`, `positionsBehind`, `competitorTraffic`, `positions` (domain to position), `competitors` (domain, position, URL, estimated traffic) | `gap-keyword` |
| `competitor` | `competitor`, `yourDomain`, `mode`, `country`, `status`, `totalKeywords` (the full size of the gap with your filters), `keywordsReturned`, `keywordsDelivered` | `competitor-compared` |
| `skipped` | inputs that weren't valid or weren't compared, with the reason | free |

When several competitors rank for the same keyword, it's merged into one row, so a keyword with `competitorsRanking: 3` is one all three of them get traffic from.

### Input examples

The classic gap, top 100 keywords:

```json
{ "yourDomain": "example.com", "competitors": ["competitor-one.com", "competitor-two.com"], "maxKeywords": 100 }
```

Page-one keywords only, easiest first, without other brands:

```json
{ "yourDomain": "example.com", "competitors": ["competitor-one.com"], "maxCompetitorPosition": 10,
  "sortBy": "difficulty", "excludeKeywordsContaining": ["amazon", "etsy"] }
```

Keywords where you already rank but a competitor beats you, in the UK:

```json
{ "yourDomain": "example.co.uk", "competitors": ["competitor.co.uk"], "mode": "behind", "country": "GB" }
```

**Tips**

- **Max keyword rows** is your cost cap: 100 rows = $0.10, 1,000 rows = $1.00, plus $0.02 per competitor and the $0.005 run start.
- Branded keywords (ones that contain your brand or the competitor's, taken from the domain) are skipped by default, since you can't really win "competitor login".
- `totalKeywords` on the competitor row tells you how big the whole gap is, even if you only asked for 100 rows.
- Runs take a few seconds. Data is DataForSEO's Google keyword database, refreshed monthly, so positions are a recent snapshot, not a live check of today's results.
- To see the competitor's full keyword list (not just the gap), use [Website Traffic Checker](https://apify.com/vncntlabs/domain-seo-data).

### Output examples

A `missing` row (the competitor ranks, you don't):

```json
{
  "type": "keyword", "keyword": "customised tshirt", "gapType": "missing",
  "searchVolume": 135000, "cpc": 7.82, "competition": "HIGH", "keywordDifficulty": 51, "intent": "transactional",
  "competitorsRanking": 1, "bestCompetitor": "printful.com", "bestPosition": 7,
  "bestUrl": "https://www.printful.com/make-your-own-shirt",
  "yourDomain": "gelato.com", "yourPosition": null, "competitorTraffic": 5.5,
  "positions": { "printful.com": 7 }, "country": "US"
}
```

A `behind` row (you both rank, they're ahead):

```json
{
  "type": "keyword", "keyword": "print on demand", "gapType": "behind",
  "searchVolume": 22200, "cpc": 8.78, "keywordDifficulty": 76, "intent": "commercial",
  "bestCompetitor": "printify.com", "bestPosition": 3, "bestUrl": "https://printify.com/print-on-demand/",
  "yourPosition": 4, "yourUrl": "https://www.gelato.com/print-on-demand", "positionsBehind": 1
}
```

A competitor summary row:

```json
{ "type": "competitor", "competitor": "printful.com", "yourDomain": "gelato.com", "mode": "missing",
  "country": "US", "status": "ok", "totalKeywords": 17299, "keywordsReturned": 50, "keywordsDelivered": 48 }
```

The dataset has two views, **Gap keywords** and **Competitor summary**. Export to CSV, Excel or JSON, or send results to Google Sheets, Slack or email with Apify integrations.

### Pricing (pay per event)

| Event | Price | When it is charged |
|---|---|---|
| Actor start | $0.005 | once per run |
| `competitor-compared` | $0.02 | one competitor compared with your domain that returned keywords |
| `gap-keyword` | $0.001 | one keyword row delivered (merged across competitors) |

So 1 competitor with 100 keywords costs $0.125, and 3 competitors with 300 keywords cost $0.365.

You are not charged for:

- competitors with no matching keywords, and competitors the data provider couldn't answer for;
- skipped inputs, and anything beyond your run's maximum charge. The run lowers the keyword limit to fit your maximum charge and says so in the log.

**Apify free plan:** 2 competitors and 50 keywords per run. Any paid Apify plan unlocks 5 competitors and 1,000 keywords.

### Use from AI agents (MCP)

AI assistants such as Claude, ChatGPT and Cursor can run this Actor through [Apify's MCP server](https://docs.apify.com/platform/integrations/mcp) (`https://mcp.apify.com`). The agent can look up the Actor, read its input schema, run it and read the results. Runs use your own Apify account and are charged at the prices on this page.

- **Actor name:** `vncntlabs/keyword-gap-finder`
- **Server URL with only this tool:** `https://mcp.apify.com?tools=vncntlabs/keyword-gap-finder`. The default `https://mcp.apify.com` also works; the agent can then search Apify Store and call the Actor by name.
- **Claude** (desktop app or claude.ai): Settings > Connectors > Add custom connector, paste the server URL, then sign in to Apify.
- **ChatGPT:** turn on Developer mode, then Settings > Apps & Connectors > Create, paste the server URL and choose OAuth.
- **Cursor:** run `/add-plugin apify` in Cursor chat and connect the Apify MCP server under Cursor Settings > Tools & MCPs, or add the server to `mcp.json`:

```json
{ "mcpServers": { "apify": { "url": "https://mcp.apify.com?tools=vncntlabs/keyword-gap-finder" } } }
```

Example prompt: *"Use the Apify Actor vncntlabs/keyword-gap-finder to find 50 keywords competitor.com ranks for in the top 10 that example.com doesn't, easiest first, and group them into blog post ideas."*

To cap the cost of an agent's run, it can pass `maxTotalChargeUsd` in the run options.

### FAQ

**Where does the data come from?** DataForSEO's Google keyword and ranking database (DataForSEO Labs), the same kind of data the big SEO suites use. Search volume is Google Ads monthly volume; difficulty and positions are DataForSEO's estimates.

**Why is my domain showing no gap?** Very new or very small sites may not be in the keyword database yet. The competitor row then says `no-data` and you aren't charged for it.

**Can I compare more than 5 competitors?** Not in one run. Run it again with the next batch; each competitor costs the same either way.

**Does it check subdomains?** It compares whole domains, so blog.example.com rankings count for example.com.

**Related tools:** [Keyword Search Volume](https://apify.com/vncntlabs/keyword-search-volume) for volume on your own list, [Google Rank Tracker](https://apify.com/vncntlabs/google-rank-tracker) to track the keywords you go after, and [Website SEO Audit](https://apify.com/vncntlabs/website-seo-audit) to fix your pages first.

Questions or a filter you'd like added? Email hello@vncntlabs.com.

Not affiliated with Google, Semrush or Ahrefs.

# Actor input Schema

## `yourDomain` (type: `string`):

Your own site, like <code>example.com</code>. A full URL works too; the whole domain is used.

## `competitors` (type: `array`):

1 to 5 competitor domains. You pay $0.02 per competitor compared, plus $0.001 per keyword row. A competitor with no matching keywords isn't charged.

## `mode` (type: `string`):

Missing is the classic keyword gap. Behind shows where you already rank but a competitor beats you, which is usually the quickest win.

## `country` (type: `string`):

2-letter country code for Google rankings and search volume, for example US, GB, CA, AU, DE.

## `language` (type: `string`):

Language code such as en, de or es. Leave empty for the country's main language (English where available).

## `maxKeywords` (type: `integer`):

Total keyword rows for the run, after merging all competitors. This is also your cost cap: 100 rows = $0.10.

## `maxCompetitorPosition` (type: `integer`):

Only keywords where the competitor ranks at this position or better. 10 = page one only, 100 = everything.

## `minSearchVolume` (type: `integer`):

Skip keywords searched fewer times a month than this.

## `sortBy` (type: `string`):

Which keywords come first. It also decides which ones are kept when there are more than Max keyword rows.

## `excludeBrandedKeywords` (type: `boolean`):

Drop keywords that contain your brand or the competitor's brand (taken from the domain name), like 'printify login'.

## `excludeKeywordsContaining` (type: `array`):

Up to 5 words or phrases. Any keyword containing one of them is dropped, for example other brands or 'free'.

## Actor input object example

```json
{
  "yourDomain": "gelato.com",
  "competitors": [
    "printify.com"
  ],
  "mode": "missing",
  "country": "US",
  "maxKeywords": 10,
  "maxCompetitorPosition": 20,
  "minSearchVolume": 10,
  "sortBy": "volume",
  "excludeBrandedKeywords": true
}
```

# Actor output Schema

## `keywords` (type: `string`):

No description

## `competitors` (type: `string`):

No description

## `all` (type: `string`):

No description

## `summary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "yourDomain": "gelato.com",
    "competitors": [
        "printify.com"
    ],
    "maxKeywords": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("vncntlabs/keyword-gap-finder").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "yourDomain": "gelato.com",
    "competitors": ["printify.com"],
    "maxKeywords": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("vncntlabs/keyword-gap-finder").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "yourDomain": "gelato.com",
  "competitors": [
    "printify.com"
  ],
  "maxKeywords": 10
}' |
apify call vncntlabs/keyword-gap-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,vncntlabs/keyword-gap-finder"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/tuIeo6oyURmy9TuYU/builds/kY3orFpewvXCGRhGu/openapi.json
