# Semrush Scraper — Website Traffic, Authority & Backlinks (`lightmoon/website-traffic-checker`) Actor

Semrush scraper for a whole list of domains at once: monthly visits, engagement, authority score, global and country rank, backlinks and six months of history. From $1.35 per 1,000 domains. No account, no API key. Unofficial, not affiliated with Semrush.

- **URL**: https://apify.com/lightmoon/website-traffic-checker.md
- **Developed by:** [Stable](https://apify.com/lightmoon) (community)
- **Categories:** SEO tools, Marketing, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.35 / 1,000 domain with traffic 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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

> **Unofficial.** This Actor is not affiliated with, endorsed by or sponsored by Semrush. It reads only publicly available pages, does not log in and does not bypass any access control. All product names and trademarks belong to their respective owners.

### How much traffic does a website get — for a list of domains, in one run

Paste domains. Get monthly visits, engagement, authority score, global and
country rank, organic and paid search traffic, backlinks and six months of
history — as CSV, Excel or JSON. No account, no API key.

**58% of domains on a real list come back with a current traffic estimate.** That
number is measured, it is printed here on purpose, and the rows that fall in the
other 42% are charged at half rate. More on both below — no competitor in this
niche states a coverage figure at all.

#### One row, from a real run

`ozon.ru`, read on 27 August 2026. Complete except the history, trimmed from six
months to two.

```json
{
  "domain": "ozon.ru",
  "brandName": "OZON",
  "visits": 230937460,
  "hasTrafficEstimate": true,
  "visitsChangePercent": -9.66,
  "latestMonth": "2026-07-01",
  "authorityScore": 91,
  "globalRank": 144,
  "countryRank": 6,
  "countryRankCountry": "Russian Federation",
  "categoryRank": 11,
  "categoryRankName": "Retail",
  "pagesPerVisit": 8.3977,
  "avgVisitDurationSeconds": 700,
  "bounceRatePercent": 36.43,
  "organicSearchTraffic": 37765932,
  "organicSearchTrafficChangePercent": -4.1,
  "paidSearchTraffic": 2041,
  "backlinks": 90028488,
  "referringDomains": 103921,
  "googlePenaltyRisk": "Low",
  "mainCountry": "RU",
  "category": "Retail",
  "dataDate": "2026-07-15",
  "updatedAt": "2026-08-12",
  "scrapedAt": "2026-08-27T14:21:52+00:00",
  "monthlyVisits": [
    { "month": "2026-07-01", "visits": 230937460, "desktopVisits": 130613928, "mobileVisits": 100323532 },
    { "month": "2026-06-01", "visits": 255631047, "desktopVisits": 136689443, "mobileVisits": 118941604 }
  ]
}
```

### Coverage, stated as a number

These are **modelled estimates**, not analytics from inside the site, and not
every domain has been modelled. Measured over 60 domains in two samples:

| | |
|---|---|
| domains that had a page at all | **82%** |
| of those, carrying a **current** traffic estimate | **58%** on a list of ordinary mid-size companies |
| the same figure on a list of household-name brands | 81% |

The lower number is the one printed here, because a real buyer's list looks like
the first sample, not the second.

**A domain with no current estimate is not dropped and not hidden.** It comes
back with `hasTrafficEstimate: false`, `visits: null`, and everything else it
does have — authority score, ranks, backlinks, organic traffic and the newest
month that *does* carry a figure. It is billed at half rate. A domain with no
page at all is named in the run summary and **costs nothing**.

### Fields

**34 per domain**, counted, plus four more on each month of history.

| | |
|---|---|
| identity | `domain`, `semrushDomain`, `brandName`, `url` |
| traffic | `visits`, `hasTrafficEstimate`, `visitsChangePercent`, `latestMonth`, `latestMonthVisits` |
| standing | `authorityScore`, `globalRank`, `countryRank`, `countryRankCountry`, `categoryRank`, `categoryRankName` |
| engagement | `pagesPerVisit`, `avgVisitDurationSeconds`, `bounceRatePercent` |
| search | `organicSearchTraffic`, `organicSearchTrafficChangePercent`, `paidSearchTraffic`, `paidSearchTrafficChangePercent` |
| links | `backlinks`, `backlinksChangePercent`, `referringDomains`, `referringDomainsChangePercent` |
| classification | `googlePenaltyRisk`, `mainCountry`, `category`, `categories` |
| freshness | `dataDate`, `updatedAt`, `scrapedAt` |
| history | `monthlyVisits` — **`month`, `visits`, `desktopVisits`, `mobileVisits`** per month |

Optional blocks, off by default so you are not charged for data you did not ask
for: monthly history, top countries, top keywords, competitors.

### Speed and behaviour under failure

- **One request per domain.** Ten domains in about 35 seconds.
- **A domain that fails does not stop the run.** It is recorded with the reason
  and the run continues to the next one.
- **Every run writes a summary** next to the dataset: how many domains went in,
  how many carried a traffic estimate, which ones had no page, which filter
  dropped how many.

### What it costs

Pay per event, and there are two — because 42% of rows are not the thing you
asked for, and charging full rate for them would be dishonest.

| event | what it is | GOLD per 1,000 |
|---|---|---|
| **Domain with traffic data** | a current monthly visits estimate, plus everything else | **$1.35** |
| **Domain found** | the page existed but has no current estimate: authority, ranks, links, organic traffic, last dated month | **$0.68** |

**Never charged:** a domain with no page at all, and a domain removed by one of
your filters.

- 500 domains, at the measured 58/42 split: about **$0.53**.
- 5,000 domains: about **$5.35**.
- Apify's $5 of monthly free credit: about **2,000 domains**.

No add-on tier, no per-field upcharge, no separate event for history, keywords
or competitors. One rate for a full row, half for a partial one.

### Limits

- **These are estimates.** They are modelled from third-party panels and
  clickstream, not measured on the site. Treat them as comparable between
  domains, not as the site's own analytics.
- **58% coverage on an ordinary list**, as above.
- **The figures lag.** Each row carries `dataDate` and `updatedAt` so you can
  see exactly how old the number is rather than guessing.
- **Small and new domains are the ones most often missing** — the model needs
  volume before it publishes a figure.
- **On the free plan** everything works at the FREE rate until Apify's monthly
  platform credit runs out; the run then stops cleanly and keeps what it has.

# Actor input Schema

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

One website per line. Paste them any way you have them — `stripe.com`, `https://www.stripe.com/pricing` and `sales@stripe.com` all mean the same site and are read as one row. Subdomains such as `blog.stripe.com` are treated as separate sites, because they have separate traffic.

## `maxDomains` (type: `integer`):

Stop after this many rows. 0 means no limit.

## `includeMonthlyHistory` (type: `boolean`):

Add a month-by-month visit history, each month split into desktop and mobile. Off by default so a lead list stays one flat line per site.

## `monthsOfHistory` (type: `integer`):

How many months to keep when the history is on.

## `includeTopCountries` (type: `boolean`):

Add the countries the visits come from, with each country's share and its own desktop/mobile split.

## `countriesPerDomain` (type: `integer`):

How many countries to keep per website when traffic by country is on.

## `includeTopKeywords` (type: `boolean`):

Add the search terms the site ranks for, with its position, the monthly search volume and the cost per click advertisers pay for that term.

## `keywordsPerDomain` (type: `integer`):

How many keywords to keep per website when top organic keywords is on.

## `includeCompetitors` (type: `boolean`):

Add the sites with the most overlapping audience, each with a relevance score.

## `competitorsPerDomain` (type: `integer`):

How many competitors to keep per website when closest competitors is on.

## `includeTrafficSources` (type: `boolean`):

Add the sites sending traffic in, and the sites visitors go to after leaving. The second half is how you spot a partner, a payment provider or a competitor catching the exit.

## `includeAiTraffic` (type: `boolean`):

Add visits arriving from AI assistants, named platform by platform with each one's share.

## `onlyWithTrafficEstimate` (type: `boolean`):

Skip sites whose most recent month has not been published yet. Off by default: those rows still carry the authority score, the ranks, the backlinks and the last month that does have a figure.

## `minVisits` (type: `integer`):

0 means no minimum.

## `maxVisits` (type: `integer`):

0 means no maximum. Useful for finding sites small enough to be worth approaching.

## `minAuthorityScore` (type: `integer`):

0 to 100. 0 means no minimum.

## `maxAuthorityScore` (type: `integer`):

0 means no maximum.

## `countries` (type: `array`):

Two-letter country codes, matched against the site's main audience country. Leave empty to keep all.

## `categories` (type: `array`):

Words matched against the site's categories, for example `finance` or `retail`. Leave empty to keep all.

## Actor input object example

```json
{
  "domains": [
    "stripe.com"
  ],
  "maxDomains": 100,
  "includeMonthlyHistory": false,
  "monthsOfHistory": 6,
  "includeTopCountries": false,
  "countriesPerDomain": 5,
  "includeTopKeywords": false,
  "keywordsPerDomain": 5,
  "includeCompetitors": false,
  "competitorsPerDomain": 5,
  "includeTrafficSources": false,
  "includeAiTraffic": false,
  "onlyWithTrafficEstimate": false,
  "minVisits": 0,
  "maxVisits": 0,
  "minAuthorityScore": 0,
  "maxAuthorityScore": 0,
  "countries": [
    "US",
    "DE"
  ],
  "categories": [
    "finance"
  ]
}
```

# Actor output Schema

## `traffic` (type: `string`):

No description

## `authority` (type: `string`):

No description

## `engagement` (type: `string`):

No description

## `audience` (type: `string`):

No description

## `all` (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": [
        "stripe.com",
        "notion.so",
        "figma.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("lightmoon/website-traffic-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 = { "domains": [
        "stripe.com",
        "notion.so",
        "figma.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("lightmoon/website-traffic-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 '{
  "domains": [
    "stripe.com",
    "notion.so",
    "figma.com"
  ]
}' |
apify call lightmoon/website-traffic-checker --silent --output-dataset

```

## MCP server setup

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