# Bulk URL Status Code & Redirect Checker — Bouncefern (`cybermax/url-status-checker`) Actor

Bulk HTTP status code checker and redirect checker: paste URLs or an old -> new redirect map, get status, final URL, every redirect hop, broken links (404), loops, 302s and HTTPS downgrades. Verify site migrations, find broken links, alert on changes. $1 per 1,000 URLs, no start fee.

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

## Pricing

$1.00 / 1,000 url 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

## Bouncefern: Bulk URL Status Code & Redirect Checker

#### Paste URLs, see which ones break, bounce or loop

Give it a list of URLs (or an `old -> new` redirect map); get each URL's HTTP status, final URL, every redirect hop, broken links (404/410), redirect loops, 302s that should be 301s, HTTPS-to-HTTP downgrades and timeouts. $1 per 1,000 URLs, no start fee.

**[▶ Try it now with a prefilled input](https://apify.com/cybermax/url-status-checker)** · $0.001 per URL (10,000 URLs = $10) · no start fee, so a 3-URL check costs $0.003 · Apify's free plan includes $5 of credit a month

**Built for:** SEO teams checking redirects after a migration · marketers checking campaign and affiliate links · developers and QA testing deploys · anyone with a spreadsheet column of URLs to verify

**Real output** (real run on Apify, 25 Oct 2026, the prefilled input: 3 URLs in 1.9 s, $0.003):

| URL | First status | Final status | Final URL | Redirects | Issues |
|---|---|---|---|---|---|
| http://apify.com/ | 301 | 200 | https://apify.com/ | 1 | none |
| https://apify.com/store | 200 | 200 | https://apify.com/store | 0 | none |
| https://apify.com/this-page-does-not-exist-404 | 404 | 404 | (same) | 0 | broken (404/410) |

```json
{"urls": ["http://apify.com", "https://apify.com/store", "https://apify.com/this-page-does-not-exist-404"]}
```

### Ready-made inputs (one click)

| Job | Input | Result |
|---|---|---|
| **First try** (3 URLs) | the prefilled input above | Status, final URL and issues for each. |
| **Verify a redirect map** | `{"urls": ["http://example.com/old-page -> https://example.com/new-page"]}` | `matchesExpected: true/false` per line. |
| **Only the broken ones** | `{"urls": ["…your list…"], "onlyProblems": true}` | Only URLs with errors or issues; healthy URLs are free. |
| **What Googlebot gets** | `{"urls": ["…"], "userAgent": "googlebot"}` | Status and redirects for the Googlebot user agent. |
| **Daily link watch** | `{"urls": ["…"], "monitor": true, "monitorKey": "landing-pages"}` | On a schedule: only URLs whose status or destination changed. |

### Use cases

- **Site migration QA:** paste the redirect map and see every line that doesn't land where it should, with the full chain.
- **Broken link and 404 checks:** campaign links, backlinks you bought, links in newsletters, product feeds.
- **Redirect chain clean-up:** find 2+ hop chains and temporary (302/307) redirects that leak SEO value.
- **Uptime-style monitoring for many URLs:** monitor mode on a schedule returns only what changed (a page that started returning 500, a redirect that now points elsewhere).
- **Feeding from a sitemap:** take every URL from [Sitemoss](https://apify.com/cybermax/sitemap-url-extractor) and check them all.

### Why Bouncefern

| | Bouncefern | Typical status checker on the Store |
|---|---|---|
| Full redirect chain | Every hop with status, Location and ms | Often final status only |
| Redirect-map check | `old -> new` lines, `matchesExpected` | Not offered |
| SEO issues | chains, 302/307, HTTPS→HTTP, no HTTPS, loops, 404/410, 5xx | Status code only |
| HEAD that servers refuse | Falls back to GET automatically | Often reported as an error |
| Changes only | Built-in monitor mode, unchanged URLs free | Not offered |
| Price | $1 per 1,000 URLs, no start fee | $0.58 to $300 per 1,000 (rival median about $2), some with a $0.035 start fee per run (Store prices on 25 Oct 2026) |

### Input

| Field | What it does |
|---|---|
| `urls` | URLs, domains, or `old -> new` lines (required). |
| `method` | `HEAD` (default, falls back to GET) or `GET`. Bodies are never downloaded. |
| `userAgent` | `browser`, `bot` or `googlebot`. |
| `maxRedirects`, `timeoutSecs`, `maxConcurrency` | Limits. |
| `onlyProblems` | Return (and charge) only URLs with errors or issues. |
| `monitor`, `monitorKey` | Only URLs that are new or changed since the last monitor run. |

### Output

One row per URL: `url`, `status` (first response), `finalStatus`, `finalUrl`, `category` (ok, redirect, not-found, client-error, server-error, timeout, dns-error, ssl-error, redirect-loop, too-many-redirects), `redirectCount`, `redirectChain` (url, status, location, ms per hop), `issues`, `ok`, `expectedUrl`, `matchesExpected`, `contentType`, `contentLength`, `server`, `xRobotsTag`, `lastModified`, `responseMs`, `method`, `error`, and `change`/`changedFields`/`previous` in monitor mode. `OUTPUT` holds counts by category.

### Pricing

- **$0.001 per URL checked** ($1 per 1,000). No start fee.
- Free: invalid lines, duplicates, healthy URLs when `onlyProblems` is on, unchanged URLs in monitor mode.
- Set a maximum charge per run in Apify's run options; Bouncefern stops cleanly when it is reached.

### Run it on a schedule

Apify Console → **Schedules** → **Create new** → cron `0 * * * *` (hourly) or `0 7 * * *` (daily) → **Add Actor** → Bouncefern with your URLs and `"monitor": true`. Through the API:

```json
POST https://api.apify.com/v2/schedules?token=YOUR_TOKEN
{
  "name": "bouncefern-landing-pages",
  "cronExpression": "0 7 * * *",
  "timezone": "America/New_York",
  "isEnabled": true,
  "actions": [{
    "type": "RUN_ACTOR",
    "actorId": "cybermax/url-status-checker",
    "runInput": {
      "body": "{\"urls\":[\"https://example.com/pricing\",\"https://example.com/signup\"],\"monitor\":true,\"monitorKey\":\"landing-pages\"}",
      "contentType": "application/json"
    }
  }]
}
```

Add an email, Slack or webhook notification on "Run succeeded" under the Actor's **Integrations** tab.

### Integrations

**API (synchronous):** `POST https://api.apify.com/v2/acts/cybermax~url-status-checker/run-sync-get-dataset-items?token=YOUR_TOKEN` with the input JSON returns the rows.

**Make / Zapier:** Apify app → "Run an Actor" (`cybermax/url-status-checker`, run synchronously, `"onlyProblems": true`) → "Get dataset items" → send each broken URL to Slack, email or a ticket.

**n8n:** Apify node ("Run an Actor and get dataset"), or HTTP Request:

```
POST https://api.apify.com/v2/acts/cybermax~url-status-checker/run-sync-get-dataset-items?token=YOUR_TOKEN
{"urls": ["https://example.com/a", "https://example.com/b"], "onlyProblems": true}
```

**Google Sheets:**

```
=IMPORTDATA("https://api.apify.com/v2/acts/cybermax~url-status-checker/runs/last/dataset/items?format=csv&fields=url,status,finalStatus,finalUrl,category,issues&token=YOUR_TOKEN")
```

**Python** (`pip install apify-client`):

```python
from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("cybermax/url-status-checker").call(run_input={"urls": ["http://apify.com", "https://apify.com/store"]})
for r in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(r["url"], r["status"], r["finalStatus"], r["issues"])
```

**AI agents (MCP):** `https://mcp.apify.com/?tools=cybermax/url-status-checker` (Authorization: `Bearer YOUR_TOKEN`). Typical prompts: "Check these 200 URLs and list the broken ones", "Does every old URL in this redirect map land on the right new page?".

### When NOT to use it

- **Pages behind a login:** you'll see the login redirect, which is often what you want to know, but not the page itself.
- **Content checks:** Bouncefern reads status and headers, not page text. For titles, descriptions and OG tags use [Unfurlwren](https://apify.com/cybermax/meta-tags-extractor).
- **Sites that block datacenter IPs** may answer 403 to any cloud checker.

### FAQ

**Why not a free online checker?** They cap you at a handful of URLs and don't run on a schedule. Bouncefern takes thousands, shows every hop, checks redirect maps and alerts only on changes.

**Why not curl in a script?** You can. Bouncefern handles HEAD fallbacks, loops, relative Location headers, concurrency, timeouts and a clean table, and an AI agent can call it.

**Can an AI agent use it (MCP)?** Yes. Add `https://mcp.apify.com/?tools=cybermax/url-status-checker` as an MCP server in Claude, Cursor, VS Code or any MCP client.

**Does it download pages?** No. It sends HEAD (or GET and closes the connection at the headers), so it's fast and light on the sites you check.

**Is it legal to use?** Checking whether public URLs respond is what browsers and search engines do on every visit. This is general information, not legal advice.

### Start now

**[▶ Try Bouncefern with a prefilled input](https://apify.com/cybermax/url-status-checker)** · $1 per 1,000 URLs, no start fee. Questions? Open an issue on the Store page and it gets answered the same day.

### Also from CyberMax

- [Sitemoss — sitemap URL extractor](https://apify.com/cybermax/sitemap-url-extractor): every URL of a site from its sitemaps, to check in bulk.
- [Unfurlwren — meta tags & Open Graph extractor](https://apify.com/cybermax/meta-tags-extractor): titles, descriptions, OG images and schema.org with SEO issues.
- [Eldwren — Wayback Machine scraper](https://apify.com/cybermax/wayback-machine): find old URLs that need redirects.
- [Linkheft — bulk domain authority checker](https://apify.com/cybermax/domain-authority): rank and authority for each domain.

### Changelog

- 2026-10-25: First release: full redirect chains, redirect-map verification, SEO issue flags, HEAD→GET fallback, Googlebot user agent, only-problems filter, monitor mode.

© 2026 CyberMax. All rights reserved.

# Actor input Schema

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

One per line. Plain URLs or domains (example.com), or a redirect map line "old-url -> expected-new-url" (also "old,new") to verify a site migration: Bouncefern then reports matchesExpected for each line. Duplicates are removed.

## `method` (type: `string`):

HEAD is fastest. Servers that reject or mishandle HEAD are retried with GET automatically. Bodies are never downloaded.

## `userAgent` (type: `string`):

Some sites answer differently to browsers and bots.

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

0 = report only the first response.

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

Timeouts are reported as category timeout.

## `maxConcurrency` (type: `integer`):

Lower it for one fragile server.

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

Skip URLs that are fine (status under 400, no issues). Skipped URLs are not charged.

## `monitor` (type: `boolean`):

For scheduled runs. Remembers each URL's status, final URL and redirect count and returns only URLs that are new or changed since the last monitor run (change, changedFields, previous). Unchanged URLs are not returned and not charged.

## `monitorKey` (type: `string`):

Optional name for this watchlist's saved state (e.g. top-landing-pages).

## Actor input object example

```json
{
  "urls": [
    "http://apify.com",
    "https://apify.com/store",
    "https://apify.com/this-page-does-not-exist-404"
  ],
  "method": "HEAD",
  "userAgent": "browser",
  "maxRedirects": 10,
  "timeoutSecs": 15,
  "maxConcurrency": 10,
  "onlyProblems": false,
  "monitor": false
}
```

# 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://apify.com",
        "https://apify.com/store",
        "https://apify.com/this-page-does-not-exist-404"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("cybermax/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://apify.com",
        "https://apify.com/store",
        "https://apify.com/this-page-does-not-exist-404",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("cybermax/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://apify.com",
    "https://apify.com/store",
    "https://apify.com/this-page-does-not-exist-404"
  ]
}' |
apify call cybermax/url-status-checker --silent --output-dataset

```

## MCP server setup

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