Skip to main content
RTILA Marketplace

Redirect Checker - project configuration

Check a URL list for redirects: status codes, chains, final destinations and timing in one report.

SEO Beginner Stable v1.0.0 Updated Updated 2026-09-18 10 min read
Download
  • Windows x86_64

    BOT_redirect-checker.exe

    98.9 MB

    Download
  • macOS Apple Silicon chmod +x

    BOT_redirect-checker.sh

    87.5 MB

    Download
  • macOS Intel chmod +x

    BOT_redirect-checker.sh

    99.4 MB

    Download
  • Linux x86_64 chmod +x

    BOT_redirect-checker.sh

    122.5 MB

    Download

Do not rename the downloaded file - the filename carries the bot's configuration id.

This tab presents the complete project configuration exactly as published - the same JSON the launcher fetches at launch - ready to read, copy, or import into the desktop product. Back to the overview tab.

Project configuration

Full project JSON for redirect-checker

Canonical byte length: 9,295 - the length of the canonical form the digest covers.

Canonical digest: e1406a349457b08595d37c635806675ee467e834b66b20ad77e627bf740b0a3f

About the delivered configuration encoding

At launch the backend delivers this configuration to the launcher as plain JSON. The block below is the complete project definition the launcher receives.

What you are reading has machine-readable equivalents, and the JSON at those routes is the same document as the JSON rendered on this page: the listing overview, the per-listing detail document and the configuration document. The digest and byte count shown in the panel header are computed over that document's canonical JSON form - recursively sorted keys, two-space indentation, no trailing newline - which is the form the provisioning pipeline signs and the reconcile control re-digests; it differs from the highlighted block above in key order and by that trailing newline, so hashing the visible text will not reproduce the digest.

