# Link Route Audit — Bulk HTTP Status & Redirects (`cliqtomedia/bulk-url-status-redirect-checker`) Actor

Check a list of public URLs before a site move or SEO review. See final HTTP status, ordered redirect destinations and broken-link flags, then export a table. Up to 100 input URLs per run.

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

## Pricing

from $2.25 / 1,000 http url results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

Check a list of public URLs before a site move or SEO review. This bulk URL status checker returns the final HTTP status, redirect destinations and broken-link flags for each processed URL. Start with one URL and open its result table. Each run accepts up to 100 input items. An empty list fails; a stopped run may return part of the list. The charge model is pay per useful HTTP result plus an Actor Start event and platform usage. Optional Apify Proxy traffic adds usage costs.

<img src="https://api.apify.com/v2/key-value-stores/nzrRxSbHbnrcN8wZ1/records/HERO_PNG_de4dc734ccbb.png?signature=1pFGZryczIzuS5ypSsHyR" width="640" alt="A supplied URL list follows redirect paths to success or broken-link results">

### Table of contents

- [What it checks](#what-it-checks)
- [Data you get](#data-you-get)
- [Quick start](#quick-start)
- [Input reference](#input-reference)
- [Input examples](#input-examples)
- [Real output example](#real-output-example)
- [Output field reference](#output-field-reference)
- [Run summary and storage](#run-summary-and-storage)
- [Pricing and cost controls](#pricing-and-cost-controls)
- [Use cases](#use-cases)
- [Scheduling and monitoring](#scheduling-and-monitoring)
- [API and integrations](#api-and-integrations)
- [Export to JSON CSV and Excel](#export-to-json-csv-and-excel)
- [Limits and partial results](#limits-and-partial-results)
- [Troubleshooting](#troubleshooting)
- [FAQ](#faq)
- [Related tools](#related-tools)
- [Support and privacy](#support-and-privacy)

### What it checks

The Actor sends HTTP requests to the URLs you supply. It starts with HEAD and uses GET when the server returns 405 or 501 for HEAD. It does not read page content. It follows safe redirect destinations and returns one row per processed unique URL.

Use it for a known list from a migration plan, link report or QA check. It does not crawl a website, find URLs, render JavaScript, log in, or check page text. A 200 response alone does not prove that a page has the right content or is indexed.

### Data you get

Each Dataset row has nine fields. Use `statusCode` to see the final HTTP response, `isBroken` to find failures, and `redirectChain` with `finalUrl` to review the route.

| Result | Meaning | Next step |
| --- | --- | --- |
| `200`, not broken | The final server returned success | Check whether `finalUrl` is the address you expect |
| `404`, broken | The server answered “Not Found” | Fix the URL or redirect |
| `0`, broken, `finalUrl: null` | The check ended without a usable HTTP response | Review DNS, connection, TLS, timeout or access |
| Redirect to `404` | A route exists but ends at a missing page | Fix the destination |

This is a point-in-time HTTP check. Server rules, location and connection mode can change the result. There is no saved snapshot comparison or automatic change alert.

### Quick start

1. Open the Actor in Apify Console and choose **Input**.
2. Switch to **JSON** and paste the minimal input below, or enter the URL objects in **URLs to check**.
3. Keep direct requests for a first check. A fresh form offers one public example.com URL; you can start this sample without editing it. API calls still require startUrls and never substitute a hidden demo.
4. Click **Start**. A run uses the selected build and run options.
5. Open **Output → URL results → Table**. Check `statusCode` and `finalUrl`.
6. Choose **Export** to save the results. Open **Storage** to read the separate summary.

The example checks a public test service with a 301 redirect to a 200 response. Site behavior may change. You can replace it with a public URL you control.

### Input reference

| Key | Form title | Type and shape | Required | Runtime default / form prefill | Range or choice | Effect and advice |
| --- | --- | --- | --- | --- | --- | --- |
| `startUrls` | URLs to check | Array of objects with a string `url` | Yes | No runtime default; UI prefill `[{"url":"https://example.com"}]` | 1–100 items; each URL up to 4,096 characters | Supply full public `http://` or `https://` URLs. List size is checked before duplicate removal. |
| `maxConcurrency` | URLs checked at once | Integer | No | 20 / 20 | 1–100 | Number of URL checks at once. Start with 2–3 for slow sites. The API form range is enforced by schema; runtime clamps finite numeric values to the range. |
| `proxyConfiguration` | Connection mode | Object | No | `{"useApifyProxy":false}` / No proxy | `useApifyProxy` boolean; optional string-array `groups` and string `countryCode` | Direct is the default. Choose available Apify Proxy groups/location only when needed; access and extra costs depend on your account. Custom proxy URLs and credentials are rejected. |
| `requestTimeoutSecs` | Request timeout (seconds) | Integer | No | 10 / 10 | 1–30 | Maximum wait for each DNS, proxy CONNECT and response-header phase. It is not a total per-URL time limit. |

A URL object has the form `{"url":"https://example.com/"}`. Strings alone are not accepted. Leading and trailing spaces are removed. Duplicate detection uses the parsed URL; query strings are kept. Invalid items are skipped and listed in `failedInputs`. If none remain valid, the run fails.

| Settings used together | Result | Cost or safety note |
| --- | --- | --- |
| More parallel checks + slow or rejecting servers | More active requests; possible retries or rate limits | Higher concurrency does not ensure a faster run |
| Proxy enabled + redirect/retry | Each request uses the selected connection mode | Extra traffic can add cost |
| Short phase timeout + several hops/retries | A check can still take longer than one phase timeout | Use the run timeout as a separate bound |

TLS certificate checks are always on. `ignoreTlsErrors` is unsupported. Headers, cookies, login details and a custom proxy URL are not input options.

### Input examples

#### Minimal check

```json
{
  "startUrls": [
    {
      "url": "https://httpbingo.org/redirect-to?url=%2Fstatus%2F200&status_code=301"
    }
  ]
}
```

Expected: a row with `statusCode: 200`, `isRedirect: true`, and `redirectChain: ["https://httpbingo.org/status/200"]`. This same URL was checked in the recorded run shown below; that run also contained other URLs.

#### Small SEO review

```json
{
  "startUrls": [
    {
      "url": "https://httpbingo.org/status/200?case=tz06-200"
    },
    {
      "url": "https://httpbun.com/status/404?case=tz06-404"
    },
    {
      "url": "https://httpbingo.org/redirect-to?url=%2Fstatus%2F200&status_code=301"
    }
  ],
  "maxConcurrency": 2,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "requestTimeoutSecs": 10
}
```

Expected: a 200 row, a 404 row and a redirected 200 row, if the test services keep these responses. These URLs are part of the same measured corpus. Use a small concurrency value for your first real list. To use Apify Proxy, change only `useApifyProxy` to `true` and choose a group you can access.

### Real output example

This is one full Dataset item from a real Cloud run on 2026-10-02. It is selected from eight results; timing and date are observed values, not fixed expectations.

```json
{
  "url": "https://httpbingo.org/redirect-to?url=%2Fstatus%2F200&status_code=301",
  "statusCode": 200,
  "statusMessage": "OK",
  "isBroken": false,
  "isRedirect": true,
  "redirectChain": [
    "https://httpbingo.org/status/200"
  ],
  "finalUrl": "https://httpbingo.org/status/200",
  "responseTime": 122,
  "checkedAt": "2026-10-02T14:18:28.271Z"
}
```

The chain lists destinations in order and includes the final URL. It does not repeat the input URL as the first hop. The array contains URLs, not objects with a status code for each hop.

### Output field reference

All nine keys are present on each result row. They are result fields, not input controls.

| Key | Table title | Type / empty value | Meaning and example |
| --- | --- | --- | --- |
| `url` | Original URL | String; not null | The submitted URL after spaces are removed; the example input URL |
| `statusCode` | HTTP status code | Integer; not null | Final HTTP code such as `200` or `404`; `0` for a technical failure without a usable final response |
| `statusMessage` | Status message | String; not null | HTTP message such as `OK`, or a safe diagnostic such as `Network request failed`; low-level error details are not stored |
| `isBroken` | Is broken | Boolean | True for status 0, HTTP codes at least 400, blocked targets, redirect loops or the hop limit |
| `isRedirect` | Is redirect | Boolean | True if a redirect was seen; it can stay true when the next target is blocked |
| `redirectChain` | Redirect chain | Array of strings; `[]` when no safe destination was added | Safe destinations in order, including the final destination; unsafe targets are excluded |
| `finalUrl` | Final URL | String or `null` | Last URL checked on a normal HTTP path. Null on a technical failure. On a redirect stop, review the broken flag and message; this is not proof of a successful arrival. |
| `responseTime` | Response time ms | Integer milliseconds; not null | Time for the URL check, including hops, phase waits, retries and retry delays; not a browser page-load metric |
| `checkedAt` | Checked at | String; UTC ISO date/time | Time when the URL check started, such as `2026-10-02T14:18:28.271Z`; use it with the result time |

The Actor does not return `redirectCount`, `contentType`, `contentLength`, `server`, page text, canonical tags or headers. To count stored safe destinations in your own code, use the array length; it need not equal every redirect seen when a target was blocked.

### Run summary and storage

**Dataset** stores the URL rows. The Actor’s output schema provides links to **URL results** and **Run records**. Run records opens the Key-value store collection. Select `RUN_SUMMARY` or `OUTPUT` there. They are separate from the nine Dataset columns.

`OUTPUT` has `results` (the Dataset rows), `summary` (the terminal summary), and `datasetUrl` (the Console Dataset link). `RUN_SUMMARY` holds that same summary. Open the run’s **Storage** tab, then its Key-value store to read these records.

| Summary key | Type | Meaning |
| --- | --- | --- |
| `received` | Integer | Original number of submitted items |
| `valid` | Integer | Accepted unique URLs before checking |
| `duplicates` | Integer | Repeated accepted URLs skipped |
| `processed`, `results` | Integer each | Number of result rows written; both use the same count |
| `domainEmpty` | Integer | Always 0; this checker has no domain-empty result |
| `technicalFailures` | Integer | Processed rows with status 0 |
| `unprocessed` | Integer | Valid URLs left without a result row |
| `attempts` | Integer | Request attempts, including DNS/socket failures, hops, retries and HEAD/GET |
| `fallbacks` | Integer | HEAD requests followed by GET |
| `retries` | Integer | Extra request attempts started after a retry decision |
| `rateLimits` | Integer | HTTP 429 responses received |
| `cancelled` | Boolean | Whether the checker received a stop signal |
| `outcome` | String | `succeeded`, `partial` or `error` |
| `timings.startedAt`, `timings.finishedAt` | UTC ISO strings | Checker start and finish; not the full platform start/pull time |
| `transport.mode` | String | `direct` or `proxy`; no proxy address or password |
| `failedInputs` | Array of objects | Rejected entries with integer zero-based `index` and safe string `reason` |

Normal reconciliation: `received = valid + duplicates + failedInputs.length`, `valid = processed + unprocessed`, and Dataset length equals `results`. HTTP 404 alone can still have summary `succeeded`: the check worked and returned an HTTP result. `partial` covers technical failures, rejected inputs, queued work or cancellation.

Before result publication, a run-level error uses a smaller summary shape: `{"outcome":"error","error":{"code":"INVALID_INPUT","message":"..."}}`. Standard counters are absent in this shape. `OUTPUT.results` is empty. Other adapter/storage/runtime errors can also end the run; review its status and log. Do not treat an empty Dataset as proof that every URL is good.

### Pricing and cost controls

The applied model is **pay per event plus platform usage**. A stored URL result with an HTTP response costs **USD 0.00225**. HTTP 404 and 503 are useful check results and count. Technical failures with status 0, duplicates, invalid inputs, queued URLs and summaries do not count as result events.

The platform charges **USD 0.001 for Actor Start** at the supported 128–256 MB memory range. This start charge can apply even when input validation fails. Compute, storage and optional proxy use are charged separately at your account rates. Check the Pricing tab before starting.

| Useful HTTP results | Result events + one start | Additional cost |
| --- | --- | --- |
| 1 | USD 0.00325 | Platform usage and optional proxy |
| 10 | USD 0.02350 | Platform usage and optional proxy |
| 100 | USD 0.22600 | Platform usage and optional proxy |
| 1,000 over 10 batches of 100 | USD 2.26000 | Usage of all 10 runs; this is arithmetic, not a single-run capacity claim |

Set a **maximum cost per run**, timeout and memory in run options. The minimum accepted cost limit is USD 0.00325. Private defaults are 256 MB and 180 seconds. Input concurrency is separate. The Actor limits the checked unique URLs to the number of result events its available event budget can cover; technical failures can leave some of that budget unused. A low budget can produce a partial result and `unprocessed` URLs. Platform usage can reduce the budget further or stop the run.

Results are saved in a batch, then useful result events are charged once each. A run-local `RESULTS_PENDING` record keeps the result batch for recovery. If a storage or charging step fails, already stored results remain available and the run can fail. A resumed run checks stored rows and platform event counts before writing or charging again. A hard stop before the batch is saved can still lose results. There is no total-cost discount or guaranteed profit promised to buyers.

### Use cases

| Buyer job | Add to `startUrls` | Review | Next step |
| --- | --- | --- | --- |
| Site migration URL check | Your old public URLs | `redirectChain`, `finalUrl`, `isBroken` | Compare the final destination with your own migration map |
| Broken link list | URLs from a link report | `statusCode`, `isBroken`, `statusMessage` | Fix or replace failing links |
| QA after a release | Known public endpoints | `statusCode`, `responseTime`, `checkedAt` | Re-check failed endpoints and keep the dated export |
| Redirect audit | Known redirecting URLs | Ordered `redirectChain`, `isRedirect` | Review extra hops or broken destinations |

The Actor does not import a sitemap or compare an old-to-new map for you. It checks the list you provide.

### Scheduling and monitoring

To repeat a known list, save the input as an Apify task, then create a schedule for that task in Console. Choose a small list, a time and run limits. Every scheduled run can incur usage costs.

Keep dated exports if you need to compare runs. There is no built-in snapshot diff, uptime SLA or automatic change alert. Scheduling does not add those features. This guide does not create a schedule for you. See the [Apify scheduling guide](https://docs.apify.com/platform/schedules).

### API and integrations

Use the private Actor ID from your own authorized Apify account. Set `APIFY_TOKEN` in your environment; never place it in a URL or commit it. Save the input as `input.json`.

```bash
curl --fail-with-body --silent --show-error \
  --request POST \
  --header "Authorization: Bearer ${APIFY_TOKEN:?Set APIFY_TOKEN locally}" \
  --header 'Content-Type: application/json' \
  --data-binary @input.json \
  'https://api.apify.com/v2/acts/NmhMbSI7fgkagucYf/runs?build=0.1.10&memory=256&timeout=180&maxTotalChargeUsd=0.05'
```

This starts a paid run; it does not wait for completion. Read the returned `data.id` with `GET /v2/actor-runs/{runId}` until the run ends. Then read `GET /v2/datasets/{defaultDatasetId}/items` for the rows and the run’s Key-value store records for the summary. Keep the same Bearer header. Supply an exact available build from your Actor; newer builds may replace the example version.

Use `statusCode` or `isBroken` in your next system, and pass `finalUrl` only after checking the result. The [Apify API reference](https://docs.apify.com/api/v2) explains run and storage requests. Apify’s SDK/client can perform the same steps. This Actor has no custom MCP server or verified MCP tool; it does not need a new service installation.

### Export to JSON CSV and Excel

1. Open a completed run’s **Output → URL results**.
2. Select **Table** to scan the rows, or **JSON** to view field names and values.
3. Click **Export** and choose JSON, CSV or Excel (XLSX).
4. Keep all nine columns when another tool needs the full result. Array and null display can differ across export formats; use JSON to preserve these types.
5. Download `RUN_SUMMARY` separately from Storage when you also need rejected or unprocessed counts.

Exports read the stored results; you do not need to start another run for each format. See [Dataset storage and export](https://docs.apify.com/platform/storage/dataset).

### Limits and partial results

- At most **100 input items** per run, counted before duplicate removal. Split larger lists yourself.
- Concurrency range 1–100, default 20. Actual Cloud capacity was checked at concurrency 3 with 100 simple HTTP results; this does not promise the same speed or success for all sites.
- Up to 10 redirect hops; loops and the hop limit produce broken results. A final target can be present in the chain before the cap prevents fetching it.
- Up to 2 extra retries per request for network failures, 429 or 5xx. HEAD→GET fallback adds a request. Requests can therefore exceed the number of URLs.
- Request phase timeout 1–30 seconds, default 10. Several phases, hops and retries can take longer than one timeout value.
- Only public HTTP/HTTPS destinations. Private-network, loopback and unsafe targets are blocked, including at redirects and retries. TLS verification stays on.
- URL credentials, secret query values and fragments are rejected. Custom proxy credentials are not accepted.
- Results are saved as a batch after checking. A graceful stop can save finished and active rows and count queued URLs in `unprocessed`; a hard platform kill or storage failure may lose final results. There is no streaming or resume guarantee.
- A status 0, 403, 429 or blocked result does not prove the page is absent. It reports the response or failure seen by this run.

### Troubleshooting

| Symptom | Possible reason | Check | Action |
| --- | --- | --- | --- |
| Input form says “This field is required” | Empty URL list | `startUrls` object array | Add at least one full public URL |
| FAILED with `INVALID_INPUT` | Missing/empty/too-large list, unsupported option, or no valid URLs | Error summary and input shape | Correct the input; do not add secrets |
| Status 0 with null final URL | DNS, TLS, connection failure, timeout or blocked target | `statusMessage`, failed inputs and logs | Verify a public URL and retry a small subset |
| HTTP 404 | Server returned Not Found | Submitted and final URLs | Correct the URL or redirect |
| Fewer rows than input items | Duplicates, rejected entries, or queued work | `duplicates`, `failedInputs`, `unprocessed` | Fix the input or split a list |
| Succeeded but PARTIAL | Some checks failed technically or input was rejected | Summary, status0 rows | Review the failed subset; a platform success is not proof all URLs are good |
| Many 429/slow checks | Server rate limits or slow response | `rateLimits`, `attempts`, `retries` | Reduce concurrency and wait before a small re-check |
| Run stopped before results appeared | Batch saving and hard stop | Terminal status, summary/storage presence | Use smaller lists and enough run time; do not assume saved rows |

Log events use numeric counts and safe event names. They do not contain raw proxy addresses or detailed low-level errors.

### FAQ

#### Does it detect soft 404 pages?

No. It does not read page content. A page can return 200 while showing an error message.

#### Can I see the status of every redirect hop?

The Dataset stores destination URLs, not a status code for each hop. `statusCode` is the final HTTP code, or 0 on technical failure.

#### Is a redirect always broken?

No. A redirect to 200 normally has `isRedirect: true` and `isBroken: false`. A redirect to 404 is broken.

#### Is the response time a speed score?

No. It is the whole URL check time from the run environment, including retries and waits. It is not a Core Web Vital.

#### Can I use login pages or internal addresses?

Public login page addresses can return an HTTP status, but the Actor does not sign in. Private or internal destinations are blocked.

#### Does a schedule compare results for me?

No. Export the dated rows and compare them in your own system.

### Related tools

Use your spreadsheet or migration map with this Actor’s exported `finalUrl` and `statusCode` fields. No extra product is required.

### Support and privacy

For a bug or question, use the developer contact or Issues route shown on the Actor page in Apify. Include the run ID, list size, connection mode and a safe description of the problem. Do not send tokens, cookies, proxy passwords or a private URL list. Use the [Apify help center](https://help.apify.com/) for account or platform support.

Do not submit secrets in URL paths, query values or other input. Apify keeps the original INPUT record; this Actor cannot remove secrets you already submitted. Public URLs and final destinations are stored in Dataset/OUTPUT. Share exports only when the URLs are safe to share.

Checks access only public targets. This Actor is independent and is not affiliated with the websites it checks. It does not certify site ownership, content, access rights, availability or SEO ranking. Review the actual HTTP result and the limits above before acting on it.

# Actor input Schema

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

Add 1–100 public HTTP/HTTPS URL objects. The Input form offers example.com as a small sample; API input must still include startUrls. Duplicate URLs are checked once. Invalid items are listed in the run summary. Do not add secrets or login details.

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

How many URLs to check in parallel (1-100).

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

Direct requests by default. Optional Apify Proxy; custom proxy URLs and credentials are unsupported.

## `requestTimeoutSecs` (type: `integer`):

Maximum wait for each DNS, proxy CONNECT and response-header phase. Total check time includes retries and redirects. TLS verification is always enabled.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://example.com"
    }
  ],
  "maxConcurrency": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "requestTimeoutSecs": 10
}
```

# Actor output Schema

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

No description

## `records` (type: `string`):

Open RUN_SUMMARY for counters or OUTPUT for results and summary. INPUT is also retained by the platform; do not submit secrets.

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

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

# Run the Actor and wait for it to finish
run = client.actor("cliqtomedia/bulk-url-status-redirect-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": [
    {
      "url": "https://example.com"
    }
  ]
}' |
apify call cliqtomedia/bulk-url-status-redirect-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,cliqtomedia/bulk-url-status-redirect-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/NmhMbSI7fgkagucYf/builds/8kTIlfU3t7fw2lAzX/openapi.json
