# Backlink Placement Verifier & Client Report (`exceptional_nugget/backlink-placement-verifier`) Actor

Verify supplied backlink placements, anchors and rel attributes. Export evidence and a printable agency report.

- **URL**: https://apify.com/exceptional\_nugget/backlink-placement-verifier.md
- **Developed by:** [LibriHouse](https://apify.com/exceptional_nugget) (community)
- **Categories:** SEO tools, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 placement checkeds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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 Placement Verifier & Client Report

Check whether a promised backlink is still present, uses the agreed anchor text, and has the required link attributes. Supply known source pages and expected targets; receive one evidence record per placement and a printable agency report. No proxy, paid API or AI key is required.

### Quick start

```json
{
  "placements": [
    {
      "sourceUrl": "https://example.com/",
      "targetUrl": "https://iana.org/domains/example",
      "expectedAnchor": "Learn more",
      "requireFollow": true
    }
  ],
  "maxRedirects": 3,
  "timeoutSecs": 15,
  "delayMillis": 250
}
```

The example checks the real link on example.com. Replace the row with your client placements. A changed demo anchor may correctly produce a mismatch.

| Input | Meaning |
|---|---|
| `placements` | 1–1000 objects; each requires `sourceUrl` and `targetUrl`. |
| `expectedAnchor` | Optional exact, case-sensitive text after collapsing whitespace. Omit to accept any anchor. Empty string requires an empty text anchor. Image alt text is not counted as anchor text. |
| `requireFollow` | Optional boolean, default false. When true, the same matching link must lack `nofollow`, `sponsored` and `ugc`; the page must also lack a robots/googlebot nofollow or none directive. |
| `maxRedirects` | 0–5 per source page, default 3. |
| `timeoutSecs` | 2–30 seconds per request including DNS, default 15. |
| `delayMillis` | 100–5000 ms between requests, default 250. |

Target matching is exact after standard URL parsing and fragment removal. Paths, case-sensitive paths, trailing slashes and query strings remain significant. Relative links respect the page's first HTML base URL. Redirects on the source page are followed; the target itself is not fetched or resolved through a redirect service.

### Results and reports

- `verified`: at least one matching link satisfies all supplied placement requirements.
- `missing`: no matching link was found in a complete successful HTML response.
- `mismatch`: the link exists, but no single link satisfies all supplied requirements.
- `unknown`: a blocked, failed, non-HTML, truncated or otherwise unsupported response prevents a conclusive check.

`matches` contains up to 10 matching-link evidence entries with anchor text, rel tokens and requirement checks. `matchCount` counts all matches in the inspected HTML. Evidence text is bounded (500-character anchors and 10 rel tokens of 30 characters each); `EVIDENCE_CAPPED` indicates more matches exist. `found`, `anchorMatches` and `followEligible` can be null when not established. A verified placement may still have a `PAGE_NOINDEX` warning: this is link evidence, not a claim that a search engine indexes or values it.

The default dataset exports as JSON, CSV or Excel in Apify. Open **Printable client report** for `REPORT` HTML and **Audit summary** for `SUMMARY` JSON. Download the report and print it to PDF if needed. A partial report explicitly shows missing work. Use `itemIndex` to join back to your input; duplicate rows are checked and billed separately.

Schedule the same input in Apify for recurring checks. This Actor checks current placement requirements; it does not maintain cross-run history or send messages. Export snapshots or connect your own workflow to compare runs and notify clients.

### Pricing

Launch price: **$3 per 1,000 completed placement checks** (`placement-checked`, $0.003 each), plus the Apify start event ($0.00005 at the default 256 MB) and platform usage. Start-event count increases above 1 GB. Confirm the current Pricing tab before running. For 100 checks, mapping events total $0.30 plus the start event and platform usage. Reports and issue lists have no extra event fee.

Successful HTTP observations are charged even when the result is missing, mismatched, blocked (403/429), non-HTML or otherwise unknown. DNS, TLS, request timeout and unsafe-target errors with a populated `error` field have no custom check fee. The start fee and platform usage still apply. The Actor stops before work that cannot fit its event budget. Do not enable automatic dataset-item billing alongside `placement-checked`.

### Boundaries and privacy

Only publicly reachable HTTP(S) on standard ports is supported. Credentials in URLs, private/reserved network destinations and unsafe redirect targets are rejected. DNS answers are checked and the selected public address is pinned to the connection. Do not supply URLs containing secrets or personal query parameters.

This is static HTTP HTML inspection with a 2 MB body cap. It does not execute JavaScript, inspect rendered visibility/CSS, cross into iframes, discover backlinks, check domain authority, interpret robots.txt, verify Google indexing, or certify ranking impact. Only UTF-8/ASCII and identity-encoded HTML is parsed. Site geography, access rules and personalization can change the result. It does not retry blocked requests.

Data remains in your Apify run storage; no external analytics/database is used. Storage retention and access follow your Apify account settings. Runs use limited permissions. Interrupted runs may have a report snapshot up to 24 rows behind the dataset; the dataset is authoritative. Normal completion, graceful abort and spending-limit stops refresh the report. Inspect interrupted paid runs before resurrection: dataset writes and charges are not a cross-service transaction.

### Support

Include a run ID, sanitized input and expected result in an Actor issue. Never share API tokens. Source-specific failures should be reviewed before telling a client that a placement was removed.

# Actor input Schema

## `placements` (type: `array`):

1–1000 {sourceUrl, targetUrl, expectedAnchor?, requireFollow?} records. Exact target URL; optional case-sensitive anchor and boolean follow requirement.

## `timeoutSecs` (type: `integer`):

Per-request deadline including DNS lookup. Range 2–30 seconds.

## `maxRedirects` (type: `integer`):

Maximum redirects followed for each supplied source page. Range 0–5.

## `delayMillis` (type: `integer`):

Delay between page requests and redirect hops. Range 100–5000 milliseconds.

## Actor input object example

```json
{
  "placements": [
    {
      "sourceUrl": "https://example.com/",
      "targetUrl": "https://iana.org/domains/example"
    }
  ],
  "timeoutSecs": 15,
  "maxRedirects": 3,
  "delayMillis": 250
}
```

# Actor output Schema

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

No description

## `report` (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 = {
    "placements": [
        {
            "sourceUrl": "https://example.com/",
            "targetUrl": "https://iana.org/domains/example"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("exceptional_nugget/backlink-placement-verifier").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 = { "placements": [{
            "sourceUrl": "https://example.com/",
            "targetUrl": "https://iana.org/domains/example",
        }] }

# Run the Actor and wait for it to finish
run = client.actor("exceptional_nugget/backlink-placement-verifier").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 '{
  "placements": [
    {
      "sourceUrl": "https://example.com/",
      "targetUrl": "https://iana.org/domains/example"
    }
  ]
}' |
apify call exceptional_nugget/backlink-placement-verifier --silent --output-dataset

```

## MCP server setup

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

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/xuseJEbcXcxIOsgU2/builds/P4X7SvEKJDytlnJ4c/openapi.json
