Bulk Redirect Checker: 301 Chains, Loops & Redirect Maps avatar

Bulk Redirect Checker: 301 Chains, Loops & Redirect Maps

Pricing

$0.50 / 1,000 urls

Go to Apify Store
Bulk Redirect Checker: 301 Chains, Loops & Redirect Maps

Bulk Redirect Checker: 301 Chains, Loops & Redirect Maps

Bulk redirect checker: every hop of each URL's 301/302 redirect chain, final URL and status code, redirect loops, meta refresh, HTTPS downgrade, and old -> new redirect map validation for site migrations. $0.50 per 1,000 URLs, no start fee; unreachable or blocked URLs are free. API, MCP, n8n.

Pricing

$0.50 / 1,000 urls

Rating

0.0

(0)

Developer

Quan Ta

Quan Ta

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 hours ago

Last modified

Share

Paste a list of URLs — or a redirect map of old URL -> new URL pairs — and get one clean row per URL with every hop of the redirect chain, where it really ends, and plain issue codes: redirect loops, chains, temporary (302) instead of permanent (301) redirects, meta refreshes, HTTPS → HTTP downgrades, redirects to the homepage, dead destinations and mismatches against the URL you expected.

Every URL gets every hop and up to 17 issue codes in a single pass:

WhatDetails
Every hopURL, HTTP status, Location, redirect type (301 / 302 / 303 / 307 / 308 / meta refresh) and time per hop
Where it endsFinal URL, final status code, page title, content type
Expected destinationOptional per line: does the chain end exactly where your redirect map says? (expectedMatch)
Loops & limitsRedirect loops, chains longer than your limit, 3xx without Location, unparseable Location, redirects to mailto: and other non-web addresses
Chain qualityChains of 2+ redirects, temporary redirects, meta-refresh redirects, JavaScript redirect pages, permanent-only chains
HTTPShttp:// → https:// upgrade, HTTPS → HTTP downgrade, invalid / expired certificates on the way
SEO red flagsDeep URL redirected to the homepage (soft-404 risk), cross-domain redirects, final 4xx / 5xx
Dead destinationsThe start URL redirects, but the target does not answer

No browser, no proxy, no API keys. In our test, a list of 30 mixed real-world URLs (23 traced, 7 that failed fast) took about 11 seconds at the default settings (10 in parallel), plus a few seconds for the run to start. $0.0005 per URL ($0.50 per 1,000) — URLs that can't be reached or block automated access are free.

Who is it for?

  • SEO & site migrations: paste your redirect map (old URL -> new URL) before and after launch; filter expectedMatch = false to see every old URL that lands in the wrong place, on a 404, on the homepage, or through a 302.
  • SEO audits: find redirect chains and loops that waste crawl budget, temporary redirects that should be permanent, and HTTP pages that never upgrade to HTTPS.
  • Marketing & PPC teams: check that campaign, QR-code and short links (bit.ly, t.co …) still end on the right landing page.
  • Affiliate & link managers: expand tracking links and verify the final destination.
  • Developers: verify http → https → www canonicalisation and redirect rules after a deploy.

