# Backlink Analyzer Pro (`winningsolutions/ws-backlink-scraper`) Actor

Analyze backlink profiles for domains and URLs in 14 modes: overview, link lists, anchors, referring domains, competitor gap, history, timeseries, and bulk comparison. Pay per result row on Apify.

- **URL**: https://apify.com/winningsolutions/ws-backlink-scraper.md
- **Developed by:** [Winning Solutions](https://apify.com/winningsolutions) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.30 / 1,000 result rows

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

## Backlink Analyzer - 14 Backlink Analysis Modes in One Actor

A **research Actor** that analyzes backlink profiles for domains, subdomains, and page URLs. Add **targets**, pick an **analysis mode**, and adjust filters and limits. The Actor returns structured JSON with neutral field names.

It covers **profile overview**, **backlink lists**, **anchors**, **referring domains**, **competitor gap**, **history**, **timeseries**, and **bulk comparison** for up to 1000 targets.

Designed for **SEO teams, agencies, and developers** who need programmatic backlink intelligence without managing a second data account. Pay per result row on Apify. No external API signup required.

> ## Fourteen modes, one Actor
>
> **Start with Overview (summary) for a quick profile. Switch to Backlink List or Domain Gap for deeper work.**
>
> Each mode writes one dataset row per result unit. One run writes one mode. Open the Results tab first. Diagnosis rows explain empty runs and input errors. No silent failures.

### Use Cases

- Run a **backlink profile overview** before a full audit
- Export a **backlink list** with rank and spam filters
- Find **competitor gap** sources that link to rivals but not to you
- Compare **bulk metrics** across many domains in one run
- Track **historical backlink trends** and timeseries changes

### Index

- [Release Notes](#release-notes)
- [Features](#features)
- [Pricing](#pricing)
- [Input](#input)
- [API and MCP usage](#api-and-mcp-usage)
- [Output](#output)

### Release Notes

#### v2.0.3 - Output identity

- **Results tab:** Every row shows `analyzed_target` and `analysis_mode`.
- **One mode per run:** Other tabs are column views of the same rows.

#### v2.0 - Factory rebuild

- **Pay per event:** Apify PPE billing. No separate data account for users.
- **Neutral exports:** Field names like source\_domain and anchor\_text in every row.
- **14 analysis modes:** Summary, lists, gap, history, timeseries, and bulk.
- **Diagnosis rows:** Empty runs and errors write explicit dataset rows.

### Features

📊 **Profile overview:** Domain rank, backlink counts, spam score, and referring domain totals in one row.

🔗 **Backlink list mode:** Flat rows with source URL, target URL, anchor, dofollow, and dates.

🎯 **Gap analysis:** Domain and page intersection modes find sources linking to competitors but not you.

📈 **History and timeseries:** Track backlink and referring domain changes over time.

⚖️ **Bulk comparison:** Compare ranks, backlink counts, or spam scores for up to 1000 targets.

🔍 **Quality filters:** Dofollow, rank, spam score, TLD, language, and domain blocklist on list modes.

📅 **Date ranges:** History and timeseries modes accept from and to dates.

📋 **Results tab:** Every row shows the analyzed target and the selected mode.

⚡ **Diagnosis rows:** Invalid input, no results, and source errors stay visible in the dataset.

### Pricing

#### Regular pricing

| Cost item | Rate |
| --------- | ---- |
| Actor start | $0.02 |
| Result row (1 dataset row) | $0.0033 |
| Per 1,000 result rows | $3.30 |
| Apify platform compute (RAM/time) | Billed by Apify platform pricing |

> **Cost per result row: ~$0.0033** - A default summary run costs about $0.023 (start + one row).

You pay only for meaningful result rows. Diagnosis rows are free.

#### Free plan limit

Runs from Apify free plan accounts are limited to 100 result rows per run.
The run finishes normally at that point and keeps every result already written.

#### Cost Examples

**Scenario A: Profile overview (1 target, summary mode)**

- Actor start: $0.02
- 1 result row: $0.0033
- **Total: ~$0.023**

**Scenario B: Backlink list (100 rows)**

- Actor start: $0.02
- 100 result rows: $0.33
- **Total: ~$0.35**

**Scenario C: Bulk comparison (50 targets)**

- Actor start: $0.02
- 50 result rows: $0.165
- **Total: ~$0.185**

### Input

See the **Input** tab in the Apify Console for the full schema.

| Parameter | Required | Default | Description |
| --------- | -------- | ------- | ----------- |
| targets | yes | none | Domains or URLs to analyze. Up to 1000 entries. |
| mode | no | summary | Analysis type: summary, backlinks, anchors, gap, bulk, and more. |
| maxResultsPerTarget | no | 100 | Max rows per target. Hard cap 1000. |
| competitors | gap modes | none | Competitor domains for intersection modes. |
| linkType, minDomainRank, maxSpamScore | no | all / 0 / 100 | Quality filters on list modes. |
| deduplicateByDomain | no | true | One row per referring domain on supported modes. |

#### Input example

```json
{
  "targets": ["example.com"],
  "mode": "summary",
  "maxResultsPerTarget": 100
}
```

### API and MCP usage

Run the Actor via Apify API, CLI, or MCP. Pass the same JSON as the Console Input tab.

```bash
apify call winningsolutions/ws-backlink-scraper --input '{"targets":["example.com"],"mode":"summary"}'
```

### Output

One run writes one analysis mode.

1. Open the **Results** tab. That tab always shows `analyzed_target` and `analysis_mode`.
2. Open the tab that matches the selected mode. Example: mode Referring Domains uses the Referring Domains tab.
3. Skip the other tabs. Empty columns stay hidden. Those tabs show leftover numbers only.

Each dataset row includes identity fields, analysis fields, and `_metadata`:

```json
{
  "analyzed_target": "example.com",
  "analysis_mode": "referring_domains",
  "source_domain": "ref.example",
  "domain_rank": 415,
  "total_backlinks": 8026,
  "_metadata": {
    "target": "example.com",
    "mode": "referring_domains",
    "runAt": "2026-09-08T10:00:00.000Z",
    "resultCharged": true
  }
}
```

Download results as JSON, CSV, Excel, or HTML from the run overview.

# Actor input Schema

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

One entry per line. Domains and subdomains without https:// and www. (e.g. example.com), individual pages as full URLs (e.g. https://shop.example.com/category/). Up to 1000 entries.

## `includeSubdomains` (type: `boolean`):

On: data for the full domain including all subdomains (e.g. example.com + blog.example.com). Off: exact target only.

## `excludeInternalBacklinks` (type: `boolean`):

Links from subdomains of the same domain pointing to the target will not be counted.

## `includeIndirectLinks` (type: `boolean`):

Counts links that point to the target via a redirect or canonical.

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

Which analysis the actor performs. One run writes one mode. Open the Results tab first, then the tab that matches this mode. Other tabs hide empty columns.

## `bulkMetric` (type: `string`):

Which metric to retrieve for all targets in bulk.

## `backlinksStatusType` (type: `string`):

Which links to return: all, active only, or lost only.

## `groupingMode` (type: `string`):

All links, one link per referring domain, or one link per anchor.

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

Required for "Domain Gap" and "Page Gap" modes. The actor finds sources that link to these competitors but not to your target.

## `linkType` (type: `string`):

Restrict results to a specific link type.

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

Only include referring domains at or above this rank value.

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

Exclude referring domains with a spam score above this threshold.

## `rankScale` (type: `string`):

Scale in which rank values are returned.

## `tldFilter` (type: `array`):

Only include sources with these top-level domains (e.g. de, at, ch). Leave empty for all.

## `languageFilter` (type: `string`):

ISO language code to filter by (e.g. de, en). Leave empty for all.

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

Referring domains that should never appear in results (blocklist).

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

Upper limit per target. Hard-capped at 1000 to control run size.

## `orderBy` (type: `string`):

Field and direction, e.g. rank,desc or domain\_from\_rank,desc.

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

Start date (YYYY-MM-DD). Earliest available: 2019-01-30.

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

End date (YYYY-MM-DD). Leave empty for today.

## `groupRange` (type: `string`):

Grouping interval for timeseries results.

## `deduplicateByDomain` (type: `boolean`):

Write only one entry per referring domain into the dataset.

## Actor input object example

```json
{
  "targets": [
    "example.com"
  ],
  "includeSubdomains": true,
  "excludeInternalBacklinks": true,
  "includeIndirectLinks": true,
  "mode": "summary",
  "bulkMetric": "referring_domains",
  "backlinksStatusType": "live",
  "groupingMode": "as_is",
  "linkType": "all",
  "minDomainRank": 0,
  "maxSpamScore": 100,
  "rankScale": "one_thousand",
  "maxResultsPerTarget": 100,
  "orderBy": "rank,desc",
  "groupRange": "month",
  "deduplicateByDomain": true
}
```

# Actor output Schema

## `dataset` (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("winningsolutions/ws-backlink-scraper").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("winningsolutions/ws-backlink-scraper").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 winningsolutions/ws-backlink-scraper --silent --output-dataset

```

## MCP server setup

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

```

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/V9FTtDN8dXwlrT2zB/builds/3Nqwb2WRUdSrtldvf/openapi.json
