Redirect Checker & Bulk URL Status: Chains, Loops, 301 Map QA
Pricing
$0.80 / 1,000 url checkeds
Redirect Checker & Bulk URL Status: Chains, Loops, 301 Map QA
Bulk redirect checker and HTTP status code checker. Traces every hop (301/302/307/308, meta refresh) and flags redirect chains, loops, 404s, soft 404s, noindex targets and redirect-map mismatches after a site migration. First 20 URLs free, then $0.0008/URL.
Pricing
$0.80 / 1,000 url checkeds
Rating
0.0
(0)
Developer
Umair Saleem Mohammad Saleem
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 hours ago
Last modified
Categories
Share
Answer first: this actor is a bulk redirect checker and HTTP status code checker for SEO, site migrations and link cleanup. Give it a list of URLs, old → new pairs, a redirect map CSV (paste it, or a Google Sheets / Drive / Dropbox link) or a sitemap. It follows every hop itself (301, 302, 303, 307, 308 and meta refresh), records the status and Location of each one, and gives every URL a verdict and a one-line fix: REDIRECT_CHAIN, LOOP, TOO_MANY_REDIRECTS, TEMPORARY_REDIRECT (302 where a 301 belongs), BROKEN_4XX, SERVER_ERROR, SOFT_404, REDIRECTS_TO_HOMEPAGE, TARGET_NOINDEX, MAP_MISMATCH / NOT_REDIRECTED (the redirect doesn't land where your map says), HTTPS_TO_HTTP, SSL_ERROR, DNS_ERROR and more. It also writes a fix list CSV and a flattened redirects CSV (source → final URL for every chain, ready for your redirect rules). The first 20 URLs of every run are free, then $0.0008 per URL ($0.80 per 1,000). URLs that block the checker (401/403/429 or a bot challenge), invalid lines and duplicates are never billed.
| Quick facts | |
|---|---|
| Best for | Site migration QA (old → new redirect maps), redirect chain and loop cleanup, broken link / 404 checks, HTTP → HTTPS and www checks, checking old sitemaps or backlink targets after a relaunch |
| Input | URLs (one per line), old new pairs with optional expected status (410), a redirect map CSV (pasted or by link), or a sitemap URL |
| Output | One row per URL: verdict, severity, chainText (e.g. 301 → 302 → 200), hops, finalStatus, finalUrl, expectedUrl, matchesExpected, issues[], fix, finalTitle, finalRobots, finalCanonical, chain[] (every hop with status, Location and time) + FIX_LIST.csv, FLATTENED_REDIRECTS.csv, SUMMARY |
| Price | First 20 URLs free every run, then $0.0008 per URL checked. No start fee. Same price with the final-page check on or off |
| Needs | No API keys, no proxies, no login. Plain HTTP requests, max 4 at a time per host |
| Not included | JavaScript (window.location) redirects, crawling a whole site for links (use our Internal Link Audit for that), rank tracking |
Try it now: the input is prefilled with 4 lines, so the first run is free.
Sample output (real run, 20 Oct 2026)
Build 0.1.2, run zMx0ss7vuq6Ngmrui, 15 input lines (3 of them old → new pairs), finished in about 8 seconds. All 15 were within the 20 free URLs, so the run cost $0. Full public dataset: JSON · CSV · FIX_LIST.csv
| URL checked | Verdict | Status chain | Lands on |
|---|---|---|---|
| support.google.com/webmasters/answer/93633 | REDIRECT_CHAIN | 301 → 301 → 200 | developers.google.com/search/docs/crawling-indexing/301-redirects |
| docs.apify.com/platform/actors/running/ | REDIRECT_CHAIN + TEMPORARY_REDIRECT | 301 → 302 → 200 | docs.apify.com/actors/running |
| http://wikipedia.org | REDIRECT_CHAIN | 301 → 301 → 200 | https://www.wikipedia.org/ |
| httpbin.org/redirect/3 | REDIRECT_CHAIN + TEMPORARY_REDIRECT | 302 → 302 → 302 → 200 | httpbin.org/get |
| developers.google.com/search/docs/advanced/crawling/301-redirects | REDIRECT_OK | 301 → 200 | …/search/docs/crawling-indexing/301-redirects |
| twitter.com/apify → expected x.com/apify | MAP_OK | 301 → 200 | https://x.com/apify |
| http://github.com/about → expected https://github.com/about | MAP_OK | 301 → 200 | https://github.com/about |
| http://apify.com/store → expected apify.com/pricing (deliberately wrong) | MAP_MISMATCH | 301 → 200 | https://apify.com/store |
| http://bing.com | REDIRECT_OK + HTTP_FINAL, CANONICAL_ELSEWHERE | 301 → 200 | http://www.bing.com/ (canonical says https) |
| httpbin.org/status/404 | BROKEN_4XX | 404 | – |
| expired.badssl.com | SSL_ERROR | – | CERT_HAS_EXPIRED: certificate has expired |
| http://localhost:8080/x | PRIVATE_HOST (not requested, not billed) | – | – |
One row from that run (docs.apify.com/platform/actors/running/), trimmed:
{"inputUrl": "https://docs.apify.com/platform/actors/running/","verdict": "REDIRECT_CHAIN","severity": "warning","chainText": "301 → 302 → 200","hops": 2,"finalStatus": 200,"finalUrl": "https://docs.apify.com/actors/running","issueCodes": "REDIRECT_CHAIN, TEMPORARY_REDIRECT","issueSummary": "REDIRECT_CHAIN: 2 hops: 301 → 302 → 200 | TEMPORARY_REDIRECT: 302 at https://docs.apify.com/actors/running/","fix": "Multi-hop chain. Update the first rule to point straight at the final URL (one 301) and update internal links.","chain": [{ "step": 0, "url": "https://docs.apify.com/platform/actors/running/", "status": 301, "type": "redirect", "location": "https://docs.apify.com/actors/running/" },{ "step": 1, "url": "https://docs.apify.com/actors/running/", "status": 302, "type": "redirect", "location": "https://docs.apify.com/actors/running" },{ "step": 2, "url": "https://docs.apify.com/actors/running", "status": 200, "type": "final" }],"charged": false}
(These are public pages picked to show each verdict. A chain on someone else's site is just an observation, not a claim that it hurts them.)
Verdicts and what to do
| Verdict | Severity | Meaning | Fix |
|---|---|---|---|
OK / REDIRECT_OK / MAP_OK / STATUS_OK | ok | 200 directly, one clean 301/308 to a 200, lands where your map says, or returns the status you expected (e.g. 410) | – |
MAP_MISMATCH | error | Redirects, but not to the URL in your map | Point the rule at the expected URL |
NOT_REDIRECTED | error | Your map expects a redirect, the URL answers itself | Add the missing 301 |
STATUS_MISMATCH | error | Status differs from the one you expected (e.g. expected 410, got 200) | Fix the rule or the expectation |
LOOP / TOO_MANY_REDIRECTS | error | Never reaches a page (more than 10 hops by default; Googlebot follows up to 10) | Remove the conflicting rule |
BROKEN_4XX / SERVER_ERROR | error | Ends on 404, 410, 5xx… | 301 to the closest live page, or 410 on purpose |
TARGET_NOINDEX | error | Redirects to a noindex page (meta robots or X-Robots-Tag) | Remove noindex or pick another target |
DNS_ERROR / SSL_ERROR / TIMEOUT / CONNECTION_ERROR | error | Host doesn't resolve, bad certificate, no answer | Fix DNS / certificate / server |
REDIRECT_CHAIN | warning | 2+ hops | Point the first URL straight at the final one (see FLATTENED_REDIRECTS.csv) |
TEMPORARY_REDIRECT | warning | A 302/303/307 in the chain | Use 301 or 308 for permanent moves |
REDIRECTS_TO_HOMEPAGE | warning | Deep URL dumped on the homepage (Google often treats it as a soft 404) | Redirect to the closest matching page |
SOFT_404 | warning | 200 page that says "not found" | Return 404/410 or redirect properly |
META_REFRESH | warning | Client-side refresh used as a redirect | Replace with a server 301 |
HTTPS_TO_HTTP / HTTP_FINAL | warning / notice | Chain drops to HTTP, or ends on HTTP | Keep every hop on HTTPS |
CANONICAL_ELSEWHERE, CROSS_DOMAIN, NOINDEX | notice | Final page's canonical points elsewhere; redirect leaves the domain; page is noindex | Check it is intended |
BLOCKED, PRIVATE_HOST, INVALID_INPUT | notice | 401/403/429/bot challenge, internal address, unreadable line | Never billed |
Input
Plain list, pairs and expected statuses in one box:
{"urls": ["https://example.com/old-page","https://old-site.com/blog/post-1 https://new-site.com/blog/post-1","https://example.com/discontinued-product 410"]}
A migration redirect map (header names like old/new, source/destination, from/to and status are recognised; comma, semicolon or tab):
{"redirectMapCsv": "old_url,new_url,status\n/blog/seo-tips,/guides/seo-tips,301\n/old-pricing,/pricing,301\n/spring-sale,,410","baseUrl": "https://www.example.com"}
Or a link: "redirectMapUrl": "https://docs.google.com/spreadsheets/d/<id>/edit#gid=0" (share as Anyone with the link can view). Or check an old sitemap after launch: "sitemapUrl": "https://old.example.com/sitemap.xml", "maxUrls": 5000.
Options: maxRedirects (10), checkTargetPage (on: noindex, canonical, soft 404, meta refresh), followMetaRefresh (on), strictTrailingSlash (off: /page = /page/), browserUserAgent (off), maxConcurrency (10), requestTimeoutSecs (20), maxUrls (1,000; up to 20,000).
What a run costs
| URLs | Price |
|---|---|
| 20 | $0 (free every run) |
| 100 | $0.064 |
| 1,000 | $0.784 |
| 10,000 | $7.98 |
Set Maximum cost per run in the run options and the actor stops exactly there (tested: cap $0.004 → 20 free + 5 billed URLs, then a clean stop with stoppedAtSpendLimit: true in SUMMARY).
How it compares (live Apify Store prices, verified 20 Oct 2026)
| Actor | Price | Map QA (old → expected) | Notes |
|---|---|---|---|
| This actor | 20 free/run, then $0.0008/URL | yes (pairs, CSV, Sheets link) | Chains, loops, soft 404, noindex target, homepage dumps, fix list + flattened CSV |
| Broken link / bulk status checkers (several) | $0.001–$0.0025 per URL | no | Status codes and chains |
| Budget bulk status checkers | ~$0.00008–$0.0006/URL + $0.005–$0.035 start fee | no | Cheaper at very large volume, start fee on small runs |
| Site migration redirect map validator | $0.005 per mapping | yes | 6× the price per row |
For AI agents / MCP
Works as a tool in Claude, ChatGPT, Cursor or any agent through the Apify MCP server (cygnix_labs/redirect-checker) or the API. Ask: "Check these 300 old URLs redirect to the new site and give me the ones that don't." The agent passes:
{ "redirectMapUrl": "https://docs.google.com/spreadsheets/d/<id>/edit#gid=0", "maxUrls": 300 }
and reads verdict, matchesExpected and fix from the dataset, or the ready FIX_LIST.csv. Run it synchronously with POST https://api.apify.com/v2/acts/cygnix_labs~redirect-checker/run-sync-get-dataset-items.
FAQ
How do I check if a 301 redirect works? Put the old URL and the new URL on one line (old new). MAP_OK means it lands there; MAP_MISMATCH shows where it really goes; TEMPORARY_REDIRECT means it's a 302, not a 301.
How do I find redirect chains and loops in bulk? Paste the URLs or your sitemap. Every row shows the full chain (301 → 302 → 200), and FLATTENED_REDIRECTS.csv lists source → final for each chain so you can rewrite the rules as single hops.
Does it follow JavaScript redirects? No, only HTTP redirects and meta refresh (no browser, which keeps it fast and cheap). Search engines also prefer server-side 301s.
Why is a URL BLOCKED? The server answered 401/403/429 or a bot challenge, so nothing could be checked. It's free. Try browserUserAgent: true or check from your own network.
Does /page vs /page/ count as a mismatch? Not by default. Turn on strictTrailingSlash if it matters. Host case, default ports and #fragments are always ignored.
Is it safe to run on a live site? Yes: plain GET requests, max 4 at a time per host, no form posts. Bodies are only read for final HTML pages (first 1.5 MB).
Changelog
- 0.1 (20 Oct 2026): first public release. Hop-by-hop tracing, map QA (pairs, CSV, Sheets/Drive/Dropbox links, relative paths), sitemap input (indexes, .gz), 20+ verdicts with fixes, fix list + flattened redirects CSVs, spend cap safe, private-address guard.
More tools by Cygnix Labs
- Internal Link Audit: Orphan Pages & Sitemap Crawl: crawl your site for orphan pages and broken internal links.
- Website SEO Audit & Site Audit Crawler: page-level technical SEO + AEO score.
- Content Decay Audit: find pages losing traffic after a migration.
- Planning the migration? Our skill Plan 301 Redirects for a Site Migration Without Losing SEO (Claude Code / Cursor / Codex) builds the redirect map this actor tests.