Website Migration QA & Redirect Auditor avatar

Website Migration QA & Redirect Auditor

Under maintenance

Pricing

$1.00 / 1,000 url auditeds

Go to Apify Store
Website Migration QA & Redirect Auditor

Website Migration QA & Redirect Auditor

Under maintenance

Audit website migrations: validate redirect chains, destinations, canonicals, and indexability between old and new URL sets.

Pricing

$1.00 / 1,000 url auditeds

Rating

0.0

(0)

Developer

kingii98

kingii98

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

Audit a website migration before or after launch. Given the old URL set and the new URL set — as two XML sitemaps or two explicit lists — the Actor fetches every old URL without automatically following redirects, validates each redirect target as public, follows a bounded chain, classifies the outcome, and compares the final URL against the new URL set. It reports redirect loops and over-long chains, 4xx/5xx destinations, missing destinations, canonical and noindex regressions, and new URLs that no old URL maps to.

This is migration QA, not a generic crawler: every old URL is checked exactly once per run, and each run is stateless — no snapshot is persisted between runs.

The package reuses the safe HTTP and SSRF validation core of the sitemap_health_monitor Actor in this repository; that package and its tests are unchanged.

What it checks

  • HTTP status of every old URL, without hiding intermediate redirects
  • Full redirect chain, with every hop target validated as a public address before it is followed
  • Redirect loops and chains exceeding maxRedirects
  • 4xx/5xx final responses and redirect responses without a Location
  • Destination matching of the final URL against the new URL set (exact, normalized, or none)
  • Canonical regressions on HTML destinations (canonical differs from the final URL), gated by checkCanonical
  • Indexability regressions from meta robots and X-Robots-Tag, gated by checkIndexability
  • New URLs that no audited old URL successfully resolves to (via exact or normalized final-destination match)

Input

Provide either the sitemap pair or the URL lists — not both.

{
"oldSitemapUrl": "https://old.example.com/sitemap.xml",
"newSitemapUrl": "https://new.example.com/sitemap.xml",
"maxUrls": 500,
"concurrency": 10,
"timeoutSecs": 20,
"maxRedirects": 5,
"checkCanonical": true,
"checkIndexability": true
}
{
"oldUrls": ["https://old.example.com/pricing", "https://old.example.com/about"],
"newUrls": ["https://new.example.com/pricing", "https://new.example.com/about-us"]
}
FieldDescription
oldSitemapUrl / newSitemapUrlPublic HTTP(S) XML sitemaps for the old and new sites. Nested sitemap indexes and gzip payloads are supported. Both must be provided together.
oldUrls / newUrlsExplicit URL lists, used instead of the sitemap pair. Both must be non-empty; entries are normalized and deduplicated.
maxUrlsHard cap on old and new URL counts. Lists longer than this are rejected before any network work; sitemap-derived sets are truncated. Default 500; maximum 5,000.
concurrencyConcurrent old-URL audits. Default 10; maximum 50.
timeoutSecsPer-request timeout. Default 20 seconds; range 2-60.
maxRedirectsMaximum redirect hops followed per old URL. Default 5; range 0-10.
checkCanonicalFlag canonical mismatches on HTML destinations. Enabled by default.
checkIndexabilityFlag noindex destinations. Enabled by default.

Invalid combinations (a missing pair member, both modes at once, empty lists, URLs with credentials or non-HTTP schemes, counts above maxUrls) fail fast with a clear validation error before any network work.

Output

Every run writes one summary record, one url-result record per audited old URL, and one new-only record per unreferenced new URL to the default dataset.

Summary:

{
"recordType": "summary",
"checkedAt": "2026-08-07T09:15:00+00:00",
"oldUrlCount": 2,
"newUrlCount": 2,
"redirected": 1,
"direct": 0,
"missingDestination": 1,
"broken": 0,
"loops": 0,
"canonicalRegressions": 0,
"indexabilityRegressions": 0,
"newOnlyCount": 0,
"errors": 0
}

Per-URL result:

{
"recordType": "url-result",
"oldUrl": "https://old.example.com/pricing",
"finalUrl": "https://new.example.com/pricing",
"status": 200,
"redirectChain": [
{"url": "https://old.example.com/pricing", "status": 301},
{"url": "https://new.example.com/pricing", "status": 200}
],
"outcome": "redirected",
"destinationMatched": true,
"destinationMatchType": "exact",
"canonicalUrl": "https://new.example.com/pricing",
"indexable": true,
"issues": [],
"error": null,
"checkedAt": "2026-08-07T09:15:00+00:00"
}

outcome is one of direct (2xx without redirects), redirected (2xx after redirects), broken (4xx/5xx or a redirect without Location), loop (redirect cycle or chain over maxRedirects), or error (fetch or validation failure, with details in error). The loops summary count includes chains that exceeded maxRedirects; the precise reason is in issues.

Issue codes: redirect-loop, redirect-chain-too-long, http-4xx, http-5xx, redirect-without-location, missing-destination, canonical-mismatch, noindex, fetch-error.

destinationMatchType is exact (final URL equals a new URL after normalization), normalized (matches when scheme case and trailing slashes are ignored), or none. destinationMatched and match type are only set when a final response was received.

New-only records have the form {"recordType": "new-only", "url": "...", "checkedAt": "..."} and list new URLs that no old URL successfully resolved to. A new URL is covered when an audited old URL ends on it with a direct or redirected outcome and an exact or normalized destination match — including migrations to a different domain. Results with loop, error, or broken outcomes never cover a new URL. Order follows the input newUrls or new sitemap order.

Pricing

The Actor uses Apify pay-per-event pricing with the url-audited charge event. When monetization is enabled, users are charged $0.001 per old URL audited. One url-audited event corresponds to one old URL audit, including its bounded redirect-chain and destination checks.

Apify platform usage (compute units and other resources consumed by the run) may still be shown to users according to their plan and Apify's pricing rules, as described in the Actor's listing.

The Actor respects the run's maximum total charge: if the remaining budget cannot cover every old URL, it audits only the chargeable prefix; if no URL can be charged, it stops before page checks.

Final pricing is configured in the Apify Store listing and may change subject to Apify's pricing-change notice rules.

Security and privacy

  • Only public HTTP(S) targets are accepted.
  • URL credentials, localhost, and non-public, loopback, link-local, multicast, unspecified, or reserved addresses are rejected.
  • Every redirect target is resolved and validated before it is followed; a redirect to a private address fails that URL with an error record instead of being fetched.
  • URL counts, concurrency, redirects, response bytes, sitemap sizes, and timeouts are all capped before or during network work.
  • The Actor does not use a browser, proxy, LLM, external database, or third-party analytics service.
  • Each run is stateless; results live only in the run's default dataset, subject to the retention and access settings of the Apify account running the Actor.

Do not place secrets, private URLs, or personal data in any input field.

Limitations

  • JavaScript-rendered pages are not rendered; checks use HTTP responses only.
  • Sitemap inputs must be valid XML sitemaps; nested indexes are followed up to 20 files.
  • Canonical and indexability checks apply to HTML responses only.
  • New-only detection requires an audited old URL to successfully resolve to the new URL; a new URL whose only mapping is broken, looping, or failed is still reported as new-only.
  • Network failures and rate limits are reported as per-URL errors; they are not automatically retried indefinitely.
  • The Actor does not send notifications itself. Use Apify schedules, webhooks, or an automation platform.

Support

For reproducible issues, open an issue from the Actor page and include the Apify run ID, sanitized input, expected result, and affected public URL. Do not include API tokens or private data.

This Actor audits migration mappings; it does not provide legal, security-audit, or uptime guarantees.