# Redirect Chain Checker: Bulk URL Redirect Tracer, 301/302 (`eliai/redirect-chain-checker`) Actor

Bulk URL redirect tracer: every 301/302 hop, final URL and hop count per URL, flagging loops, long chains and http hops; short links expand too. 100 URLs cost $0.10. Runs with limited permissions, so AI agents can call and pay for it through Apify's x402 agentic payments (experimental).

- **URL**: https://apify.com/eliai/redirect-chain-checker.md
- **Developed by:** [Broke to Built](https://apify.com/eliai) (community)
- **Categories:** Developer tools, SEO tools, Automation
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 redirect checks

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

## Redirect Chain Checker - bulk URL redirect tracer for every 301/302 hop to the final URL

**Paste a URL, get the whole redirect path.** Every hop with its status code and `Location` header, the final destination and its status, the hop count, and the SEO problems hiding in the chain - redirect loops, chains that are too long, insecure `http://` hops, and 302s doing a 301's job.

No API key. No browser. No actor-start fee - **$0.02 per URL traced**, flat, however many hops the chain turns out to have.

**> Run it on the Apify Store: https://apify.com/eliai/redirect-chain-checker** - use it from the console, the API, or as an agent tool over Apify MCP.

Use it as a **redirect checker**, **URL redirect tracker**, **301 vs 302 checker**, **redirect loop detector**, **short-link expander** (bit.ly, t.co, lnkd.in), **HTTP status checker**, or a scriptable stand-in for `curl -ILs` across a whole list of URLs.

***

### What it does

- Follows redirects **hop by hop, up to 15**, recording each **URL + status code + `Location`**
- Reports the **final URL**, **final status**, and the **hop count**
- Flags the issues that matter for SEO and migrations:
  - **Redirect loop** - followed to the 15-hop cap, then reported instead of hanging your pipeline
  - **Long chain** (more than 2 hops) - leaks link equity, adds latency, may stop being followed
  - **Insecure hop** - the chain passes through plain `http://` before landing on HTTPS
  - **302 where 301 belongs** - a temporary redirect quietly withholding ranking signals
- **Bulk**: pass a list, get one record per URL in a single run
- Never crashes on a bad URL - an unreachable host becomes an `error` entry in the chain, and **error-only traces are not charged**

### Input

Single URL:

```json
{ "url": "http://github.com" }
```

Bulk (one record per URL, `maxUrls` is also your budget cap):

```json
{ "urls": ["http://github.com", "https://bit.ly/3xyzabc"], "maxUrls": 25 }
```

| Field | Type | Default | Notes |
|---|---|---|---|
| `url` | string | `http://github.com` | One URL. A bare domain gets `https://` prepended. |
| `urls` | array of strings | - | Bulk list; takes precedence over `url`. |
| `maxUrls` | integer | `25` | Hard cap on URLs processed - and therefore on spend. |

### Output - real, from a live run (2026-08-09)

```json
[
  {
    "url": "http://github.com",
    "finalUrl": "https://github.com/",
    "finalStatus": 200,
    "hops": 1,
    "hasRedirect": true,
    "redirectChain": [
      { "url": "http://github.com", "status": 301, "location": "https://github.com/" },
      { "url": "https://github.com/", "status": 200, "location": null }
    ],
    "issues": ["Chain passes through insecure http://"],
    "summary": "1 hop(s) -> 200, 1 issue(s)"
  },
  {
    "url": "https://bit.ly/3xyzabc",
    "finalUrl": "https://drive.google.com/drive/folders/1h58cRaUSsDuzotaMOSMsfMkwGTwdpFBR?usp=sharing",
    "finalStatus": 404,
    "hops": 1,
    "hasRedirect": true,
    "redirectChain": [
      { "url": "https://bit.ly/3xyzabc", "status": 301, "location": "https://drive.google.com/drive/folders/1h58cRaUSsDuzotaMOSMsfMkwGTwdpFBR?usp=sharing" },
      { "url": "https://drive.google.com/...", "status": 404, "location": null }
    ],
    "issues": [],
    "summary": "1 hop(s) -> 404, 0 issue(s)"
  }
]
```

That second record is the everyday win: the short link resolves fine, but the thing it points at is **gone**. A plain "does this URL work" check follows the redirect and reports 404 with no idea where the rot is.

### Call it from anywhere

```bash
curl -X POST "https://api.apify.com/v2/acts/eliai~redirect-chain-checker/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "content-type: application/json" \
  -d '{"urls":["http://github.com"],"maxUrls":25}'
```

### Use cases

- **Site migration QA** - after a replatform, verify every old URL lands on the right new one in **one** hop, not three
- **SEO audits** - find the chains and 302s that bleed link equity and crawl budget
- **Short-link forensics** - expand `bit.ly` / `t.co` / `lnkd.in` and see the real destination *before* you click it
- **Affiliate and UTM QA** - confirm tracking parameters survive every hop
- **Agent tooling** - one deterministic JSON answer to "where does this URL actually go", callable over Apify MCP

### Honest limits

- Follows **HTTP-level** redirects only: `Location` headers on 3xx responses. **Meta-refresh and JavaScript redirects are not followed** - if a page redirects via `<meta http-equiv="refresh">` or `window.location`, the chain ends at that page's 200.
- 12-second timeout per hop, 15-hop cap.
- Requests are made with a plain HTTP client (no browser, no proxy rotation). Sites behind aggressive bot protection may answer 403 to us and 200 to you.
- Follows the chain as an anonymous visitor - no cookies, no login, no geo targeting, so redirects that branch on session or country will show the anonymous branch.

### Pricing, and how it compares

**$0.02 per URL traced** - one `redirect-checked` event per URL, regardless of hop count. **No actor-start fee**, so a one-URL check costs exactly $0.02 and 100 URLs cost exactly $2.00.

Measured against the named alternatives on the store, re-checked 2026-08-15:

| Actor | Price shape | 1 URL | 100 URLs |
|---|---|---|---|
| **eliai/redirect-chain-checker** (this one) | $0.02/URL, no start fee | **$0.02** | $2.00 |
| `q_services/redirect-chain-checker` | $0.005 start + $0.0002/item | $0.0052 | $0.025 |
| `mighty_monk/redirect-chain-checker` | $0.00005 start + $0.002/item | $0.0021 | $0.20 |
| `davidbenittah/redirect-chain-auditor` | $0.005 start + $0.005/item | $0.010 | $0.505 |

**Be honest about which you need.** If you are sweeping thousands of URLs for raw status codes, a per-item actor above is cheaper and you should use it. This one is priced for the **diagnostic** job - the full hop-by-hop chain *plus* the loop / long-chain / insecure-hop / 302-vs-301 analysis in the same record, with a flat per-URL price that has no start fee to amortize and no surprise item count.

### FAQ

**How do I see where a URL redirects to?** Pass it in. `redirectChain` lists every hop with its status code and `Location`; `finalUrl` and `finalStatus` show where you actually land. Works on shortened links.

**Why are redirect chains bad for SEO?** Each extra hop leaks link equity and adds latency, and search engines may stop following long chains entirely - which is why more than 2 hops is flagged.

**What is the difference between a 301 and a 302?** 301 is permanent (ranking signals transfer); 302 is temporary (the old URL stays indexed). A 302 doing a permanent job withholds equity from the new URL - this actor flags that pattern.

**Can it detect redirect loops?** Yes. Loops are followed to the 15-hop cap and then reported in `issues` rather than hanging.

**Can I audit a whole list of URLs?** Yes - pass an array in `urls` (capped by `maxUrls`); you get one record per URL.

**Does it follow meta-refresh or JavaScript redirects?** No - HTTP `Location` redirects only. See *Honest limits*.

**What happens if a URL is unreachable?** You get a record whose chain ends in an `error` entry instead of a failed run, and that trace is **not charged**.

### Related actors

Same toolbox, same account - each does one job well:

- [Broken Link Checker](https://apify.com/eliai/broken-link-checker) - crawl a page and find every dead link
- [Website SEO Tech Auditor](https://apify.com/eliai/website-seo-tech-auditor) - the full technical SEO pass on one URL
- [Sitemap Analyzer](https://apify.com/eliai/sitemap-analyzer) - parse and validate a sitemap
- [Robots.txt Analyzer](https://apify.com/eliai/robots-txt-analyzer) - see what you are actually blocking
- [DNS Records Lookup](https://apify.com/eliai/dns-records-lookup) - A, AAAA, MX, TXT, NS in one call
- [Security Headers Checker](https://apify.com/eliai/security-headers-checker) - HSTS, CSP, and friends
- [Webpage Links Extractor](https://apify.com/eliai/webpage-links-extractor) - pull every link off a page

Built by Broke to Built.

### Changelog

- 2026-11-01: Page text only: a clearer page heading. Code, output and price are unchanged.

### For AI agents

This Actor is built to be called by software, not just by people.

- **Mount it directly as an MCP tool** — no Store search, no ranking, just this one tool:
  `https://mcp.apify.com/?actors=eliai/redirect-chain-checker`
- **Or call it over HTTP** and get the results in the same request:
  `POST https://api.apify.com/v2/acts/eliai~redirect-chain-checker/run-sync-get-dataset-items`
- **Costs are predictable before you call.** Pricing is pay-per-event (see Pricing above), so an agent can budget a run in advance instead of discovering the bill afterwards.
- **Send only the field you mean.** If you pass the bulk field, it is used on its own; the single-value field is a fallback, never merged into your request. You are charged for the items you sent and nothing else.

# Actor input Schema

## `url` (type: `string`):

A URL to trace redirects for (e.g. http://example.com)

## `urls` (type: `array`):

Multiple URLs to trace in one run

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

Maximum number of URLs processed in one run; anything beyond it is skipped, so this also caps the cost.

## Actor input object example

```json
{
  "url": "http://github.com",
  "urls": [],
  "maxUrls": 25
}
```

# Actor output Schema

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

Every item this run produced. Export as JSON, CSV or Excel from the dataset view.

# 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 = {
    "url": "http://github.com",
    "urls": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("eliai/redirect-chain-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 = {
    "url": "http://github.com",
    "urls": [],
}

# Run the Actor and wait for it to finish
run = client.actor("eliai/redirect-chain-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 '{
  "url": "http://github.com",
  "urls": []
}' |
apify call eliai/redirect-chain-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,eliai/redirect-chain-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/9KfDi3Pua70KEylkQ/builds/8SlYdec8eMsfvkj1b/openapi.json
