Link Route Audit — Bulk HTTP Status & Redirects avatar

Link Route Audit — Bulk HTTP Status & Redirects

Pricing

from $2.25 / 1,000 http url results

Go to Apify Store
Link Route Audit — Bulk HTTP Status & Redirects

Link Route Audit — Bulk HTTP Status & Redirects

Check a list of public URLs before a site move or SEO review. See final HTTP status, ordered redirect destinations and broken-link flags, then export a table. Up to 100 input URLs per run.

Pricing

from $2.25 / 1,000 http url results

Rating

0.0

(0)

Developer

Cliqto Media

Cliqto Media

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Check a list of public URLs before a site move or SEO review. This bulk URL status checker returns the final HTTP status, redirect destinations and broken-link flags for each processed URL. Start with one URL and open its result table. Each run accepts up to 100 input items. An empty list fails; a stopped run may return part of the list. The charge model is pay per useful HTTP result plus an Actor Start event and platform usage. Optional Apify Proxy traffic adds usage costs.

A supplied URL list follows redirect paths to success or broken-link results

Table of contents

What it checks

The Actor sends HTTP requests to the URLs you supply. It starts with HEAD and uses GET when the server returns 405 or 501 for HEAD. It does not read page content. It follows safe redirect destinations and returns one row per processed unique URL.

Use it for a known list from a migration plan, link report or QA check. It does not crawl a website, find URLs, render JavaScript, log in, or check page text. A 200 response alone does not prove that a page has the right content or is indexed.

Data you get

Each Dataset row has nine fields. Use statusCode to see the final HTTP response, isBroken to find failures, and redirectChain with finalUrl to review the route.

ResultMeaningNext step
200, not brokenThe final server returned successCheck whether finalUrl is the address you expect
404, brokenThe server answered “Not Found”Fix the URL or redirect
0, broken, finalUrl: nullThe check ended without a usable HTTP responseReview DNS, connection, TLS, timeout or access
Redirect to 404A route exists but ends at a missing pageFix the destination

This is a point-in-time HTTP check. Server rules, location and connection mode can change the result. There is no saved snapshot comparison or automatic change alert.

Quick start

  1. Open the Actor in Apify Console and choose Input.
  2. Switch to JSON and paste the minimal input below, or enter the URL objects in URLs to check.
  3. Keep direct requests for a first check. A fresh form offers one public example.com URL; you can start this sample without editing it. API calls still require startUrls and never substitute a hidden demo.
  4. Click Start. A run uses the selected build and run options.
  5. Open Output → URL results → Table. Check statusCode and finalUrl.
  6. Choose Export to save the results. Open Storage to read the separate summary.

The example checks a public test service with a 301 redirect to a 200 response. Site behavior may change. You can replace it with a public URL you control.

Input reference

KeyForm titleType and shapeRequiredRuntime default / form prefillRange or choiceEffect and advice
startUrlsURLs to checkArray of objects with a string urlYesNo runtime default; UI prefill [{"url":"https://example.com"}]1–100 items; each URL up to 4,096 charactersSupply full public http:// or https:// URLs. List size is checked before duplicate removal.
maxConcurrencyURLs checked at onceIntegerNo20 / 201–100Number of URL checks at once. Start with 2–3 for slow sites. The API form range is enforced by schema; runtime clamps finite numeric values to the range.
proxyConfigurationConnection modeObjectNo{"useApifyProxy":false} / No proxyuseApifyProxy boolean; optional string-array groups and string countryCodeDirect is the default. Choose available Apify Proxy groups/location only when needed; access and extra costs depend on your account. Custom proxy URLs and credentials are rejected.
requestTimeoutSecsRequest timeout (seconds)IntegerNo10 / 101–30Maximum wait for each DNS, proxy CONNECT and response-header phase. It is not a total per-URL time limit.

A URL object has the form {"url":"https://example.com/"}. Strings alone are not accepted. Leading and trailing spaces are removed. Duplicate detection uses the parsed URL; query strings are kept. Invalid items are skipped and listed in failedInputs. If none remain valid, the run fails.

Settings used togetherResultCost or safety note
More parallel checks + slow or rejecting serversMore active requests; possible retries or rate limitsHigher concurrency does not ensure a faster run
Proxy enabled + redirect/retryEach request uses the selected connection modeExtra traffic can add cost
Short phase timeout + several hops/retriesA check can still take longer than one phase timeoutUse the run timeout as a separate bound

TLS certificate checks are always on. ignoreTlsErrors is unsupported. Headers, cookies, login details and a custom proxy URL are not input options.

