# Bulk URL Status & Redirect Checker (`fleet261114/url-status-checker`) Actor

Check thousands of URLs for HTTP status, full redirect chains, broken links, redirect loops, HTTPS downgrades and canonical mismatches. Fast HEAD requests, polite per-host limits.

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

## Pricing

from $0.56 / 1,000 url results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 & Redirect Checker

Paste a list of URLs and get, for each one: the final HTTP status, **every redirect hop** (status and Location), the final URL, response time, content type, and clear flags for **broken links, redirect loops, too many redirects, HTTPS-to-HTTP downgrades** and, optionally, **canonical-tag mismatches**.

It uses lightweight HEAD requests (falling back to GET when a server mishandles HEAD), runs up to 50 requests in parallel, and keeps at most 2 parallel requests per website by default, so it is quick without hammering anyone's server.

### Use it for

- **Site migrations and redirect maps:** check that every old URL lands on the right new page in one hop.
- **Broken-link audits:** run a list of URLs (for example from a sitemap export) and keep only the problems.
- **SEO hygiene:** find redirect chains, HTTP downgrades and pages whose canonical tag points elsewhere.
- **Monitoring:** schedule it daily on your key pages and get alerted on failures through Apify's integrations.

### Input

| Field | What it does |
|---|---|
| **URLs to check** (required) | One per line, up to 100,000 per run. Missing scheme → `https://`. Duplicates are checked once. |
| Return only problem URLs | Return only broken, redirecting, downgrading or canonical-mismatch URLs. You pay only for the results returned. |
| Check the canonical tag | Reads the start of each final HTML page (max 512 KB) to compare `<link rel="canonical">` with the final URL. Slower (GET instead of HEAD). |
| Max redirects to follow | Default 10; more is reported as "too many redirects". |
| Timeout per request | Default 15 s. |
| Parallel requests (total / per host) | Defaults 10 / 2. |
| Use HEAD requests | Default on. Off = always GET. |

### Output

One item per URL. A real example from a test run:

```json
{
  "url": "http://gov.uk/",
  "finalUrl": "https://www.gov.uk/",
  "statusCode": 200,
  "ok": true,
  "broken": false,
  "redirectCount": 2,
  "redirectChain": [
    { "url": "http://gov.uk/", "status": 301, "location": "https://gov.uk/" },
    { "url": "https://gov.uk/", "status": 301, "location": "https://www.gov.uk/" },
    { "url": "https://www.gov.uk/", "status": 200, "location": null }
  ],
  "responseTimeMs": 201,
  "contentType": "text/html; charset=utf-8",
  "contentLength": 11261,
  "server": "nginx",
  "canonicalUrl": "https://www.gov.uk/",
  "canonicalMismatch": false,
  "redirectLoop": false,
  "tooManyRedirects": false,
  "httpsDowngrade": false,
  "error": null,
  "checkedAt": "2026-11-15T05:29:32.646Z"
}
```

`broken` is true for a final status of 400 or above, a network error (DNS, timeout, refused connection, TLS), a redirect loop, or too many redirects; `error` then says which. A `RUN_SUMMARY` record in the run's key-value store has the totals and any invalid input lines.

### Pricing

Pay per result: **$0.0008 per URL result returned** ($0.80 per 1,000), plus Apify's small run-start fee. Invalid lines and duplicates are not charged; with "Return only problem URLs", healthy URLs are not charged either. You can set a maximum cost per run; the Actor stops cleanly when it is reached.

### Limits and honest notes

- Status codes are what the server returns to this Actor's requests from Apify's data centers. Some sites (behind bot protection such as Cloudflare challenges) answer automated requests with 403 or 429 even though the page works in a browser. Such results are real responses, but not proof that the page is down for people.
- Only HTTP-level redirects (3xx with Location) are followed. JavaScript and `<meta refresh>` redirects are not.
- Response times are measured from Apify's servers and include network distance; use them for comparisons, not as page-speed scores.
- Check only sites you have a legitimate reason to check, at sensible concurrency. The defaults are deliberately polite.
- No personal data is collected: only URLs, status codes and response headers listed above.

