Redirect Chain Checker avatar

Redirect Chain Checker

Pricing

$0.15 / 1,000 redirect checks

Go to Apify Store
Redirect Chain Checker

Redirect Chain Checker

Trace public HTTP/HTTPS URLs hop by hop to see the terminal URL, domain, status, timing, and redirect issues. Review clear audit rows for SEO checks, site migrations, and link QA.

Pricing

$0.15 / 1,000 redirect checks

Rating

0.0

(0)

Developer

Maxime Dupré

Maxime Dupré

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

7 days ago

Last modified

Share

🔗 Trace every redirect path

SEO teams, developers, and site owners can use Redirect Chain Checker to trace public HTTP/HTTPS URLs hop by hop. Get each URL's terminal URL and domain, status code, redirect hops, response times, and diagnosed issues in a clear dataset. Use it to review link changes, find terminal errors, and check redirect paths before a site migration.

Use cases

📦 See the full redirect chain

Each saved dataset row represents one submitted public HTTP/HTTPS URL. The Actor follows server-side redirects and records the ordered hops, terminal destination, status codes, timing, and issue details it observes.

The resultScope choice controls which rows are returned. all keeps clean and issue rows. issuesOnly keeps rows with a diagnosed issue. A clean chain has an empty issueTypes array; an issue row can include redirectLoop, maxDepthExceeded, terminalError, temporaryRedirect, insecureHop, longChain, or resolutionError.

These are point-in-time network observations. A later check can see a different status, destination, or response time.

▶️ Run a URL redirect audit

  1. Add one or more public URLs that start with http:// or https://.
  2. Choose all or issuesOnly for resultScope.
  3. Set maxDepth when you need a different redirect boundary, or leave it empty to use 10.
  4. Start the run and open the dataset or the output links.

The Actor checks only the URLs you submit. It does not crawl a domain, discover new URLs, render page content, or follow client-side JavaScript or meta-refresh navigation. It checks public destinations without a source login or API key and does not audit private, local-network, login-gated, paywalled, CAPTCHA-protected, or otherwise access-controlled destinations.

⚙️ Input

Input fields

FieldTypeWhat it does
urlsarray of stringsRequired. Adds 1–10,000 public HTTP/HTTPS URLs to check. Each URL is checked separately.
resultScopestringChoose all to return clean and issue rows, or issuesOnly to return only rows with a diagnosed issue. Defaults to all.
maxDepthintegerSets the maximum number of redirect responses to follow for each URL. A chain that needs more hops is reported as exceeding this limit. Leave it empty to use 10.

This is the public input from a successful current-beta default-input run:

{
"urls": [
"https://example.com",
"https://httpbin.org/redirect/2",
"https://httpbin.org/status/404"
],
"resultScope": "all",
"maxDepth": 10
}

🧾 Output

Run output links

FieldTypeWhat it does
resultsstringOpens the default dataset with completed URL audit rows.
summary.urlsCheckedstringOpens the run's count of submitted URLs checked.
summary.urlsWithIssuesstringOpens the run's count of checked URLs with one or more diagnosed issues.

Dataset audit rows

FieldTypeWhat it does
submittedUrlstringThe public URL submitted for checking.
terminalUrlstring or nullThe last URL reached after redirects, or null when no terminal response was reached.
terminalDomainstring or nullThe domain at the terminal URL, or null when no terminal response was reached.
terminalStatusCodeinteger or nullThe final HTTP status code, or null when no terminal response was reached.
redirectHopCountintegerThe number of redirect responses in the chain.
hopsarray of objectsThe ordered responses seen while the URL was checked.
hops[].urlstringThe URL requested at that hop.
hops[].statusCodeintegerThe HTTP status code returned at that hop.
hops[].redirectUrlstring, optionalThe absolute URL reached by that redirect. It is omitted for the terminal response.
hops[].responseTimeMsintegerThe time to receive that response, in milliseconds.
chainResolutionTimeMsintegerThe total time to resolve the redirect chain, in milliseconds.
checkedAtdate-time stringThe UTC time when the URL audit was recorded.
isShortenerbooleanWhether the submitted URL uses a recognizable URL-shortener domain.
isCleanbooleanWhether the chain reached its destination without a diagnosed redirect issue.
issueTypesarray of stringsIssue identifiers in priority order. An empty array means no issue was found.
diagnosisstring, optionalA plain-language explanation of the redirect issues. It is omitted when no issue is found.

