# Website Traffic Checker: Bulk Traffic History & Trends (`automa-flow/website-traffic-history-checker`) Actor

Check website traffic history for up to 10,000 domains per run: monthly organic search traffic since 2015 from public website profiles plus the Chrome popularity tier, with month-over-month, year-over-year, 6-month trend and peak. $0.003 per domain with history.

- **URL**: https://apify.com/automa-flow/website-traffic-history-checker.md
- **Developed by:** [Vadim Bezrukov](https://apify.com/automa-flow) (community)
- **Categories:** SEO tools, Lead generation, 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 domain with traffic histories

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

## Website Traffic Checker: Bulk Traffic History & Trends

Paste a list of websites and get each one's **monthly organic search traffic since 2015**, with month-over-month and year-over-year change, a 6-month trend, the peak month, the top countries and its rank in your list, plus the site's **Chrome popularity tier** (top 1K ... top 1M) for every year since 2021. One run checks up to 10,000 domains, from a pasted list or another Actor's Dataset.

Built for three jobs:

- **SEO agencies and analysts** comparing the same competitor set every month.
- **Website buyers** checking a site's traffic trend before an acquisition.
- **Sales teams** sorting a lead list by website size and growth.

> **What the numbers mean.** `traffic` is estimated monthly organic search traffic from the public website profiles on AhrefsTop: what a site gets from its Google rankings, **not total visits**. `cruxTier` comes from the Chrome UX Report top lists: the site's place among the most visited sites in Chrome, all channels included, in tiers (top 1,000, 5,000, 10,000, 50,000, 100,000, 500,000, 1 million). Use both to compare sites and see trends, not to match someone's analytics account.

### Quick start: 5 domains, 24 months

```json
{
  "targets": ["semrush.com", "ahrefs.com", "moz.com", "backlinko.com", "zapier.com"],
  "months": 24
}
```

Each domain becomes one row. This is moz.com from 2026-11-01, shortened to two of its 24 months:

```json
{
  "domain": "moz.com",
  "status": "OK",
  "latestMonth": "2026-10",
  "trafficLatest": 944502,
  "trafficValueLatest": 2142268,
  "momPct": -4.1,
  "yoyPct": -17.9,
  "trend6m": "flat",
  "peakMonth": "2025-06",
  "peakTraffic": 1951844,
  "months": [
    { "month": "2024-11", "traffic": 1181705, "trafficValue": 2466179 },
    { "month": "2026-10", "traffic": 944502, "trafficValue": 2142268 }
  ],
  "topCountries": [
    { "country": "US", "traffic": 662236, "share": 0.701 },
    { "country": "IN", "traffic": 81559, "share": 0.086 }
  ],
  "cruxTier": 500000,
  "cruxMonth": "2026-09",
  "cruxTier24mAgo": 100000,
  "cruxTrend": "down"
}
```

`trafficValue` is what that traffic would cost as Google Ads clicks, in US dollars. Open the **Traffic by domain** view for the table, or switch **Output rows** to `long` for one row per domain and month, ready for Google Sheets and charts.

### What it costs

| Event | Price | When |
| --- | --- | --- |
| Domain with traffic history | **$0.003** | per domain with a monthly traffic series (`OK`) |
| Domain with Chrome tier only | $0.0005 | per domain without a public profile that still has a Chrome tier (`TIER_ONLY`) |

Never charged: `NO_DATA`, `INVALID_TARGET`, `SOURCE_FAILED`, `CHARGE_LIMIT`. No run fee; platform usage is included. It works on the Apify free plan too.

| Run | You pay |
| --- | --- |
| 5 well-known sites | $0.015 |
| 100 domains, 61 with history and 22 with a tier only | $0.194 |
| 1,000 domains with history | $3.00 |

Set **Maximum cost per run** to bound the bill. When it is reached, the run stops reading new profiles, keeps every delivered row, marks the rest `CHARGE_LIMIT` and still succeeds.

### Coverage: what we measured

On 2026-11-01 we checked a fixed set of 100 domains (40 large sites, 40 mid-size SEO and content sites, 20 small business sites):

| Group | Domains | Monthly traffic, 12 months or more | Chrome tier | Either |
| --- | ---: | ---: | ---: | ---: |
| Large, well-known sites | 40 | 38 | 36 | 38 |
| Mid-size SEO and content sites | 40 | 23 | 30 | 33 |
| Small business sites | 20 | 0 | 12 | 12 |
| Total | 100 | 61 | 78 | 83 |

Traffic profiles exist for sites in AhrefsTop's list of top websites; smaller sites get a Chrome tier when they are among Chrome's top million, and `NO_DATA` (free) otherwise. Tiers do move: 39% of the domains changed tier between September 2024 and September 2026, and mid-size SEO publishers fell the most (moz.com, searchenginejournal.com and neilpatel.com from the top 100,000 to the top 500,000).

### How it compares

| | Traffic scrapers based on Similarweb pages | This Actor |
| --- | --- | --- |
| History | last 3 months of visits | monthly search traffic since 2015, Chrome tier yearly since 2021 |
| Metric | total visits (all channels) | organic search traffic and its $ value; Chrome popularity tier |
| Batch size | varies | up to 10,000 domains per run |
| Small sites | often zero or missing | a Chrome tier for sites in Chrome's top million |
| Failed lookups | depends on the listing | never charged |

Need total visits for the last few months rather than a multi-year trend? A Similarweb-based scraper is the better fit.

### More inputs

#### Read domains from another Actor's Dataset

Run it after a lead scraper or any Actor that writes websites into a Dataset:

```json
{
  "datasetId": "YOUR_DATASET_ID",
  "targetField": "domain",
  "months": 12
}
```

With the default `domain` column, rows without it fall back to `website`, then `url`. Dot paths such as `company.website` work too. In an Apify integration set `datasetId` to `{{resource.defaultDatasetId}}`; the run gets read access to that Dataset only. A run reads up to 10,000 rows, and `RUN_SUMMARY.nextDatasetOffset` says where the next run should start.

#### A fixed period

Set `dateFrom` and `dateTo` (`yyyy-mm`, from `2015-01`) instead of `months`. Empty `dateTo` means the last finished month.

#### Traffic only

Set `includeTier` to `false` to skip the Chrome lists; the run is about 20 seconds faster, and sites without a traffic profile become `NO_DATA`.

### Run it every month

The natural repeat is the same list once a month: save it as a Task and add an Apify schedule such as `0 6 3 * *` (06:00 UTC on the 3rd). Each run adds the newest month next to the old ones. Profiles read in the last 7 days come from your account's cache: same rows and price, faster.

### Output and statuses

Every input gets a row; duplicates are checked once.

| Status | Meaning | Charged |
| --- | --- | --- |
| `OK` | a monthly traffic series with at least one month of 1 visit or more | $0.003 |
| `TIER_ONLY` | no public traffic profile, but a Chrome popularity tier | $0.0005 |
| `NO_DATA` | neither source knows the site | no |
| `INVALID_TARGET` | not a public domain after removing scheme, path and `www.` | no |
| `SOURCE_FAILED` | a source refused or failed after 3 attempts, or its pages changed shape or moved | no |
| `CHARGE_LIMIT` | your maximum cost per run was reached first | no |

Main columns: `domain` (normalized host, subdomains kept), `input`, `latestMonth`, `trafficLatest`, `trafficValueLatest`, `momPct`, `yoyPct` (needs 13 months), `trend6m` (`up`, `flat`, `down`), `peakMonth`, `peakTraffic`, `firstMonthWithData`, `rankInSet` (by latest traffic in this run), `months`, `topCountries`, `cruxTier`, `cruxTier24mAgo`, `cruxTrend`, `cruxHistory`, `fromCache`, `checkedAt`, `sources`, `error`, `fingerprint`.

The run ends **FAILED** only when no domain could be answered for a source-side reason, or when the input has no domain at all; nothing is charged then. `RUN_SUMMARY` in the Key-Value Store has the counts per status, cache hits, profile requests, the Chrome list months read and the charged events.

### Use with AI agents through Apify MCP

Add this Actor to an MCP client such as Claude or Cursor:

```text
https://mcp.apify.com?tools=automa-flow/website-traffic-history-checker
```

Example prompt:

```text
Run automa-flow/website-traffic-history-checker for these competitor domains with
months 24. Sort them by trafficLatest, show yoyPct, trend6m and cruxTrend, and
list TIER_ONLY and NO_DATA domains separately. Keep maxTotalChargeUsd at 1.
```

An agent can predict the bill before the run: at most $0.003 per domain.

### Sources and limitations

- Traffic: public website profiles on [AhrefsTop](https://ahrefstop.com), read once per domain at a polite pace (at most 5 requests a second). This Actor is not affiliated with Ahrefs.
- Tiers: [Chrome UX Report](https://developer.chrome.com/docs/crux) top lists as published monthly in [zakird/crux-top-lists](https://github.com/zakird/crux-top-lists).
- Traffic is search traffic, not visits; a site that lives on direct, social or email traffic looks smaller than it is. Tiers are coarse.
- Only sites in AhrefsTop's list have traffic; very small sites can be `TIER_ONLY` or `NO_DATA`.
- Either source can change or refuse requests. The Actor then reports `SOURCE_FAILED` and charges nothing; it never fills in numbers.

### Release history

See the [changelog](CHANGELOG.md).

# Changelog

This Actor's version history is a separate document: https://apify.com/automa-flow/website-traffic-history-checker/changelog.md

# Actor input Schema

## `targets` (type: `array`):

Websites to check, one per line: example.com, https://www.example.com/page or blog.example.com. Scheme, path and www. are removed, subdomains are kept, duplicates are checked once. Up to 10,000 per run.

## `datasetId` (type: `string`):

Read the domains from an Apify Dataset instead, for example a lead list from another Actor. The run gets read access to this Dataset only. In an integration, set it to {{resource.defaultDatasetId}}.

## `targetField` (type: `string`):

Column that holds the website. With the default domain, rows without it fall back to website and then url. Dot paths such as company.website work.

## `datasetOffset` (type: `integer`):

Rows to skip before the first one read. A run reads up to 10,000 rows; RUN_SUMMARY.nextDatasetOffset says where the next run starts.

## `months` (type: `integer`):

How many recent months to return, newest last. Public history starts in 2015, so a longer request returns what exists. Ignored when Date from is set.

## `dateFrom` (type: `string`):

Optional first month, 2015-01 or later. Overrides Months of history.

## `dateTo` (type: `string`):

Optional last month. Empty means the last finished month.

## `includeTier` (type: `boolean`):

Adds the site's Chrome UX Report tier (top 1K ... 1M sites) for the latest month and once a year back to 2021. Sites without a public traffic profile then still get a TIER_ONLY row. Adds about 20 seconds per run.

## `outputFormat` (type: `string`):

wide: one row per domain with a months array and trend columns. long: one row per domain and month, ready for Google Sheets and charts.

## `useCache` (type: `boolean`):

Domains this account already checked in the last 7 days come from its cache: same data and price, faster, and the profile site is not asked again.

## Actor input object example

```json
{
  "targets": [
    "semrush.com",
    "ahrefs.com",
    "moz.com",
    "backlinko.com",
    "zapier.com"
  ],
  "targetField": "domain",
  "datasetOffset": 0,
  "months": 24,
  "includeTier": true,
  "outputFormat": "wide",
  "useCache": true
}
```

# Actor output Schema

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

No description

## `monthly` (type: `string`):

No description

## `runSummary` (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 = {
    "targets": [
        "semrush.com",
        "ahrefs.com",
        "moz.com",
        "backlinko.com",
        "zapier.com"
    ],
    "months": 24
};

// Run the Actor and wait for it to finish
const run = await client.actor("automa-flow/website-traffic-history-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 = {
    "targets": [
        "semrush.com",
        "ahrefs.com",
        "moz.com",
        "backlinko.com",
        "zapier.com",
    ],
    "months": 24,
}

# Run the Actor and wait for it to finish
run = client.actor("automa-flow/website-traffic-history-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 '{
  "targets": [
    "semrush.com",
    "ahrefs.com",
    "moz.com",
    "backlinko.com",
    "zapier.com"
  ],
  "months": 24
}' |
apify call automa-flow/website-traffic-history-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automa-flow/website-traffic-history-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/P8yrwuRXZM9NlJ6q7/builds/hG12AICyYdV4rRxcM/openapi.json
