# Keyword Difficulty Checker — Ahrefs Alternative (`khadinakbar/ahrefs-keyword-difficulty-checker`) Actor

Check independent keyword difficulty scores for up to 100 exact keywords. Target a country and language, filter the 0–100 score range, sort your shortlist, and export structured results. Not Ahrefs proprietary KD.

- **URL**: https://apify.com/khadinakbar/ahrefs-keyword-difficulty-checker.md
- **Developed by:** [Khadin Akbar](https://apify.com/khadinakbar) (community)
- **Categories:** SEO tools
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $300.00 / 1,000 completed keyword difficulty batches

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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 Difficulty Checker — Ahrefs Alternative

Turn a list of up to 100 keywords into a ranked SEO shortlist. Get an independent 0–100 organic keyword difficulty score, filter by your chosen range, and export the matching keywords as JSON, CSV, or Excel through Apify.

**This is an independent alternative to the keyword-difficulty workflow. It is not affiliated with Ahrefs and does not return Ahrefs' proprietary KD score.** Scores from different tools use different methods and should not be treated as interchangeable.

### What you get

- Exact keyword checks, without adding unrelated keyword ideas.
- Country and language targeting with validated combinations.
- Inclusive minimum and maximum difficulty filters.
- Input order, easiest-first, or hardest-first sorting.
- A summary of available, unavailable, and filtered keywords, plus score-band counts.

No external account, login, cookies, or API key is required from the caller. Run the Actor using your Apify account.

### Quick start

```json
{
  "keywords": ["web scraping tools", "seo keyword research", "content planning"],
  "country": "us",
  "languageCode": "en",
  "minDifficulty": 0,
  "maxDifficulty": 40,
  "sortBy": "difficulty_asc"
}
```

The Actor checks the supplied keywords and exports available scores from 0 through 40, ordered from easiest to hardest. Repeated phrases are checked once after trimming, Unicode normalization and lowercasing. Empty input is rejected; keywords are never silently replaced with demonstration searches.

### Input

| Field | Default | Meaning |
|---|---|---|
| `keywords` | Required | 1–100 phrases, one per list entry, up to 80 characters each. No comma-separated entries. |
| `country` | `us` | A supported two-letter country code. Use the input dropdown. |
| `languageCode` | `en` | A supported language in the chosen country, such as `en`, `de`, `fr`, or `es`. |
| `minDifficulty` | `0` | Lowest score to export, inclusive. |
| `maxDifficulty` | `100` | Highest score to export, inclusive. |
| `sortBy` | `input` | `input`, `difficulty_asc`, or `difficulty_desc`. |

Country and language must be a supported pair. For example, use `de` with `de` for German-language searches in Germany. Unsupported combinations are rejected before a paid lookup. See the supported-market list included with the source package.

### Output

One dataset row represents one requested keyword with an available score that matches the range. This illustrative record describes the format; it is not a measured lookup:

```json
{
  "keyword": "web scraping tools",
  "country": "us",
  "languageCode": "en",
  "keywordDifficulty": 32,
  "difficultyBand": "30-49",
  "metric": "independent_organic_difficulty",
  "retrievedAt": "2026-11-02T00:00:00.000Z"
}
```

The four neutral score bands are `0-29`, `30-49`, `50-69`, and `70-100`. They group the scale for sorting and reporting; they do not guarantee ranking outcomes. A score of zero is valid. Missing scores are unavailable, never converted to zero.

Download dataset rows from the Apify Console or retrieve the default dataset through the Apify API. The key-value store also contains:

| Record | Contents |
|---|---|
| `OUTPUT` | Terminal outcome, counts, warnings, and acknowledged batch event. |
| `RUN_SUMMARY` | The same result plus execution identity and timestamps. |
| `RESULTS` | Matching rows, unavailable keywords, and score distribution; retained before export for recovery. |

`COMPLETE` means matching rows were exported. `PARTIAL` means some requested keywords had no available score. `VALID_EMPTY` means the lookup completed with no available scores or no matches for the range. Invalid input and allowance refusals are explained separately. Required service or upstream failure fails the run.

### Pricing

The Actor uses **Pay per event (PPE)**: **$0.30 per completed batch of 1–100 unique keywords**, plus Apify platform usage. Check the live Pricing tab for the current effective price before running.

A completed batch is charged once even if every keyword is unavailable or your filters exclude every score. Filtering does not reduce the lookup fee. Invalid input, an allowance refusal before dispatch, or a failed/unconfirmed research request has no custom batch fee. There is no custom startup or per-keyword event. Apify platform usage can still accrue on unsuccessful runs.

The completed-batch fee can apply if a subsequent export fails. In that case, review `RESULTS` and the terminal records. Uncertain requests, charges and exports are not retried automatically. Set a event spending limit that covers $0.30 plus your chosen allowance for platform usage; the event spending limit does not cap platform usage.

Free research is subject to shared caller and portfolio allowances. A refusal is reported before further research. Increasing an Actor input does not override those limits.

### Scope and limits

Use this for exact-keyword triage and a repeatable content shortlist. It does not provide backlink counts, referring domains needed to rank, search volume, CPC, live SERP results, historical trends or ranking predictions. Ahrefs remains a separate product with its own dataset, methodology, research interface and broader SEO features.

`retrievedAt` is the Actor's retrieval time, not a claim that the underlying search results were refreshed at that moment. Availability and scores can differ by market and language. Search intent and the actual ranking pages still need editorial review.

### When to use it

Use this Actor when you already have an exact keyword list and need difficulty-based triage. Avoid it when your decision requires Ahrefs proprietary scores, live ranking pages, backlink targets or search-volume forecasts. For discovering new phrases and broader keyword metrics, pair this Actor with [Keyword Metrics Explorer](https://apify.com/khadinakbar/ahrefs-keyword-explorer) instead.

For example, a content editor can paste a candidate list, choose a market, set `maxDifficulty` to 40 and sort easiest first. The editor reviews the exported shortlist and search intent before adding topics to the editorial calendar. Keeping the original list and market together makes the next content review repeatable.

### API and AI-agent workflow

An authorized caller can start the Actor through the Apify API. The following example uses your Apify token locally; it does not request a backend API key:

```bash
curl --request POST \
  'https://api.apify.com/v2/acts/khadinakbar~ahrefs-keyword-difficulty-checker/run-sync-get-dataset-items?maxTotalChargeUsd=0.35&timeout=120' \
  --header "Authorization: Bearer $APIFY_TOKEN" \
  --header 'Content-Type: application/json' \
  --data '{"keywords":["content planning"],"country":"us","languageCode":"en","maxDifficulty":40}'
```

A completed one-keyword batch and a completed 100-keyword batch each have a $0.30 custom event fee. For example, two completed batches that each return 100 rows cost $0.60 in custom fees. Add platform usage; smaller batches are not charged per keyword.

An AI agent can request: “Check these exact keywords for the US in English, export scores no higher than 40, and sort easiest first.” An integration should supply the corresponding input above, inspect the terminal outcome, and read the default dataset. A completed empty shortlist is useful evidence only when the summary says the research completed. Do not treat configuration or upstream failures as an empty content opportunity list, and do not repeat an uncertain charged request automatically. Hosted MCP discovery and client behavior have not yet been tested for this candidate.

> Check these exact keywords for the US in English, export scores no higher than 40, and sort easiest first. Read the run outcome and dataset, and report unavailable keywords separately.

### Recovery and troubleshooting

If the run reports `POLICY_LIMIT`, check its remaining spending limit and research allowance before starting another lookup. For a completed lookup with an export error, use the saved `RESULTS` record and the run ID to recover the shortlist. A configuration or upstream failure is a failed lookup rather than evidence that the keyword has a zero score. Request, billing and export checkpoints stop automatic repetition when a prior effect is uncertain.

### Builder's note

I designed this checker to keep missing metrics separate from zero scores. A missing score means there is no supported difficulty estimate for that keyword in the selected market; zero is a usable value at the bottom of the scale. The shortlist and summary preserve that distinction so a content plan does not accidentally prioritize unavailable keywords.

### Responsible use

Use keyword lists you are authorized to process. The Actor is independently developed and is not endorsed by Ahrefs. Avoid putting confidential terms in public tasks, datasets or support messages.

### Support

Use the Actor's Issues tab and include the Apify run ID and the expected behavior. Do not include secrets or sensitive keyword lists in a public issue.

# Actor input Schema

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

Enter 1–100 phrases, one per entry. Phrases are normalized and deduplicated. Maximum 80 characters per phrase; commas and control characters are rejected.

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

Select the search market. Pair it with a language available in that country.

## `languageCode` (type: `string`):

Select a language supported in the chosen country. Unsupported pairs fail before a paid lookup.

## `minDifficulty` (type: `integer`):

Lowest independent score to export, inclusive.

## `maxDifficulty` (type: `integer`):

Highest independent score to export, inclusive. A completed batch is charged even if this filter excludes every score.

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

Keep keyword input order or sort matching scores. Equal scores retain input order.

## Actor input object example

```json
{
  "keywords": [
    "web scraping tools",
    "seo keyword research",
    "content planning"
  ],
  "country": "us",
  "languageCode": "en",
  "minDifficulty": 0,
  "maxDifficulty": 100,
  "sortBy": "input"
}
```

# Actor output Schema

## `output` (type: `string`):

No description

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

No description

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

No description

## `recovery` (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 = {
    "keywords": [
        "web scraping tools",
        "seo keyword research",
        "content planning"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/ahrefs-keyword-difficulty-checker").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": [
        "web scraping tools",
        "seo keyword research",
        "content planning",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("khadinakbar/ahrefs-keyword-difficulty-checker").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 '{
  "keywords": [
    "web scraping tools",
    "seo keyword research",
    "content planning"
  ]
}' |
apify call khadinakbar/ahrefs-keyword-difficulty-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,khadinakbar/ahrefs-keyword-difficulty-checker"
        }
    }
}
```

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/g9rpHWQB0yGijnV02/builds/hUoXCkdQcChAPrgPp/openapi.json
