Bulk HTTP status checker for up to 100,000 URLs.

Status code, full redirect chain and final URL for every link in the list. Most bulk HTTP status checkers stop between 25 and a few hundred URLs a run, so a real list means pasting the same page over and over. This one takes 100,000 in a single job. Paste it below, or send it from code. Try 15,000 URL checks your first month, on us.

Try it now. Paste a few URLs.

We check them on the next screen. Nothing to sign up for to start.

Missing https:// is fine, we add it. Up to 100,000 URLs from this form.

You'll sign up on the next screen, your URLs come with you.

The ceiling

Every other bulk HTTP status checker has a limit you will hit today.

The tools that rank for this search were built for spot checks. They take 25 URLs, or 100, or a couple of hundred. That is fine for a handful of redirects and useless for a sitemap, a backlink export or a product catalogue.

At 100,000 URLs a job there is no batching step. You do not split the file, you do not paste the same page forty times, and you do not write a loop around someone else's form. One list in, one report out, and the job runs on our machines so you can close the tab.

The other thing a limit hides: a tool checking 100 URLs from one IP never has to solve bot detection. At fifty thousand it is the whole problem, and a status code that says 403 because we were blocked is worse than no answer at all. That is why the report separates a genuine 403 from a block against us, instead of handing you a column of numbers to re-check by hand.

Prefer it from code? The same job runs through the REST API, the Python and Node SDKs and MCP, so a status sweep can live in CI rather than in a browser tab.

Status codes

What each HTTP status code becomes in the report.

The useful question is not what a code means in the RFC. It is what you have to do about it across fifty thousand rows, and which ones you can ignore.

200, 206
working
It answered. Nothing to do.
301, 302, 307, 308
moved
Reported as the code the server actually sent, with the full chain and the final URL. A 308 is a 308 here, not flattened into "redirect".
200 + not-found body
soft 404
Answers OK while the page says it cannot find anything. Detected by comparing body length, title and known not-found patterns. Invisible to anything reading only the status line.
404, 410
gone
The only verdict we call broken. 410 stays a 410, because "deliberately removed" and "missing" are different decisions when you write redirects.
401, 403, 418
recovered / still refusing
Re-requested by an independent route before any verdict is written. If it answers, it is Recovered and reported as working. If it refuses every route, it is Still refusing, listed apart and never counted as broken.
429
rate limited
Paced per host rather than recorded as a failure, which is the part a home-grown runner usually skips.
451
blocked for legal reasons
Unavailable from the region the request came from. Reported apart from both dead and refused.
5xx, timeouts
temporary
Retried before anything is reported. A blip is not a broken link.

The 403 problem

Why a status check you wrote yourself stops telling the truth.

Everyone who checks URLs at volume writes this script once. It works on a thousand URLs and starts lying somewhere around five thousand.

A runner making requests from one machine and one address gets turned away after a few thousand of them. The responses come back 403, 429 or a reset connection, and a single-attempt runner writes them down as failures. You open twenty by hand and find nineteen load perfectly.

The fix is not more concurrency. It is a second attempt from somewhere else, plus pacing per host so the door does not get shut in the first place. That is the part that stops being a weekend project.

Measured on our own production database over the 90 days to 21 September 2026, across 603 jobs and 41,308 distinct domains: 56,892 URLs refused at least one request, and 13,597 of them answered when re-requested by an independent route. That is 23.9%.

Every one is a row your own run would have handed you as broken.

How we decide what counts as broken

API · SDKs · MCP

Run a bulk status code check from CI, a cron or an agent.

One backend and one pool of credits behind every surface. One credit per URL wherever the request came from, on every plan, with no developer tier to buy.

# 50,000 URLs, one call, a job id back
curl -X POST https://api.bulkurlchecker.com/v2/jobs \
  -H "Authorization: Bearer $BUC_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"urls": [...]}'

{ "job_id": "9024c1a6", "queued": 50000 }

# cursor is stable while the run is still finishing
curl .../v2/jobs/9024c1a6/results?cursor=...

{ "url": "/old", "status": 301, "final_url": "/new" }
{ "url": "/gone", "status": 404, "verdict": "gone" }

REST API. Start a job and poll it, or use the blocking call for small batches. Idempotency-Key makes retries safe, results page with stable cursors, and every response carries a request id and the rate-limit headers.

Python and Node SDKs. Type-hinted Python with a CLI, strict TypeScript with ESM and CJS builds, both MIT licensed with a webhook signature helper.

Webhooks and MCP. A signed job.completed event posted to your endpoint, and a hosted MCP server that works in Claude, ChatGPT and Cursor over OAuth with no key to paste.

Docs, quickstarts and the OpenAPI spec

FAQ

Bulk HTTP status checking questions.

If yours is not here, write to us and a person answers. The address is at the bottom of this page.

How do I check HTTP status codes for thousands of URLs at once?
Paste the list into the box on this page, or POST it to the API and poll the job. As a bulk URL status checker it takes up to 100,000 URLs in one run and returns the status code, the full redirect chain and the final URL for each one. It runs on our machines, so you can close the tab.
Why does my own script report 403s on pages that work in a browser?
Because a run from one machine and one address starts getting turned away after a few thousand requests, and a single-attempt runner records that as a failure. We re-request those by an independent route before writing a verdict. Over the 90 days to 21 September 2026, across 603 jobs and 41,308 domains, 56,892 URLs refused at least one request and 13,597 of them answered on a later attempt.
Can I run a bulk status code check from CI or a cron job?
Yes. There is a REST API with idempotency keys and cursor pagination, Python and Node SDKs with webhook signature helpers, an OpenAPI spec and a Postman collection, plus signed webhooks so you are told rather than polling. A hosted MCP server is available if you would rather ask Claude or ChatGPT to run the check.
Does it detect soft 404s?
Yes. A page answering 200 with a not-found body is flagged separately, by comparing response body length, title and a set of known not-found patterns. A status-code-only check cannot see these, and they are why a clean report is not always a true one.

Try 15,000 URL checks your first month, on us.

No card. Setting up a scheduled check costs nothing; only the runs use credits, and unused credits roll over.

See pricing

We use analytics cookies to improve your experience. Opt out anytime in Cookie Settings. Privacy Policy

Settings