Check redirects
See every stop a link makes before it lands: each hop with its redirect code, target address and response time, up to the final page. Spot a 302 that should be a 301, or a chain grown to four hops. You pay per use, with no subscription.
Run it online
Run this on our servers with your account. Free tools run in your browser; this one bills your KIT balance per the price above.
A single redirect is easy to reason about; three or four chained together, each added by a different team over a different year, is how sites quietly start losing search rankings and shaving seconds off load time without anyone noticing.
How redirect chains actually accumulate
Nobody sets out to build a four-hop redirect chain on purpose. It happens one migration at a time: a URL structure changes and gets a redirect, then a domain moves to https and gets another, then a CDN or campaign tool adds a tracking redirect on top, and each addition is reasonable in isolation. Years later the original link still works, but a visitor's browser is quietly making three or four extra round trips to get there, and nobody remembers why.
Why the type of each redirect matters
A 301 tells search engines and browsers the move is permanent and safe to cache and follow directly next time; a 302 or 307 says the opposite, that it might change back, so it gets re-checked on every visit. A chain built entirely from temporary redirects when the moves were actually permanent means paying the latency cost of every hop, forever, on every single request.
What you can do with it
Post-migration link audits
Confirm old URLs after a domain or platform migration resolve in one clean hop instead of bouncing through several legacy redirects.
SEO redirect cleanup
Find chains built from temporary redirects that should be permanent, so search engines pass link value through cleanly.
Marketing link and campaign QA
Trace a shortened or tracked campaign URL through every intermediate hop before it goes into a paid ad or newsletter.
Site performance audits
Identify pages losing load time to unnecessary redirect hops that accumulated over years of incremental changes.
FAQ
How many redirect hops is too many?
One or two hops with permanent status codes is normal; three or more is usually worth investigating, since each hop adds latency with no benefit to the visitor.
Is this free to use?
There's no free tier — free tiers get abused and slow everyone down. No subscription, no tokens, no invented credits, and a failed task is never charged.
Am I charged for a failed check?
No. Failed tasks retry automatically up to three times and are never billed; only completed checks are charged.
What is the difference between a 301 and a 302 redirect?
A 301 says the move is permanent, so browsers and search engines can remember it and go straight to the new address next time. A 302 or 307 says it might change back, so it is checked again on every visit.
Can I see where a shortened link leads before using it?
Yes. Enter the short link and the check follows every hop for you, listing each intermediate address with its code and response time, up to the final page. Teams often do this before a campaign link goes into an ad or a newsletter.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/web/redirect-chain \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com"}'const res = await fetch("https://api.kit.forhosting.com/web/redirect-chain", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"url": "https://example.com"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/web/redirect-chain",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"url": "https://example.com"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/web/redirect-chain", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"url":"https://example.com"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"url":"https://example.com"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/web/redirect-chain", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"url": "https://example.com"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "web.redirect_chain",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
timeout_sec | 30 |
max_crawl_pages | 25 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
This redirect checker API follows a URL through every hop it takes and returns the full chain, not just the final destination.
What the endpoint returns
Instead of a single final answer, you get the entire path — useful for spotting exactly where a chain grew a hop it did not need. Send a URL to POST /web/redirect-chain and the task follows every redirect in sequence, recording the status code, the target and the response time at each hop, all the way to the final URL that returns actual content.
Where this fits into ongoing maintenance
Running it on a schedule catches chains that grow silently over time, one well-intentioned redirect at a time. Because it is async and delivered by signed webhook, the check fits naturally into a periodic site audit, a pre-launch QA pass after a domain migration, or an SEO tooling pipeline that flags any URL taking more than one or two hops to resolve.
What a healthy result looks like
Fixing the source link once is always cheaper than living with the extra round trip indefinitely. A single hop, or at most two, with a permanent status code is the goal for most links; anything longer is worth tracing back to its origin and collapsing into a direct redirect, since every extra hop is pure latency with no benefit to the visitor.
Technical questions
What does a redirect chain checker actually show?
Every hop between the starting URL and the final destination, including the status code, target URL and response time at each step, not just the final result.
Does it distinguish permanent from temporary redirects?
Yes, the status code returned for each hop shows whether it was a permanent redirect like 301 or a temporary one like 302 or 307.
How do I get the results?
By signed webhook when the task finishes, recommended for automation, or a signed link valid for 24 hours.
What is the cost?
$0.002 per request, one price regardless of how many hops the chain contains.
Can I check redirect chains for a large list of URLs?
Yes, submit each URL as its own async task and track them by task_id, which scales naturally to auditing an entire site's link structure.