# Ahrefs Keyword Difficulty Checker — KD Score & SERP (`bovi/ahrefs-keyword-difficulty-scraper`) Actor

Get Ahrefs Keyword Difficulty (KD 0-100) for any keyword in bulk, plus the backlinks-to-rank shortage and the full top-SERP overview (each result with Domain Rating, URL Rating, traffic & keywords). No Ahrefs login, no API key. Pay per keyword.

- **URL**: https://apify.com/bovi/ahrefs-keyword-difficulty-scraper.md
- **Developed by:** [Vitalii Bondarev](https://apify.com/bovi) (community)
- **Categories:** SEO tools, Marketing
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $26.19 / 1,000 keyword difficulty results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

**Get Ahrefs Keyword Difficulty (KD) scores in bulk — with the full top-10 SERP breakdown included.** This ahrefs keyword difficulty scraper returns KD 0–100, the referring-domain gap you need to crack the top 10, and a rich `serp_overview` for every ranking page — no Ahrefs account, no API key, pay only per result.

### Features

- **Bulk KD lookup** — pass a list of up to 5,000 keywords, get one clean record per keyword
- **Country-specific data** — set any two-letter country code (`us`, `gb`, `de`, `fr`, …)
- **Full SERP breakdown** — not just the score: each of the top-10 ranking pages comes back with DR, UR, traffic, keyword count, top keyword, and top keyword volume
- **Backlinks-to-rank gap** — the `backlinks_to_rank` field tells you exactly how many referring domains a new page is short of to reach the top 10
- **Zero buyer key required** — the actor uses a real stealth browser that navigates the Ahrefs free-KD page; the page handles its own challenge and fires the data call itself; we intercept the response
- **Failed lookups visible but never billed** — if a keyword returns no data, it appears in your dataset with an error note so you have full visibility; you are not charged for it
- **Results streamed per row** — each keyword is pushed the moment it is ready, so a timeout never discards completed work

### What data you get

One dataset row per keyword:

| Field | Type | Description |
|---|---|---|
| `keyword` | string | The keyword as submitted |
| `country` | string | Two-letter country code |
| `keyword_difficulty` | integer 0–100 | Ahrefs KD score |
| `backlinks_to_rank` | integer | Referring domains needed to reach top 10 |
| `last_update` | string | When Ahrefs last refreshed this keyword's index |
| `serp_count` | integer | Number of results in `serp_overview` |
| `checked_at` | ISO datetime | When the run fetched this keyword |
| `error` | string or null | Set if the lookup failed; null on success |
| `serp_overview` | array | One object per ranking page (see below) |

**`serp_overview` sub-fields (per ranking page):**

| Sub-field | Description |
|---|---|
| `position` | SERP rank (1–10) |
| `title` | Page title |
| `url` | Full URL |
| `domain_rating` | Ahrefs DR of the root domain |
| `url_rating` | Ahrefs UR of the specific page |
| `traffic` | Estimated monthly organic traffic |
| `keywords` | Total keywords the page ranks for |
| `top_keyword` | The keyword driving the most traffic to that page |
| `top_volume` | Monthly search volume of the top keyword |

**Example output records (verified cloud run):**

```json
{
  "keyword": "seo tools",
  "country": "us",
  "keyword_difficulty": 82,
  "backlinks_to_rank": 399,
  "serp_count": 7,
  "last_update": "2025-05",
  "checked_at": "2026-06-21T10:00:00+00:00",
  "error": null,
  "serp_overview": [
    {
      "position": 1,
      "title": "The Best SEO Tools of 2025",
      "url": "https://example.com/seo-tools",
      "domain_rating": 91,
      "url_rating": 52,
      "traffic": 48200,
      "keywords": 3100,
      "top_keyword": "seo tools",
      "top_volume": 110000
    }
  ]
}
````

```json
{
  "keyword": "keyword research",
  "country": "us",
  "keyword_difficulty": 91,
  "backlinks_to_rank": 835,
  "serp_count": 9,
  "error": null
}
```

### Input

```json
{
  "keywords": ["seo tools", "keyword research", "link building"],
  "country": "us",
  "maxItems": 0,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

| Parameter | Required | Default | Description |
|---|---|---|---|
| `keywords` | Yes | — | List of keywords to check. Also accepts a comma-separated string or `[{"keyword": "..."}]` objects |
| `country` | No | `"us"` | Two-letter country code for the keyword index |
| `maxItems` | No | `0` (no cap) | Optional hard cap on how many keywords to process in one run |
| `proxyConfiguration` | No | Apify RESIDENTIAL | Proxy settings. A residential exit is used by default; no external key needed |

### Pricing

This actor charges **$0.027 per keyword that returns a KD score** (charge event: `kd-result`).

- A keyword that fails to return data (e.g. not in the Ahrefs index, or a transient access issue) appears in your dataset with an `error` note — **it is never billed**
- That is roughly 10% under comparable keyword-difficulty checkers on the Apify Store
- Browser compute runs on your Apify account — our cost-of-goods is $0, and that saving goes to you

### FAQ

**Do I need an Ahrefs subscription or API key?**
No. This actor uses the Ahrefs free keyword difficulty tool — the same page any visitor can open in a browser. The actor navigates that page in a resilient stealth browser; the page handles its own security challenge and fires the data request itself. No Ahrefs account, no paid API access, and no external key of any kind is required from you.

**How many keywords can I run per batch, and how fast is it?**
The actor supports up to 5,000 keywords per run. Each keyword requires a full browser navigation to reliably reach the protected endpoint, which takes roughly 80–95 seconds. A 3,600-second run (the Apify default timeout) can therefore process around 35–40 keywords. For larger lists, split them across multiple runs, or increase the run timeout in the actor's run options. Completed rows are streamed to your dataset immediately, so you never lose work if a run ends early.

**Is the `serp_overview` data included at no extra charge?**
Yes. The full `serp_overview` array — with DR, UR, traffic, keyword count, top keyword, and top volume for every ranking page — is included in every billed `kd-result` event. There is no separate charge for the SERP data.

**How does this compare to other keyword difficulty checkers on the Store?**
Most alternatives return only the KD score, backlink count, and a timestamp. This actor adds the complete `serp_overview` array: nine fields per ranking page, letting you see not just how hard a keyword is to rank for, but exactly who you are competing against and how strong each competitor's page is. That extra data is useful for gap analysis, content briefs, and link-building targeting.

### Use cases

**SEO keyword research** — score a seed list before committing resources. A KD of 82 with 399 required backlinks signals a different content investment than a KD of 35 with 40.

**Content planning and editorial calendars** — combine KD with the `serp_overview` traffic numbers to prioritize keywords where the top-10 pages earn significant traffic. If page-1 incumbents have low traffic despite ranking, rethink the opportunity.

**Niche and site research** — feed competitor keyword lists into the actor to understand which of their ranking terms are genuinely defensible vs. winnable. The per-page DR/UR breakdown shows whether the top results are entrenched authority sites or thin pages you can outrank.

**Programmatic SEO audits** — integrate the dataset output into your pipeline to score hundreds of target pages' primary keywords, flag high-KD outliers, and update difficulty scores on a regular cadence without manual Ahrefs dashboard work.

**Link-building prioritization** — `backlinks_to_rank` gives you a concrete referring-domain target. Filter your keyword list to those where the gap is reachable within your link-building budget and focus outreach there first.

# Actor input Schema

## `keywords` (type: `array`):

Keywords to look up Ahrefs Keyword Difficulty for. One KD row is returned per keyword.

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

Two-letter country code for the keyword index (KD and SERP are country-specific). E.g. "us", "gb", "de".

## `maxItems` (type: `integer`):

Optional cap on how many keywords to process (0 = no cap).

## `proxyConfiguration` (type: `object`):

Proxy used to reach the target. A residential exit is recommended for reliable access; it defaults to Apify RESIDENTIAL.

## Actor input object example

```json
{
  "keywords": [
    "seo tools",
    "keyword research"
  ],
  "country": "us",
  "maxItems": 0,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `results` (type: `string`):

Dataset of Keyword Difficulty records, one per keyword.

# 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 = {
    "keywords": [
        "seo tools",
        "keyword research",
        "link building"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("bovi/ahrefs-keyword-difficulty-scraper").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 = { "keywords": [
        "seo tools",
        "keyword research",
        "link building",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("bovi/ahrefs-keyword-difficulty-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "keywords": [
    "seo tools",
    "keyword research",
    "link building"
  ]
}' |
apify call bovi/ahrefs-keyword-difficulty-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=bovi/ahrefs-keyword-difficulty-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Ahrefs Keyword Difficulty Checker — KD Score & SERP",
        "description": "Get Ahrefs Keyword Difficulty (KD 0-100) for any keyword in bulk, plus the backlinks-to-rank shortage and the full top-SERP overview (each result with Domain Rating, URL Rating, traffic & keywords). No Ahrefs login, no API key. Pay per keyword.",
        "version": "0.1",
        "x-build-id": "Tje5QzLXuDBVpGVto"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/bovi~ahrefs-keyword-difficulty-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-bovi-ahrefs-keyword-difficulty-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/bovi~ahrefs-keyword-difficulty-scraper/runs": {
            "post": {
                "operationId": "runs-sync-bovi-ahrefs-keyword-difficulty-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/bovi~ahrefs-keyword-difficulty-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-bovi-ahrefs-keyword-difficulty-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "keywords"
                ],
                "properties": {
                    "keywords": {
                        "title": "Keywords",
                        "type": "array",
                        "description": "Keywords to look up Ahrefs Keyword Difficulty for. One KD row is returned per keyword.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "country": {
                        "title": "Country",
                        "type": "string",
                        "description": "Two-letter country code for the keyword index (KD and SERP are country-specific). E.g. \"us\", \"gb\", \"de\".",
                        "default": "us"
                    },
                    "maxItems": {
                        "title": "Max keywords",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Optional cap on how many keywords to process (0 = no cap).",
                        "default": 0
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Proxy used to reach the target. A residential exit is recommended for reliable access; it defaults to Apify RESIDENTIAL.",
                        "default": {
                            "useApifyProxy": true,
                            "apifyProxyGroups": [
                                "RESIDENTIAL"
                            ]
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
