# Redirect & Canonical Destination Validator (`x2ppi/redirect-canonical-destination-validator`) Actor

Checks public URL redirects, final HTTP status, canonical URLs, and expected migration targets.

- **URL**: https://apify.com/x2ppi/redirect-canonical-destination-validator.md
- **Developed by:** [Yota](https://apify.com/x2ppi) (community)
- **Categories:** SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $16.00 / 1,000 url validations

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/platform/actors/running/actors-in-store#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

## Redirect & Canonical Destination Validator

Validate public URL migration mappings in bulk before or after a site move. For every source URL, the Actor records the redirect chain, final HTTP status, final canonical URL, expected-target checks, a concise migration-QA verdict, and an actionable next step for every detected mismatch.

Use it when an SEO, engineering, or QA team needs to verify that old URLs land on the intended replacement pages—not merely that a redirect exists.

### Start with the ready-made migration check

Use the public [Validate Website Redirects & Canonicals](https://apify.com/x2ppi/redirect-canonical-destination-validator/examples/validate-url-migration-mapping) task when you want a bounded, prefilled migration-QA run. Duplicate the task, paste a CSV migration sheet, and set the run's maximum charge before starting.

### What it checks

- Redirect path and hop count (up to 10 redirects)
- Final HTTP status
- HTML canonical link on the final page
- Mismatches between the final URL, canonical URL, and expected migration target
- A `pass` or `needs-attention` verdict with deterministic, issue-linked remediation actions

### Input

Provide `urlMappings` such as:

```json
{
  "urlMappings": [
    {
      "sourceUrl": "https://old.example.com/product-a",
      "expectedTargetUrl": "https://www.example.com/product-a"
    }
  ]
}
```

For a redirect-only health check, omit `expectedTargetUrl`. For a migration QA check, include the approved target URL for every mapping.

#### Paste a spreadsheet CSV

You can also export a migration sheet as CSV and paste it into **URL mappings CSV**. The first two columns may be used without headers, or use these headers:

```csv
sourceUrl,expectedTargetUrl
https://old.example.com/product-a,https://www.example.com/product-a
```

When both JSON mappings and CSV rows are supplied, duplicate source URLs are checked once.

Use public `http` or `https` URLs only. The Actor rejects localhost and non-public DNS addresses, checks every redirect destination again, follows at most 10 redirects, and reads at most 2 MiB per response.

### Pricing

- From $0.02 per completed URL validation (Free-tier price; eligible higher tiers receive a progressive Store discount)
- A validation is charged only after its result is stored in the default Dataset.
- Failed requests are not charged.

For example, 100 stored validation results cost up to $2.00 at the Free-tier price. A DNS, timeout, or connection failure is logged and is not billed.

### Automate it

Use the Actor from a deployment script, CI job, or any Apify integration. Keep the token outside source control and pass it as an environment variable:

```bash
curl -X POST "https://api.apify.com/v2/acts/x2ppi~redirect-canonical-destination-validator/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"urlMappingsCsv":"sourceUrl,expectedTargetUrl\\nhttps://old.example.com/a,https://www.example.com/a"}'
```

For a release gate, save the approved migration sheet as an Apify task and alert on any `needs-attention` result. Review the stored `issues` and `recommendations` before changing production redirects or canonical tags.

### How to interpret results

- `verdict: "pass"` means the Actor found no checked HTTP, redirect-chain, expected-target, or canonical mismatch.
- `verdict: "needs-attention"` means `issues` and `recommendations` explain what to review next. Recommendations are technical QA guidance; confirm the migration plan before changing production redirects or canonicals.
- `expectedTargetMatchesFinalUrl: false` means the redirect finished at a different page than the supplied migration target.
- `finalCanonicalMatchesFinalUrl: false` means the destination page declares another canonical URL.
- `issues` contains concise flags for non-2xx finals, long redirect chains, and mapping/canonical mismatches.

### Output fields for QA handoff

- `redirectChain`: every observed redirect hop, including status and `Location` target.
- `finalUrl` and `finalStatus`: where the request ended.
- `finalCanonicalUrl`: canonical declared by the final HTML response, if present.
- `recommendations`: issue code, priority, and a concrete next action for an engineer or SEO reviewer.

### Boundaries

This Actor makes bounded public HTTP requests only. It rejects localhost and non-public DNS addresses, checks redirect destinations again, follows at most 10 redirects, and reads at most 2 MiB per response. It does not log in, bypass access controls, use customer credentials, or confirm indexing, ranking, or migration success in search engines.

This is an HTTP and HTML QA tool. It does not confirm indexing, ranking, or migration success in search engines.

# Actor input Schema

## `urlMappings` (type: `array`):

Public source URLs and optional expected final destinations. Maximum 1,000 unique source URLs.

## `urlMappingsCsv` (type: `string`):

Paste a CSV export from a migration sheet. Use sourceUrl,expectedTargetUrl headers, or put source URL in column 1 and expected target in column 2.

## `maxUrls` (type: `integer`):

Limits the number of unique source URLs processed in this run.

## `maxConcurrency` (type: `integer`):

Caps concurrent public HTTP requests.

## `requestTimeoutSecs` (type: `integer`):

Stops an individual request after this number of seconds.

## Actor input object example

```json
{
  "urlMappings": [
    {
      "sourceUrl": "https://example.com/",
      "expectedTargetUrl": "https://example.com/"
    }
  ],
  "urlMappingsCsv": "sourceUrl,expectedTargetUrl\nhttps://old.example.com/product-a,https://www.example.com/product-a",
  "maxUrls": 25,
  "maxConcurrency": 5,
  "requestTimeoutSecs": 15
}
```

# Actor output Schema

## `validationResults` (type: `string`):

One stored result per completed public URL validation, including redirect, canonical, expected-target, verdict, and remediation fields.

# 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 = {
    "urlMappings": [
        {
            "sourceUrl": "https://example.com/",
            "expectedTargetUrl": "https://example.com/"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("x2ppi/redirect-canonical-destination-validator").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 = { "urlMappings": [{
            "sourceUrl": "https://example.com/",
            "expectedTargetUrl": "https://example.com/",
        }] }

# Run the Actor and wait for it to finish
run = client.actor("x2ppi/redirect-canonical-destination-validator").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "urlMappings": [
    {
      "sourceUrl": "https://example.com/",
      "expectedTargetUrl": "https://example.com/"
    }
  ]
}' |
apify call x2ppi/redirect-canonical-destination-validator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=x2ppi/redirect-canonical-destination-validator",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/gKGP2uMOTq19gfaIw/builds/xW5uBIPIWx3MK7uka/openapi.json
