# Linkheft — Domain Authority Checker & Website Rank API (`cybermax/domain-authority`) Actor

Bulk domain authority checker from open web data: a 0–100 authority score, rank among 133M domains in the Common Crawl web graph, 4-month trend and referring subnets. Monitor mode returns only rank changes. No API key, $0.002 per ranked domain.

- **URL**: https://apify.com/cybermax/domain-authority.md
- **Developed by:** [CyberMax](https://apify.com/cybermax) (community)
- **Categories:** SEO tools, AI, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 domain rankeds

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

## Linkheft: bulk domain authority checker & website rank API (open data, no API key)

**Check the authority of any list of domains in seconds.** For each domain, Linkheft returns a **0–100
authority score**, its **rank among 133 million domains** in the Common Crawl web graph, a **tier** (top 100,
top 1,000 … top 10 million), a **4-month rank trend** (rising, falling, stable) and its **referring subnets**
(backlink diversity from the Majestic Million). It works for link-building prospects, lead lists, SEO audits
and AI agents that need to know whether a site is "big". It costs **$0.002 per ranked domain** ($2 per 1,000),
and domains that aren't ranked are free.

### Why Linkheft

- **Open data, not scraped SEO tools.** Most "domain authority" Actors log into or scrape Moz, Ahrefs or Semrush
  and charge ~$0.009–0.015 per domain, and they break when those sites change. Linkheft ranks domains with open,
  published data: the [Common Crawl](https://commoncrawl.org/web-graphs) host-level web graph (harmonic
  centrality and PageRank over 133,241,980 domains, release `cc-main-2026-jul-aug-sep`) and the
  Majestic Million (CC BY 3.0). The whole method is described below.
- **Fast and cheap enough for big lists.** Each lookup streams only the ~800 KB shards of a pre-built index that it
  needs. In real Apify runs, 12 domains took 1.3 s and **3,000 domains took 11 s**. That's 5–7× cheaper than the
  scraper Actors, and domains that aren't ranked cost nothing.
- **Trend, not just a number.** Every ranked domain is compared with the web graph from ~4 months earlier
  (`cc-main-2026-mar-apr-may`), so you can see which sites are climbing and which are fading.
- **Agent-ready records.** They're flat and stable, and you can pass in URLs, emails or subdomains
  (`https://www.stripe.com/pricing`, `jane@acme.co.uk`, `blog.hubspot.com`).

**Real example** (live run, 2026-09-23):

| Domain | Authority | Tier | Trend (4 mo) | Referring subnets |
|---|---|---|---|---|
| wordpress.org | 84 | top 100 | stable (−19%) | 198,879 |
| stripe.com | 78 | top 100 | stable (−1.6%) | 51,463 |
| openai.com | 76 | top 100 | stable (+14.3%) | 53,508 |
| hubspot.com | 70 | top 1,000 | stable (−19.5%) | 41,084 |
| anthropic.com | 66 | top 1,000 | stable (−16.1%) | 24,118 |
| notion.so | 64 | top 1,000 | stable (+4.6%) | 18,243 |
| acme.co.uk | 15 | top 10,000,000 | stable (+0.4%) | — |

### What you get (one record per unique domain)

| Field | Meaning |
|---|---|
| `domain` | The domain that was ranked (subdomains fall back to their main domain unless ranked on their own) |
| `status` | `ok` (ranked, charged), `unranked` (not in the top 10M or the Majestic Million, free) or `invalid` (free) |
| `authorityScore` | 0–100, log scale of the web-graph rank: rank 1 = 100, the last of 133M domains = 0. Top 100 ≈ 75+, top 10,000 ≈ 50, top 1M ≈ 26 |
| `tier` | `top 100`, `top 1,000`, `top 10,000`, `top 100,000`, `top 1,000,000`, `top 10,000,000` |
| `webGraphRank` / `topPercent` | Harmonic-centrality rank in the Common Crawl web graph, and that rank as a % of all domains |
| `trend` / `rankChangePct` | `rising` / `falling` when the rank moved 20%+ (change = (old − new) / max(old, new), so −100…+100%), else `stable`; `new-in-top-10m` if it wasn't in the top 10M ~4 months earlier |
| `referringSubnets` | Distinct IP subnets linking to the domain (Majestic), for top-1M domains |
| `commonCrawl` | `harmonicRank`, `pageRankRank`, `hosts` (subdomains seen), `prevHarmonicRank`, release names, total domains |
| `majestic` | `globalRank`, `refSubnets`, `refIps`, list date |

A `SUMMARY` record in the run's key-value store has counts and a top-25 leaderboard.

### Input

```json
{ "domains": ["stripe.com", "https://www.notion.so/product", "jane@acme.co.uk"], "sortBy": "score", "minAuthorityScore": 30 }
```

- `domains`: up to 100,000 domains, URLs or email addresses; duplicates are merged and charged once.
- `sortBy`: `input` (default) or `score` (highest first).
- `minAuthorityScore`: drop ranked domains below this score. Dropped domains aren't charged.
- `monitor` / `monitorKey`: only return what changed since the last run (see below).

**First try:** the prefilled input (`stripe.com`, `notion.so`, `hubspot.com`, `anthropic.com`) runs in about 10 s
including start-up and costs about $0.008.

### Ready-made inputs (first try in one click)

**No account yet?** See real results first on the free demo page: [a free checker page plus 117 SaaS/AI sites ranked](https://huggingface.co/spaces/shaw276/domain-authority-checker).

Paste one into the **JSON** tab of the input form (or send it to the API) and press **Start**. Each is sized so the first run is quick and cheap; you pay only for results (Apify's compute is included in the price).

| Preset | What you get | Cost |
|---|---|---|
| Authority of 4 sites | 0–100 score, global rank, tier, 4-month trend, referring subnets | $0.008 |
| Rank competitors (sorted) | the same, strongest first | $0.008 |
| Mixed input: emails, URLs, domains | each cleaned to its domain and ranked | $0.006 |

**Authority of 4 sites**

```json
{"domains": ["stripe.com", "notion.so", "hubspot.com", "anthropic.com"]}
```

**Rank competitors (sorted)**

```json
{"domains": ["asana.com", "trello.com", "monday.com", "clickup.com"], "sortBy": "score"}
```

**Mixed input: emails, URLs, domains**

```json
{"domains": ["jane@shopify.com", "https://www.wikipedia.org/", "github.com"]}
```

Same thing from a script (returns the results directly):

```bash
curl -s -X POST "https://api.apify.com/v2/acts/cybermax~domain-authority/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H 'content-type: application/json' -d '{"domains": ["stripe.com", "notion.so", "hubspot.com", "anthropic.com"]}'
```

### Output (real record)

```json
{
  "input": "stripe.com", "domain": "stripe.com", "status": "ok",
  "authorityScore": 78, "scoreBasis": "common-crawl-harmonic-rank", "tier": "top 100",
  "webGraphRank": 64, "topPercent": 0.000048, "trend": "stable", "rankChangePct": -1.6,
  "commonCrawl": { "harmonicRank": 64, "pageRankRank": 66, "hosts": 95, "prevHarmonicRank": 63,
    "release": "cc-main-2026-jul-aug-sep", "prevRelease": "cc-main-2026-mar-apr-may", "totalDomains": 133241980 },
  "majestic": { "globalRank": 140, "refSubnets": 51463, "refIps": 137486, "date": "2026-09-23" },
  "referringSubnets": 51463
}
```

### Monitor mode: only what changed

Set `"monitor": true` to watch a list (your backlink prospects, competitors, customer domains). Each run compares
every domain with the previous run of the same watchlist and returns **only domains that are new or changed**:
a different `authorityScore`, `tier`, `webGraphRank`, Majestic rank, or `status` (e.g. a small site entering the
ranked list). Unchanged domains are skipped and **not charged**. Check time, notes and release names are ignored.
Use `monitorKey` to keep several watchlists apart; state is kept in your account's named key-value store
`domain-authority-monitor`. The first run returns everything as `new`; counts are in the `SUMMARY` record under
`monitor`.

```json
{ "domains": ["stripe.com", "notion.so", "hubspot.com"], "monitor": true, "monitorKey": "competitors" }
```

A changed row is the normal record plus (shape only; values illustrative):

```json
{ "domain": "notion.so", "change": "changed", "changedFields": ["authorityScore", "webGraphRank"],
  "changes": { "authorityScore": { "from": 64, "to": 65 }, "webGraphRank": { "from": 1500, "to": 1400 } } }
```

### Pricing

- **$0.002 per ranked domain** (event `domain-ranked`), i.e. $2 per 1,000.
- Unranked, invalid and duplicate inputs are free. Set a maximum charge per run in Apify, and Linkheft
  stops cleanly when it's reached.

### FAQ

**Is this Moz Domain Authority?** No. Moz DA, Ahrefs DR and Semrush AS are proprietary. Linkheft is an open 0–100 score from the Common Crawl web graph and the Majestic Million, with the method published below, so you can explain every number. It answers the same question: how big and well linked is this site?

**How many domains can I check at once?** Up to 100,000 per run. A real run of 3,000 domains took 11 seconds.

**What does it cost compared with Moz/Ahrefs/Semrush scrapers?** $0.002 per ranked domain. The most-used scraper Actors for those tools charge $0.009–$0.015 per result (Apify Store, 24 Sep 2026), and unranked domains are free here.

**Do I need a Moz, Ahrefs or Semrush account or API key?** No. Everything comes from open data.

**Can I filter a prospect list by authority?** Yes: `minAuthorityScore` drops domains below a score, and dropped domains are not charged.

**Can an AI agent use it?** Yes, through Apify's MCP server (`https://mcp.apify.com/?tools=cybermax/domain-authority`), and it's in the official MCP Registry. Records are flat and stable.

### Run it on a schedule

The underlying open data changes about **monthly** (Majestic Million) and **quarterly** (a new Common Crawl
web graph), so a **weekly or monthly** schedule is enough; daily runs would mostly return nothing. Console →
**Schedules** → **Create new** → cron `0 8 * * 1` (Mondays 8:00) or `0 8 1 * *` (1st of the month) → **Add Actor**
→ pick Linkheft (or a saved task) with your list and `"monitor": true`. Or via the API:

```json
POST https://api.apify.com/v2/schedules?token=YOUR_TOKEN
{"name":"linkheft-weekly","cronExpression":"0 8 * * 1","timezone":"America/New_York","isEnabled":true,
 "actions":[{"type":"RUN_ACTOR","actorId":"cybermax/domain-authority",
   "runInput":{"body":"{\"domains\":[\"stripe.com\",\"notion.so\"],\"monitor\":true,\"monitorKey\":\"weekly\"}","contentType":"application/json"}}]}
```

With monitor mode scheduled runs are cheap: you only pay for domains whose score or rank moved. To get alerted,
open the Actor's **Integrations** tab and add an email, Slack or webhook notification on "Run succeeded".

### Integrations

**Make:** Apify app → "Run an Actor" (Actor `cybermax/domain-authority`, input `{"domains":["stripe.com","notion.so"]}`, run synchronously) → "Get dataset items".

**Zapier:** Apify app → "Run Actor" action with the input JSON, or the "Finished Actor Run" trigger to push scores into a sheet or CRM.

**n8n:** Apify node ("Run Actor and get dataset"), or an HTTP Request node:

```
POST https://api.apify.com/v2/acts/cybermax~domain-authority/run-sync-get-dataset-items?token=YOUR_TOKEN
{"domains": ["stripe.com", "notion.so"], "sortBy": "score"}
```

**Google Sheets:** Apify's Google Sheets integration, or pull the latest run into a cell:

```
=IMPORTDATA("https://api.apify.com/v2/acts/cybermax~domain-authority/runs/last/dataset/items?format=csv&token=YOUR_TOKEN")
```

**Python:**

```python
from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("cybermax/domain-authority").call(run_input={"domains": ["stripe.com", "notion.so"], "sortBy": "score"})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["domain"], item.get("authorityScore"), item.get("tier"))
```

**JavaScript:**

```js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('cybermax/domain-authority').call({ domains: ['stripe.com', 'notion.so'], sortBy: 'score' });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

**AI agents (MCP):** Linkheft is a tool on Apify's hosted MCP server,
`https://mcp.apify.com/?tools=cybermax/domain-authority` (header `Authorization: Bearer <your Apify token>`).
Claude Desktop / Cursor config:

```json
{ "mcpServers": { "linkheft": { "url": "https://mcp.apify.com/?tools=cybermax/domain-authority",
  "headers": { "Authorization": "Bearer YOUR_APIFY_TOKEN" } } } }
```

Example prompts: *"Which of these 200 link prospects are in the top 100,000 sites?"*, *"Is acme-widgets.com an
established site or a tiny one?"*, *"Rank these competitors by authority."*

### How the score works

1. The Common Crawl web graph ranks every domain it crawled by **harmonic centrality**: how close a domain is,
   in links, to all others. Big, well-linked sites rank near 1.
2. `authorityScore = round(100 × (1 − log10(rank) / log10(totalDomains)))`. That's all there is to it, so you
   can recompute it.
3. Domains that are in the Majestic Million but outside the web graph's top 10M get a score for rank
   10,000,001 (an upper bound) and `scoreBasis: "majestic-only …"`.

### When NOT to use Linkheft

- **You need Moz DA, Ahrefs DR or Semrush AS specifically.** These are proprietary metrics; Linkheft's score
  correlates with "how big and well-linked is this site", but it's a different, open number.
- **You need individual backlinks or anchor texts.** Linkheft ranks domains; it doesn't list links.
- **Tiny or brand-new sites.** Domains outside the top 10 million of the web graph and the Majestic Million
  come back `unranked` (free). That's an answer in itself (the site is very small), but not a score.
- **Page-level authority.** Scores are per domain, not per URL.

### Also from CyberMax

- [DomainDNA — tech stack, email security & domain age](https://apify.com/cybermax/domain-intel): what each domain runs on and how old it is.
- [Hollerdex — website emails, phones & socials](https://apify.com/cybermax/website-contacts): contacts for the domains worth reaching out to.
- [Keyfern — keyword ideas from 5 autocomplete engines](https://apify.com/cybermax/keyword-ideas): what their audience searches for.
- [Swellmeter — Google Trends verdicts](https://apify.com/cybermax/google-trends): whether those topics are rising.
- [SnapScout — website screenshot + page text](https://apify.com/cybermax/website-screenshot): see each prospect's homepage.

All tools: [Boardroom Buys](https://apify.com/cybermax/sec-insider-tracker) · [HireHeat](https://apify.com/cybermax/hiring-signals) · [Gripeline](https://apify.com/cybermax/app-reviews) · [HireHeat Jobs](https://apify.com/cybermax/career-site-jobs) · [Printwren](https://huggingface.co/spaces/shaw276/docs-pages-as-pdfs?soon=html-to-pdf) · [Logolark](https://huggingface.co/spaces/shaw276/saas-logos-brand-colors?soon=logo-finder)

### Data, license and attribution

- Common Crawl Web Graph, domain-level ranks (commoncrawl.org), used under the Common Crawl Terms of Use.
- Majestic Million by Majestic-12 Ltd, licensed [CC BY 3.0](https://creativecommons.org/licenses/by/3.0/).
- The pre-built index is also published free as a Hugging Face dataset:
  [Linkheft Open Domain Ranks](https://huggingface.co/datasets/shaw276/open-domain-ranks). It's refreshed when
  Common Crawl publishes a new web graph.

Not affiliated with Common Crawl, Majestic, Moz, Ahrefs or Semrush. No personal data is collected.

### Changelog

- 2026-09-23: Monitor mode (`monitor`, `monitorKey`: only domains whose score, rank, tier or status changed are returned and charged), schedule & integration recipes.

© 2026 CyberMax. All rights reserved.

# Actor input Schema

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

One per line, up to 100,000. Domains, full URLs or email addresses all work (https://www.stripe.com/pricing → stripe.com). Subdomains fall back to their main domain unless the web graph ranks them on their own (e.g. user.github.io).

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

Order of the output rows.

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

0–100. Drop ranked domains below this score (they are not charged). Handy for filtering link prospects or lead lists.

## `monitor` (type: `boolean`):

Watch this list over time. Each run compares every domain with the previous run of the same watchlist and returns (and charges) only domains that are new or whose authority score, tier, web-graph rank, Majestic rank or status (ranked/unranked) changed. Changed rows get `change`, `changedFields` and `changes` (from/to). Unchanged domains are skipped and not charged. The first run returns everything as `new`. The open data refreshes about monthly (Majestic Million) and quarterly (Common Crawl web graph), so a weekly or monthly schedule is enough.

## `monitorKey` (type: `string`):

Optional name for this watchlist's saved state, e.g. `link-prospects` or `competitors`, so several watchlists can be monitored separately and you can edit the list without losing history. Empty = derived from the domain list.

## Actor input object example

```json
{
  "domains": [
    "stripe.com",
    "notion.so",
    "hubspot.com",
    "anthropic.com"
  ],
  "sortBy": "input",
  "minAuthorityScore": 0,
  "monitor": false
}
```

# Actor output Schema

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

No description

## `summary` (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",
        "hubspot.com",
        "anthropic.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("cybermax/domain-authority").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",
        "hubspot.com",
        "anthropic.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("cybermax/domain-authority").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",
    "hubspot.com",
    "anthropic.com"
  ]
}' |
apify call cybermax/domain-authority --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,cybermax/domain-authority"
        }
    }
}
```

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/wzTdP713JZTD8DQCv/builds/u94Ws3fKRWadhwXpa/openapi.json