Download this JSON
{
  "name": "Redirect Checker",
  "settings": {
    "urls": [
      "about:blank"
    ],
    "headless": false,
    "max_concurrent_workers": 3,
    "humanoidEnabled": false,
    "proxyEnabled": false,
    "captchaEnabled": false,
    "matchTimezoneAndLocale": false,
    "block_resources": false,
    "get_urls_from_sitemap": false,
    "respect_robots_txt": false,
    "skip_initial_navigation": true,
    "variables": [
      {
        "name": "urls_to_check",
        "value": "https://httpbin.org/redirect/1\nhttps://httpbin.org/redirect/3\nhttps://httpbin.org/status/301\nhttps://httpbin.org/status/302\nhttps://www.google.com\nhttps://this-domain-does-not-exist-9x7q.com",
        "required": true,
        "is_list": true
      }
    ]
  },
  "datasets": {
    "Redirect_Report": {
      "item_selector": "css=html",
      "properties": [
        {
          "name": "Source_URL",
          "type": "text",
          "selector": "variable=normalized_url"
        },
        {
          "name": "Final_URL",
          "type": "text",
          "selector": "variable=last_final_url"
        },
        {
          "name": "Status_Code",
          "type": "text",
          "selector": "variable=last_http_status"
        },
        {
          "name": "Status_Text",
          "type": "text",
          "selector": "variable=last_http_status_text"
        },
        {
          "name": "Redirect_Count",
          "type": "text",
          "selector": "variable=last_redirect_count"
        },
        {
          "name": "Navigation_OK",
          "type": "text",
          "selector": "variable=last_navigation_ok"
        },
        {
          "name": "Error",
          "type": "text",
          "selector": "variable=last_navigation_error"
        },
        {
          "name": "Content_Type",
          "type": "text",
          "selector": "variable=last_content_type"
        },
        {
          "name": "Server",
          "type": "text",
          "selector": "variable=last_server"
        },
        {
          "name": "Protocol",
          "type": "text",
          "selector": "variable=last_protocol"
        },
        {
          "name": "Response_Time_ms",
          "type": "text",
          "selector": "variable=last_response_time_ms"
        },
        {
          "name": "X_Robots_Tag",
          "type": "text",
          "selector": "variable=last_x_robots_tag"
        },
        {
          "name": "Cache_Control",
          "type": "text",
          "selector": "variable=last_cache_control"
        },
        {
          "name": "Chain_Status_Codes",
          "type": "text",
          "selector": "variable=last_redirect_chain",
          "transformations": [
            {
              "type": "script",
              "code": "if(!Array.isArray(value)||value.length===0)return '';return value.map(function(h){return h.status||'?';}).join(' -> ');",
              "default_value": ""
            }
          ]
        },
        {
          "name": "Chain_Details",
          "type": "text",
          "selector": "variable=last_redirect_chain",
          "transformations": [
            {
              "type": "script",
              "code": "if(!Array.isArray(value)||value.length===0)return '';return value.map(function(h,i){return 'Hop '+(i+1)+': '+((h.status)||'?')+' '+(h.location||h.url||'');}).join(' | ');",
              "default_value": ""
            }
          ]
        },
        {
          "name": "Chain_Visual",
          "type": "text",
          "selector": "variable=last_redirect_chain",
          "transformations": [
            {
              "type": "script",
              "code": "if(!Array.isArray(value)||value.length===0)return '';var p=[];for(var i=0;i<value.length;i++){var h=value[i];p.push((h.url||'')+' --['+(h.status||'?')+']--> '+(h.location||''));}return p.join('\\n');",
              "default_value": ""
            }
          ]
        },
        {
          "name": "Has_301",
          "type": "text",
          "selector": "variable=last_redirect_chain",
          "transformations": [
            {
              "type": "script",
              "code": "return String(Array.isArray(value)&&value.some(function(h){return h.status===301;}));",
              "default_value": "false"
            }
          ]
        },
        {
          "name": "Has_302",
          "type": "text",
          "selector": "variable=last_redirect_chain",
          "transformations": [
            {
              "type": "script",
              "code": "return String(Array.isArray(value)&&value.some(function(h){return h.status===302;}));",
              "default_value": "false"
            }
          ]
        },
        {
          "name": "Has_303",
          "type": "text",
          "selector": "variable=last_redirect_chain",
          "transformations": [
            {
              "type": "script",
              "code": "return String(Array.isArray(value)&&value.some(function(h){return h.status===303;}));",
              "default_value": "false"
            }
          ]
        },
        {
          "name": "Has_307",
          "type": "text",
          "selector": "variable=last_redirect_chain",
          "transformations": [
            {
              "type": "script",
              "code": "return String(Array.isArray(value)&&value.some(function(h){return h.status===307;}));",
              "default_value": "false"
            }
          ]
        },
        {
          "name": "Has_308",
          "type": "text",
          "selector": "variable=last_redirect_chain",
          "transformations": [
            {
              "type": "script",
              "code": "return String(Array.isArray(value)&&value.some(function(h){return h.status===308;}));",
              "default_value": "false"
            }
          ]
        },
        {
          "name": "Redirect_Type",
          "type": "text",
          "selector": "variable=last_redirect_chain",
          "transformations": [
            {
              "type": "script",
              "code": "var c=Array.isArray(value)?value:[];if(c.length===0)return 'No HTTP Redirect';var s=c.map(function(h){return h.status;});if(s.indexOf(301)!==-1)return '301 Permanent';if(s.indexOf(308)!==-1)return '308 Permanent';if(s.indexOf(302)!==-1)return '302 Temporary';if(s.indexOf(303)!==-1)return '303 See Other';if(s.indexOf(307)!==-1)return '307 Temporary';return 'Redirect ('+s.join(',')+')';",
              "default_value": "Unknown"
            }
          ]
        },
        {
          "name": "Chain_Length_Verdict",
          "type": "text",
          "selector": "variable=last_redirect_count",
          "transformations": [
            {
              "type": "script",
              "code": "var n=Number(value);if(!isFinite(n)||n===0)return 'No Redirect';if(n<=2)return 'OK';if(n<=5)return 'Long Chain';return 'Redirect Loop Risk';",
              "default_value": "Unknown"
            }
          ]
        }
      ],
      "required_fields": [
        "Source_URL"
      ]
    },
    "Errors": {
      "item_selector": "css=html",
      "properties": [
        {
          "name": "Source_URL",
          "type": "text",
          "selector": "variable=normalized_url"
        },
        {
          "name": "Status_Code",
          "type": "text",
          "selector": "variable=last_http_status"
        },
        {
          "name": "Error",
          "type": "text",
          "selector": "variable=last_navigation_error"
        }
      ],
      "required_fields": [
        "Source_URL"
      ]
    },
    "Destination_URLs": {
      "item_selector": "css=html",
      "properties": [
        {
          "name": "Destination_URL",
          "type": "text",
          "selector": "variable=last_final_url"
        }
      ],
      "required_fields": [
        "Destination_URL"
      ]
    }
  },
  "commands": [
    {
      "command": "for_each",
      "params": {
        "source_type": "variable",
        "variable": "urls_to_check",
        "as": "target_url",
        "do": [
          {
            "command": "try_catch",
            "params": {
              "try": [
                {
                  "command": "goto",
                  "params": {
                    "url": "${target_url}"
                  }
                }
              ],
              "catch": [
                {
                  "command": "comment",
                  "params": {
                    "text": "Navigation failed: ${last_error}"
                  }
                }
              ]
            }
          },
          {
            "command": "extract_data",
            "params": {
              "dataset": "Redirect_Report"
            }
          },
          {
            "command": "extract_data",
            "params": {
              "dataset": "Errors",
              "filter_condition": "item.Navigation_OK === false || item.Status_Code === null || item.Status_Code === ''"
            }
          },
          {
            "command": "extract_data",
            "params": {
              "dataset": "Destination_URLs",
              "filter_condition": "item.Destination_URL && item.Destination_URL !== ''"
            }
          }
        ]
      }
    }
  ],
  "authors": []
}

