# Scraper Output Guard: Apify Actor Data Quality Monitor (`lineagersiui/scraper-output-guard`) Actor

Monitor Apify Actors for silent failures: runs that succeed but return empty, truncated or drifting data. One verdict per Actor. Free demo, no token needed.

- **URL**: https://apify.com/lineagersiui/scraper-output-guard.md
- **Developed by:** [Lineage RSIUI](https://apify.com/lineagersiui) (community)
- **Categories:** Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$5.00 / 1,000 actor 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

## Scraper Output Guard

**Catch silent scraper failures.** A run can finish with status `SUCCEEDED` and still be broken: it returned 40 items instead of 500, a key field went empty, or the site changed and a field disappeared. Scraper Output Guard checks the **content** of your own Apify Actor runs, not just their status, and gives each Actor a verdict: `ok`, `warning` or `unhealthy`, with the reasons.

### What is Scraper Output Guard? An Apify Actor monitor for empty, truncated and drifting data

For each Actor you list, it compares its most recent runs and flags:

- **Failed runs:** the latest run failed, or the recent failure rate is high
- **Item-count drops:** fewer items than your minimum, or sharply below the median of recent runs
- **Early stops:** the run asked for N items (`maxItems`, `maxResults`, `resultsLimit`...) but returned far fewer while reporting success
- **Empty required fields:** fields you name (e.g. `price` or `seller.name`) are empty in too many sampled items
- **Schema drift:** fields present in an older run's first sampled item are missing from the latest run's first sampled item
- **Duplicates:** repeated items in the sample

### Who it is for

Anyone who runs scrapers on a schedule and feeds the data into reports, price monitors, lead lists or AI pipelines, where a quietly half-empty dataset costs more than a failed run.

### Try it free first

Run it with no input. It runs a **free demo on built-in sample data**: three sample Actors (one healthy, one truncated, one with schema drift) so you can see the verdicts and output format. Demo runs are not billed. One demo result:

```json
{
  "actorId": "demo/truncated-scraper",
  "verdict": "unhealthy",
  "reasons": [
    "Item count 40 is more than 50% below the recent median 500.",
    "Input maxItems=500 but only 40 items (possible early stop)."
  ],
  "latestRunId": "d4",
  "latestItemCount": 40,
  "runsChecked": 3,
  "demo": true
}
```

### How to use it on your Actors

1. In Apify Console, create an API token with **read** access to the Actors, runs and datasets you want checked.
2. Paste it into **Apify API token**, and list Actor IDs (`username/actor-name`, up to 50).
3. Optionally list **required fields** as dotted paths, and adjust the thresholds. Example input: `{"apiToken": "<read-only token>", "actorIds": ["username/my-scraper"], "requiredFields": ["price"]}`
4. Schedule it (for example daily after your scrapers run). Open the dataset's **Verdicts** view. The `SUMMARY` record in the key-value store has the totals. Turn on **Only output Actors with problems** to keep the dataset short.

### Run it automatically: schedules, webhooks, Make, Zapier, n8n

- Use an Apify **schedule** to run it daily after your scrapers.
- Or start it from a **webhook** when a scraper run finishes.
- Like any Actor, it can be started from Make, Zapier or n8n through Apify's integrations, so its verdicts can feed your alerts.

### Apify Actor run monitor: when to use this

- **Status alerts only:** if you only need alerts when runs fail, Apify's free monitoring Actors may be enough.
- **Content checks:** use Scraper Output Guard when a run can "succeed" with bad data. It combines item-count drops, early stops, empty required fields, schema drift and duplicates into one verdict per Actor, from a single run with no extra setup.

### Output

One dataset item per Actor checked: `actorId`, `verdict` (`ok`, `warning`, `unhealthy`, or `unknown` if it couldn't be read), `reasons`, `latestItemCount`, `latestRunId`, `runsChecked`. Reasons may name fields and counts; **your item values are never output**.

### How much does it cost to monitor Apify Actors?

Pay per event: **$0.005 per Actor checked** (`actor-checked` event).

- **Example:** checking 10 Actors once a day is about 300 events a month, which is $1.50.
- **Billed:** every Actor that gets a verdict (`ok`, `warning` or `unhealthy`, including "No runs found").
- **Not billed:** Actors that can't be read (`unknown`); demo runs.
- **Cap:** set a maximum charge per run in the run options.
- See the Pricing tab for the full, current price.

### Privacy and limits

- Your token is sent only to `api.apify.com`. It is never logged or written to the output. Use a read-only token.
- Reads run metadata and up to 1,000 sampled items per run.
- These are heuristic checks. They can't prove your data is correct or complete.
- This is an unofficial utility, not affiliated with Apify. It was built with the help of AI tools under the developer's direction, and its checks were tested on sample data.

### FAQ

**Does it re-run or change my Actors?** No. It only reads runs and datasets.

**What if a run is still in progress?** The Actor gets a `warning` that says so. Schedule the guard after your scrapers usually finish.

**How do I monitor Apify Actors for empty datasets?** List them in **Actor IDs**, set **Minimum items per successful run**, and schedule this Actor daily. Any run below the minimum is flagged `unhealthy`.

**Can I check Actors built by other developers?** Yes, if your token can read your runs of them. Apify's own test only checks that an Actor returns at least one item; this checks the size and content of *your* runs.

**Why does it need a token?** To read your runs and datasets through the Apify API. Use a read-only token; it is never logged or written to the output.

# Actor input Schema

## `apiToken` (type: `string`):

Personal token with read access to the Actors, runs and datasets to check. Sent only to api.apify.com; never logged or stored in output. Leave empty to run a free demo on sample data.

## `actorIds` (type: `array`):

username/actor-name or Actor ID, up to 50. Each Actor successfully checked is one billed event; Actors that cannot be read are not billed. Leave empty for the demo.

## `recentRuns` (type: `integer`):

How many of the most recent runs of each Actor to compare (1-20).

## `minItems` (type: `integer`):

A successful run with fewer items than this is flagged.

## `requiredFields` (type: `array`):

Fields every item should have, as dotted paths (e.g. price or seller.name). Empty values are counted.

## `maxCountDropPercent` (type: `integer`):

Flag the latest run if its item count is this much below the median of the recent runs.

## `maxNullRatePercent` (type: `integer`):

Warn when a required field is empty in more than this share of sampled items.

## `sampleSize` (type: `integer`):

Items read from each run dataset for the content checks (1-1000).

## `alertsOnly` (type: `boolean`):

If enabled, Actors with verdict ok are left out of the output. Those checks are still billed (the check was done); SUMMARY counts them.

## Actor input object example

```json
{
  "recentRuns": 5,
  "minItems": 1,
  "requiredFields": [],
  "maxCountDropPercent": 50,
  "maxNullRatePercent": 30,
  "sampleSize": 200,
  "alertsOnly": false
}
```

# Actor output Schema

## `verdicts` (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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("lineagersiui/scraper-output-guard").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("lineagersiui/scraper-output-guard").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 '{}' |
apify call lineagersiui/scraper-output-guard --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lineagersiui/scraper-output-guard"
        }
    }
}
```

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/rlT0SCdM2pG6wA98o/builds/OfcKHRymKk2yw786j/openapi.json
