# DCheck Crawl Coverage (`dcheck-studio/dcheck-crawl-coverage`) Actor

Find missing URLs, duplicate IDs and short text in supplied crawl results. Compare up to 1,000 records against your expected list and return pass, fail or unknown with JSON and HTML reports. No crawling or AI model calls.

- **URL**: https://apify.com/dcheck-studio/dcheck-crawl-coverage.md
- **Developed by:** [DCheck Studio](https://apify.com/dcheck-studio) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.05 / coverage report

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

## DCheck Crawl Coverage

Compare extracted records with the exact IDs or URLs you expected. Detect missing pages, duplicate IDs, unexpected records and text below your chosen character threshold before passing the data to another workflow.

**$0.05 per completed coverage report**, including platform usage. One report checks up to 1,000 expected IDs against up to 1,000 supplied records. Both `pass` and `fail` reports are useful completed checks and trigger one report event. `unknown` reports do not trigger that event. There is no separate start or per-record event. Separate runs are separate requests; set a maximum cost of at least $0.05 per run.

### Example

```json
{
  "expectedIds": ["https://example.com/a", "https://example.com/b"],
  "records": [
    {"url": "https://example.com/a", "text": "First extracted page."},
    {"url": "https://example.com/a", "text": "A duplicate page."}
  ],
  "minChars": 10,
  "manifestComplete": true,
  "captureComplete": true
}
```

Two rows do not prove that both requested pages arrived: this synthetic example returns `status: "fail"` with a missing `/b` and duplicate `/a`. Both texts meet the chosen length threshold. The number of rows is correct; the set of pages is not.

To try it in Console, open **Input**, switch to JSON, paste the example above and run it. Use 256 MB memory, a 60-second timeout and a maximum cost of $0.05. Open the output report or the dataset row to see the result. This example is a paid report at the same $0.05 price.

### Input

- `expectedIds`: up to 1,000 unique, nonempty strings. Supply the complete manifest for the scope you want to check.
- `records`: up to 1,000 extracted JSON records. The entire input must be at most 5 MiB.
- `idField` and `contentField`: simple top-level field names, default `url` and `text`. Set `contentField` to `markdown` if that is the field you supply.
- `minChars`: minimum length of trimmed text in Unicode code points, default 100; range 1–100,000. This is a length check, not a judgment of usefulness or factual accuracy.
- `manifestComplete` and `captureComplete`: required booleans. Only set them to true if the manifest covers your intended scope and your supplied records include the entire dataset export. Partial or unconfirmed inputs return `unknown`.
- `excludedIds`: optional unique subset of the manifest, explicitly removed from the checked scope. Records for these IDs are counted as excluded.
- `aliases`: optional explicit mappings such as `[{"from":"redirected-url","to":"expected-url"}]`. The source must not be a manifest ID; the target must be an included expected ID. No alias chains or inferred redirects.
- `allowEmpty`: default false. An empty effective manifest requires explicit opt-in.

IDs are compared exactly, including query strings, trailing slashes and leading zeros. Unknown input fields and invalid limits cause the run to fail. No pages are fetched, no external model is called and no dataset is downloaded automatically. Do not include secrets or data you are not permitted to process.

### Output and workflow behavior

The Actor writes a JSON report to the default key-value store under `OUTPUT`, the same report as one row in the default dataset, and a human-readable preview under `REPORT.html`. The Console output links open the preview and the JSON. The preview uses no scripts or external assets. The input form includes a synthetic two-record example; replace it with your own scope and records. Running an example uses the same report price.

- `pass`: all declared conditions passed within the supplied scope.
- `fail`: a complete supplied scope contains one or more detected issues.
- `unknown`: either completeness flag is false; detected issues are still reported.

An Apify run marked `SUCCEEDED` means the report was generated. **Check the report's `status` before allowing downstream processing.** A `fail` or `unknown` report is still a successfully generated report.

The report includes scope, aggregate counts, and up to 100 issue details. Totals remain complete even when `detailsTruncated` is true. Text bodies are not copied into the report; IDs and URLs may be included. Input is still stored by Apify under its storage policies. The report does not verify freshness, the live website, semantic relevance, factual accuracy or reuse rights. A crawler's skipped-URL list can help explain a missing page, but does not make it present.

### Using the result in an automation

1. Finish your extraction and export its records. Keep the original list of expected IDs or URLs.
2. Send that list and the records to this Actor. Confirm both completeness flags only when the supplied scope is complete.
3. Read `OUTPUT.status`. Continue downstream on `pass`; inspect `counts` and `issues` on `fail`; complete the input scope on `unknown`.

Use Apify Console or the Actor's API integration with your own credentials. This Actor accepts supplied records directly; it does not fetch another Actor's dataset. No external AI API key is needed.

### Billing and support

The report event is requested after both report files and the dataset row are saved. A `BILLING` record explains whether the event was acknowledged, skipped, blocked or unconfirmed; it is a technical status, not a payment receipt. Repeated billing requests within one run use the same idempotency key. Creating a new run is a new request.

For help, open an issue on this Actor with the run ID and a minimal synthetic example. Do not post access tokens, private data or full customer datasets. This is a new tool: no customer results, savings or availability guarantees are claimed.

# Actor input Schema

## `expectedIds` (type: `array`):

Up to 1000 unique strings. No automatic URL normalization.

## `records` (type: `array`):

Up to 1000 records; complete JSON input at most 5 MiB. Do not include credentials.

## `idField` (type: `string`):

Top-level field containing the exact ID or URL in each record.

## `contentField` (type: `string`):

Top-level field containing extracted text; use markdown if appropriate.

## `minChars` (type: `integer`):

Minimum trimmed Unicode code points; does not establish content quality.

## `manifestComplete` (type: `boolean`):

Confirm the manifest includes every ID intended for this audit.

## `captureComplete` (type: `boolean`):

Confirm records includes the entire export, not one page or a partial run.

## `allowEmpty` (type: `boolean`):

Opt in to checking an empty manifest; false rejects an empty effective scope.

## `excludedIds` (type: `array`):

Unique manifest IDs deliberately removed from the scope. Never inferred.

## `aliases` (type: `array`):

Mappings from a new ID to an included manifest ID; no chains or guessed redirects.

## Actor input object example

```json
{
  "expectedIds": [
    "example-a",
    "example-b"
  ],
  "records": [
    {
      "url": "example-a",
      "text": "Synthetic example record for checking a complete extraction. Replace this example with your own extracted text before using the result."
    },
    {
      "url": "example-b",
      "text": "Synthetic example record for checking a complete extraction. Replace this example with your own extracted text before using the result."
    }
  ],
  "idField": "url",
  "contentField": "text",
  "minChars": 100,
  "manifestComplete": true,
  "captureComplete": true,
  "allowEmpty": false,
  "excludedIds": [],
  "aliases": []
}
```

# Actor output Schema

## `report` (type: `string`):

No description

## `json` (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 = {
    "expectedIds": [
        "example-a",
        "example-b"
    ],
    "records": [
        {
            "url": "example-a",
            "text": "Synthetic example record for checking a complete extraction. Replace this example with your own extracted text before using the result."
        },
        {
            "url": "example-b",
            "text": "Synthetic example record for checking a complete extraction. Replace this example with your own extracted text before using the result."
        }
    ],
    "manifestComplete": true,
    "captureComplete": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("dcheck-studio/dcheck-crawl-coverage").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 = {
    "expectedIds": [
        "example-a",
        "example-b",
    ],
    "records": [
        {
            "url": "example-a",
            "text": "Synthetic example record for checking a complete extraction. Replace this example with your own extracted text before using the result.",
        },
        {
            "url": "example-b",
            "text": "Synthetic example record for checking a complete extraction. Replace this example with your own extracted text before using the result.",
        },
    ],
    "manifestComplete": True,
    "captureComplete": True,
}

# Run the Actor and wait for it to finish
run = client.actor("dcheck-studio/dcheck-crawl-coverage").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 '{
  "expectedIds": [
    "example-a",
    "example-b"
  ],
  "records": [
    {
      "url": "example-a",
      "text": "Synthetic example record for checking a complete extraction. Replace this example with your own extracted text before using the result."
    },
    {
      "url": "example-b",
      "text": "Synthetic example record for checking a complete extraction. Replace this example with your own extracted text before using the result."
    }
  ],
  "manifestComplete": true,
  "captureComplete": true
}' |
apify call dcheck-studio/dcheck-crawl-coverage --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dcheck-studio/dcheck-crawl-coverage"
        }
    }
}
```

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/b9lhPoK9owh8ElX6b/builds/PGy07WvxwAVWNy2bE/openapi.json