Frequently asked questions

How do I check a list of URLs for redirects in bulk?
Paste your URLs into the list field, one per line, and start the run. The bot walks the list with up to three parallel workers, navigates each URL, and records the full redirect chain into the Redirect_Report dataset. A six-URL test list is pre-loaded so your very first run doubles as a self-test.
What is a redirect chain and why does its length matter?
A chain is the sequence of hops between the URL you submit and the URL the browser finally lands on. Each hop costs latency and can leak ranking signals if intermediate URLs are temporary. The Chain_Status_Codes, Chain_Details and Chain_Visual columns show every hop, and Chain_Length_Verdict grades it: OK at two hops or fewer, Long Chain up to five, Redirect Loop Risk beyond that.
How do I find 302 redirects that should be 301?
Filter the Redirect_Report output on the Has_302 column or on Redirect_Type showing 302 Temporary. A permanent move served as a temporary redirect tells crawlers the old URL may return, which is the most common migration mistake this bot surfaces.
What is the difference between 301 302 303 307 and 308 status codes?
301 is a permanent move that may rewrite the request method; 308 is permanent but preserves the method; 302 is temporary and may rewrite the method; 307 is temporary and preserves the method; 303 tells the client to fetch another resource with a GET. For SEO auditing the practical split is permanent (301, 308) versus temporary (302, 307), and the Redirect_Type column classifies each URL accordingly.
How do I audit redirects after a website migration?
Export your old URL list from the previous CMS, sitemap or server logs, paste it into the checker, and run it against the live site. Then review three things: URLs whose Final_URL is not the intended new page, rows where Redirect_Type says temporary, and rows where Chain_Length_Verdict flags Long Chain or Redirect Loop Risk. Re-run the same list weekly to catch regressions.
Why does the checker block images scripts and stylesheets?
The bot only needs the navigation itself, not the rendered page. Blocking images, media, fonts, styles, scripts and background requests makes each check dramatically faster and lighter on bandwidth. The trade-off is documented in the limits section: a redirect that only fires from client-side script will not be observed.
Can it detect redirect loops?
Yes, indirectly and honestly. A browser gives up on a loop and the navigation fails, so the URL lands in the Errors dataset with Navigation_OK false and the engine error text. Chains that are merely very long are graded Redirect Loop Risk by the Chain_Length_Verdict column before they become hard failures.
What do I do with a URL that returns no redirect?
Nothing is wrong - Redirect_Type reads No HTTP Redirect and Chain_Length_Verdict reads No Redirect, with Status_Code showing the direct response, usually 200. In a migration audit these rows deserve attention: an old URL still serving content directly instead of forwarding is a duplicate-content risk.
How many URLs can one run check?
There is no built-in cap; the list length governs the run. Three workers process URLs in parallel, so a few hundred typical URLs finish in minutes. Very large lists mainly need patience and proportionate request rates against the target server.
Does the bot follow redirects all the way to the final destination?
Yes. Navigation behaves exactly like a real browser session: the engine follows every hop, then records the final URL, the final status, the response headers of the last hop, and the full chain of intermediate statuses and locations.
Can I check redirects without a paid SEO tool?
That is the point of this bot. It is a free desktop launcher, your URL list never leaves your machine except as requests to the URLs themselves, and the report exports to CSV, JSON or XLSX for review in any spreadsheet.
Does the bot need an internet connection to run?
Yes on first run: the launcher fetches its configuration by id from the backend at launch, so an internet connection is required at least the first time it starts.
Can I rename the downloaded file?
No. The downloaded file must keep its exact name - the filename carries the per-bot configuration id, and renaming it breaks the configuration fetch at launch.