### Use it from the API, a schedule or an AI agent

**API.** Start a run and get the results in one call (replace `YOUR_APIFY_TOKEN`):

```bash
curl -X POST "https://api.apify.com/v2/actors/fleet261114~url-status-checker/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"urls": ["http://python.org", "https://example.com"]}'
```

This waits up to 5 minutes. For bigger jobs, start a run with `POST /v2/acts/fleet261114~url-status-checker/runs` and read its dataset when it finishes. Apify's JavaScript and Python clients wrap the same calls.

**Schedules and integrations.** Create a task with your input and attach an Apify schedule (for example daily). Use Apify's integrations (webhooks, Make, Zapier, n8n, Google Sheets and others) to send the results onward.

**AI agents (MCP).** Add this Actor as a tool in any MCP client (Claude, Cursor and others) through Apify's hosted MCP server:

```
https://mcp.apify.com?tools=fleet261114/url-status-checker
```

The agent sees the input schema and the field descriptions above and can call the Actor directly. Set a maximum cost per run in the call options to cap spending.

### FAQ

**Why does a page that works in my browser show 403?** Some sites block automated requests from data centers (bot protection). The result is the server's real answer to this Actor, not proof the page is down for people.

**Does it follow JavaScript redirects?** No, only HTTP redirects (3xx with a Location header).

**Can I check a whole website?** Give it the list of URLs, for example from a sitemap export. It checks the URLs you supply; it does not crawl links.

**What does a typical run cost?** At $0.0008 per result: 1,000 URLs cost about $0.80. With "Return only problem URLs" you pay only for the problems.

### Questions and problems

Open an issue on the Actor's **Issues** tab with the run link.

# Actor input Schema

## `urls` (type: `array`):

One URL per line (up to 100,000 per run). URLs without a scheme get https://. Duplicates are checked once.

## `onlyProblems` (type: `boolean`):

Return only URLs that are broken, redirect, downgrade to HTTP or have a canonical mismatch. All URLs are still checked; you pay only for the results returned.

## `checkCanonical` (type: `boolean`):

Download the start of each final HTML page (up to 512 KB) and compare its <link rel="canonical"> with the final URL. Slower; uses GET instead of HEAD.

## `maxRedirects` (type: `integer`):

A URL with more redirects than this is reported as broken (too many redirects).

## `timeoutSecs` (type: `integer`):

How long to wait for each request before reporting a timeout.

## `concurrency` (type: `integer`):

Requests running at the same time across all websites.

## `perHostConcurrency` (type: `integer`):

Keeps the load on any one website low.

## `useHeadRequests` (type: `boolean`):

HEAD is faster and lighter. If a server answers HEAD with an error, the URL is re-checked with GET automatically.

## Actor input object example

```json
{
  "urls": [
    "http://python.org",
    "https://wordpress.org/this-page-does-not-exist",
    "https://example.com"
  ],
  "onlyProblems": false,
  "checkCanonical": false,
  "maxRedirects": 10,
  "timeoutSecs": 15,
  "concurrency": 10,
  "perHostConcurrency": 2,
  "useHeadRequests": true
}
```

# Actor output Schema

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

No description

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

No description

# 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 = {
    "urls": [
        "http://python.org",
        "https://wordpress.org/this-page-does-not-exist",
        "https://example.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("fleet261114/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 = { "urls": [
        "http://python.org",
        "https://wordpress.org/this-page-does-not-exist",
        "https://example.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("fleet261114/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 '{
  "urls": [
    "http://python.org",
    "https://wordpress.org/this-page-does-not-exist",
    "https://example.com"
  ]
}' |
apify call fleet261114/url-status-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,fleet261114/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/nmG15wPOlvkjbjdYy/builds/CWmn5piqJhEizikIF/openapi.json
