# Backlink Checker - Referring Domains & Link Gap, Open Data (`tidytools/backlink-gap`) Actor

Referring domains of any website, strongest first, with authority score and Chrome traffic rank, plus a competitor link gap: sites linking to your competitors but not to you. Common Crawl web graph, no Ahrefs login. $1.50 per 1,000 referring domains.

- **URL**: https://apify.com/tidytools/backlink-gap.md
- **Developed by:** [Yukai Lin](https://apify.com/tidytools) (community)
- **Categories:** SEO tools, Marketing, Lead generation
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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 does Backlink Checker (Referring Domains & Link Gap) do?

**Give it domains, get the websites that link to them** (authority score and Chrome traffic rank for each): **$1.50 per 1,000 referring domains**. **Give it your site and 1-10 competitors, get the sites that link to them but not to you**: **$3.00 per 1,000 link prospects**. Domains the web graph does not know, duplicates, invalid lines and empty results are free; there is no start fee. Data: the open Common Crawl web graph (domain level, July-September 2026), not Ahrefs or Semrush. Jump to [How to use it](#how-to-use-it).

Two jobs, in bulk and in seconds, for **any website on the web**:

1. **Referring domains**: the websites that link to a domain, **strongest first**, each with a **0-100 authority score** and its **Chrome traffic rank** (Top 1K ... Top 1M websites by real visitors).
2. **Link gap** ("link intersect"): enter your website and up to 10 competitors and get the **websites that link to your competitors but not to you**, ranked by how many competitors they link to, then by authority. These are your link-building and PR prospects: directories, review sites, partner pages, blogs and news sites that already cover businesses like yours.

**Open data, no scraping of SEO tools, no login.** The links come from the public [Common Crawl web graph](https://commoncrawl.org/web-graphs) (domain level, July-September 2026: 2.1 billion links between 133 million domains), the traffic ranks from Google's public Chrome UX Report. Nothing is read from Ahrefs, Semrush or Moz.

#### Real results (3 October 2026)

**Referring domains** (each domain also gets the list itself, strongest first):

| Domain | All referring domains | Among the 5M best-connected sites | Strongest referring domains (authority) |
|---|---|---|---|
| bbc.co.uk | 249,224 | 104,990 | top 1,000 listed |
| zapier.com | 48,072 | 14,804 | adobe.com (85), dropbox.com (82), paypal.com (85), stripe.com (85) with filters authority >= 40, real visitors, no big platforms |
| apify.com | 3,556 | 1,527 | google.com (98), wordpress.org (91), amazon.com (88), github.com (87) |
| scrapingbee.com | 956 | 434 | wikipedia.org (91), github.com (87), medium.com (84), hubspot.com (78) |
| a site nobody links to | 0 | 0 | free row, not charged |

**Link gap**: `scrapingbee.com` against 4 competitors (scraperapi.com, zenrows.com, scrapingant.com, oxylabs.io), at least 2 competitors: **163 prospects** in under a second, led by comparison and review sites that link to all four or three of them (e.g. beehiiv.com, flipsnack.com, europeanbusinessreview.com, savedelete.com). `plausible.io` against usefathom.com, simpleanalytics.com and matomo.org (2+ competitors, real visitors only): 30 prospects such as smashingmagazine.com, yoast.com, cam.ac.uk and buzzsprout.com.

### Use cases

- **Link building**: find the sites that link to two or more competitors but not to you (`minCompetitorsLinked: 2`), keep the ones with real visitors (`onlyWithChromeTraffic`), and contact them.
- **Competitor research**: see who links to a competitor, strongest first: partners, customers, press, directories.
- **Backlink audit**: list the referring domains of your own site and check which strong sites already link to you.
- **PR and outreach lists**: news sites and blogs that wrote about companies in your niche.
- **Due diligence**: check who links to a domain before you buy it or partner with it.

### How much does it cost?

| Event | Price | When |
|---|---|---|
| Referring domain | **$1.50 / 1,000 rows** | one website linking to a domain on your list |
| Link prospect | **$3.00 / 1,000 rows** | link gap mode: one website linking to your competitors but not to you |

**Free:** domains that are not in the web graph, rows removed by your filters, duplicates, invalid lines and link gap runs that find nothing. **No start fee.** Larger Apify plans get the usual volume discount (Silver 10%, Gold and above 20%).

**Examples:** the top 100 referring domains of 50 websites = 5,000 rows = **$7.50**. A link gap against 3 competitors returning 200 prospects = **$0.60**.

For comparison (Apify Store, checked 8 October 2026): the most used backlink Actors (s-r/backlinks-checker, santhej/backlink-checker, Semrush-based ones) return individual backlinks (page URLs, anchor text) from commercial tools' crawlers and charge per backlink row; one competitor-gap Actor charges $0.15 per domain. This Actor does not have page URLs or anchor texts: it works at the domain level, from open data, with a lower price per row.

#### Control your cost

- **Before it starts**, the run logs its worst-case cost and compares it with your **maximum charge per run**. Rows that would pass the maximum are not returned: `SUMMARY.status` is `LIMIT_REACHED` and `SUMMARY.notProcessed` lists what was left out.
- `maxReferringDomainsPerDomain` (default 100) and `maxResults` cap the number of charged rows.
- "Max results per run" must be at least 1; a value of 0 or less stops the run with one free `invalid_input` row (nothing is looked up or charged).
- Every row has `charged: true` or `false`; failed rows have an `error` that ends with "(not charged)".

### How to use it

**Referring domains:** choose "Referring domains of my domains", paste domains or URLs into **Domains** (or pick a **Dataset ID**), set **Max referring domains per domain** and click **Start**. Open the **Referring domains** tab.

**Link gap:** choose "Link gap", enter **Your domain** and 1-10 **Competitors**, optionally **Linking to at least N competitors** (2 finds the sites that link to businesses like yours on purpose), and click **Start**. Open the **Link gap (prospects)** tab.

In "Link gap" mode a "Dataset ID" is not used (it only adds domains in "Referring domains" mode): it is ignored, listed in `SUMMARY.ignoredInputs`, and nothing is read from it or charged for it.

Filters for both modes: **Minimum authority**, **Only websites with real visitors** (in Chrome's top 1 million), **Leave out big platforms** (about 90 sites where anyone can get a link: google.com, youtube.com, github.com, medium.com, blogspot.com, amazonaws.com, linkedin.com...; on by default for the link gap, off for referring domains; review sites and directories stay in) and **Exclude domains**.

Subdomains are checked as their registrable domain (`blog.example.co.uk` becomes `example.co.uk`): the web graph counts links between registrable domains.

#### Input example

This is the input the form is prefilled with; a run with it takes a few seconds and costs only cents:

```json
{
    "mode": "referringDomains",
    "domains": [
        "apify.com",
        "scrapingbee.com"
    ],
    "maxReferringDomainsPerDomain": 25
}
```

#### Output examples

Referring domains mode (real row, 3 October 2026):

```json
{
    "mode": "referringDomains",
    "domain": "zapier.com",
    "input": "zapier.com",
    "referringDomain": "adobe.com",
    "position": 1,
    "authorityScore": 85,
    "chromeTrafficBucket": 1000,
    "trafficRank": "Top 1K websites (Chrome)",
    "targetReferringDomains": 48072,
    "targetListedReferringDomains": 14804,
    "targetListTruncated": true,
    "found": true,
    "dataRelease": "cc-main-2026-jul-aug-sep",
    "charged": true,
    "checkedAt": "2026-10-03T13:49:45.617Z"
}
```

Link gap mode (real row):

```json
{
    "mode": "linkGap",
    "yourDomain": "scrapingbee.com",
    "prospect": "beehiiv.com",
    "position": 3,
    "authorityScore": 68,
    "chromeTrafficBucket": 500000,
    "trafficRank": "Top 500K websites (Chrome)",
    "linksToCompetitors": [
        "zenrows.com",
        "scrapingant.com",
        "oxylabs.io"
    ],
    "competitorsLinked": 3,
    "competitorsChecked": [
        "scraperapi.com",
        "zenrows.com",
        "scrapingant.com",
        "oxylabs.io"
    ],
    "linksToYou": false,
    "mayAlreadyLinkToYou": false,
    "prospectUrl": "https://beehiiv.com/",
    "dataRelease": "cc-main-2026-jul-aug-sep",
    "charged": true,
    "checkedAt": "2026-10-03T13:49:46.629Z"
}
```

#### What "strongest first" and the scores mean

- Only the **5 million best-connected websites** of the web graph (by harmonic centrality, the same rank as our Domain Authority Checker) are listed as referring domains, and at most **1,000 per domain**. `targetReferringDomains` is the full count of linking domains, `targetListedReferringDomains` how many of them are among the listed websites, and `targetListTruncated: true` means there are more than 1,000.
- **Authority (0-100)** is our open-data score (rank in the web graph plus number of referring domains), **not** Moz DA or Ahrefs DR. It is the same score as our [Domain Authority Checker](https://apify.com/tidytools/domain-authority).
- **Traffic rank** is the Chrome UX Report popularity bucket of the referring website (Top 1K ... Top 1M); `null` means it is not in Chrome's top 1 million.

### Use it from code

```bash
curl -X POST "https://api.apify.com/v2/acts/tidytools~backlink-gap/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode":"linkGap","yourDomain":"mysite.com","competitors":["competitor1.com","competitor2.com"],"minCompetitorsLinked":2}'
```

**With AI agents (MCP):** connect Apify's MCP server (`https://mcp.apify.com?tools=tidytools/backlink-gap`) to Claude, Cursor or any MCP client and ask, for example, "Which sites link to both of my competitors but not to me?". Minimal input: `{"domains": ["example.com"]}`.

### Limitations

- **Domain level, not page level:** you get the linking websites, not the individual pages, URLs or anchor texts, and no follow/nofollow.
- **Common Crawl sees a large share of the public web, not all of it.** Counts are lower than Ahrefs' or Semrush's; a site that links to you may be missing if the crawl did not reach the linking page.
- **Quarterly snapshot** (currently July-September 2026), not live: a link added last week is not in it yet, and a link removed since then is still counted.
- Only the 5 million best-connected websites can appear as referring domains, and at most 1,000 per domain. Small sites linking to you (personal blogs, spam) are counted in `targetReferringDomains` but not listed.
- **Link gap with a very popular own site:** if your own site has more than 1,000 listed referring domains, a weak prospect might already link to you outside the stored list; such rows say `mayAlreadyLinkToYou: true`.

### FAQ

**Does the Actor collect usage data?** The Actor sends one anonymous usage counter per run (input type, item count range, outcome) to improve the tool; no URLs, content or account data.

**What happens when I enter something that is not a domain?** Each invalid line becomes a free result row with `errorType: "invalid_input"` and the run still ends as succeeded. If nothing usable is left (no valid domain, no "Your domain", a bad Dataset ID, "Linking to at least N competitors" higher than the number of competitors), you get one free `invalid_input` row explaining what to fix; nothing is looked up or charged.

**Does it work for URLs, subdomains and e-mail addresses?** Yes: `https://blog.example.co.uk/page` and `info@example.co.uk` are both checked as `example.co.uk`. The same domain written differently (`Example.com`, `www.example.com`, `https://example.com/pricing`) is one domain and charged once. Entries can be separated by line breaks, spaces, tabs, commas or semicolons, and pasted quotes or brackets (`"example.com"`, `<example.com>`) are ignored.

**What counts as invalid?** Text that is not a domain, IP addresses and `localhost`, internal names (`.local`, `.internal`), unknown top-level domains (`foo.invalidtld`), labels longer than 63 characters, and objects or numbers in the list. "Your domain" takes one website; a competitor that is the same website as "Your domain" is skipped with a free `invalid_input` row.

**Is the data live? How often is it refreshed?** No. It is the quarterly Common Crawl web graph (currently July-September 2026, loaded 3 October 2026) plus the Chrome UX Report; we load a new release when Common Crawl publishes one. Every row carries `dataRelease`.

**What if a link gap finds nothing?** One free row says why (none of the competitors is in the web graph, or every referring domain already links to you or is filtered out).

**Why is my site "not found"?** None of the 5 million best-connected websites links to it in the July-September 2026 web graph (or the crawl did not reach it). The row is free.

**Is the link gap the same as Ahrefs' Link Intersect?** It answers the same question (who links to them and not to me) at the domain level, from open data.

**Can I use the results commercially?** Yes. Common Crawl data is free to use under its terms of use; the Chrome UX Report data is CC BY 4.0 (Google).

### Support

Open an issue in the **Issues** tab with your input and the run link. Issues are checked regularly.

# Actor input Schema

## `mode` (type: `string`):

"Referring domains": the websites that link to each domain in your list, strongest first. "Link gap": websites that link to your competitors but not to you (link prospects), ranked by how many competitors they link to.

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

Domains or website addresses, one per line (example.com, https://www.example.com/page); spaces, commas and semicolons also separate entries. Subdomains are checked as their registrable domain (blog.example.co.uk -> example.co.uk). Up to 1,000 per run; duplicates are merged. Invalid lines become a result row with errorType "invalid_input" (not charged).

## `yourDomain` (type: `string`):

Your website. Prospects that already link to it are left out.

## `monitorName` (type: `string`):

Reuse the same name and Your domain across runs to compare the sampled Common Crawl domain graph between data releases. SUMMARY reports newly observed and lost-from-sample referring domains only when both releases have complete lists. These are not verified backlink gains or losses. No extra paid rows.

## `competitors` (type: `array`):

1 to 10 competitor domains. A prospect is a website that links to at least one of them (see "Linking to at least N competitors") and not to you.

## `minCompetitorsLinked` (type: `integer`):

Only prospects that link to at least this many of your competitors. 2 or more finds sites that link to businesses like yours on purpose (directories, review sites, partner lists).

## `minAuthority` (type: `integer`):

Leave out referring domains with a lower open-data authority score (same score as our Domain Authority Checker). 0 = keep all.

## `onlyWithChromeTraffic` (type: `boolean`):

Keep only referring domains that are in Chrome's top 1 million websites (Chrome UX Report): sites real people visit, not link farms or abandoned blogs.

## `excludeBigPlatforms` (type: `boolean`):

Leave out about 90 big platforms where links come from user pages, hosted sites, app listings or link shorteners rather than editorial choices (google.com, youtube.com, github.com, medium.com, blogspot.com, wordpress.com, amazonaws.com, linkedin.com, reddit.com...). Review sites and directories stay in. Default: on for the link gap, off for referring domains.

## `excludeDomains` (type: `array`):

Referring domains to leave out, e.g. social networks or your own other sites.

## `maxReferringDomainsPerDomain` (type: `integer`):

Referring domains mode: at most this many rows per domain, strongest (best-connected) first. Up to 1,000.

## `maxResults` (type: `integer`):

Stop after this many charged rows in total (referring domains or link prospects). Link gap default: 200.

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

Also check the domains in another Actor run's dataset, e.g. the website field of a lead list.

## `datasetField` (type: `string`):

Field with the domain or URL, e.g. "website" or "domain" (dot paths work). Empty = the first URL field found.

## Actor input object example

```json
{
  "mode": "referringDomains",
  "domains": [
    "apify.com",
    "scrapingbee.com"
  ],
  "minCompetitorsLinked": 1,
  "minAuthority": 0,
  "onlyWithChromeTraffic": false,
  "maxReferringDomainsPerDomain": 25
}
```

# Actor output Schema

## `referring` (type: `string`):

No description

## `gap` (type: `string`):

No description

## `full` (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 = {
    "mode": "referringDomains",
    "domains": [
        "apify.com",
        "scrapingbee.com"
    ],
    "maxReferringDomainsPerDomain": 25
};

// Run the Actor and wait for it to finish
const run = await client.actor("tidytools/backlink-gap").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 = {
    "mode": "referringDomains",
    "domains": [
        "apify.com",
        "scrapingbee.com",
    ],
    "maxReferringDomainsPerDomain": 25,
}

# Run the Actor and wait for it to finish
run = client.actor("tidytools/backlink-gap").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 '{
  "mode": "referringDomains",
  "domains": [
    "apify.com",
    "scrapingbee.com"
  ],
  "maxReferringDomainsPerDomain": 25
}' |
apify call tidytools/backlink-gap --silent --output-dataset

```

## MCP server setup

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

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/20WDEXIozaSOcbUFu/builds/CFRLhygafidkh7qax/openapi.json