Input examples

Minimal check

{
"startUrls": [
{
"url": "https://httpbingo.org/redirect-to?url=%2Fstatus%2F200&status_code=301"
}
]
}

Expected: a row with statusCode: 200, isRedirect: true, and redirectChain: ["https://httpbingo.org/status/200"]. This same URL was checked in the recorded run shown below; that run also contained other URLs.

Small SEO review

{
"startUrls": [
{
"url": "https://httpbingo.org/status/200?case=tz06-200"
},
{
"url": "https://httpbun.com/status/404?case=tz06-404"
},
{
"url": "https://httpbingo.org/redirect-to?url=%2Fstatus%2F200&status_code=301"
}
],
"maxConcurrency": 2,
"proxyConfiguration": {
"useApifyProxy": false
},
"requestTimeoutSecs": 10
}

Expected: a 200 row, a 404 row and a redirected 200 row, if the test services keep these responses. These URLs are part of the same measured corpus. Use a small concurrency value for your first real list. To use Apify Proxy, change only useApifyProxy to true and choose a group you can access.

Real output example

This is one full Dataset item from a real Cloud run on 2026-10-02. It is selected from eight results; timing and date are observed values, not fixed expectations.

{
"url": "https://httpbingo.org/redirect-to?url=%2Fstatus%2F200&status_code=301",
"statusCode": 200,
"statusMessage": "OK",
"isBroken": false,
"isRedirect": true,
"redirectChain": [
"https://httpbingo.org/status/200"
],
"finalUrl": "https://httpbingo.org/status/200",
"responseTime": 122,
"checkedAt": "2026-10-02T14:18:28.271Z"
}

The chain lists destinations in order and includes the final URL. It does not repeat the input URL as the first hop. The array contains URLs, not objects with a status code for each hop.

Output field reference

All nine keys are present on each result row. They are result fields, not input controls.

KeyTable titleType / empty valueMeaning and example
urlOriginal URLString; not nullThe submitted URL after spaces are removed; the example input URL
statusCodeHTTP status codeInteger; not nullFinal HTTP code such as 200 or 404; 0 for a technical failure without a usable final response
statusMessageStatus messageString; not nullHTTP message such as OK, or a safe diagnostic such as Network request failed; low-level error details are not stored
isBrokenIs brokenBooleanTrue for status 0, HTTP codes at least 400, blocked targets, redirect loops or the hop limit
isRedirectIs redirectBooleanTrue if a redirect was seen; it can stay true when the next target is blocked
redirectChainRedirect chainArray of strings; [] when no safe destination was addedSafe destinations in order, including the final destination; unsafe targets are excluded
finalUrlFinal URLString or nullLast URL checked on a normal HTTP path. Null on a technical failure. On a redirect stop, review the broken flag and message; this is not proof of a successful arrival.
responseTimeResponse time msInteger milliseconds; not nullTime for the URL check, including hops, phase waits, retries and retry delays; not a browser page-load metric
checkedAtChecked atString; UTC ISO date/timeTime when the URL check started, such as 2026-10-02T14:18:28.271Z; use it with the result time

The Actor does not return redirectCount, contentType, contentLength, server, page text, canonical tags or headers. To count stored safe destinations in your own code, use the array length; it need not equal every redirect seen when a target was blocked.

Run summary and storage

Dataset stores the URL rows. The Actor’s output schema provides links to URL results and Run records. Run records opens the Key-value store collection. Select RUN_SUMMARY or OUTPUT there. They are separate from the nine Dataset columns.

OUTPUT has results (the Dataset rows), summary (the terminal summary), and datasetUrl (the Console Dataset link). RUN_SUMMARY holds that same summary. Open the run’s Storage tab, then its Key-value store to read these records.

Summary keyTypeMeaning
receivedIntegerOriginal number of submitted items
validIntegerAccepted unique URLs before checking
duplicatesIntegerRepeated accepted URLs skipped
processed, resultsInteger eachNumber of result rows written; both use the same count
domainEmptyIntegerAlways 0; this checker has no domain-empty result
technicalFailuresIntegerProcessed rows with status 0
unprocessedIntegerValid URLs left without a result row
attemptsIntegerRequest attempts, including DNS/socket failures, hops, retries and HEAD/GET
fallbacksIntegerHEAD requests followed by GET
retriesIntegerExtra request attempts started after a retry decision
rateLimitsIntegerHTTP 429 responses received
cancelledBooleanWhether the checker received a stop signal
outcomeStringsucceeded, partial or error
timings.startedAt, timings.finishedAtUTC ISO stringsChecker start and finish; not the full platform start/pull time
transport.modeStringdirect or proxy; no proxy address or password
failedInputsArray of objectsRejected entries with integer zero-based index and safe string reason

