# Website Backlink Checker & Audit (`aerodynamic_tripod/website-backlink-checker`) Actor

Check backlinks, referring domains, anchors, link status, spam score, domain rank, and live backlink verification for any website. Export clean SEO audit data for competitor research and backlink analysis.

- **URL**: https://apify.com/aerodynamic\_tripod/website-backlink-checker.md
- **Developed by:** [SearchShark Tools](https://apify.com/aerodynamic_tripod) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $150.00 / 1,000 domain reports

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?

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

## 🔗 Website Backlink Checker & Audit

**Website Backlink Checker & Audit** lets you collect **backlinks, referring domains, anchor-text distribution, backlink quality signals, and optional live link status** for domains, subdomains, and URLs.

Build backlink reports, prioritize important links, inspect lost-link signals, research competitors, and export structured SEO data **without manually checking referring pages one by one**.

- 🔎 **Discover backlinks:** retrieve backlink data through a managed upstream Apify backlink provider
- 📊 **Audit backlink quality:** add deterministic priority scores, bands, recommended actions, and reason codes
- 🧭 **Analyze referring domains:** see which domains link to a target and normalize source authority to a stable 0–100 scale
- 🏷 **Analyze anchor text:** inspect which anchors appear most often and their observed share
- 🧪 **Verify selected links live:** optionally fetch referring pages and confirm whether a matching link is currently present
- 🧹 **Get cleaner output:** normalize targets, remove duplicate targets, deduplicate detailed rows, and enforce per-target output caps
- ⚡ **Automate workflows:** consume results through Apify Dataset, API, integrations, spreadsheets, databases, monitoring systems, or AI workflows

***

### 📦 What data does Website Backlink Checker & Audit return?

The exact fields depend on the selected report type.

| | |
| --- | --- |
| 🎯 **Target input** | 🔗 **Normalized target** |
| 🧭 **Target scope** | 📄 **Report type** |
| 🕒 **Checked timestamp** | 🧩 **Data source** |
| 🔎 **Provider request ID** | ▶️ **Actor run ID** |
| 🌐 **Source domain** | 🔗 **Source URL** |
| 📰 **Source page title** | 🎯 **Target URL** |
| 🏷 **Anchor text** | ✅ **Dofollow status** |
| 📈 **Source domain rank** | ⚠️ **Backlink spam score** |
| 🗓 **First seen** | 🗓 **Last seen** |
| ❌ **Lost status** | 🧪 **Live verification status** |
| ⭐ **Priority score** | 🚦 **Priority band** |
| 🧭 **Recommended action** | 🧾 **Reason codes** |

> **Unavailable provider fields are returned as `null` or an empty array.** The Actor does **not invent SEO metrics** that the current upstream provider does not expose.

The public `dataSource` value for the current adapter is:

```text
ApifyUpstream
```

***

### 🚀 Features

Website Backlink Checker & Audit is designed for **SEO research, backlink monitoring, reclamation, and automation**.

- **Multiple targets:** process up to 20 domains, subdomains, or absolute URLs in one run
- **Five report types:** `summary`, `backlinks`, `audit`, `anchors`, and `referring_domains`
- **Up to 1,000 persisted detail rows per target**
- **Target normalization:** equivalent domain inputs are normalized before processing
- **Duplicate-target removal:** duplicate normalized targets are not processed twice
- **Stable public schema:** provider-specific snake\_case data is mapped into predictable camelCase records
- **Authority normalization:** upstream 0–1000 source-domain authority is converted to a public 0–100 scale
- **Deterministic audit scoring:** audit rows receive transparent priority fields instead of a black-box recommendation
- **Optional live verification:** selected referring pages can be checked at run time
- **SSRF-safe verification:** private, loopback, link-local, metadata-service, and unsafe redirect destinations are blocked
- **Partial-failure protection:** one failed target does not erase successful targets from the same run
- **Named storage:** summaries and errors are kept separately from normal result rows
- **Spending guard:** the Actor reserves billable capacity before starting provider work for a target
- **No customer backlink-provider API key:** users do not need to create or configure a separate backlink-data account
- **No browser required for live verification:** selected pages are fetched with bounded HTTP requests and HTML parsing

***

## ⬇️ Input

You can configure Website Backlink Checker & Audit directly from the **Apify Console** or send input programmatically through the **Apify API**.

### 🎯 Targets

Add one or more domains, subdomains, or URLs.

Examples:

```text
example.com
blog.example.com
https://example.org/resources/
```

Current limits:

```text
Minimum: 1 target
Maximum: 20 targets
```

Targets are normalized before processing.

Equivalent root-domain inputs can collapse into one normalized target, preventing duplicate work and duplicate billing.

***

### 📄 Report type

Supported report types:

```text
summary
backlinks
audit
anchors
referring_domains
```

Default:

```text
audit
```

#### `summary`

Returns a compact backlink-profile overview for each successful target.

#### `backlinks`

Returns flat backlink rows.

#### `audit`

Returns backlink rows, then adds scoring fields such as:

```text
priorityScore
priorityBand
recommendedAction
reasonCodes
```

Optional live verification can also be enabled for this mode.

#### `anchors`

Returns anchor-text distribution rows.

#### `referring_domains`

Returns one flat row per observed referring domain.

***

### 🧭 Target scope

Supported values:

```text
root_domain
subdomain
exact_url
```

Default:

```text
root_domain
```

`exact_url` requires an absolute HTTP or HTTPS URL.

***

### 🔢 Maximum results per target

Controls the maximum number of **persisted detail rows** returned for each target.

```text
Minimum: 1
Default: 100
Maximum: 1000
```

For example:

```text
Targets:
example.com
example.org

Maximum results per target:
100
```

can persist up to:

```text
100 detail rows for example.com
+
100 detail rows for example.org
=
200 detail rows
```

The requested number is a **maximum, not a guarantee**.

> Some upstream analysis modes can perform or return more work before the local output cap is applied. The Actor still caps persisted detail rows to `maxResultsPerTarget`, but upstream cost may not be strictly proportional to the final row count.

***

### 🔴 Backlink status

Controls which backlink state is returned.

```text
live
lost
all
```

Default:

```text
live
```

- `live` excludes provider-reported lost backlinks.
- `all` includes available live and lost data.
- `lost` is supported only for `backlinks` and `audit`.

For lost-only backlink and audit reports, the Actor locally keeps rows where `isLost = true` before applying the final row limit.

`lost` is rejected for `summary`, `anchors`, and `referring_domains` because those report shapes do not expose enough per-row lost-state data to apply the filter truthfully.

***

### 🧹 Backlink grouping

Available values:

```text
as_is
one_per_domain
one_per_anchor
```

Default:

```text
one_per_domain
```

Grouping applies to detailed `backlinks` and `audit` output.

The Actor requests a larger candidate pool when necessary, applies the grouping locally, and then enforces `maxResultsPerTarget`.

- `as_is` keeps backlink rows as returned.
- `one_per_domain` keeps one backlink per source domain.
- `one_per_anchor` keeps one backlink per anchor text.

`summary`, `anchors`, and `referring_domains` are already aggregate report types, so this setting does not change their rows.

***

### ✅ Dofollow only

```text
Default: false
```

When enabled, the current upstream adapter asks the provider to return dofollow backlinks only.

***

### 📈 Minimum source domain rank

Public scale:

```text
Minimum: 0
Default: 0
Maximum: 100
```

The upstream provider uses a 0–1000 authority scale.

The Actor translates the public input before the provider call:

```text
Public 80 -> Upstream 800
```

and normalizes returned authority back to the public scale:

```text
Upstream 800 -> Public 80
```

This keeps your Dataset output on a predictable 0–100 scale.

***

### ⚠️ Maximum backlink spam score

```text
Minimum: 0
Default: 100
Maximum: 100
```

Supported report types:

```text
backlinks
audit
referring_domains
```

The Actor applies this filter locally using `backlinkSpamScore` before enforcing the final row limit.

It is rejected for `summary` and `anchors`, where an equivalent per-row spam-score filter cannot be applied truthfully.

***

### 🗓 First seen from

Optional format:

```text
YYYY-MM-DD
```

Default:

```text
null
```

Supported only for:

```text
backlinks
audit
```

The Actor filters provider-reported `first_seen` values locally before applying the final row limit.

It is rejected for the other report types because their current upstream row shapes do not expose equivalent first-seen data.

***

### 🏷 Anchor contains

Optional case-insensitive text filter.

Default:

```text
null
```

Supported report types:

```text
backlinks
audit
anchors
```

The Actor applies the filter locally to `anchorText` before enforcing the final row limit.

It is rejected for `summary` and `referring_domains`.

***

### 🧪 Verify links live

```text
Default: false
```

Live verification is available for:

```text
backlinks
audit
```

When enabled, the Actor fetches selected referring pages and checks whether a matching destination is currently present.

Possible verification states include:

```text
confirmed
missing
blocked
unreachable
unsupported_content
not_checked
```

A blocked or unreachable referring page is **not automatically classified as a lost link**.

Provider-reported state and live verification remain separate signals.

***

### 🔢 Maximum links to verify

```text
Minimum: 0
Default: 25
Maximum: 100
```

The Actor never verifies more rows than it actually returns.

In audit mode, rows are pre-scored and the highest-priority candidates are selected for verification first.

***

### 🧹 Deduplicate results

```text
Default: true
```

Detailed rows are deduplicated using stable keys appropriate to the report type.

For backlinks, identity is based on normalized link details such as source URL, target URL, anchor text, and link type when available.

***

### ⚙️ Provider concurrency

```text
Minimum: 1
Default: 5
Maximum: 10
```

This controls how many target workflows may call the upstream provider concurrently.

***

### ⚙️ Verification concurrency

```text
Minimum: 1
Default: 3
Maximum: 5
```

This controls concurrent live referring-page checks.

***

### 🌐 Proxy configuration

An optional Apify proxy can be used for **live verification**.

The discovery provider call itself runs as a separate Apify Actor call.

Use a verification proxy when selected referring pages block or restrict direct requests.

***

### 🧪 Example input — backlink audit

```json
{
  "targets": [
    "example.com",
    "example.org"
  ],
  "reportType": "audit",
  "scope": "root_domain",
  "maxResultsPerTarget": 100,
  "backlinkStatus": "live",
  "grouping": "one_per_domain",
  "dofollowOnly": false,
  "minDomainRank": 20,
  "maxSpamScore": 70,
  "verifyLive": true,
  "maxLinksToVerify": 25,
  "deduplicateResults": true,
  "apiConcurrency": 5,
  "verificationConcurrency": 3
}
```

> Inputs that the current upstream adapter cannot faithfully forward are still parsed for compatibility but are documented above as adapter limitations.

***

## ⬆️ Output

The Actor uses structured Apify storage so each output type remains easy to consume.

### 📊 Default Dataset

The default Dataset contains the requested report records.

For:

```text
summary
```

the summary record is available as the main result.

For detailed modes:

```text
backlinks
audit
anchors
referring_domains
```

the detailed rows are written to the default Dataset.

***

### 📋 Summaries Dataset

A separate summaries Dataset stores the overview row for each successful target.

This is useful because detailed report modes still perform a summary step before collecting detail rows.

Typical summary fields:

```text
recordType
targetInput
targetNormalized
scope
reportType
checkedAt
dataSource
providerRequestId
runId
domainRank
totalBacklinks
referringDomains
referringMainDomains
referringDomainsNofollow
referringIps
brokenBacklinks
backlinksSpamScore
firstSeen
returnedRows
```

Fields not exposed by the current upstream summary mode remain `null`.

***

### ⚠️ Errors Dataset

Target-specific failures are written separately.

Example shape:

```json
{
  "recordType": "error",
  "targetInput": "invalid target",
  "targetNormalized": null,
  "errorCode": "INVALID_TARGET",
  "errorMessage": "Invalid target",
  "retryable": false,
  "attempts": 1,
  "failedAt": "2026-09-08T05:40:00.000Z"
}
```

Successful targets remain available even when another target fails.

If every target fails, the Actor fails instead of silently reporting a successful empty run.

***

### 🧾 OUTPUT summary

The Actor also writes a compact run summary containing fields such as:

```text
runId
defaultDatasetId
summariesDatasetId
errorsDatasetId
processedTargets
failedTargets
returnedRows
verifiedPages
confirmedLinks
missingLinks
duplicateTargetsRemoved
providerCostUsd
```

This makes it easy for another workflow to inspect the run without reading every Dataset row.

***

### 📊 Example summary result

```json
{
  "recordType": "summary",
  "targetInput": "example.com",
  "targetNormalized": "example.com",
  "scope": "root_domain",
  "reportType": "summary",
  "checkedAt": "2026-09-08T05:40:00.000Z",
  "dataSource": "ApifyUpstream",
  "providerRequestId": "upstream-run-id",
  "runId": "actor-run-id",
  "domainRank": null,
  "totalBacklinks": 100,
  "referringDomains": 100,
  "referringMainDomains": null,
  "referringDomainsNofollow": null,
  "referringIps": null,
  "brokenBacklinks": null,
  "backlinksSpamScore": 2.5,
  "firstSeen": null,
  "returnedRows": 0
}
```

`domainRank` is intentionally `null` here because the observed upstream summary exposes an **average referring-domain rank**, not a true target-domain rank. The Actor does not relabel that metric into something it is not.

***

### 🔗 Example backlink result

```json
{
  "recordType": "backlink",
  "targetInput": "example.com",
  "targetNormalized": "example.com",
  "scope": "root_domain",
  "reportType": "backlinks",
  "checkedAt": "2026-09-08T05:40:00.000Z",
  "dataSource": "ApifyUpstream",
  "providerRequestId": "upstream-run-id",
  "runId": "actor-run-id",
  "sourceDomain": "api.druphelp.com",
  "sourceUrl": "https://api.druphelp.com/article",
  "sourceTitle": "Example page",
  "sourceStatusCode": null,
  "sourceCountry": null,
  "sourceLanguage": null,
  "sourcePlatformTypes": [],
  "targetDomain": "example.com",
  "targetUrl": "http://example.com/dir/file",
  "targetStatusCode": null,
  "finalTargetUrl": null,
  "anchorText": "Example",
  "textBefore": null,
  "textAfter": null,
  "dofollow": true,
  "attributes": [],
  "linkType": null,
  "semanticLocation": null,
  "imageUrl": null,
  "imageAlt": null,
  "backlinkRank": null,
  "sourcePageRank": null,
  "sourceDomainRank": 10,
  "backlinkSpamScore": 5,
  "firstSeen": "2024-02-29 07:08:28 +00:00",
  "previousSeen": null,
  "lastSeen": "2026-09-03 18:03:16 +00:00",
  "isNew": null,
  "isLost": false,
  "isBroken": null,
  "linksOnSourcePage": null,
  "linksFromSourceDomain": null,
  "verificationStatus": "not_checked",
  "linkPresentNow": null,
  "verifiedAt": null,
  "redirected": null,
  "priorityScore": null,
  "priorityBand": null,
  "recommendedAction": null,
  "reasonCodes": []
}
```

In `audit` mode, the priority fields are populated by the Actor's audit layer.

***

### 🏷 Example anchor result

```json
{
  "recordType": "anchor",
  "targetInput": "example.com",
  "targetNormalized": "example.com",
  "scope": "root_domain",
  "reportType": "anchors",
  "checkedAt": "2026-09-08T05:40:00.000Z",
  "dataSource": "ApifyUpstream",
  "providerRequestId": "upstream-run-id",
  "runId": "actor-run-id",
  "anchorText": "link",
  "backlinks": 6,
  "referringDomains": null,
  "dofollowBacklinks": null,
  "firstSeen": null,
  "lastSeen": null,
  "sharePercent": 6
}
```

***

### 🌐 Example referring-domain result

```json
{
  "recordType": "referring_domain",
  "targetInput": "example.com",
  "targetNormalized": "example.com",
  "scope": "root_domain",
  "reportType": "referring_domains",
  "checkedAt": "2026-09-08T05:40:00.000Z",
  "dataSource": "ApifyUpstream",
  "providerRequestId": "upstream-run-id",
  "runId": "actor-run-id",
  "sourceDomain": "news.example",
  "sourceDomainRank": 10,
  "backlinks": 3,
  "dofollowBacklinks": 2,
  "backlinkSpamScore": 10,
  "firstSeen": null,
  "lastSeen": null,
  "isNew": null,
  "isLost": null
}
```

***

### ⭐ Audit priority fields

Audit mode adds:

```text
priorityScore
priorityBand
recommendedAction
reasonCodes
```

Recommended actions can include:

```text
reclaim
protect
investigate
monitor
ignore
```

The audit is deterministic: the same mapped backlink signals produce the same score and recommendation.

The Actor does **not** automatically recommend disavowing a domain.

***

### 🧪 Live verification

When enabled, selected referring pages are fetched at run time.

The verifier:

1. validates that the URL is public HTTP or HTTPS
2. blocks private and unsafe destination ranges
3. revalidates redirects
4. caps response size and request duration
5. parses link destinations from the returned HTML
6. compares normalized destinations against the selected target and scope
7. returns one visible verification status

Verification states:

```text
confirmed
missing
blocked
unreachable
unsupported_content
not_checked
```

A provider-reported lost backlink and a currently missing backlink are **not the same concept**.

Use both:

```text
isLost
verificationStatus
```

when investigating reclamation opportunities.

***

### 🧹 Deduplication

Targets are normalized before processing.

Detailed records are deduplicated when `deduplicateResults` is enabled.

The Actor also enforces the requested per-target output cap after mapping upstream rows.

This is especially important for upstream analysis modes that can return more rows than the requested public limit.

***

### ⚡ Performance

Backlink discovery is performed through a managed **Apify Actor call**, not by launching a browser inside this Actor.

Optional live verification uses bounded HTTP requests and HTML parsing.

This keeps browser overhead out of the normal workflow while still allowing selected links to be checked against the current referring page.

The Actor currently uses:

```text
Node.js 22+
TypeScript
Apify SDK
Cheerio
undici
```

***

### 🛡 Reliability

The Actor is designed so one target does not destroy the results of another.

If you process:

```text
example.com
example.org
bad-target
```

and one target fails, successful target results are still written.

The Actor records target-specific errors in the errors Dataset.

If **all targets fail**, the run fails instead of silently returning an empty success.

Before provider work begins for a target, the billing layer checks whether enough run spending capacity remains for the reserved events.

***

### 🔐 Security

Customers do **not** provide a separate backlink-provider username, password, or API key.

The current production runtime uses Apify's Actor-to-Actor call flow for backlink discovery.

Optional live verification includes SSRF protections:

```text
private IP ranges blocked
loopback blocked
link-local blocked
metadata-service ranges blocked
non-HTTP(S) schemes blocked
redirect destinations revalidated
response size capped
request time capped
```

Secrets and raw authorization values are not intended to appear in public Dataset records or the final `OUTPUT` object.

***

## 🔌 API & integrations

Website Backlink Checker & Audit can be started programmatically through the **Apify API**.

You can connect results to:

- Google Sheets
- Make
- Zapier
- Airtable
- CRMs
- SEO dashboards
- internal APIs
- data warehouses
- monitoring systems
- AI agents
- MCP workflows

Every run produces structured Dataset rows plus a compact `OUTPUT` summary.

***

### 🧪 CLI example

```bash
apify call YOUR_USERNAME/website-backlink-checker -i '{
  "targets": ["example.com"],
  "reportType": "audit",
  "maxResultsPerTarget": 100,
  "verifyLive": false
}'
```

When using Windows PowerShell, a JSON input file is often more reliable than large inline JSON strings.

Example:

```powershell
$payload = @{
  targets = @("example.com")
  reportType = "audit"
  maxResultsPerTarget = 100
  verifyLive = $false
} | ConvertTo-Json -Compress

[System.IO.File]::WriteAllText(
  "$PWD\INPUT.json",
  $payload,
  (New-Object System.Text.UTF8Encoding($false))
)

apify call YOUR_USERNAME/website-backlink-checker -f INPUT.json -o
```

***

## 💡 Example use cases

#### ♻️ Link reclamation

Run:

```text
reportType = audit
verifyLive = true
```

Then focus on rows where the recommendation and verification signals indicate that a valuable link may deserve restoration work.

Useful fields:

```text
sourceDomain
sourceUrl
sourceDomainRank
backlinkSpamScore
isLost
verificationStatus
priorityScore
recommendedAction
reasonCodes
```

***

#### 🛡 Protect strong backlinks

Use audit output to find backlinks worth monitoring.

Useful signals:

```text
high sourceDomainRank
dofollow = true
verificationStatus = confirmed
recommendedAction = protect
```

***

#### 🔎 Backlink research

Use `backlinks` mode to export a flat list of referring pages and target destinations.

This works well for:

```text
SEO audits
competitive research
link-profile reviews
content promotion research
PR research
```

***

#### 🧭 Referring-domain analysis

Use:

```text
reportType = referring_domains
```

to inspect which domains contribute backlinks.

Useful fields:

```text
sourceDomain
sourceDomainRank
backlinks
dofollowBacklinks
backlinkSpamScore
```

***

#### 🏷 Anchor-text analysis

Use:

```text
reportType = anchors
```

to understand the observed anchor distribution.

Useful fields:

```text
anchorText
backlinks
sharePercent
```

***

#### 📊 Fast profile overview

Use:

```text
reportType = summary
```

when you only need a compact backlink-profile overview.

This is a useful first pass before deciding which domains need a deeper audit.

***

## ⚠️ Current limitations

The Actor intentionally avoids claiming data that the current upstream provider does not expose.

Current limitations include:

```text
No proprietary backlink index owned by this Actor
No Ahrefs, Semrush, or Moz parity claim
No proprietary DR / DA / Authority Score branding
No automatic Google disavow recommendation
No automatic outreach emails
No persistent cross-run history in the MVP
No competitor backlink-gap report in the MVP
No browser-rendered verification for JavaScript-only pages
```

#### Upstream coverage

Backlink discovery depends on the current managed upstream Apify provider.

Results therefore reflect that provider's:

```text
index coverage
crawl recency
available row shape
mode behavior
provider availability
```

The Actor adds normalization, audit scoring, storage, billing controls, and optional live verification, but it does **not** claim that its raw discovery coverage is larger than the upstream source.

#### Upstream mode behavior

Observed upstream behavior can differ by mode.

For example, during migration probes:

- detail `backlinks` mode respected a one-row request
- `summary` mode used its own analysis limit
- `anchors` mode returned a full anchor distribution even when a one-row limit was requested

The adapter enforces the public output cap locally, but upstream work and cost can occur before that cap.

#### Current compatibility inputs

The public schema still contains several filters from the earlier provider contract.

The current upstream adapter directly maps:

```text
target
reportType -> upstream outputMode
maxResultsPerTarget
dofollowOnly
minDomainRank
live status -> exclude lost
```

Other compatibility fields are not all forwarded upstream yet.

Those fields remain documented in the Input section so users can distinguish the stable public contract from current adapter capabilities.

***

## 💳 Cost & billing notes

The Actor uses pay-per-event billing guards internally.

Configured event names include:

```text
domain-report
result-row
verified-page
```

The final Store price should be based on **measured upstream Actor cost plus Apify compute and optional verification/proxy cost**.

Upstream charges are not purely per persisted row.

During migration testing, even very small one-target probes had non-zero minimum upstream charges.

For that reason, do not interpret `maxResultsPerTarget = 1` as meaning the provider cost will be approximately one row's price.

The price shown in the Apify Store is the customer-facing source of truth after release pricing is finalized.

***

## ❓ FAQ

### Where does the backlink data come from?

Backlink discovery is retrieved through a managed upstream Apify backlink provider.

The public Dataset identifies the source as:

```text
ApifyUpstream
```

The Actor then maps the upstream data into its own stable output contract.

***

### Do I need my own backlink-provider API key?

**No.**

Customers do not enter a separate backlink-provider username, password, or API key.

***

### Is this the same as Ahrefs, Semrush, or Moz?

**No.**

The Actor does not claim equivalent crawl coverage or proprietary metrics.

It provides a commercial workflow around the current upstream backlink source:

```text
bulk targets
normalized output
audit scoring
optional live verification
partial-failure handling
Apify storage
API automation
```

***

### Why is `domainRank` sometimes null?

The current upstream summary response exposes an **average source-domain rank**, not a target-domain authority metric.

The Actor deliberately leaves `domainRank` as:

```text
null
```

instead of relabeling an average referring-domain metric as the target's own rank.

***

### Why are many backlink fields null?

The stable public schema is broader than the current upstream row shape.

If the provider does not expose a field such as:

```text
sourceCountry
sourceLanguage
linkType
semanticLocation
imageUrl
previousSeen
sourceStatusCode
```

the Actor returns `null` or an empty array rather than fabricating data.

***

### Why is source domain rank divided by 10?

The current upstream provider uses a 0–1000 authority scale.

The Actor's public contract uses 0–100.

Example:

```text
Upstream rank: 800
Public sourceDomainRank: 80
```

***

### Can I verify every backlink live?

You can request up to:

```text
100 live verifications per target
```

but verification is intentionally limited because every referring-page fetch adds time, network work, and potential proxy cost.

For larger reports, use audit mode and verify only the highest-priority rows.

***

### Does `missing` mean the backlink is definitely permanently lost?

**No.**

It means the verifier did not find the matching link in the fetched page at that time.

A page can change, block the request, serve different content, require JavaScript, or later restore the link.

Use `verificationStatus` together with the provider's `isLost` signal.

***

### What happens if a referring page blocks the verifier?

The Actor reports a state such as:

```text
blocked
unreachable
unsupported_content
```

instead of pretending the backlink is missing.

***

### What happens if one target fails?

Other valid targets continue.

The failed target is written to the errors Dataset.

If every target fails, the Actor run fails.

***

### Can I export the results?

Yes.

Apify Dataset results can be exported in formats supported by the platform, including common workflows such as:

```text
JSON
CSV
Excel
XML
```

***

### Can I use it through an API?

Yes.

The Actor is designed for both interactive Console runs and programmatic Apify API workflows.

***

## 🧭 Recommended workflow

For most backlink-audit jobs:

1. Start with `summary` for a quick profile overview.
2. Run `audit` only on targets that need deeper inspection.
3. Keep `maxResultsPerTarget` modest while validating the target.
4. Use `minDomainRank` to reduce low-authority discovery rows when useful.
5. Enable `verifyLive` only when current-page confirmation adds value.
6. Keep `maxLinksToVerify` focused on the most important candidates.
7. Review `isLost` and `verificationStatus` as separate signals.
8. Export the final Dataset into your SEO, CRM, reporting, or monitoring workflow.

For anchor research, use `anchors` directly.

For domain-level link-profile analysis, use `referring_domains`.

***

## 💬 Feedback & support

Found a bug or have a feature request?

Use the Actor's **Issues** tab on Apify.

Useful future additions may include:

```text
Competitor backlink-gap reports
Persistent snapshots
Cross-run new/lost change detection
Scheduled monitoring
Alerts and webhooks
More adapter-side filters
Provider fallback support
Domain-level rollups
Additional link-opportunity enrichment
```

***

### 🚀 Backlink data without the manual checking

Enter your targets, choose a report type, run the Actor, and receive **structured backlink data** ready for **SEO audits, link reclamation, competitor research, reporting, APIs, and automation**.

Add live verification only where it creates real value, and use the Actor's audit fields to focus attention on the links that matter most.

# Actor input Schema

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

Enter 1–20 domains, subdomains, or absolute URLs.

## `reportType` (type: `string`):

Choose a summary, detailed backlinks, scored audit, anchors, or referring domains.

## `scope` (type: `string`):

Exact URL requires each target to be an absolute HTTP(S) URL.

## `maxResultsPerTarget` (type: `integer`):

Maximum flat detail rows returned for each target.

## `backlinkStatus` (type: `string`):

Select backlink state. Lost-only is supported only for backlinks and audit reports.

## `grouping` (type: `string`):

Local grouping for detailed backlinks and audit reports.

## `dofollowOnly` (type: `boolean`):

Ask the provider to include only dofollow backlinks.

## `minDomainRank` (type: `integer`):

Minimum source domain rank on the public 0–100 scale.

## `maxSpamScore` (type: `integer`):

Maximum backlink spam score on the 0-100 scale. Supported for backlinks, audit, and referring\_domains.

## `firstSeenFrom` (type: `string`):

Optional ISO date in YYYY-MM-DD format. Supported only for backlinks and audit.

## `anchorContains` (type: `string`):

Optional case-insensitive anchor-text filter. Supported for backlinks, audit, and anchors.

## `verifyLive` (type: `boolean`):

Fetch selected referring pages. Valid only for backlinks and audit reports.

## `maxLinksToVerify` (type: `integer`):

Verify 0–100 of the highest-priority returned backlinks per target.

## `deduplicateResults` (type: `boolean`):

Remove duplicate normalized result keys.

## `apiConcurrency` (type: `integer`):

Concurrent provider workflows.

## `verificationConcurrency` (type: `integer`):

Concurrent live page checks.

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

Optional proxy used only for live verification; provider API calls never use it.

## Actor input object example

```json
{
  "targets": [
    "example.com"
  ],
  "reportType": "audit",
  "scope": "root_domain",
  "maxResultsPerTarget": 100,
  "backlinkStatus": "live",
  "grouping": "one_per_domain",
  "dofollowOnly": false,
  "minDomainRank": 0,
  "maxSpamScore": 100,
  "verifyLive": false,
  "maxLinksToVerify": 25,
  "deduplicateResults": true,
  "apiConcurrency": 5,
  "verificationConcurrency": 3
}
```

# Actor output Schema

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

No description

## `summaries` (type: `string`):

No description

## `errors` (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": [
        "example.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("aerodynamic_tripod/website-backlink-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": ["example.com"] }

# Run the Actor and wait for it to finish
run = client.actor("aerodynamic_tripod/website-backlink-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": [
    "example.com"
  ]
}' |
apify call aerodynamic_tripod/website-backlink-checker --silent --output-dataset

```

## MCP server setup

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