This complete row is from a successful current-beta run. It shows a two-hop chain with temporary redirects and a long-chain diagnosis:

{
"submittedUrl": "https://httpbin.org/redirect/2",
"terminalUrl": "https://httpbin.org/get",
"terminalDomain": "httpbin.org",
"terminalStatusCode": 200,
"redirectHopCount": 2,
"hops": [
{
"url": "https://httpbin.org/redirect/2",
"statusCode": 302,
"redirectUrl": "https://httpbin.org/relative-redirect/1",
"responseTimeMs": 687
},
{
"url": "https://httpbin.org/relative-redirect/1",
"statusCode": 302,
"redirectUrl": "https://httpbin.org/get",
"responseTimeMs": 1105
},
{
"url": "https://httpbin.org/get",
"statusCode": 200,
"responseTimeMs": 831
}
],
"chainResolutionTimeMs": 2623,
"checkedAt": "2026-08-09T16:14:24.892Z",
"isShortener": false,
"isClean": false,
"issueTypes": [
"temporaryRedirect",
"longChain"
],
"diagnosis": "The chain contains a temporary 302 redirect. The chain contains more than one redirect hop."
}

When maxDepth stops a chain before a terminal response, the terminal URL, domain, and status can be null. This is a genuine row from a successful issuesOnly run:

{
"submittedUrl": "https://httpbin.org/redirect/2",
"terminalUrl": null,
"terminalDomain": null,
"terminalStatusCode": null,
"redirectHopCount": 2,
"hops": [
{
"url": "https://httpbin.org/redirect/2",
"statusCode": 302,
"redirectUrl": "https://httpbin.org/relative-redirect/1",
"responseTimeMs": 368
},
{
"url": "https://httpbin.org/relative-redirect/1",
"statusCode": 302,
"redirectUrl": "https://httpbin.org/get",
"responseTimeMs": 311
}
],
"chainResolutionTimeMs": 679,
"checkedAt": "2026-08-09T16:14:24.825Z",
"isShortener": false,
"isClean": false,
"issueTypes": [
"maxDepthExceeded",
"temporaryRedirect",
"longChain"
],
"diagnosis": "The redirect chain exceeds the selected maximum depth. The chain contains a temporary 302 redirect. The chain contains more than one redirect hop."
}

💳 Pricing

Pricing is pay per event. The buyer-facing event is Redirect check: one public URL is traced through its redirect chain and saved with hop details, terminal destination when reached, status, and diagnosis. See the Store pricing panel for the current rate.

🔌 Integrations

Use the dataset and output links in Apify Console or the Apify API. Apify schedules and webhooks can run or notify your workflow when you need recurring checks.

❓ FAQ

Does it follow client-side JavaScript or meta-refresh redirects?

No. It traces server-side HTTP redirects only. It does not render pages or execute client-side JavaScript or meta-refresh navigation.

Can it check a private or login-protected URL?

No. It checks public HTTP/HTTPS URLs without a source login or API key. Private, local-network, login-gated, paywalled, CAPTCHA-protected, and other access-controlled destinations are not supported.

What does maxDepth do?

It sets the maximum number of redirect responses to follow for each URL. If the chain needs more hops, the row can include maxDepthExceeded, and terminal fields can be null when no terminal response was reached.

What does issuesOnly change?

It changes which rows are returned. all includes clean and issue rows, while issuesOnly returns only rows with a diagnosed issue.

Can it show 301 and 302 redirects?

Yes. Each hop includes its HTTP statusCode. A 302 response can also add temporaryRedirect to issueTypes when the Actor diagnoses it as an issue.

Does it crawl a whole website?

No. Submit the URLs you want to check. The Actor does not discover links or crawl a domain.

Why can a later check show a different status or response time?

Each row is a point-in-time observation from the run environment. Server changes, network conditions, and geography can change a later result.

Can it identify shortened URLs?

Yes, when the submitted URL uses a recognizable URL-shortener domain, isShortener is true.

📝 Changelog

0.0: Initial release

🆘 Support

For issues, questions, or feature requests, file a ticket and I'll fix or implement it in less than 24h 🫡

Made with ❤️ by Maxime Dupré