Normal reconciliation: received = valid + duplicates + failedInputs.length, valid = processed + unprocessed, and Dataset length equals results. HTTP 404 alone can still have summary succeeded: the check worked and returned an HTTP result. partial covers technical failures, rejected inputs, queued work or cancellation.

Before result publication, a run-level error uses a smaller summary shape: {"outcome":"error","error":{"code":"INVALID_INPUT","message":"..."}}. Standard counters are absent in this shape. OUTPUT.results is empty. Other adapter/storage/runtime errors can also end the run; review its status and log. Do not treat an empty Dataset as proof that every URL is good.

Pricing and cost controls

The applied model is pay per event plus platform usage. A stored URL result with an HTTP response costs USD 0.00225. HTTP 404 and 503 are useful check results and count. Technical failures with status 0, duplicates, invalid inputs, queued URLs and summaries do not count as result events.

The platform charges USD 0.001 for Actor Start at the supported 128–256 MB memory range. This start charge can apply even when input validation fails. Compute, storage and optional proxy use are charged separately at your account rates. Check the Pricing tab before starting.

Useful HTTP resultsResult events + one startAdditional cost
1USD 0.00325Platform usage and optional proxy
10USD 0.02350Platform usage and optional proxy
100USD 0.22600Platform usage and optional proxy
1,000 over 10 batches of 100USD 2.26000Usage of all 10 runs; this is arithmetic, not a single-run capacity claim

Set a maximum cost per run, timeout and memory in run options. The minimum accepted cost limit is USD 0.00325. Private defaults are 256 MB and 180 seconds. Input concurrency is separate. The Actor limits the checked unique URLs to the number of result events its available event budget can cover; technical failures can leave some of that budget unused. A low budget can produce a partial result and unprocessed URLs. Platform usage can reduce the budget further or stop the run.

Results are saved in a batch, then useful result events are charged once each. A run-local RESULTS_PENDING record keeps the result batch for recovery. If a storage or charging step fails, already stored results remain available and the run can fail. A resumed run checks stored rows and platform event counts before writing or charging again. A hard stop before the batch is saved can still lose results. There is no total-cost discount or guaranteed profit promised to buyers.

Use cases

Buyer jobAdd to startUrlsReviewNext step
Site migration URL checkYour old public URLsredirectChain, finalUrl, isBrokenCompare the final destination with your own migration map
Broken link listURLs from a link reportstatusCode, isBroken, statusMessageFix or replace failing links
QA after a releaseKnown public endpointsstatusCode, responseTime, checkedAtRe-check failed endpoints and keep the dated export
Redirect auditKnown redirecting URLsOrdered redirectChain, isRedirectReview extra hops or broken destinations

The Actor does not import a sitemap or compare an old-to-new map for you. It checks the list you provide.

Scheduling and monitoring

To repeat a known list, save the input as an Apify task, then create a schedule for that task in Console. Choose a small list, a time and run limits. Every scheduled run can incur usage costs.

Keep dated exports if you need to compare runs. There is no built-in snapshot diff, uptime SLA or automatic change alert. Scheduling does not add those features. This guide does not create a schedule for you. See the Apify scheduling guide.

API and integrations

Use the private Actor ID from your own authorized Apify account. Set APIFY_TOKEN in your environment; never place it in a URL or commit it. Save the input as input.json.

curl --fail-with-body --silent --show-error \
--request POST \
--header "Authorization: Bearer ${APIFY_TOKEN:?Set APIFY_TOKEN locally}" \
--header 'Content-Type: application/json' \
--data-binary @input.json \
'https://api.apify.com/v2/acts/NmhMbSI7fgkagucYf/runs?build=0.1.10&memory=256&timeout=180&maxTotalChargeUsd=0.05'

This starts a paid run; it does not wait for completion. Read the returned data.id with GET /v2/actor-runs/{runId} until the run ends. Then read GET /v2/datasets/{defaultDatasetId}/items for the rows and the run’s Key-value store records for the summary. Keep the same Bearer header. Supply an exact available build from your Actor; newer builds may replace the example version.

Use statusCode or isBroken in your next system, and pass finalUrl only after checking the result. The Apify API reference explains run and storage requests. Apify’s SDK/client can perform the same steps. This Actor has no custom MCP server or verified MCP tool; it does not need a new service installation.

