# SEO Competitor Keywords - Domain Ranked Keywords & Keyword Gap (`tenfoldfleet/seo-competitor-keywords`) Actor

Find the Google keywords any domain or competitor ranks for: position, ranking URL, search volume, CPC, keyword difficulty, intent and traffic, plus organic competitors and the keyword gap between 2-5 domains. No Semrush or Ahrefs needed. $3 per 1,000 keywords + $0.02 per domain; errors free.

- **URL**: https://apify.com/tenfoldfleet/seo-competitor-keywords.md
- **Developed by:** [Tenfold Fleet](https://apify.com/tenfoldfleet) (community)
- **Categories:** SEO tools, Marketing, Developer tools
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 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

### What does SEO Competitor Keywords do?

**SEO Competitor Keywords** finds the **Google keywords any domain or competitor ranks for**, with the **position**, the **ranking URL**, **search volume**, **CPC**, **keyword difficulty**, **search intent** and **estimated traffic** on every row. It also lists the **organic competitors** of a domain and runs a **keyword gap** between your site and up to 4 competitors, so you see the keywords they win and you don't.

It works like the "Organic Research", "Organic Competitors" and "Keyword Gap" reports of Semrush or Ahrefs, as an API: **no Semrush or Ahrefs subscription needed**. Data comes from the DataForSEO Labs Google database (billions of keywords, 94 countries). Run it from the Apify Console, the API, Zapier, Make, n8n or an AI agent through MCP.

### Why use it?

- **Competitor keyword research:** see every keyword a competitor gets traffic from, which page ranks, and how much traffic it brings.
- **Keyword gap / content gap:** find the keywords 1-4 competitors rank for and your site doesn't rank for at all. Keywords that several competitors share come first.
- **Find your real competitors:** list the domains that rank for the same keywords as you, with common keywords, average position and their total traffic.
- **SEO reporting and rank tracking:** export the positions of your own domain with the previous position, new/up/down flags and the featured snippet flag.
- **Agencies and AI agents:** bulk-analyze up to 50 domains per run and feed the JSON into reports, spreadsheets or LLM workflows.

### What data can it extract?

| Field | Description |
|---|---|
| `keyword` | Google keyword the domain ranks for |
| `position` / `previousPosition` | Organic position now and at the previous SERP update |
| `rankingUrl` / `rankingTitle` | The page that ranks and its title |
| `searchVolume` | Average monthly Google searches |
| `etv` / `trafficCost` | Estimated monthly traffic from the keyword and its value in ad spend |
| `cpc`, `competition` | Google Ads cost per click and competition |
| `keywordDifficulty` | How hard it is to reach the top 10 (0-100) |
| `intent` / `secondaryIntents` | Informational, navigational, commercial or transactional |
| `serpFeatures` / `isFeaturedSnippet` | SERP features on the page (people also ask, video, local pack...) and whether the domain holds the featured snippet |
| `totalRankedKeywords` | How many keywords the domain ranks for in total (with your filters) |
| `competitorDomain`, `commonKeywords`, `avgPosition`, `competitorEtv` | Competitors mode: the competing domain, shared keywords, its average position and total traffic |
| `yourPosition`, `positions`, `bestCompetitor`, `competitorsRanking` | Keyword gap mode: your position, every domain's position, the best-ranking competitor and how many competitors rank |

### How to find the keywords a competitor ranks for

1. Open the Actor and pick a **Mode**: *Ranked keywords*, *Organic competitors* or *Keyword gap*.
2. Enter one or more **domains** (`example.com` or any URL). For a keyword gap, put **your domain first**, then 1-4 competitors.
3. Choose the **country** and **language** (94 countries; names or codes like `US`, `GB`, `de` work).
4. Optional: set **Max rows per domain** (up to 10,000), **Max Google position** (10 = first page) and **Min monthly search volume**.
5. Click **Start** and download the results as JSON, CSV, Excel or HTML.

### How much does it cost?

Pay per result, no subscription:

- **$3 per 1,000 keywords** ($0.003 per ranked-keyword or keyword-gap row)
- **$3 per 1,000 competitor rows** ($0.003 per competitor)
- **$0.02 per domain** with data (covers the data provider's fixed fee per lookup)

Example: the top 500 keywords of one competitor cost $1.52. Invalid domains, domains with no data, duplicates and errors are **free**. Set a max cost per run and the Actor stops there, only buying the data you can pay for.

**Free Apify plan:** 1 domain and 10 rows per run (keyword gap: your domain vs 1 competitor), because every lookup costs the developer a data fee. Any paid Apify plan gets up to 10,000 rows per domain and 50 domains per run.

### Input

```json
{
    "mode": "keywordGap",
    "domains": ["apify.com", "scrapingbee.com", "brightdata.com"],
    "location": "United States",
    "language": "English",
    "maxRowsPerDomain": 500,
    "maxPosition": 20,
    "minSearchVolume": 100,
    "gapType": "missing"
}
```

### Output

One row per keyword (or competitor). Download it as JSON, CSV, Excel or HTML, or read it through the API.

```json
{
    "type": "rankedKeyword",
    "domain": "apify.com",
    "keyword": "web scraping tools",
    "position": 3,
    "previousPosition": 5,
    "rankingUrl": "https://apify.com/...",
    "searchVolume": 9900,
    "etv": 1210.5,
    "cpc": 6.12,
    "keywordDifficulty": 48,
    "intent": "commercial",
    "serpFeatures": ["people_also_ask", "video"],
    "isFeaturedSnippet": false,
    "totalRankedKeywords": 6953,
    "location": "United States",
    "language": "English"
}
```

Keyword gap rows add `yourPosition` (null = you don't rank), `positions` (`{"apify.com": null, "brightdata.com": 5}`), `rankingUrls`, `bestCompetitor` and `competitorsRanking`. Rows with an `error` field are free notes (invalid domain, no data).

### Tips

- Rows come **highest traffic first**, so a small **Max rows per domain** already gives the keywords that matter.
- Use **Max Google position 10** to see only first-page keywords, and **Min monthly search volume** to skip the long tail.
- **Missing** gap = content ideas (competitors rank, you don't). **Shared** gap = keywords you can push up (both rank; compare positions).
- Enter the root domain (`example.com`) for the whole site, or a subdomain (`blog.example.com`) for just that part.
- Big runs (many domains with 10,000 rows each) can take a while. If the run's timeout comes close, the Actor stops cleanly: you keep and pay for the rows already found, and the domains not reached are listed as free rows.

### FAQ

#### Do I need a Semrush, Ahrefs or DataForSEO account?

No. The data access is included in the price per result.

#### How fresh is the data?

Positions come from the DataForSEO Labs Google database, which is refreshed continuously; each row's SERP is usually from the last few weeks. It is an estimate like Semrush or Ahrefs data, not a live Google check.

#### Which countries are supported?

94 countries, with local languages (for example United States English/Spanish, Canada English/French, Switzerland German/French/Italian).

#### Why does a domain return no keywords?

Small or new sites may not rank in the top 100 for any keyword the database tracks in that country. Those rows are free; try another country. If 10 domains in a row have no data, the run stops and lists the rest as free rows, because that almost always means the wrong country or language.

### Disclaimer

This Actor returns aggregated search-engine statistics about public websites. It does not collect personal data. Keyword metrics are estimates. Not affiliated with Google, Semrush or Ahrefs.

### More tools from Tenfold Fleet

| Actor | Output |
|---|---|
| [AliExpress Keyword Scraper - Exact Sold Counts by Search Term](https://apify.com/tenfoldfleet/aliexpress-search-scraper) | product |
| [Amazon Product Scraper - Details, Prices & Search by ASIN](https://apify.com/tenfoldfleet/amazon-product-scraper) | product |
| [ATS Jobs Scraper - Greenhouse, Lever, Ashby & 5 More](https://apify.com/tenfoldfleet/ats-jobs-scraper) | job posting |
| [Backlinks Checker - Referring Domains, Anchors & Domain Rank](https://apify.com/tenfoldfleet/backlinks-checker) | backlink |
| [Bilibili Scraper - Videos, Comments, Danmaku & Search](https://apify.com/tenfoldfleet/bilibili-scraper) | video or comment |
| [Businesses Without Websites - Local Leads with Phone & Rating](https://apify.com/tenfoldfleet/businesses-without-websites) | lead |
| [Contact Details Scraper - One Lead Record per Company Website](https://apify.com/tenfoldfleet/company-contact-finder) | website with contacts |
| [Google Ads Transparency Center Scraper - Competitor Ads by Site](https://apify.com/tenfoldfleet/google-ads-transparency-scraper) | ad |
| [Google AI Overviews Checker - Citations & Domain Tracker](https://apify.com/tenfoldfleet/google-ai-overviews-checker) | keyword checked |
| [Google Jobs Scraper - Salary, Apply Links & Posting Dates](https://apify.com/tenfoldfleet/google-jobs-scraper) | job listing |
| [Google Keyword Planner Alternative - Ideas, Bids & Volume](https://apify.com/tenfoldfleet/google-keyword-planner) | keyword idea |
| [Google News Scraper - Articles, Real URLs & Full Text](https://apify.com/tenfoldfleet/google-news-scraper) | article |
| [Google Trends Scraper - Interest, Regions & Related Queries](https://apify.com/tenfoldfleet/google-trends-scraper) | keyword |
| [Keyword Ideas & Related Keywords - Difficulty, Volume & CPC](https://apify.com/tenfoldfleet/keyword-ideas) | keyword idea |
| [Keyword Search Volume, CPC & Difficulty Checker (Bulk)](https://apify.com/tenfoldfleet/keyword-search-volume) | keyword with data |
| [Remote Job Board Scraper - Remote Jobs Aggregator, 7 Sites](https://apify.com/tenfoldfleet/remote-jobs-aggregator) | unique remote job |
| [SEEK Job Scraper - Australia, NZ, Jobstreet & JobsDB](https://apify.com/tenfoldfleet/seek-job-scraper) | job listing |
| [SEO Audit Tool - Technical On-Page SEO Checker & Score](https://apify.com/tenfoldfleet/seo-audit-tool) | page audit |
| [Shopify Inventory Scraper - SKUs, Variants & In-Stock Status](https://apify.com/tenfoldfleet/shopify-products-scraper) | product |
| [Shopify App & Theme Detector - Store Analyzer & Contacts](https://apify.com/tenfoldfleet/shopify-store-analyzer) | shopify store |
| [Sitemap URL Extractor - All URLs from sitemap.xml & robots.txt](https://apify.com/tenfoldfleet/sitemap-url-extractor) | url |
| [Technology Detector - Wappalyzer & BuiltWith Alternative](https://apify.com/tenfoldfleet/tech-stack-detector) | website |
| [URL to Markdown - Web Page to LLM-Ready Text for AI Agents](https://apify.com/tenfoldfleet/url-to-markdown) | page |
| [Website Traffic Checker - Bulk Domain Traffic Estimate](https://apify.com/tenfoldfleet/website-traffic-checker) | domain with traffic data |
| [Workday Jobs Scraper - myworkdayjobs.com API with Salary](https://apify.com/tenfoldfleet/workday-jobs-scraper) | job posting |
| [YouTube Livestream & Channel Scraper - Videos, Likes & Stats](https://apify.com/tenfoldfleet/youtube-channel-scraper) | video |
| [YouTube Comments Scraper - Replies, Likes & Sort by Newest](https://apify.com/tenfoldfleet/youtube-comments-scraper) | comment |
| [YouTube Shorts Analytics Scraper - Views, Likes & Hashtags](https://apify.com/tenfoldfleet/youtube-shorts-scraper) | short |
| [YouTube Captions Downloader - Transcript & Subtitles Scraper](https://apify.com/tenfoldfleet/youtube-transcript-scraper) | transcript |

# Actor input Schema

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

rankedKeywords: every Google keyword each domain ranks for (position, ranking URL, volume, CPC, difficulty, intent, traffic). competitors: the domains that compete with each domain in organic search. keywordGap: keywords your competitors rank for and you do not (or keywords you share), for 2-5 domains with yours first.

## `domains` (type: `array`):

Domains or URLs, one per line (example.com, https://www.example.com/blog). rankedKeywords and competitors: 1-50 domains, each analyzed separately. keywordGap: 2-5 domains, YOUR domain first, then up to 4 competitors. www. and paths are removed; subdomains such as blog.example.com are kept.

## `location` (type: `string`):

Country whose Google results you want. A country name or 2-letter code works ("United States", "US", "GB", "Germany"); 94 countries.

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

Search language, as a name or code ("English", "en", "de"). If the language has no data for the chosen country, the country's main language is used instead (for example Germany + English uses German). 21 countries support more than one language, for example United States English/Spanish, Canada English/French, Switzerland German/French/Italian, Belgium French/Dutch/German and India English/Hindi. English is also available in Cyprus, Egypt, Greece, Saudi Arabia and the UAE.

## `maxRowsPerDomain` (type: `integer`):

Most keywords (or competitors) returned per domain, highest traffic first. In keywordGap mode this is the most gap keywords fetched per competitor before merging. Up to 10,000.

## `maxPosition` (type: `integer`):

Only keywords where the domain (in keywordGap: the competitor, and for shared also you) ranks at this position or better. 10 = first page only. In competitors mode, only these positions count toward common keywords.

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

Only keywords with at least this many Google searches a month. 0 = all keywords. Not used in competitors mode.

## `gapType` (type: `string`):

keywordGap mode only. missing: keywords at least one competitor ranks for and your domain (the first one) does not rank for at all. shared: keywords both you and a competitor rank for, with both positions.

## `excludeTopDomains` (type: `boolean`):

competitors mode only. Leave out sites that rank for almost everything (wikipedia.org, youtube.com, amazon.com, reddit.com and similar), so the list shows real business competitors.

## Actor input object example

```json
{
  "mode": "rankedKeywords",
  "domains": [
    "apify.com"
  ],
  "location": "United States",
  "language": "English",
  "maxRowsPerDomain": 100,
  "maxPosition": 100,
  "minSearchVolume": 0,
  "gapType": "missing",
  "excludeTopDomains": true
}
```

# Actor output Schema

## `results` (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 = {
    "domains": [
        "apify.com"
    ],
    "maxRowsPerDomain": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("tenfoldfleet/seo-competitor-keywords").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 = {
    "domains": ["apify.com"],
    "maxRowsPerDomain": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("tenfoldfleet/seo-competitor-keywords").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 '{
  "domains": [
    "apify.com"
  ],
  "maxRowsPerDomain": 100
}' |
apify call tenfoldfleet/seo-competitor-keywords --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,tenfoldfleet/seo-competitor-keywords"
        }
    }
}
```

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/yP7hpZL4d9olkodbn/builds/ghso3ssZNH5dVPGOA/openapi.json
