# Ahrefs SEO Scraper: Domain Rating, Traffic & AI Visibility (`nice_dev/ahrefs-seo-scraper`) Actor

Ahrefs website data without an account: Domain Rating, organic traffic, traffic value, keywords, top countries, competitors and monthly history since 2015, plus top websites by country and category and AI visibility leaderboards. Export to JSON, CSV or Excel.

- **URL**: https://apify.com/nice_dev/ahrefs-seo-scraper.md
- **Developed by:** [Nice Dev](https://apify.com/nice_dev) (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 $0.86 / 1,000 website with ahrefstop data

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/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 is Ahrefs SEO Scraper?

**Ahrefs SEO Scraper** extracts **Ahrefs website data from [AhrefsTop](https://ahrefstop.com) and [Ahrefs](https://ahrefs.com)**: **Domain Rating, organic search traffic, traffic value, organic keywords, top countries, top keywords, competitors and the monthly traffic history since 2015**, for any list of domains. It also gives the **top websites ranking** of 170 countries and 25 categories, the **AI visibility leaderboards** (the brands ChatGPT, Gemini, Perplexity, Copilot, Grok or Google AI Overviews mention most, and the websites they cite most), and the full list of the **about 200,000 websites AhrefsTop tracks**. It works as an **Ahrefs API alternative** with **no Ahrefs account, no API key and no subscription**: run it on a schedule, call it from your code, or plug it into Make, Zapier or n8n.

Type a few **domains** (`zapier.com`), pick a **country** for its top websites, or tick **AI leaderboards**, click **Start**, and download the rows in JSON, CSV or Excel. It is **fast: 1,000 top websites in under a minute, a full website page with its history in about 2 seconds**. A domain AhrefsTop does not track comes back marked as not found, and is **not billed**.

### 📋 What data can you extract from Ahrefs?

One row per website, per ranking entry or per AI leaderboard entry, 58 fields:

| Category | What you get |
| --- | --- |
| 🌐 **Website** | domain, name and tagline, description, category — `zapier.com`, `Computers & Electronics` |
| 🏅 **Authority** | Ahrefs Domain Rating (0-100) and referring domains (linking websites) with their monthly change — `91`, `87,196` |
| 🚦 **Organic traffic** | exact monthly organic search visits (not "3.6M"), change, last month, a year ago — `3,631,009` |
| 💵 **Traffic value** | what that traffic would cost in search ads per month, and its change — `5,253,565` |
| 🔑 **Keywords** | number of organic keywords, the 5 top keywords with search volume, traffic, Google position and changes — `chatgpt`, position `16` |
| 🌍 **Countries** | the 5 countries that bring most traffic, exact visits and share — `US`, 34.3 % |
| 🏆 **Ranks** | worldwide rank, rank in the main country, rank in the category, with their change — `Poland 50`, category rank `95` |
| 🥊 **Competitors** | competing websites with traffic and pages, the 5 websites ranked next to it; with the option, 10 competitors with Domain Rating, traffic value and ranks |
| 📅 **History** | organic traffic and traffic value per month since June 2015, referring domains per month since April 2015 — 137 months for `zapier.com` |
| 📊 **Top websites rankings** | country, category, list (ranking or trending), rank and rank change, rounded traffic — `youtube.com`, rank `1` |
| 🤖 **AI visibility** | platform, month, board (brands or cited websites), rank, name, link, number of AI answers — `Walmart`, `107,952` |
| 🕷️ **Crawl status** (option) | whether AhrefsBot may crawl the website, per host and port, and when Ahrefs last checked |

Every field, with an example, is listed in the **Output** section below.

A website row carries the full website data. A row of a top websites ranking carries what the ranking shows (rank, category, rounded traffic); tick **Full website data for each top website** to get the full data for each of them too.

### ✅ Why use Ahrefs SEO Scraper?

- 📈 **The widest website data**: exact traffic, traffic value, Domain Rating, 5 countries, 5 keywords, competitors, similarly ranked websites and the monthly history since 2015, in one row per website.
- 🌍 **Every website AhrefsTop tracks**: list the about 200,000 domains, keep only one ending (`.fr`, `.de`…), a Domain Rating range, a traffic floor or some categories — for link prospecting or market maps.
- 🏆 **Top websites by country and category**: 170 countries plus worldwide, 25 categories, the ranking and the month's biggest climbers and fallers.
- 🤖 **AI visibility leaderboards**: who ChatGPT, Gemini, Perplexity, Copilot, Grok, Claude, Google AI Overviews and Google AI Mode mention and cite most, for each of the last 12 months.
- 🔑 **No Ahrefs account, no API key**: nothing to sign up for, no monthly plan to keep.
- 🆓 **Pay only for data**: a domain AhrefsTop does not track is returned free, so you can paste a long list without checking it first.
- 🔔 **Monitoring built in**: tick **Only new rows**, schedule the Actor, and each run returns (and charges) only the rows it never delivered before.
- 🔌 API, scheduling, monitoring, integrations (Make, Zapier, n8n, Google Sheets…), proxy rotation and JSON/CSV/Excel export via the Apify platform.

### 🚀 How to scrape Ahrefs

1. Create a free Apify account.
2. Open **Ahrefs SEO Scraper** and type your **Domains**, one per line (e.g. `zapier.com`).
3. Or pick a **Top websites: country** and categories, tick **Every website AhrefsTop tracks**, choose **AI leaderboards: platforms** — or paste AhrefsTop pages into **AhrefsTop / Ahrefs URLs**. All of them can run together.
4. Set **Max rows** (1000 by default, 0 = no limit) — and **Max rows per list** when you read several rankings — then click **Start**.
5. Download the dataset in JSON, CSV, Excel or via API.

### 💰 How much does it cost to scrape Ahrefs?

This Actor uses **pay per event** pricing: you pay for each row delivered, by kind, plus a small fee per run start. Platform usage (compute, proxy) is included in the price. The current price of each event is shown in the **Pricing** tab.

| Event | When it is charged |
| --- | --- |
| `website` | a website row with data: a domain you asked for, a website of the tracked list, or a ranking row read in full with **Full website data** (one event, never two) |
| `top-website` | a row of a top websites ranking |
| `ai-leaderboard-row` | one entry (brand or cited website) of an AI leaderboard |
| `competitor-details` | paid option, off by default: each competitor delivered with its own metrics (up to 10 per website) |
| `crawl-status` | paid option, off by default: each website delivered with its AhrefsBot crawl status |

**Free rows**: a domain AhrefsTop does not track (`found: false`), and an AI leaderboard row of a platform Ahrefs does not publish on its own, or whose check could not be made (`platformPublished` not true) — they repeat the combined board. The monthly history is free too. Rows skipped by **Only new rows** are not charged, and **Domain endings** and **Exclude domains containing** remove domains before any page is read, at no cost.

The Domain Rating, traffic and category filters need the figure first: a row they drop costs a small filter fee instead of the row's price (`filter-check` for a ranking row, `detail-filter-check` when the website page had to be read) — filtering never costs more than taking everything.

### ⚙️ Input

A list of domains:

```json
{
    "domains": ["zapier.com", "semrush.com", "otodom.pl"]
}
```

Top websites of France, all websites and finance, ranking and trending lists, 50 rows per list:

```json
{
    "location": "france",
    "topWebsitesCategories": ["all", "finance"],
    "topWebsitesMode": "both",
    "maxItemsPerQuery": 50
}
```

Every French website AhrefsTop tracks with a Domain Rating of 50 or more:

```json
{
    "allTrackedDomains": true,
    "domainSuffixes": [".fr"],
    "minDomainRating": 50,
    "maxItems": 500
}
```

AI visibility leaderboards of ChatGPT and Perplexity for the last 3 months:

```json
{
    "aiPlatforms": ["chatgpt", "perplexity"],
    "aiMonths": 3,
    "aiLeaderboard": "both"
}
```

Or with pages pasted from your browser, and only the newcomers of a ranking at each run:

```json
{
    "startUrls": [
        { "url": "https://ahrefstop.com/websites/zapier.com" },
        { "url": "https://ahrefstop.com/websites/united-states/finance" }
    ],
    "onlyNew": true,
    "stateKey": "us-finance"
}
```

| Field | Notes |
| --- | --- |
| `domains` | Domains, one per line: `zapier.com`, `www.zapier.com` or a full URL (`https://zapier.com/apps`). A domain AhrefsTop does not track comes back as `found: false`, free. Up to 10,000 domains. |
| `startUrls` | AhrefsTop pages: a website page (`https://ahrefstop.com/websites/zapier.com`, also its `/competitors` page) or a ranking page (`https://ahrefstop.com/websites/united-states/finance`, `https://ahrefstop.com/websites/3`). Max 1,000 URLs. |
| `allTrackedDomains` | Read the full list of websites AhrefsTop tracks (about 200,000) and deliver one website row each, up to **Max rows**. |
| `domainSuffixes` | Keep only domains ending with one of these: `.fr`, `.co.uk`, `.de`. Applied before any page is read, to every domain of the run. |
| `location`, `locations` | Country of the top websites ranking (`worldwide`, `united-states`, `france`…); `locations` adds more. `worldwide` lists up to 1,000 websites, a country or a category up to 100. |
| `topWebsitesCategories` | Categories of the ranking: `all` (every website) or e.g. `finance`, `news`, `shopping`. Every country is crossed with every category and every list, one search each (max 500 searches per run). |
| `topWebsitesMode` | `ranking` (most organic traffic), `trending` (the 10 biggest climbers and 10 biggest fallers of the month: a country's categories all show the country's list, so it is read once per country; each worldwide category has its own) or `both`. |
| `enrichTopWebsites` | Also read the full website page of each website of the rankings: delivered and billed as a website row that keeps its rank. |
| `aiPlatforms` | AI leaderboards to read: `all`, `chatgpt`, `gemini`, `perplexity`, `copilot`, `grok`, `claude`, `google-ai-overviews`, `google-ai-mode` (US data). A platform Ahrefs does not publish on its own comes back with `platformPublished: false` (or null when that could not be checked), free. |
| `aiMonths` | How many months back from the latest one: `1` to `12`. |
| `aiLeaderboard` | `brands` (names AI assistants mention), `sources` (websites they cite) or `both`. |
| `maxItems`, `maxItemsPerQuery` | Rows for the whole run (`1000` by default, `0` = no limit); rows taken from each ranking, trending list, AI platform (all its months and boards together) and from the tracked list (`0` = the whole list). |
| `includeHistory`, `includeCompetitorDetails`, `includeCrawlStatus` | Monthly history arrays (free, on by default); competitor details (paid option, one more page per website); AhrefsBot crawl status (paid option, one more request per website). |
| `excludeKeywords` | Skip any domain whose name contains one of these words (case ignored), e.g. `casino`. Applied before any page is read. |
| `minDomainRating`, `maxDomainRating` | Domain Rating range, e.g. at least `50`. Top website rows without full website data have no Domain Rating and are kept. |
| `minOrganicTraffic` | Keep only websites with at least this many monthly organic visits, e.g. `10,000`. |
| `onlyCategories` | Keep only websites of these AhrefsTop categories, e.g. `finance`. |
| `onlyNew`, `stateKey`, `resetState` | Monitoring: only the rows never delivered under this memory key (e.g. `us-finance`); `resetState` forgets the memory. |
| Advanced | `proxyConfiguration` (Apify proxy by default, included in the price; the residential proxy is not available), `maxConcurrency`, `maxRequestsPerMinute`, `minRequestIntervalMs`, `maxRequestRetries`, `debugLog`. |

### 📦 Output

A real website row (`zapier.com`, both paid options off), with the long arrays shortened to their first entries:

```json
{
    "type": "website",
    "id": "zapier.com",
    "url": "https://ahrefstop.com/websites/zapier.com",
    "scrapedAt": "2026-10-16T05:23:19.844Z",
    "found": true,
    "error": null,
    "inputDomain": "zapier.com",
    "domain": "zapier.com",
    "dataMonth": "2026-10-01",
    "title": "Zapier: Automate your work",
    "description": "Zapier is an online automation platform that connects hundreds of web applications to automate repetitive tasks and workflows. It enables the creation of automated sequences called Zaps, where triggers in one app initiate actions in others, facilitating data movement and process automation across services such as email, messaging, project management, and cloud storage.",
    "category": "Computers & Electronics",
    "categorySlug": "computers-and-electronics",
    "globalRank": null,
    "globalRankLabel": ">1000",
    "globalRankChange": null,
    "countryRank": null,
    "countryRankChange": null,
    "countryRankCountry": null,
    "categoryRank": 95,
    "categoryRankChange": 18,
    "organicTraffic": 3631009,
    "organicTrafficChange": 285411,
    "organicTrafficPrevious": 3345598,
    "organicTrafficYearAgo": 4241549,
    "trafficValue": 5253565,
    "trafficValueChange": -178298,
    "organicKeywords": 819400,
    "domainRating": 91,
    "linkingWebsites": 87196,
    "linkingWebsitesChange": 980,
    "topCountry": "US",
    "topCountryShare": 0.343,
    "topCountries": [
        {
            "countryCode": "US",
            "country": "United States",
            "isoNumeric": "840",
            "organicTraffic": 1248760,
            "organicTrafficPrevious": 1337676,
            "organicTrafficChange": -88916,
            "share": 0.343
        }
    ],
    "topKeywordsCountry": "US",
    "topKeyword": "chatgpt",
    "topKeywords": [
        {
            "keyword": "chatgpt",
            "volume": 18900000,
            "volumeChange": -240000,
            "traffic": 121800,
            "trafficChange": 121700,
            "position": 16,
            "positionChange": 31
        }
    ],
    "competitors": [{ "domain": "wordstream.com", "organicTraffic": 608000, "organicTrafficChange": -57500, "pages": 1100 }],
    "similarlyRanked": [
        { "domain": "youtube.com", "organicTraffic": 3500000000, "organicTrafficChange": 1700000000, "rank": 1, "rankChange": 2 }
    ],
    "historyMonths": 137,
    "trafficHistory": [
        { "month": "2015-06-01", "organicTraffic": 65229, "trafficValue": 183323 },
        { "month": "2026-10-01", "organicTraffic": 3631009, "trafficValue": 5253565 }
    ],
    "linkingWebsitesHistory": [
        { "month": "2015-04-01", "linkingWebsites": 3813 },
        { "month": "2026-09-01", "linkingWebsites": 87196 }
    ],
    "competitorDetails": [],
    "crawlStatus": [],
    "crawlAllowed": null,
    "rankingCountry": null,
    "rankingCountrySlug": null,
    "rankingCategorySlug": null,
    "rankingList": null,
    "rank": null,
    "rankChange": null,
    "trendDirection": null,
    "platform": null,
    "platformPublished": null,
    "leaderboard": null,
    "label": null,
    "citedUrl": null,
    "value": null
}
```

A row of a ranking (`type` = `topWebsite`) fills the website, rank and ranking columns; an AI leaderboard row (`type` = `aiLeaderboard`) fills the platform, board, rank, label, link and value columns. Columns that do not apply to a row are `null` (or an empty array).

You can download the dataset in various formats such as JSON, HTML, CSV or Excel.

#### All 58 fields

| Fields | What you get |
| --- | --- |
| `type`, `id`, `url`, `scrapedAt` | `website`, `topWebsite` or `aiLeaderboard`; the row's id (`zapier.com`, `united-states/all/ranking/youtube.com`); the page it was read from; ISO timestamp |
| `found`, `error`, `inputDomain` | **Website**: `false` when AhrefsTop does not track the domain (row free, metrics null) and why; what you typed |
| `domain`, `dataMonth`, `title`, `description`, `category`, `categorySlug` | `zapier.com`, `2026-10-01` (month of the data), `Zapier: Automate your work`, AhrefsTop's description, `Computers & Electronics`, `computers-and-electronics` |
| `globalRank`, `globalRankLabel`, `globalRankChange` | **Ranks**: worldwide rank by organic traffic (`null` outside the top 1,000, then `>1000`), places won or lost |
| `countryRank`, `countryRankChange`, `countryRankCountry` | rank in the main country: `50`, `-4`, `Poland` for `otodom.pl` |
| `categoryRank`, `categoryRankChange` | rank in its category worldwide: `95`, `18` |
| `organicTraffic`, `organicTrafficChange`, `organicTrafficPrevious`, `organicTrafficYearAgo` | **Organic traffic**: `3631009` exact (rounded as shown on ranking rows), change, previous month, a year ago |
| `trafficValue`, `trafficValueChange` | **Traffic value** per month in search ads: `5253565`, `-178298` |
| `organicKeywords` | keywords the website ranks for, as rounded by AhrefsTop: `819400` |
| `domainRating`, `linkingWebsites`, `linkingWebsitesChange` | **Authority**: Domain Rating `91`, referring domains `87196`, change `980` |
| `topCountry`, `topCountryShare`, `topCountries` | **Countries**: `US`, `0.343`; the 5 countries with exact visits, previous month, change and share |
| `topKeywordsCountry`, `topKeyword`, `topKeywords` | **Keywords**: `US`, `chatgpt`; 5 keywords with volume, traffic, position and their changes |
| `competitors`, `similarlyRanked` | **Competitors**: websites ranking for the same keywords (traffic, change, pages); the 5 websites ranked next to it |
| `historyMonths`, `trafficHistory`, `linkingWebsitesHistory` | **History**: `137` months; traffic and traffic value per month since June 2015; referring domains per month since April 2015 |
| `competitorDetails` | **Competitor details** option: 10 competitors with description, Domain Rating, traffic, traffic value, pages and ranks |
| `crawlStatus`, `crawlAllowed` | **AhrefsBot crawl status** option: per host and port, allowed or not, Ahrefs' explanation and last check; `true` when allowed on the main host over HTTPS |
| `rankingCountry`, `rankingCountrySlug`, `rankingCategorySlug`, `rankingList` | **Top websites rankings**: `Worldwide`, `worldwide`, `all`, `ranking` or `trending` |
| `rank`, `rankChange`, `trendDirection` | position in the ranking or the AI board, places won or lost, `up` or `down` in a trending list |
| `platform`, `platformPublished`, `leaderboard` | **AI visibility**: `chatgpt`; `false` when the platform is not published on its own, `null` when unknown (both free); `brands` or `sources` |
| `label`, `citedUrl`, `value` | `Walmart` or `wikipedia.org`; link of a cited website; number of AI answers in the month: `107952` |

### 💡 Tips

#### How to get more results

Tick **Every website AhrefsTop tracks** and set `maxItems` to `0` to get every tracked website (about 200,000). The `worldwide` ranking goes to 1,000 websites; a country or a category ranking to 100, and some have fewer (a country's finance ranking can hold only a few websites). Add more countries in `locations` and more categories to read many rankings in one run.

#### How to reduce costs

The price is per row, so the levers are `maxItems`, `maxItemsPerQuery`, `domainSuffixes` and `excludeKeywords` (free: applied before any page is read), the Domain Rating, traffic and category filters (a dropped row costs only the filter fee, lower than a row) and `onlyNew` for recurring runs (you never pay twice for the same row). The two paid options stay off unless you need them. Turning `includeHistory` off makes rows lighter but does not change the price.

#### Several rankings in one run

Fill `locations`, `topWebsitesCategories` and `topWebsitesMode`: the Actor reads one ranking per country × category × list (3 countries × 4 categories × 2 lists = 24 rankings, up to 500 per run). The single `location` field still works and is added to the list. Set `maxItemsPerQuery` to give every ranking its own cap: without it the first rankings can use up the whole `maxItems` budget. You can also paste several ranking pages into `startUrls`.

#### Find link prospects in one country

Tick **Every website AhrefsTop tracks**, set **Domain endings** to `.de`, a Domain Rating range (`minDomainRating` 30, `maxDomainRating` 70 to skip the giants) and a traffic floor: you get the matching German websites with their traffic, Domain Rating, top keywords and competitors.

#### Monitoring: only the new rows

Tick **Only new rows** (`onlyNew`) and schedule the Actor. The first run returns everything; each later run skips the rows already delivered: they are not saved, not charged, and with **Full website data** their website page is not read again. On a ranking, a later run returns the newcomers to the ranking — or, with **Max rows per list** or **Max rows** below the size of the list, the next websites down the list. The memory lives in a named key-value store of your account (`ahrefs-seo-scraper-seen`, up to 150,000 rows per key) and is only updated with rows that really reached the dataset, so a failed run never hides anything. Give each schedule its own `stateKey` (two schedules sharing a key would hide each other's rows), and tick `resetState` once to start over.

### 🔌 Integrations and API

Call the Actor via the Apify API, the JavaScript or Python clients, or connect it with integrations and webhooks (Make, Zapier, n8n, Google Sheets, Slack, Airtable…). The dataset can be fetched as JSON or CSV from any tool.

### 🤖 Use with AI agents (MCP)

AI agents (Claude, ChatGPT, Cursor…) can find and run this Actor through the [Apify MCP server](https://mcp.apify.com), billed to their Apify account like any run. It returns one row per website, per top websites ranking entry or per AI leaderboard entry. Actor id: `nice_dev/ahrefs-seo-scraper`; MCP server with this Actor only: `https://mcp.apify.com/?tools=fetch-actor-details,nice_dev/ahrefs-seo-scraper`.

Smallest input, for a cheap first call:

```json
{
    "domains": ["zapier.com"],
    "maxItems": 10
}
```

Key output fields: `domain`, `domainRating`, `organicTraffic`, `trafficValue`, `organicKeywords`, `topCountries`, `topKeywords` and `trafficHistory`.

Cost: pay per event — one `website`, `top-website` or `ai-leaderboard-row` event per row plus a small fee per run start, domains not tracked free; see the pricing section above. Cap each call with `maxItems` and, through the API, with the run option `maxTotalChargeUsd`.

### ❓ FAQ

#### Is it legal to scrape Ahrefs?

The Actor only reads what AhrefsTop and Ahrefs show publicly to any anonymous visitor. It logs in to nothing and uses no Ahrefs account or API key. The data describes websites (traffic, links, rankings), not people; if a domain or a description names a person, that is personal data protected by GDPR: do not store it without a legitimate reason. You are responsible for using the data in compliance with Ahrefs' Terms of Use and applicable law. This Actor is not affiliated with Ahrefs.

#### Does it need a login or a proxy?

No login, no account, no API key. The proxy is included in the price: leave the default setting (the residential proxy is not available). A request the site turns away is retried at once on a new proxy session, up to 10 times on top of the retries (without a proxy, after a pause of 5 seconds, doubled at each retry up to 150 seconds).

#### Why are some figures rounded?

Website rows carry the exact figures (`3631009` visits, not "3.6M"). A row of a ranking carries the figures as the ranking prints them (`3500000000` for "3.5B"); tick **Full website data for each top website** for the exact ones. The number of organic keywords, the competitor figures and the keyword volumes are always rounded as AhrefsTop shows them.

#### Is the data safe to open in Excel or to show on a web page?

Names, taglines and descriptions are copied as AhrefsTop writes them. A text can begin with `-`, `+`, `=` or `@`: Excel and Google Sheets may read such a cell of a CSV file as a formula or as a number. The Actor leaves the text as it is, so that the JSON and the API give the real value: when you open a CSV, import these columns as text. On a web page, escape every field like any text written by a stranger.

#### Known limitations

- Only the about 200,000 websites AhrefsTop tracks have data. Any other domain comes back with `found: false` and every metric empty — free.
- A few small websites have an AhrefsTop page with links only: they come back with `found: true`, their referring domains and history, and no traffic or Domain Rating, and count as a website row.
- AI leaderboards are US data, 10 entries per board, for the last 12 months Ahrefs publishes.
- Keyword research, backlink lists and search results pages are not part of this Actor.
- `onlyNew` remembers rows, not their content: a website whose traffic changed is not returned again under the same key.
- `onlyNew` keeps 150,000 rows per memory key: for **Every website AhrefsTop tracks** (about 193,600), split the list with `domainSuffixes`, one `stateKey` each, or the oldest rows come back (the run warns you).
- A `found: false` row (free) is not remembered by `onlyNew`: the domain is looked up again on each run, and its row is delivered once AhrefsTop tracks it.
- Two runs sharing the same `stateKey` at the same time may both return the same new row.

**A run that reaches its timeout** stops itself about 45 seconds before it: no new page is asked, what it read is saved and, with `onlyNew`, remembered, and the run ends *Succeeded* with "Stopped before the run's timeout". Resurrect it to go on from there, or give the next run a longer timeout (Run options).

**A run the platform stops without warning** (out of memory)

- Resurrect it: it goes on from where it stood at most a minute before the stop. What it had read since is read again, and the rows already saved are skipped: none is delivered or charged twice, and `maxItems` still counts them.
- With `onlyNew`, the memory is saved after each write (at most once every 2 seconds): resurrect the stopped run and the rows it had saved meanwhile join the memory; leave it stopped for good, and the next run may return the rows of its last 2 seconds once more.

#### Something doesn't work?

The last line of the log counts the rows saved, the pages read and the requests that failed after every retry. Those requests are listed, with the reason, in the `FAILED_REQUESTS` record of the run's key-value store. A run that saved nothing and had failed requests fails, and its last message gives the cause.

If AhrefsTop changes its pages, you are told instead of paying for blank rows. If the first 20 rows read all lack their domain, month, traffic or rank — or, on a website page, its Domain Rating, referring domains, countries, keywords, competitors or history — the run saves nothing more, stops and fails, and its last message names the missing field: at most those first rows are charged. A website that a Domain Rating or traffic filter drops because its page has no such figure counts among those 20. A run of fewer rows (a scheduled `onlyNew` run that finds a few new ones, a small **Max rows**) is checked at its end, from 5 rows: its rows are already saved, and the run fails with the missing field instead of ending green.

### 🛟 Support

Open an issue in the **Issues** tab with a link to your run: the run log and the `FAILED_REQUESTS` record of the key-value store show exactly which URLs failed and why.

# Actor input Schema

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

Domains to analyse, one per line: `zapier.com`, `www.zapier.com` or a full URL (`https://zapier.com/apps`) — the domain is read. AhrefsTop publishes about 200,000 established websites; a domain it does not track comes back as `found: false` and is not billed. Up to 10,000 domains.

## `startUrls` (type: `array`):

Pages pasted from your browser: a website page (`https://ahrefstop.com/websites/zapier.com`, also `/competitors`, or `https://ahrefs.com/websites/zapier.com`) or a ranking page (`https://ahrefstop.com/websites/united-states/finance`, `https://ahrefstop.com/websites/3`). Added to the domains and rankings below. Max 1,000 URLs.

## `allTrackedDomains` (type: `boolean`):

Read the full list of websites AhrefsTop publishes (about 200,000 domains, from its sitemaps) and deliver one website row each, up to **Max rows**. Combine with **Domain endings** (e.g. `.fr`) and the filters below to get, for example, every French website with a Domain Rating of 50 or more.

## `domainSuffixes` (type: `array`):

Keep only domains that end with one of these (`.fr`, `.co.uk`, `.de`, `.io`…). Checked before any page is read, so it also saves cost. Applies to every domain of the run (your list, rankings, every tracked website). Empty = all.

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

Fill to get the AhrefsTop ranking of the most visited websites by organic search traffic (latest month): `Worldwide` lists up to 1,000 websites, a country or a category up to 100. Leave empty for domains only.

## `locations` (type: `array`):

More countries as AhrefsTop names them in its URLs (`united-states`, `france`, `germany`…, or `worldwide`), added to the country above. Each country is crossed with each category below, then with each list chosen: 500 rankings per run at most (countries × categories × lists).

## `topWebsitesCategories` (type: `array`):

Categories of the ranking (`all` = every website). Empty = `all`.

## `topWebsitesMode` (type: `string`):

`Ranking` = the websites with the most organic search traffic; `Trending` = the 10 biggest climbers and the 10 biggest fallers of the month (a country's categories show the country's list, read once; each worldwide category has its own); `Both` = the two lists.

## `enrichTopWebsites` (type: `boolean`):

Also read the full website page of every website found in the rankings (exact traffic, traffic value, Domain Rating, countries, keywords, history; one more page per website, delivered and billed as a website row that keeps its rank).

## `aiPlatforms` (type: `array`):

Fill to get the Ahrefs AI visibility leaderboards: the 10 brands AI assistants mention most and the 10 websites they cite most, per platform and month (US data). A platform Ahrefs does not publish separately comes back flagged `platformPublished: false` (it shows the combined board). Empty = no leaderboards.

## `aiMonths` (type: `integer`):

How many months back from the latest published month (Ahrefs publishes 12).

## `aiLeaderboard` (type: `string`):

`Brands` = names AI assistants mention; `Sources` = websites they cite; `Both`.

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

Maximum number of rows (websites + top websites + AI leaderboard rows) for the whole run. 0 = no limit.

## `maxItemsPerQuery` (type: `integer`):

Maximum number of rows taken from each country × category ranking (top first), each trending list, each AI platform (all its months and boards together) and the list of tracked websites (**Every website AhrefsTop tracks**). 0 = the whole list.

## `includeHistory` (type: `boolean`):

Keep the monthly history arrays (organic traffic and traffic value since June 2015, linking websites since April 2015). Free — off only to get lighter rows.

## `includeCompetitorDetails` (type: `boolean`):

Read the AhrefsTop competitors page of each website: 10 competing websites with description, Domain Rating, organic traffic, traffic value, pages and their worldwide, country and category ranks. One more page per website; billed per competitor delivered (up to 10 per website).

## `includeCrawlStatus` (type: `boolean`):

Ask Ahrefs whether its crawler (AhrefsBot) is allowed on each website, per host (with / without `www`) and port (443 / 80), with the date Ahrefs last checked the website's crawl rules. One more request per website; billed per website checked.

## `excludeKeywords` (type: `array`):

Skip any domain whose name contains one of these words (case-insensitive), e.g. `casino`, `porn`. Applied to every domain of the run.

## `minDomainRating` (type: `integer`):

Keep only websites whose Ahrefs Domain Rating (0-100) is at least this value. 0 = no filter. Read on the website page (top website rows without **Full website data** have no Domain Rating and are kept).

## `maxDomainRating` (type: `integer`):

Keep only websites whose Domain Rating is at most this value (link prospecting: skip the giants). 100 = no filter.

## `minOrganicTraffic` (type: `integer`):

Keep only websites with at least this many estimated organic search visits in the latest month (worldwide; for a top website row, the figure of its ranking). 0 = no filter.

## `onlyCategories` (type: `array`):

Keep only websites of these AhrefsTop categories (read on the website page or the ranking row). Empty = all.

## `onlyNew` (type: `boolean`):

Skip websites, top websites and AI leaderboard rows already delivered by a previous run with the same memory key (monitoring a ranking: only newcomers are delivered — with a row limit below the size of the list, the next rows down the list instead).

## `stateKey` (type: `string`):

Name of the memory used by **Only new rows**. Give each schedule / task its own key (e.g. `top-fr-finance`) so that they do not share their memory. Letters, digits, `-` and `_`.

## `resetState` (type: `boolean`):

Forget what previous runs delivered before this run starts.

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

Apify Proxy or your own proxies. Keep the default: it is included in the price. The residential Apify proxy is not available in this Actor.

## `maxConcurrency` (type: `integer`):

Pages read in parallel.

## `maxRequestsPerMinute` (type: `integer`):

Upper bound of the request rate.

## `minRequestIntervalMs` (type: `integer`):

Minimum delay in milliseconds between two requests.

## `maxRequestRetries` (type: `integer`):

Retries per request before it is marked as failed. Behind a proxy, a request the site turns away is also retried on a new proxy session up to 10 times without using up these retries.

## `debugLog` (type: `boolean`):

Verbose log.

## Actor input object example

```json
{
  "domains": [
    "zapier.com",
    "semrush.com",
    "otodom.pl"
  ],
  "startUrls": [],
  "allTrackedDomains": false,
  "domainSuffixes": [],
  "locations": [],
  "topWebsitesCategories": [
    "all"
  ],
  "topWebsitesMode": "ranking",
  "enrichTopWebsites": false,
  "aiPlatforms": [],
  "aiMonths": 1,
  "aiLeaderboard": "both",
  "maxItems": 1000,
  "maxItemsPerQuery": 0,
  "includeHistory": true,
  "includeCompetitorDetails": false,
  "includeCrawlStatus": false,
  "excludeKeywords": [],
  "minDomainRating": 0,
  "maxDomainRating": 100,
  "minOrganicTraffic": 0,
  "onlyCategories": [],
  "onlyNew": false,
  "stateKey": "default",
  "resetState": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "maxConcurrency": 8,
  "maxRequestsPerMinute": 600,
  "minRequestIntervalMs": 0,
  "maxRequestRetries": 5,
  "debugLog": false
}
```

# 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": [
        "zapier.com",
        "semrush.com",
        "otodom.pl"
    ],
    "topWebsitesCategories": [
        "all"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("nice_dev/ahrefs-seo-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 = {
    "domains": [
        "zapier.com",
        "semrush.com",
        "otodom.pl",
    ],
    "topWebsitesCategories": ["all"],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("nice_dev/ahrefs-seo-scraper").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": [
    "zapier.com",
    "semrush.com",
    "otodom.pl"
  ],
  "topWebsitesCategories": [
    "all"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call nice_dev/ahrefs-seo-scraper --silent --output-dataset

```

## MCP server setup

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

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/2Hml7NR646o3cQBUo/builds/yB9tI0vmSNQcSD5bY/openapi.json
