Redirect Check API
A free HTTP API for tracing URL redirect chains, detecting loops, and extracting canonical and X-Robots-Tag. One URL or up to 100 at a time — JSON in, JSON out, no API key, CORS wide open.
Quick start
Trace a redirect chain in one request
Send a POST to /api/check with a JSON body. No authentication, no sign-up, CORS is open to any origin.
curl -X POST https://www.redirectcheck.org/api/check \
-H "Content-Type: application/json" \
-d '{
"url": "https://bit.ly/example",
"method": "GET",
"followMetaRefresh": true
}' const res = await fetch('https://www.redirectcheck.org/api/check', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
url: 'https://bit.ly/example',
}),
})
const data = await res.json()
console.log(data.redirects.length, data.final_result.final_url) import requests
res = requests.post(
"https://www.redirectcheck.org/api/check",
json={"url": "https://bit.ly/example"},
timeout=20,
)
data = res.json()
print(len(data["redirects"]), data["final_result"]["final_url"]) curl -X POST https://www.redirectcheck.org/api/check \
-H "Content-Type: application/json" \
-d '{
"urls": [
"https://example.com/a",
"https://example.com/b",
"https://example.com/c"
],
"method": "HEAD"
}' Endpoint reference
POST /api/check
A single endpoint handles both single-URL and bulk checks. Pass url for one URL or urls for up to 100 at a time. The response shape changes accordingly.
Request body
All fields are optional except url or urls.
| Field | Type | Default | Description |
|---|---|---|---|
| url | string | — | Single absolute URL to check. Use this or urls. |
| urls | string[] | — | Bulk list, up to 100 URLs. Response returns a results array. |
| method | "GET" | "HEAD" | "POST" | "GET" | HTTP method for the outgoing requests. POST is downgraded to GET on 301/302/303 (per RFC). |
| body | string | — | Request body for POST. Stripped on cross-origin redirects. |
| userAgent | string | Chrome (macOS) | Override the User-Agent header. Useful for Googlebot / Bingbot / mobile emulation. |
| headers | object | {} | Extra request headers. Authorization, Cookie, Proxy-Authorization are stripped on cross-origin hops. |
| cookies | string | — | Cookie header value, e.g. name=value; other=value. |
| followMetaRefresh | boolean | true | Follow <meta http-equiv="refresh"> tags as an extra hop. |
| maxHops | number | 20 | Max redirect hops before reporting MAX_HOPS_EXCEEDED. |
| ignoreSSL | boolean | false | Accepted for backwards compatibility but treated as a no-op — Cloudflare Workers cannot disable TLS verification. |
{
"url": "https://bit.ly/example",
"redirects": [
{
"from": "https://bit.ly/example",
"to": "https://example.com/",
"status_code": 301,
"type": "http",
"duration": 47,
"headers": { ... },
"canonical": null,
"x_robots_tag": null
}
],
"final_result": {
"final_url": "https://example.com/",
"status_code": 200,
"canonical": "https://example.com/",
"x_robots_tag": null,
"server": "ECS (dcb/7EA3)",
"content_type": "text/html"
},
"warnings": [],
"loop": { "detected": false, "start_step": null },
"total_duration": 132
} {
"results": [
{
"url": "https://example.com/a",
"redirects": [ ... ],
"final_result": { ... },
"warnings": [],
"loop": { ... },
"total_duration": 98
},
{ ... },
{ ... }
],
"meta": {
"count": 3,
"duration_ms": 431,
"timed_out": false
}
} Error responses are 200s, not 4xx/5xx.
When a URL cannot be fetched (DNS failure, TLS error, timeout, SSRF block), the API still returns HTTP 200 with "error": true in the body. Non-200 statuses are only used for protocol-level problems (invalid JSON body, missing URL, malformed request).
Error types
What error_type values mean
| error_type | When it happens |
|---|---|
| INVALID_URL | The URL is missing, malformed, or not a valid http(s):// URL. |
| SSRF_BLOCKED | The URL resolves to a private, loopback, link-local, or reserved IP range and was refused for safety. |
| FETCH_ERROR | Network-level failure — DNS, connection refused, TLS handshake, abrupt disconnect. |
| TIMEOUT | A single request exceeded 15 s, or a bulk run exceeded the 60 s global ceiling. |
| MAX_HOPS_EXCEEDED | The redirect chain did not terminate within maxHops steps (default 20). |
| LOOP_DETECTED | A URL in the chain was visited twice — details are in the loop field. |
Good to know
Limits, CORS, and fair use
Batch size
Up to 100 URLs per request. Requests with more URLs are rejected with a 400. For larger jobs, chunk the list client-side and run batches back to back.
Timeouts
Each individual hop caps at 15 s. A bulk run caps at 60 s total — if the ceiling is hit, completed rows are returned and the remainder report TIMEOUT.
CORS & auth
Access-Control-Allow-Origin: *, no cookies required, no API key. You can call the API directly from a browser or a CLI.
SSRF protection
Requests to private, loopback, link-local, carrier-grade NAT, and unique-local IPv6 ranges are refused with SSRF_BLOCKED. This applies at every redirect hop, not just the first URL.
Header stripping
Authorization, Cookie, and Proxy-Authorization are dropped on cross-origin hops. POST bodies are dropped on 301/302/303 (same as browsers).
Fair use
The API is free for reasonable use. Please don't hammer it in tight loops from a bot farm — if you need high-volume checking, cache results on your side and deduplicate before calling.
Legacy GET
GET /api/check still works
For quick checks from a browser or a shell pipeline, the endpoint also accepts a simple GET with query parameters. The response uses the single-URL shape.
curl "https://www.redirectcheck.org/api/check?url=https://bit.ly/example&ua=Googlebot"
Only url and ua are supported on GET. For custom headers, POST bodies, or bulk checks, use the POST endpoint.
FAQ
API questions, answered
Do I need an API key? expand_more
No. The Redirect Check API is free and unauthenticated. There's no dashboard to create, no token to manage — just POST JSON and read JSON back.
What's the rate limit? expand_more
There is no hard per-minute quota right now. The bulk endpoint caps each request at 100 URLs and a 60-second total ceiling, which acts as a natural throttle. For sustained high-volume usage, please cache aggressively and deduplicate URLs before calling.
Can I call the API from the browser? expand_more
Yes. CORS is open (Access-Control-Allow-Origin: *), so you can call fetch('https://www.redirectcheck.org/api/check') directly from any origin. No proxy required.
Why do errors return 200 OK instead of 500? expand_more
Fetch failures on the target URL are a normal part of redirect tracing — not an API failure. Returning 200 with a structured "error": true body lets clients handle mixed-success bulk results in one place. Non-200 statuses are reserved for protocol-level problems with the request itself (invalid JSON, missing URL, too many URLs).
Can I trace redirects for a POST or an authenticated endpoint? expand_more
Yes — set method: "POST" with a body string, and pass any required credentials via headers or cookies. Note that sensitive headers and request bodies are stripped on cross-origin redirects — mirroring normal browser behavior — so they won't be forwarded to unrelated hosts.
Is there a status page or changelog? expand_more
The endpoint runs on Cloudflare Workers and inherits Cloudflare's availability. Breaking changes to the API shape are avoided; when fields are added they are additive and optional.
Try the API right now
Copy any of the examples above into your terminal — no sign-up, no install, no key. Or jump back to the homepage tool if you'd rather start in a browser.