Validate a redirect map
A redirect spreadsheet can look correct row by row while containing a loop that traps crawlers or a source that points to two different destinations.
Run — free
Paste a CSV or TSV map to analyze the complete graph before deployment. The report keeps every finding tied to its record, follows each unambiguous route to its terminal target and explicitly stops when no honest final destination exists.
Check the plan before traffic moves
Redirect failures are cheapest to fix while the map is still a file. The validator reads source, target and an optional HTTP status from each record, then builds the directed graph that a server would create after launch. It reports malformed routes, unsupported status codes, a source mapped to conflicting targets and a source redirected to itself. Because the analysis is offline, it does not request staging or production addresses and cannot change the map. The result is suitable for a migration review, a release checklist or an automated quality gate without exposing unpublished paths to a third party.
Understand chains, cycles and terminal targets
Every usable source is followed until its route reaches a target that is not another source. A one-hop route is marked direct. Longer routes are marked as chains, with the number of hops, the complete path and the terminal final_target so the redirect can be flattened deliberately. A cycle is different: it has no terminal target. For a two-page loop, a longer loop or a route that enters a loop, the output says cycle and includes the repeated path but deliberately omits final_target. Ambiguous sources and self-redirects receive the same honest treatment instead of a guessed destination.
Use conservative URL and CSV rules
The input accepts comma, semicolon, tab or pipe separators and respects quoted fields, escaped quotes and surrounding spaces. Automatic detection favors a header containing source and target; an explicit delimiter remains available for unusual exports. Sources and targets may be absolute HTTP or HTTPS URLs or root-relative paths. Add base_url when both forms must be compared in one graph. The tool preserves path case, query strings and encoded characters rather than applying an aggressive canonicalization that could merge distinct routes. Hard byte and row limits reject oversized maps before graph traversal, keeping execution predictable even when the file contains thousands of redirects.
What you can do with it
Pre-launch site migration review
Validate the redirect export from an agency, CMS or crawl inventory before DNS, templates or routing rules are changed.
Continuous redirect-map quality
Run the same deterministic report in a release workflow and block conflicting sources or cycles before configuration reaches production.
Flatten legacy redirect chains
Use the reported path, hop count and terminal target to replace old multi-step routes with a reviewed direct destination.
FAQ
Does the validator visit any source or target URL?
No. It analyzes the text as an offline graph. It does not follow live redirects, test HTTP responses, check whether a target exists or send unpublished paths across the network.
What happens when the map contains a redirect cycle?
The affected resolution is marked cycle and includes the repeated path. It does not contain final_target because a terminal destination does not exist.
Which redirect status codes are accepted?
The optional redirect-code column must be named exactly `status`; `code` and `status_code` are not recognized. It accepts 301, 302, 307 and 308. A blank status defaults to 301, while another value is reported as invalid on its record.
Can the map use relative paths and absolute URLs together?
Yes, but provide base_url when they should belong to the same graph. Without it, mixed styles are reported because an absolute URL cannot be matched safely to a relative source by assumption.
Is the redirect map validator free?
The browser tool runs locally and free on desktop and mobile browsers. API automation uses the same contract and each request is billed at the published $0.002 from prepaid KIT balance.
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/seo/redirect-map-validate \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"mapping":"source,target,status\n/old-page,/new-page,301\n/new-page,/final-page,301"}'const res = await fetch("https://api.kit.forhosting.com/seo/redirect-map-validate", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"mapping": "source,target,status\n/old-page,/new-page,301\n/new-page,/final-page,301"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/seo/redirect-map-validate",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"mapping": "source,target,status\n/old-page,/new-page,301\n/new-page,/final-page,301"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/seo/redirect-map-validate", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"mapping":"source,target,status\\n/old-page,/new-page,301\\n/new-page,/final-page,301"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"mapping":"source,target,status\n/old-page,/new-page,301\n/new-page,/final-page,301"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/seo/redirect-map-validate", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"mapping": "source,target,status\n/old-page,/new-page,301\n/new-page,/final-page,301"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "seo.redirect_map_validate",
"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
max_bytes | 1048576 |
max_rows | 10000 |
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. |