# Apify Actor Run Monitor: Empty Output Alerts (`davidbenittah/apify-run-output-health-monitor`) Actor

Check up to 50 Apify Actors and find the ones that are quietly broken: no recent run, a failed or aborted run, a failure rate above your threshold, a successful run with an empty dataset, or output missing a required field. One health row per Actor, plus a summary.

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

## Pricing

$3.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/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/docs.md):

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

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.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/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

## Apify Actor Run Monitor: Empty Output Alerts

A scheduled Actor can finish with status SUCCEEDED and still deliver nothing your pipeline can use. This monitor checks execution status and output health on up to 50 Actors in one pass, so an empty dataset, a schedule that stopped firing, a run of repeated failures or a field that vanished from the output become explicit alerts instead of a report that goes wrong downstream three days later.

### What the health monitor checks on every Actor

- whether the latest run exists and is recent enough;
- whether the latest run failed, timed out, or was aborted;
- the failure rate across the most recent 1–20 runs;
- whether the latest successful dataset meets a minimum item count;
- whether one output sample contains every required dotted field path.

### Silent failures this catches

- catch a successful schedule that silently produced an empty dataset;
- audit an Actor portfolio after deployments or schema changes;
- watch stale, failed, timed-out, or repeatedly failing automations;
- verify required output fields before downstream workflows consume the data.

### Input-Output

The default input checks the public `apify/web-scraper` Actor. Apify's limited-permission run token cannot read Actor run or dataset metadata, so add a personal API token for actionable health results. Without one, inaccessible targets are returned as `unknown` rather than failing the run:

```json
{
  "actorIds": ["apify/web-scraper"]
}
````

Add a personal token and your health contract for public or private portfolios:

```json
{
  "apiToken": "YOUR_APIFY_PERSONAL_API_TOKEN",
  "actorIds": ["apify/web-scraper", "apify/website-content-crawler"],
  "maxAgeHours": 24,
  "recentRuns": 10,
  "failureRateThresholdPercent": 50,
  "minimumItems": 1,
  "requiredFields": ["url"],
  "alertsOnly": false
}
```

Apify encrypts the secret `apiToken` at rest and decrypts it only for the run. The token is sent only to `api.apify.com` in the authorization header and is never included in output or logs. Give it only the permissions needed to read the monitored Actors, runs, and datasets.

### Data returned for each Actor

| Field | What it holds |
|---|---|
| `actorRef` | The Actor inspected, as you passed it |
| `health` | `ok`, `warning`, `unhealthy` or `unknown` |
| `alertReasons` | Why it is not `ok`, in plain language |
| `latestStatus` / `latestRunAgeHours` | State and age of the most recent run |
| `failureRatePercent` | Share of failures across the recent runs inspected |
| `lastSuccessfulItemCount` | Dataset size of the last successful run |
| `missingFields` | Required dotted paths absent from the sampled item |
| `checkedAt` | Timestamp of the inspection |

The `SUMMARY` record aggregates healthy, warning, unhealthy, and unknown results.

### Pricing

Pay per Actor inspected. The `actor-checked` event is charged once before each inspection, including healthy Actors omitted by `alertsOnly`. The run stops before unpaid work when the buyer's maximum charge is reached. Dataset rows themselves are not a second billable event.

### Reading health states

- `ok`: no configured rule was violated.
- `warning`: the latest run is still in a non-terminal state.
- `unhealthy`: no run exists, a run appears stuck or failed, recent failures cross the configured threshold, the latest successful dataset is too small, or required fields are absent.
- `unknown`: the Actor or its storage could not be read; the error is isolated so the rest of the portfolio is still checked.

### FAQ

#### Does this rerun or modify monitored Actors?

No. It only reads run and dataset metadata.

#### Why is my Actor `unknown`?

The Actor or its storage could not be read. Add a personal token with the minimum read permissions needed for the target, then check the returned reason.

#### Does it inspect every dataset row?

No. It reads the item count and at most one sample row per Actor for required-field checks.

### Limits and responsible use

- Maximum 50 Actors per run.
- Maximum 20 recent runs inspected per Actor.
- Maximum 50 required field paths, 256 characters and 20 levels per path.
- A run charges once before each inspection and stops when no further `actor-checked` event fits the buyer's limit.
- At most one dataset item is sampled per Actor for field checks.
- Set `minimumItems` to `0` for Actors that intentionally produce no dataset rows.
- Field checks inspect one sample and do not prove every row has the same schema.
- Only Actors and storages accessible to the account that launches the run can be inspected.
- No proxy, browser, login scraping, personal-data targeting, automatic reruns, or outbound webhooks.

This is an unofficial independent utility and is not affiliated with Apify. Review alert thresholds against each Actor's expected schedule and output contract.

# Actor input Schema

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

Needed because limited-permission run tokens cannot read Actor run or dataset metadata. Encrypted by Apify and sent only to api.apify.com.

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

Actor IDs or username/name pairs. Both username/actor-name and username~actor-name are accepted. Hard maximum: 50.

## `maxAgeHours` (type: `integer`):

Alert when the latest run is older than this.

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

Used to calculate the recent failure rate. Hard maximum: 20.

## `failureRateThresholdPercent` (type: `integer`):

Alert when at least two terminal runs were checked and this share failed.

## `minimumItems` (type: `integer`):

A successful run below this dataset count is a silent-failure alert. Use 0 for Actors that intentionally return no dataset rows.

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

Optional dotted paths checked on one item from the latest successful dataset. Maximum: 50 paths, 256 characters and 20 levels each.

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

Omit healthy Actors from the dataset.

## Actor input object example

```json
{
  "actorIds": [
    "apify/web-scraper"
  ],
  "maxAgeHours": 24,
  "recentRuns": 10,
  "failureRateThresholdPercent": 50,
  "minimumItems": 1,
  "requiredFields": [
    "url"
  ],
  "alertsOnly": false
}
```

# Actor output Schema

## `dataset` (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 = {
    "actorIds": [
        "apify/web-scraper"
    ],
    "requiredFields": [
        "url"
    ],
    "alertsOnly": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("davidbenittah/apify-run-output-health-monitor").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 = {
    "actorIds": ["apify/web-scraper"],
    "requiredFields": ["url"],
    "alertsOnly": False,
}

# Run the Actor and wait for it to finish
run = client.actor("davidbenittah/apify-run-output-health-monitor").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 '{
  "actorIds": [
    "apify/web-scraper"
  ],
  "requiredFields": [
    "url"
  ],
  "alertsOnly": false
}' |
apify call davidbenittah/apify-run-output-health-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=davidbenittah/apify-run-output-health-monitor",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Apify Actor Run Monitor: Empty Output Alerts",
        "description": "Check up to 50 Apify Actors and find the ones that are quietly broken: no recent run, a failed or aborted run, a failure rate above your threshold, a successful run with an empty dataset, or output missing a required field. One health row per Actor, plus a summary.",
        "version": "1.0",
        "x-build-id": "Vc7lTAttBn8gcTbso"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/davidbenittah~apify-run-output-health-monitor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-davidbenittah-apify-run-output-health-monitor",
                "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/davidbenittah~apify-run-output-health-monitor/runs": {
            "post": {
                "operationId": "runs-sync-davidbenittah-apify-run-output-health-monitor",
                "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/davidbenittah~apify-run-output-health-monitor/run-sync": {
            "post": {
                "operationId": "run-sync-davidbenittah-apify-run-output-health-monitor",
                "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": [
                    "actorIds"
                ],
                "properties": {
                    "apiToken": {
                        "title": "Apify personal API token",
                        "type": "string",
                        "description": "Needed because limited-permission run tokens cannot read Actor run or dataset metadata. Encrypted by Apify and sent only to api.apify.com."
                    },
                    "actorIds": {
                        "title": "Actors to inspect",
                        "minItems": 1,
                        "maxItems": 50,
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Actor IDs or username/name pairs. Both username/actor-name and username~actor-name are accepted. Hard maximum: 50.",
                        "default": [
                            "apify/web-scraper"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxAgeHours": {
                        "title": "Maximum run age (hours)",
                        "minimum": 1,
                        "maximum": 720,
                        "type": "integer",
                        "description": "Alert when the latest run is older than this.",
                        "default": 24
                    },
                    "recentRuns": {
                        "title": "Recent runs to inspect",
                        "minimum": 1,
                        "maximum": 20,
                        "type": "integer",
                        "description": "Used to calculate the recent failure rate. Hard maximum: 20.",
                        "default": 10
                    },
                    "failureRateThresholdPercent": {
                        "title": "Failure-rate alert threshold (%)",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Alert when at least two terminal runs were checked and this share failed.",
                        "default": 50
                    },
                    "minimumItems": {
                        "title": "Minimum items expected",
                        "minimum": 0,
                        "maximum": 1000000,
                        "type": "integer",
                        "description": "A successful run below this dataset count is a silent-failure alert. Use 0 for Actors that intentionally return no dataset rows.",
                        "default": 1
                    },
                    "requiredFields": {
                        "title": "Required output fields",
                        "maxItems": 50,
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Optional dotted paths checked on one item from the latest successful dataset. Maximum: 50 paths, 256 characters and 20 levels each.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "alertsOnly": {
                        "title": "Return alerts only",
                        "type": "boolean",
                        "description": "Omit healthy Actors from the dataset.",
                        "default": 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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
