# Bulk URL Checker — Status, Redirects & SEO Tags (`haketa/bulk-url-checker`) Actor

Check thousands of URLs at once: HTTP status code, redirects, final URL, response time, content type and on-page SEO tags (title, meta description, H1, canonical, Open Graph, noindex). Fast, cheap bulk link auditing for SEO, QA and migrations.

- **URL**: https://apify.com/haketa/bulk-url-checker.md
- **Developed by:** [Haketa](https://apify.com/haketa) (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

from $0.70 / 1,000 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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Bulk URL Checker — Status, Redirects, Response Time & SEO Tags

Check **thousands — or millions — of URLs at once.** Paste a list (or upload a file) and get, for every URL: **HTTP status code, redirects, final URL, response time, HTTPS, content type**, plus the on-page **SEO tags** (title, meta description, H1, canonical, Open Graph, robots/noindex, word count).

Fast, cheap, and built for scale — ideal for **SEO audits, broken-link checks, redirect audits, site migrations and uptime/health monitoring.**

---

### Why this Actor?

Checking one URL is easy. Checking **your whole site, your whole backlink list, or a million URLs** is not — you need concurrency, retries, redirect handling and clean structured output. This Actor does exactly that: point it at a big list of URLs and get one tidy row per URL, ready for a spreadsheet or a pipeline.

- **SEO audits** — pull titles, meta descriptions, H1s, canonicals and noindex flags across every page.
- **Broken-link / dead-link checks** — find 404s, 5xx errors and timeouts at scale.
- **Redirect audits** — see what redirects where, and to which final URL (great for migrations).
- **Uptime & health checks** — status code and response time for a list of endpoints.
- **List enrichment** — enrich a list of domains/URLs with status and metadata before further work.

Because it runs on plain HTTP (no browser), it's **fast and inexpensive**, so large lists stay cheap.

---

### What you get

One record per URL:

| Field | Description |
| --- | --- |
| `url` | The URL you submitted |
| `statusCode` | HTTP status code (200, 301, 404, 500…) |
| `ok` | Whether it's healthy (2xx/3xx) |
| `finalUrl` | URL after following redirects |
| `redirected` | Whether it redirected |
| `responseTimeMs` | Response time in milliseconds |
| `isHttps` | Whether the final URL is HTTPS |
| `contentType` | Content type (text/html, application/pdf…) |
| `server` | Server header |
| `title` | Page title |
| `metaDescription` | Meta description |
| `h1` | First H1 |
| `canonical` | Canonical URL |
| `ogTitle` / `ogImage` | Open Graph title & image |
| `metaRobots` | Robots meta content |
| `isNoindex` | Whether the page is set to noindex |
| `wordCount` | Body word count |
| `error` | Error message, if the check failed |
| `scrapedAt` | Timestamp |

---

### Example output

```json
{
  "url": "https://example.com",
  "statusCode": "200",
  "ok": "true",
  "finalUrl": "https://example.com/",
  "redirected": "false",
  "responseTimeMs": "312",
  "isHttps": "true",
  "contentType": "text/html",
  "title": "Example Domain",
  "metaDescription": "",
  "h1": "Example Domain",
  "canonical": "",
  "isNoindex": "false",
  "wordCount": "28",
  "scrapedAt": "2026-07-08T15:00:00.000Z"
}
````

A broken URL comes back with `ok: "false"` and either a status code (404, 500) or an `error` (timeout, DNS failure).

***

### Input

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `urls` | array | — | **Required.** The URLs to check. Paste a list, or upload / link a text/CSV file of URLs. |
| `checkSeo` | boolean | `true` | Also extract SEO tags. Turn off for a pure status/redirect check (faster). |
| `maxConcurrency` | integer | `50` | URLs checked in parallel (up to 500). |
| `timeoutSecs` | integer | `30` | Give up on a URL after this many seconds. |

#### Status-only check (fastest)

```json
{
  "urls": [{ "url": "https://example.com" }, { "url": "https://example.com/old-page" }],
  "checkSeo": false,
  "maxConcurrency": 200
}
```

#### Full SEO audit

```json
{
  "urls": [{ "url": "https://mysite.com" }, { "url": "https://mysite.com/blog" }],
  "checkSeo": true
}
```

You can also give a **remote file of URLs** (one per line, or a CSV) via the input's file/link option — perfect for very large lists.

***

### Use cases in detail

#### 1. SEO audit at scale

Run your whole sitemap through it and export titles, meta descriptions, H1s, canonicals and noindex flags. Instantly spot missing/duplicate titles, thin content (low `wordCount`), or pages accidentally set to `noindex`.

#### 2. Broken-link & error monitoring

Feed a list of URLs (your links, your backlinks, your product pages) and filter by `ok: "false"` to find every 404, 5xx and timeout.

#### 3. Redirect audit for migrations

Before/after a site migration, check that old URLs redirect to the right `finalUrl` with the right status — catch redirect chains and loops.

#### 4. Uptime & response-time checks

Schedule the Actor over a list of endpoints and track `statusCode` + `responseTimeMs` over time.

#### 5. Pre-processing a URL list

Have a messy list of domains? Run it through to normalize, resolve redirects and drop the dead ones before scraping or outreach.

***

### How to use it

1. Click **Try for free**.
2. Paste or upload your URLs.
3. Click **Start**.
4. Export results as **JSON, CSV, Excel**, or via the Apify API.

Runs scale with your list — hundreds of URLs finish in seconds, millions run cheaply on plain HTTP.

***

### Calling from the API

```bash
curl -X POST "https://api.apify.com/v2/acts/YOUR_ACTOR_ID/runs?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "urls": [{"url":"https://example.com"}], "checkSeo": true }'
```

Then fetch the dataset:

```bash
curl "https://api.apify.com/v2/acts/YOUR_ACTOR_ID/runs/last/dataset/items?token=YOUR_APIFY_TOKEN&format=csv"
```

Works with webhooks, Zapier, Make and n8n.

***

### Frequently asked questions

**How many URLs can it handle?**
From a handful to millions — it auto-scales concurrency and streams results to the dataset.

**Does it follow redirects?**
Yes — `finalUrl` is the destination after redirects, and `redirected` tells you if it moved.

**Does it render JavaScript?**
No — it uses fast HTTP fetching, so it reads the server-rendered HTML (title, meta, etc.). This keeps large runs cheap. JS-only content won't appear.

**Can I do a status-only check without SEO?**
Yes — set `checkSeo: false` for a faster, lighter run.

**What about broken or unreachable URLs?**
They're included with `ok: "false"` and a status code or error, so nothing is silently dropped.

**Can I upload a big file of URLs?**
Yes — the URL input accepts a pasted list or a linked/uploaded text/CSV file.

***

### Tips

- **Turn off SEO for pure link-checking** — much faster on huge lists.
- **Raise `maxConcurrency`** for speed on big runs (mind the target servers).
- **Filter on `ok` / `statusCode`** to isolate broken URLs; on `redirected` for migration checks; on `isNoindex` for SEO issues.
- **Enable a proxy** for very large runs or to avoid rate limits from a single IP.

***

### Notes

This Actor performs standard HTTP requests to the URLs you provide and reads publicly returned headers and HTML. Use it on URLs you have the right to check, and be considerate with concurrency toward target servers.

***

### Support

Want SSL certificate details, hreflang, structured-data checks, or another field? Open an issue from the Actor's page.

# Actor input Schema

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

The URLs to check. Paste a list, or upload a file / link to a remote text/CSV of URLs. Handles thousands to millions.

## `checkSeo` (type: `boolean`):

Also extract on-page SEO tags (title, meta description, H1, canonical, Open Graph, robots). Turn off for a pure status/redirect check (faster).

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

How many URLs to check in parallel. Higher = faster, but be considerate of target servers.

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

Give up on a URL after this many seconds.

## `proxyConfiguration` (type: `object`):

Apify Proxy. Off by default — enable it for large runs or geo-specific checks.

## Actor input object example

```json
{
  "urls": [
    {
      "url": "https://apify.com"
    },
    {
      "url": "https://github.com"
    },
    {
      "url": "https://example.com"
    }
  ],
  "checkSeo": true,
  "maxConcurrency": 50,
  "timeoutSecs": 30,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `url` (type: `string`):

The URL checked

## `statusCode` (type: `string`):

HTTP status code

## `ok` (type: `string`):

Whether the URL is healthy (2xx/3xx)

## `finalUrl` (type: `string`):

URL after redirects

## `redirected` (type: `string`):

Whether it redirected

## `responseTimeMs` (type: `string`):

Response time in ms

## `isHttps` (type: `string`):

Whether final URL is HTTPS

## `contentType` (type: `string`):

Content type

## `server` (type: `string`):

Server header

## `title` (type: `string`):

Page title

## `metaDescription` (type: `string`):

Meta description

## `h1` (type: `string`):

First H1

## `canonical` (type: `string`):

Canonical URL

## `ogTitle` (type: `string`):

Open Graph title

## `ogImage` (type: `string`):

Open Graph image

## `metaRobots` (type: `string`):

Meta robots

## `isNoindex` (type: `string`):

Whether noindex is set

## `wordCount` (type: `string`):

Body word count

## `error` (type: `string`):

Error, if the check failed

## `scrapedAt` (type: `string`):

Timestamp

# 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": [
        {
            "url": "https://apify.com"
        },
        {
            "url": "https://github.com"
        },
        {
            "url": "https://example.com"
        }
    ],
    "maxConcurrency": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("haketa/bulk-url-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": [
        { "url": "https://apify.com" },
        { "url": "https://github.com" },
        { "url": "https://example.com" },
    ],
    "maxConcurrency": 50,
}

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

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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": [
    {
      "url": "https://apify.com"
    },
    {
      "url": "https://github.com"
    },
    {
      "url": "https://example.com"
    }
  ],
  "maxConcurrency": 50
}' |
apify call haketa/bulk-url-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=haketa/bulk-url-checker",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Bulk URL Checker — Status, Redirects & SEO Tags",
        "description": "Check thousands of URLs at once: HTTP status code, redirects, final URL, response time, content type and on-page SEO tags (title, meta description, H1, canonical, Open Graph, noindex). Fast, cheap bulk link auditing for SEO, QA and migrations.",
        "version": "0.1",
        "x-build-id": "pqSoa91JUpSM3A8hV"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/haketa~bulk-url-checker/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-haketa-bulk-url-checker",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/haketa~bulk-url-checker/runs": {
            "post": {
                "operationId": "runs-sync-haketa-bulk-url-checker",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/haketa~bulk-url-checker/run-sync": {
            "post": {
                "operationId": "run-sync-haketa-bulk-url-checker",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "urls"
                ],
                "properties": {
                    "urls": {
                        "title": "URLs to check",
                        "type": "array",
                        "description": "The URLs to check. Paste a list, or upload a file / link to a remote text/CSV of URLs. Handles thousands to millions.",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "checkSeo": {
                        "title": "Extract SEO tags",
                        "type": "boolean",
                        "description": "Also extract on-page SEO tags (title, meta description, H1, canonical, Open Graph, robots). Turn off for a pure status/redirect check (faster).",
                        "default": true
                    },
                    "maxConcurrency": {
                        "title": "Max concurrency",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "How many URLs to check in parallel. Higher = faster, but be considerate of target servers.",
                        "default": 50
                    },
                    "timeoutSecs": {
                        "title": "Timeout per URL (s)",
                        "minimum": 3,
                        "maximum": 120,
                        "type": "integer",
                        "description": "Give up on a URL after this many seconds.",
                        "default": 30
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Apify Proxy. Off by default — enable it for large runs or geo-specific checks.",
                        "default": {
                            "useApifyProxy": false
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
