# Bulk URL Status Checker — HTTP Codes & Redirect Chains (`actor-forge/bulk-url-status-checker`) Actor

Paste a list of URLs and get each one's HTTP status code, final URL after redirects, the full redirect chain, response time and error type (404, 5xx, DNS, timeout, SSL). No crawling: exactly the URLs you give. $0.20 per 1,000 URLs.

- **URL**: https://apify.com/actor-forge/bulk-url-status-checker.md
- **Developed by:** [ActorForge](https://apify.com/actor-forge) (community)
- **Categories:** SEO tools, Developer tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.20 / 1,000 link checkeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Bulk URL Status Checker — HTTP Codes & Redirect Chains

Paste a list of URLs and get each one's HTTP status code, final URL after redirects, the full redirect chain, response time and error type (404, 5xx, DNS, timeout, SSL). No crawling: exactly the URLs you give. $0.20 per 1,000 URLs.

**Check a list of URLs in bulk** and get, for every URL, the **HTTP status code**, the **final URL** after redirects, the **full redirect chain** (each hop with its 301/302/307/308 status), the **response time** and, when it fails, the **error type** (404, 410, 5xx, DNS failure, timeout, SSL error, redirect loop). Exactly the URLs you paste are checked: nothing is crawled and no links are followed, so 10,000 URLs cost the same as 10,000 checks.

Use it for **site migrations and redirect QA** (do the old URLs land on the right new pages with a single 301?), cleaning link lists and backlink exports, checking affiliate, ad or QR-code destinations, monitoring a set of key pages on a schedule, or validating URLs in a spreadsheet before an import.

Bot-protected answers (LinkedIn's 999, Cloudflare challenges, 403/429 walls) are reported separately as **blocked**, never as broken, because those pages usually work in a browser.

**$0.20 per 1,000 URLs.** URLs pointing at internal network addresses are refused and never charged.

### What data does it return?

Every run outputs clean, schema-validated rows like these:

| url | category | status | finalStatus | finalUrl | redirectHops | responseTimeMs |
| --- | --- | --- | --- | --- | --- | --- |
| https://httpbin.org/status/404 | broken | 404 | 404 | https://httpbin.org/status/404 | 0 | 644 |
| http://apify.com/ | redirect | 301 | 200 | https://apify.com/ | 1 | 311 |
| https://www.wikipedia.org/wiki/Web_scraping | redirect | 301 | 200 | https://en.wikipedia.org/wiki/Web_scraping | 1 | 237 |
| https://example.com/ | ok | 200 | 200 | https://example.com/ | 0 | 116 |
| https://github.com/apify/crawlee | ok | 200 | 200 | https://github.com/apify/crawlee | 0 | 710 |

### How much does it cost?

Transparent pay-per-event pricing — you only pay for what you get, and the
actor **always respects your run budget**: set a maximum total charge and it
stops cleanly at the cap instead of overrunning.

| Event | Price | Charged | Worked example |
| --- | --- | --- | --- |
| `link-checked` | $0.0002 | per unique URL checked | 1,000 URLs = $0.20; 10,000 URLs = $2.00 |
| `apify-actor-start` | $0.00005 | per run per GB of memory (platform start fee) | One run at 1 GB = $0.00005 |

### Input options

| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `startUrls` | array | yes | — | One URL per line (up to 10,000). Each URL is requested once (HEAD, confirmed with GET when the server refuses HEAD) and redirects are followed to the final page. Duplicates are checked once. Pages are not crawled and links on them are not followed. |
| `checkListOnly` | boolean | no | `true` | Always on for this listing: only the given URLs are checked. |
| `reportMode` | string | no | `"all"` | All: every URL with its status (default). Broken + redirects: only URLs that fail or redirect. Broken: only failing URLs (4xx/5xx, dead domains, timeouts, SSL errors, redirect loops). Same price whatever you pick. |
| `reportBlocked` | boolean | no | `true` | Some sites refuse automated checks (LinkedIn answers 999, others 403/429 or a Cloudflare challenge). Those links probably work in a browser, so they are reported separately as 'blocked', never as broken. Turn off to hide them. |
| `maxLinks` | integer | no | `10000` | Stop after checking this many URLs (each one is a link-checked event). |
| `ignoreLinkGlobs` | array | no | `[]` | URLs matching these patterns are neither checked nor reported (and not charged), e.g. https://www.linkedin.com/\*\* (\*\* = anything, \* = anything except /). |

### Limits & honest notes

- Checks only the URLs you give: it does not crawl pages or check the links on them. To find broken links across a whole website, use Broken Link Checker.
- Some sites refuse automated requests: LinkedIn answers 999, others answer 403 or 429 or show a Cloudflare challenge. Those links usually work in a browser, so they are reported as 'blocked' (status kept) instead of broken. Hide them with 'Report bot-blocked links' or skip them with 'Ignore links matching'.
- Each unique link is checked once with a HEAD request; when a server refuses HEAD or answers a common error status (400, 403, 404, 405, 410, 5xx…) or drops the connection, the result is confirmed with GET before it is called broken. Redirects are followed up to 10 hops, with the full chain recorded. Each request times out after 20 seconds.
- Polite by design: at most 2 requests at a time per host, and a 429 'Too Many Requests' pauses that host for its Retry-After. Very link-heavy external hosts (GitHub, for example) therefore take a while to check.
- Redirects are followed up to 10 hops; a longer chain or a loop is reported as broken (too-many-redirects). JavaScript or meta-refresh redirects are not followed.
- Links to internal network addresses (localhost, private IPs, cloud metadata) are never requested and never charged.
- Respects your run budget: set a maximum total charge and the run stops cleanly at the cap and reports everything checked so far.

### Related ActorForge actors

- [Broken Link Checker](https://apify.com/actor-forge/broken-link-checker) — crawl a whole site and find every broken link on it
- [Sitemap URL Extractor](https://apify.com/actor-forge/sitemap-extractor) — get every URL of a site to check

### Changelog

- **2026-10-23** — Initial release: URL-list listing of Broken Link Checker (new checkListOnly mode: no crawl, up to 10,000 URLs), $0.20 per 1,000 URLs.

***

*Built and maintained by **ActorForge**. Reliability first: every actor in the
portfolio is monitored by an automated nightly self-test, and breakages are
typically fixed the same day.*

# Actor input Schema

## `startUrls` (type: `array`):

One URL per line (up to 10,000). Each URL is requested once (HEAD, confirmed with GET when the server refuses HEAD) and redirects are followed to the final page. Duplicates are checked once. Pages are not crawled and links on them are not followed.

## `checkListOnly` (type: `boolean`):

Always on for this listing: only the given URLs are checked.

## `reportMode` (type: `string`):

All: every URL with its status (default). Broken + redirects: only URLs that fail or redirect. Broken: only failing URLs (4xx/5xx, dead domains, timeouts, SSL errors, redirect loops). Same price whatever you pick.

## `reportBlocked` (type: `boolean`):

Some sites refuse automated checks (LinkedIn answers 999, others 403/429 or a Cloudflare challenge). Those links probably work in a browser, so they are reported separately as 'blocked', never as broken. Turn off to hide them.

## `maxLinks` (type: `integer`):

Stop after checking this many URLs (each one is a link-checked event).

## `ignoreLinkGlobs` (type: `array`):

URLs matching these patterns are neither checked nor reported (and not charged), e.g. https://www.linkedin.com/\*\* (\*\* = anything, \* = anything except /).

## Actor input object example

```json
{
  "startUrls": [
    "http://apify.com",
    "https://httpbin.org/status/404",
    "https://example.com"
  ],
  "checkListOnly": true,
  "reportMode": "all",
  "reportBlocked": true,
  "maxLinks": 10000,
  "ignoreLinkGlobs": []
}
```

# Actor output Schema

## `results` (type: `string`):

One row per URL: status code, final URL, redirect chain, error type and response time.

## `summary` (type: `string`):

URLs checked, broken by error type, redirects, bot-blocked URLs, and why the run stopped.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        "http://apify.com",
        "https://httpbin.org/status/404",
        "https://example.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("actor-forge/bulk-url-status-checker").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "startUrls": [
        "http://apify.com",
        "https://httpbin.org/status/404",
        "https://example.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("actor-forge/bulk-url-status-checker").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    "http://apify.com",
    "https://httpbin.org/status/404",
    "https://example.com"
  ]
}' |
apify call actor-forge/bulk-url-status-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,actor-forge/bulk-url-status-checker"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/VpZz5c4dNF3vEoU4a/builds/B8gugvopOStniG6Nl/openapi.json