How to use

  1. Add your URLs in URLs to check — one per line. Full URLs are checked exactly as typed (http:// and https://, www and non-www, trailing slash — these are different redirect tests). Bare domains (example.com) start on http:// so you see the whole http → https → www chain.
  2. To check a redirect map, put the expected destination on the same line: https://old.com/page -> https://new.com/page. A tab also works (paste two columns straight from a spreadsheet — a third column such as 301 is ignored), and so does a space. The expected URL may be a path (/new-page) on the same site. Lines that can't be read safely are listed as invalid and are free.
  3. Click Start. Download the results as CSV, Excel, JSON or use the API.

Input example

{
"urls": [
"http://wikipedia.org -> https://www.wikipedia.org/",
"http://example.com/old-page -> https://example.com/new-page",
"https://httpbin.org/redirect/2",
"http://github.com"
],
"maxRedirects": 10,
"userAgent": "browser"
}

Output example (real row)

{
"input": "http://wikipedia.org -> https://www.wikipedia.org/",
"url": "http://wikipedia.org/",
"status": "ok",
"charged": true,
"errorCode": null,
"expectedUrl": "https://www.wikipedia.org/",
"expectedMatch": true,
"finalUrl": "https://www.wikipedia.org/",
"finalStatusCode": 200,
"redirectCount": 2,
"redirectChain": "301 → 301 → 200",
"redirectPath": "http://wikipedia.org/ → https://wikipedia.org/ → https://www.wikipedia.org/",
"permanentOnly": true,
"httpsUpgrade": true,
"issues": ["REDIRECT_CHAIN"],
"issueCount": 1,
"hops": [
{ "step": 1, "url": "http://wikipedia.org/", "statusCode": 301, "location": "https://wikipedia.org/", "type": "301", "timeMs": 249, "tlsError": null },
{ "step": 2, "url": "https://wikipedia.org/", "statusCode": 301, "location": "https://www.wikipedia.org/", "type": "301", "timeMs": 69, "tlsError": null },
{ "step": 3, "url": "https://www.wikipedia.org/", "statusCode": 200, "location": null, "type": null, "timeMs": 294, "tlsError": null }
],
"finalTitle": "Wikipedia",
"totalTimeMs": 619
}

The same run also found http://example.com/old-page -> https://example.com/new-page → status: "http_error", redirectChain: "404", issues: ["FINAL_4XX", "EXPECTED_MISMATCH"] — the old URL was never redirected.

Validate a redirect map (site migration)

  1. Export your redirect map as two columns (old URL, new URL) and paste it into URLs to check — one pair per line.
  2. Run it on the old domain before launch (staging rules) and again after launch.
  3. Open the Redirect map QA view and filter expectedMatch = false. The issues column tells you why: EXPECTED_MISMATCH with REDIRECT_TO_HOMEPAGE, FINAL_4XX, TEMPORARY_REDIRECT or REDIRECT_CHAIN.
  4. Options for the comparison: Ignore a trailing slash (on by default) and Ignore the query string (off by default — turn it on when the site adds tracking parameters). Host case and default ports are always ignored; scheme, host, path and query otherwise must match.

Issue codes

CodeMeaning
REDIRECT_LOOPThe chain comes back to a URL it already visited (cookies are kept like a browser, so "set a cookie and redirect to itself" is not a false loop)
TOO_MANY_REDIRECTSMore redirects than Max redirects to follow (default 10)
REDIRECT_CHAIN2 or more redirects before the final page — each extra hop costs time and link equity
TEMPORARY_REDIRECTAt least one 302 / 303 / 307 in the chain (search engines may keep the old URL)
META_REFRESH_REDIRECTAn HTML <meta http-equiv="refresh"> redirect (delay up to 10 s)
HTTPS_TO_HTTPA hop goes from HTTPS back to plain HTTP
REDIRECT_TO_HOMEPAGEA deep URL ends on the homepage — often a lazy migration rule (soft-404 risk)
CROSS_DOMAIN_REDIRECTThe chain ends on another domain (www. is ignored)
FINAL_4XX / FINAL_5XXThe chain ends on a client / server error page
MISSING_LOCATIONA 3xx answer without a Location header
INVALID_LOCATIONA Location header that is not a valid URL
NON_HTTP_REDIRECTA redirect to mailto:, an app scheme or another non-web address
REDIRECT_TARGET_UNREACHABLEThe start URL redirects, but the destination does not answer (DNS / timeout / connection error)
EXPECTED_MISMATCHYou gave an expected URL and the chain does not end there with a page
INVALID_CERTIFICATEA hop uses an expired, self-signed or otherwise invalid HTTPS certificate (the chain is still followed)
JAVASCRIPT_REDIRECTThe chain ends on a tiny page whose script sends the browser elsewhere (window.location = …). Scripts are not run, so the real destination is not followed

Status column

Every row starts with the same columns, so failures are easy to filter:

statusMeaningCharged?
okThe chain was traced and ends on a 2xx pageYes
http_errorThe chain was traced but ends badly: a 4xx / 5xx page (HTTP_4XX / HTTP_5XX), REDIRECT_LOOP, TOO_MANY_REDIRECTS, MISSING_LOCATION, INVALID_LOCATION, NON_HTTP_REDIRECT or REDIRECT_TARGET_UNREACHABLE — these are the findings a checker is forYes
blockedThe site refused automated access (ACCESS_REFUSED = HTTP 401/403/405/429, BOT_CHALLENGE = Cloudflare / Akamai / AWS WAF challenge). The hops before the refusal are still listedNo
unreachableThe first request failed (DNS_NOT_FOUND, TIMEOUT, CONNECTION_REFUSED, CONNECTION_FAILED, TLS_ERROR), or a redirect points into a private / internal network (PRIVATE_ADDRESS, never followed)No
invalidThe input line is not a public URL or domainNo
skippedYour Max cost per run was reached before this URLNo
errorUnexpected internal error (please open an issue)No

The dataset has two ready-made table views: Overview and Redirect map QA.

Options

  • Max redirects to follow (default 10, up to 30).
  • Check as: Browser (Chrome) or the Googlebot user-agent string (smartphone) — to spot sites that redirect search engines differently. Requests still come from Apify's servers, not from Google, so firewalls that verify Googlebot by IP block them; those rows show up as blocked and are free.
  • Follow <meta http-equiv="refresh"> (on by default).
  • Ignore a trailing slash / Ignore the query string when comparing with the expected URL.
  • …or URLs from a dataset: use the output of another Actor (a sitemap or crawler). Fields url / loc / finalUrl / website / domain are read; an expectedUrl field becomes the expected destination.

Use it with n8n, Make, Zapier or Google Sheets

Every run produces a normal Apify dataset, so it works with all Apify integrations:

  • n8n — Apify node: Run an Actor → Get dataset items, then send rows to Google Sheets, Airtable or your CRM.
  • Make / Zapier — Apify app (Make: Watch Actor Runs / Run an Actor; Zapier: trigger Finished Actor Run / action Run Actor).
  • Google Sheets / Excel — download the dataset as CSV/Excel. In CSV the hops are flattened into hops/0/url, hops/0/statusCode …; the redirectChain and redirectPath columns give the same in one cell.
  • API (small lists) — POST https://api.apify.com/v2/acts/quanta1810~bulk-redirect-checker/run-sync-get-dataset-items?token=YOUR_TOKEN with the input JSON returns the results in one call (synchronous calls time out after 300 s).
  • API (bulk) — POST …/acts/quanta1810~bulk-redirect-checker/runs?token=YOUR_TOKEN, then poll the run and read GET …/datasets/{defaultDatasetId}/items, or attach a webhook for run succeeded.
  • Weekly checks — save your list as a task and add an Apify Schedule; connect the Slack or email integration to get the results.

Pricing

Pay only for results: $0.0005 per URL with a traced chain ($0.50 per 1,000). There is no start fee.

  • URLs that can't be reached on the first request, are behind bot protection, point into a private network, are invalid or were skipped are listed with the reason but not charged.
  • Set Max cost per run in the run options to cap your spend; the Actor processes as many URLs as fit and lists the rest as skipped.
  • Exact duplicate lines are checked (and charged) once. http:// vs https://, www vs non-www and a trailing slash are kept apart on purpose — they are different redirect tests.

Limits & notes

  • Up to 50,000 URLs per run — split bigger lists into several runs. With the minimum memory (256 MB) the Actor checks 5 URLs in parallel; the default 512 MB allows 10.
  • It follows HTTP redirects and HTML meta refreshes. JavaScript redirects (window.location = …) are not executed — a tiny page that contains one is reported as the final page with the JAVASCRIPT_REDIRECT issue.
  • Each URL gets at most about a minute (longer with a higher request timeout): a host that never answers is retried once and then reported as unreachable, free.
  • Requests come from Apify's datacenter IPs. Sites with strict bot protection (some news and retail sites) answer 403 or a challenge page: those rows are blocked and free, and the hops before the refusal are still shown.
  • Only public URLs are checked. Redirects into private or internal networks (10.x, 127.x, 169.254.169.254, names that resolve to such addresses …) are never followed.
  • Only the first 256 KB of the final page are read (enough for the title and meta refresh).

FAQ

Is this a bulk redirect checker? Yes — paste up to 50,000 URLs per run; each gets the full chain, hop by hop, with status codes and timing.

Can it check a 301 redirect map after a site migration? Yes — put old URL -> new URL on each line and filter expectedMatch = false.

Does it detect redirect loops and redirect chains? Yes — REDIRECT_LOOP, TOO_MANY_REDIRECTS and REDIRECT_CHAIN, with every hop listed.

Can I check 302 vs 301 redirects? Yes — every hop has its type; permanentOnly is true when the chain uses only 301/308, and TEMPORARY_REDIRECT flags any 302/303/307.

Does it expand short links (bit.ly, t.co, goo.gl)? Yes — the final URL and every intermediate hop are listed.

Is it an HTTP status code checker too? Yes — URLs without redirects simply give one hop with their status code (redirectChain: "200" or "404").

Can I check with a Googlebot user-agent? Yes — set Check as to the Googlebot user-agent string. It shows sites that redirect by user-agent; sites that verify Googlebot by IP will block it.

Can I schedule it? Yes — use Apify Schedules to run it daily, weekly or monthly.

Why was a URL not charged? Only URLs whose chain could be traced are charged. Unreachable, blocked, private-network, invalid and skipped URLs are free — see the status column.

Found a bug or need another check? Open an issue on the Actor's Issues tab — requests are welcome.

Other bulk checkers by the same developer, built to run side by side on the same list of sites:

  • Bulk Website Audit — one health score per site: on-page SEO, SSL expiry, security headers, SPF/DMARC email DNS and public contact emails.
  • Bulk PageSpeed Checker — Lighthouse scores and real-user Core Web Vitals (LCP, INP, CLS) for many URLs, mobile and desktop.

Support & changelog

Issues opened on the Issues tab are answered within 5 business days.

Need something this tool does not do yet? An extra check, a different output column or an option for your workflow — open an issue on the Issues tab and describe it. Requests from real users decide what gets built next.

  • 0.1.0 (18 October 2026) — first release.