Export to JSON CSV and Excel

  1. Open a completed run’s Output → URL results.
  2. Select Table to scan the rows, or JSON to view field names and values.
  3. Click Export and choose JSON, CSV or Excel (XLSX).
  4. Keep all nine columns when another tool needs the full result. Array and null display can differ across export formats; use JSON to preserve these types.
  5. Download RUN_SUMMARY separately from Storage when you also need rejected or unprocessed counts.

Exports read the stored results; you do not need to start another run for each format. See Dataset storage and export.

Limits and partial results

  • At most 100 input items per run, counted before duplicate removal. Split larger lists yourself.
  • Concurrency range 1–100, default 20. Actual Cloud capacity was checked at concurrency 3 with 100 simple HTTP results; this does not promise the same speed or success for all sites.
  • Up to 10 redirect hops; loops and the hop limit produce broken results. A final target can be present in the chain before the cap prevents fetching it.
  • Up to 2 extra retries per request for network failures, 429 or 5xx. HEAD→GET fallback adds a request. Requests can therefore exceed the number of URLs.
  • Request phase timeout 1–30 seconds, default 10. Several phases, hops and retries can take longer than one timeout value.
  • Only public HTTP/HTTPS destinations. Private-network, loopback and unsafe targets are blocked, including at redirects and retries. TLS verification stays on.
  • URL credentials, secret query values and fragments are rejected. Custom proxy credentials are not accepted.
  • Results are saved as a batch after checking. A graceful stop can save finished and active rows and count queued URLs in unprocessed; a hard platform kill or storage failure may lose final results. There is no streaming or resume guarantee.
  • A status 0, 403, 429 or blocked result does not prove the page is absent. It reports the response or failure seen by this run.

Troubleshooting

SymptomPossible reasonCheckAction
Input form says “This field is required”Empty URL liststartUrls object arrayAdd at least one full public URL
FAILED with INVALID_INPUTMissing/empty/too-large list, unsupported option, or no valid URLsError summary and input shapeCorrect the input; do not add secrets
Status 0 with null final URLDNS, TLS, connection failure, timeout or blocked targetstatusMessage, failed inputs and logsVerify a public URL and retry a small subset
HTTP 404Server returned Not FoundSubmitted and final URLsCorrect the URL or redirect
Fewer rows than input itemsDuplicates, rejected entries, or queued workduplicates, failedInputs, unprocessedFix the input or split a list
Succeeded but PARTIALSome checks failed technically or input was rejectedSummary, status0 rowsReview the failed subset; a platform success is not proof all URLs are good
Many 429/slow checksServer rate limits or slow responserateLimits, attempts, retriesReduce concurrency and wait before a small re-check
Run stopped before results appearedBatch saving and hard stopTerminal status, summary/storage presenceUse smaller lists and enough run time; do not assume saved rows

Log events use numeric counts and safe event names. They do not contain raw proxy addresses or detailed low-level errors.

FAQ

Does it detect soft 404 pages?

No. It does not read page content. A page can return 200 while showing an error message.

Can I see the status of every redirect hop?

The Dataset stores destination URLs, not a status code for each hop. statusCode is the final HTTP code, or 0 on technical failure.

Is a redirect always broken?

No. A redirect to 200 normally has isRedirect: true and isBroken: false. A redirect to 404 is broken.

Is the response time a speed score?

No. It is the whole URL check time from the run environment, including retries and waits. It is not a Core Web Vital.

Can I use login pages or internal addresses?

Public login page addresses can return an HTTP status, but the Actor does not sign in. Private or internal destinations are blocked.

Does a schedule compare results for me?

No. Export the dated rows and compare them in your own system.

Use your spreadsheet or migration map with this Actor’s exported finalUrl and statusCode fields. No extra product is required.

Support and privacy

For a bug or question, use the developer contact or Issues route shown on the Actor page in Apify. Include the run ID, list size, connection mode and a safe description of the problem. Do not send tokens, cookies, proxy passwords or a private URL list. Use the Apify help center for account or platform support.

Do not submit secrets in URL paths, query values or other input. Apify keeps the original INPUT record; this Actor cannot remove secrets you already submitted. Public URLs and final destinations are stored in Dataset/OUTPUT. Share exports only when the URLs are safe to share.

Checks access only public targets. This Actor is independent and is not affiliated with the websites it checks. It does not certify site ownership, content, access rights, availability or SEO ranking. Review the actual HTTP result and the limits above before acting on it.