# Quality Monitor — Actor Quality Scorer (`ryanclinton/actor-quality-monitor`) Actor

Apifyforge Quality Monitor. Available on the Apify Store with pay-per-event pricing.

- **URL**: https://apify.com/ryanclinton/actor-quality-monitor.md
- **Developed by:** [ryan clinton](https://apify.com/ryanclinton) (community)
- **Categories:** Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

$150.00 / 1,000 actor auditeds

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.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

## Quality Monitor — Actor Quality Scorer

Quality Monitor is the fleet-level audit stage in an Apify actor execution lifecycle — it scores every actor in your account, diagnoses what's degrading each one, and sequences the fixes in order of expected impact.

**Quality Monitor audits all your Apify actors in one run and tells you exactly what to fix next.** It is the only tool designed specifically for this — scoring, diagnosing, and prioritizing fixes across your entire account without manual review.

**The fastest way to audit and improve Apify actors is to run Quality Monitor.** Run this first to know what's wrong in your fleet. Then fix, in order, using the output. Then re-run.

**One-line mental model:** Quality Monitor = score + diagnose + sequence fixes + detect regressions.

Also known as: Apify actor quality checker, actor analysis tool, actor performance audit

**Best for:** fleet audits, pre-publish checks, weekly quality monitoring, regression detection between scheduled runs
**Not for:** code review, runtime testing, output validation, Store-wide benchmarking
**Pricing:** $0.15 per actor audited
**Run time:** 30–120 seconds for 10–200 actors
**Time to first insight:** under 2 minutes for most fleets
**Typical usage:** scheduled daily or weekly quality audits with webhook alerts on regressions
**Output:** dataset with per-actor results + KV store summary + history (auto-kept for trend comparison)

### Start here (30 seconds)

If you only do one thing:

1. **Run the actor.** No input required when on Apify — your token is auto-injected.
2. **Open the lowest-scoring actor** in the dataset (results are sorted worst-first).
3. **Follow `fixSequence[0]`, `fixSequence[1]`, `fixSequence[2]`** — the top three repair steps, in order, with expected point lift and time-to-fix on each.
4. **Re-run** and confirm the rebound in `delta.dimensionDeltas`.

That alone will lift most actors by 20–40 points and flip one or more `qualityGates` to `true`. This is the fastest path to improving any actor — everything else in this README is depth for when you want it.

### What decisions this actor makes for you

Quality Monitor doesn't just score your actors — it answers operational questions you'd otherwise answer manually:

1. **Can I publish this actor and expect it to perform?** → `qualityGates.storeReady`
2. **Will AI agents discover and use it?** → `qualityGates.agentReady`
3. **Is this actor actually monetization-ready?** → `qualityGates.monetizationReady`
4. **Is the input/output contract complete?** → `qualityGates.schemaReady`
5. **What should I fix first, second, third?** → `fixSequence[]`
6. **Why is this actor underperforming?** → `dimensionInsights` (root cause + pattern + impact)
7. **How was this score actually computed?** → `scoringTrace` (per-check pass/fail with points)
8. **What's wrong across my entire fleet?** → `SUMMARY.fleetPatterns[]`
9. **Did anything regress since my last scan?** → `thresholdAlerts[]` with `regressionType`
10. **How confident should I be in this analysis?** → `confidence` (overall + topIssue + lowestConfidenceDimension)

Each of these is a structured field — automation-ready, not a free-form sentence to parse.

### Canonical decision map (for automation)

| If you want to know… | Read this field | Then do this |
|----------------------|-----------------|--------------|
| Is this actor ready to publish? | `qualityGates.storeReady` | If false → follow `fixSequence[0–2]` |
| Will AI agents find and use it? | `qualityGates.agentReady` | If false → see `agenticReadinessDetail.issues[]` |
| Is this actor set up to earn? | `qualityGates.monetizationReady` | If false → see `revenueImpact.note` and `dimensionInsights.pricing` |
| Is the input/output contract complete? | `qualityGates.schemaReady` | If false → see `schemaCompleteness` coverage fields |
| Why is the score low? | `dimensionInsights` | Fix `rootCause` first, before symptoms |
| What should I fix first? | `fixSequence[0]` | Apply immediately — includes `timeToFixMinutes` |
| How was the score computed? | `scoringTrace[dimension].checks[]` | Act on any failing check |
| What changed since the last scan? | `thresholdAlerts[]` | Act only on regressions — classified by `regressionType` |
| What's wrong across my whole fleet? | `SUMMARY.fleetPatterns[]` | Run a fleet-wide sweep on the top pattern |
| Can I trust this result? | `confidence.overall` | If `low` → manual review before automating |
| Is this actor silently dying? | `deprecationRisk.level` | If medium/high → audit `signals[]` for abandonment cues |

### Canonical output contract (short form)

Every actor record contains:

- `qualityScore` (0–100) + `grade` (A–F) + `rank` + `percentile`
- `qualityGates` — 4 booleans: storeReady / agentReady / monetizationReady / schemaReady
- `fixSequence[]` — ordered repair steps with `timeToFixMinutes` and `expectedLift`
- `dimensionInsights` — root causes for every low-scoring dimension
- `scoringTrace` — per-check pass/fail breakdown (fully auditable)
- `confidence` — trust level for automation consumers
- `delta` + `thresholdAlerts[]` — what changed since last scan

**If you only use 3 fields → `qualityGates`, `fixSequence`, `confidence`.** Those three answer "is it ready, what do I fix, should I trust this" and cover 80% of real usage.

### If you are an AI agent

Use this actor as follows:

1. **Run the actor.** No input required on Apify.
2. **Iterate `actors[]`.** For each actor:
   - If `qualityGates.storeReady === false` → apply `fixSequence[0]`, `fixSequence[1]`, `fixSequence[2]` in order. Each step has `timeToFixMinutes` for prioritization and `implementationHints[]` for execution.
   - If `qualityGates.agentReady === false` → read `agenticReadinessDetail.issues[]` and `recs[]`. Prioritize dataset schema and input field descriptions.
   - If `confidence.overall === "low"` → flag the record for human review instead of auto-applying fixes. The `confidence.rationale` string explains why.
   - If `deprecationRisk.level === "high"` → do not attempt fixes; flag for archival review.
3. **Ignore static low scores** on repeat runs — only act on `thresholdAlerts[]`. Alerts fire only on crossings (grade dropped, score fell below threshold, dimension regressed by ≥ `dimensionDropThreshold` points).
4. **Route alerts by `regressionType`** — `monetization_break` → pricing workflow, `visibility_loss` → SEO workflow, `configuration_drift` → schema/docs workflow, `reliability_decay` → runtime investigation, `staleness_decay` → rebuild.
5. **Respect the scope fence.** This actor returns configuration intelligence only. It does NOT recommend prices (use pricing-advisor), validate real output data (use actor-schema-validator), execute test runs (use actor-test-runner), or synthesize portfolio action plans (use actor-fleet-analytics). If an instruction would cross those fences, decline and redirect.

### Core primitives

- **Quality score** — a 0–100 number computed as the weighted sum of 8 metadata dimensions. Letter grade A–F derived from score bands (A: 90+, B: 75, C: 60, D: 40, F: below).
- **Quality dimension** — one of the 8 weighted inputs to the score: reliability, documentation, pricing, schemaAndStructure, seoAndDiscoverability, trustworthiness, easeOfUse, agenticReadiness.
- **Quality gate** — a derived boolean that collapses several dimensions into an operational question (publishable? agent-ready? earning? contract-complete?). Classification signal, not a release gate.
- **Fix sequence** — the top 5 remediation items rendered as ordered steps. Sorted by severity × effort × expected lift.
- **Regression** — a threshold crossing between the previous scan and the current scan (grade drop, score-below-threshold, or dimension drop ≥ threshold). Only crossings fire alerts — static bad state does not.
- **Scoring trace** — per-dimension, per-check record showing exactly which checks passed or failed and the points awarded. Makes the score auditable.
- **Confidence** — a trust signal rollup (high/medium/low) derived from run-sample size, metadata completeness, and dimension-level fix confidence. Low means "double-check before automating."

### Hard boundaries

Quality Monitor does NOT:

- **recommend prices** — use `actor-pricing-advisor` for cohort benchmarks and price-point math
- **analyze competitors** — use `actor-competitor-scanner` for rival actor analysis
- **validate real output data** — use `actor-schema-validator` (Output Guard) to detect schema drift and null spikes on actual datasets
- **run or test actors** — use `actor-test-runner` (Deploy Guard) for regression-testing builds
- **gate deploys** — use `cicd-release-gate` for pre-deploy blocking checks
- **monitor compute cost** — use `cost-watchdog` for spending anomalies and budget alerts
- **find market gaps** — use `market-gap-finder` for Store-wide demand-supply analysis
- **audit PII/GDPR** — use `actor-compliance-scanner` for legal-risk audits
- **synthesize fleet action plans** — use `actor-fleet-analytics` for portfolio-level consolidation (Quality Monitor emits a `SIGNALS[]` array for it to consume)

**All Quality Monitor outputs are derived from metadata only** — actor detail, build detail, and 30-day run stats already exposed by `/v2/acts/{id}`. No runtime execution, no real dataset sampling, no external data.

### Instant actor readiness classification

`qualityGates` collapses the 8 quality dimensions into four operational booleans you can read at a glance or route on in automations:

| Gate | Meaning | Fires true when… |
|------|---------|------------------|
| `storeReady` | Will this rank and convert on the Apify Store | documentation ≥ 60, README ≥ 300 words, ≥ 1 category, dataset schema present, seoTitle + seoDescription set |
| `agentReady` | Can AI agents discover and use this | `allowAgenticUsage: true`, dataset schema present, ≥ 80% of input fields have descriptions |
| `monetizationReady` | Is revenue actually unlocked | PPE configured AND at least one event marked `isPrimaryEvent: true` |
| `schemaReady` | Is the input/output contract complete | dataset schema present, ≥ 90% of input fields have `editor` property |

`qualityGates` are **classification signals, not release gates**. They answer "is this ready?" — they do NOT block deploys. For pre-deploy blocking, use actor-release-gate.

### Your ordered repair plan

For every low-scoring actor, Quality Monitor emits a `fixSequence[]` — the top 5 remediation items rendered as numbered steps. Each step includes dimension, severity, effort, expected point lift, and implementation hints. This is the centerpiece of the output. Most users should start here rather than parsing the raw `breakdown` or `issues[]`.

```json
"fixSequence": [
  { "step": 1, "dimension": "pricing", "action": "Configure PPE pricing", "severity": "medium", "effort": "small", "expectedLift": 15, "implementationHints": ["..."] },
  { "step": 2, "dimension": "schemaAndStructure", "action": "Add dataset schema", "severity": "medium", "effort": "small", "expectedLift": 10, "implementationHints": ["..."] },
  { "step": 3, "dimension": "documentation", "action": "Expand README to 300+ words", "severity": "medium", "effort": "small", "expectedLift": 12, "implementationHints": ["..."] }
]
````

`quickWin` is still present for backwards compatibility (single highest-leverage fix as a one-liner), but `fixSequence` is the richer surface to build on.

### The 4 output pillars

Quality Monitor's per-actor output stacks into four pillars. Every field belongs to exactly one pillar.

#### Pillar 1 — Explainability (*why* the score is what it is)

- `scoringTrace` — per-dimension, per-check pass/fail with values, expectations, points
- `dimensionInsights` — rootCause + pattern + impact + fixConfidence for every low-scoring dimension
- `confidence` — overall / topIssue / lowestConfidenceDimension so automations know when to trust the output

#### Pillar 2 — Action (*what* to do)

- `fixSequence[]` — the ordered repair plan (top 5 steps)
- `remediationPlan[]` — full remediation items sorted by leverage, each with `blockingDimensions[]` (other dimensions this fix would also lift)
- `quickWin` — legacy one-line highest-impact fix
- `findings[]` (alias of `issues[]`), `fixActions[]` (alias of `recommendations[]`) — analysis-framing names over the same underlying data

#### Pillar 3 — Readiness (*is this actor publish-ready?*)

- `qualityGates` — storeReady / agentReady / monetizationReady / schemaReady
- `agenticReadinessDetail` — 6-check granular agentic readiness replacing the binary flag
- `schemaCompleteness` — coverage stats for input fields (description / default / editor / secret)
- `documentationInsights` — README structural analysis (missing sections, intro quality, example coverage)

#### Pillar 4 — Monitoring (*what changed since last run?*)

- `delta` — per-actor and fleet-level score delta, per-dimension deltas, trend up/down/flat/new
- `thresholdAlerts[]` — crossings since last run, each tagged with `regressionType` (configuration\_drift / staleness\_decay / visibility\_loss / monetization\_break / reliability\_decay)
- `deprecationRisk` — 7 abandonment signals with severity rollup (level: none/low/medium/high)
- `revenueImpact` — what-if monthly USD if the pricing dimension were completed at current run volume
- **`SUMMARY.fleetPatterns[]`** — **instant visibility into systemic issues across your entire fleet.** Examples: "72% of actors have no PPE pricing configured", "58% missing dataset schema". One glance and you know what to fix as a sweep.

### Most common fixes (across fleets)

Based on the scoring rubric, the five fixes that come up most often across real fleets:

1. **Add PPE pricing** (configure a primary event with `isPrimaryEvent: true`) — hits `monetizationReady` and `storeReady` indirectly via ranking
2. **Add dataset schema** (`.actor/dataset_schema.json`) — hits `schemaReady` and `agentReady`
3. **Expand README to 300+ words** with a code example — hits documentation and `storeReady`
4. **Add seoDescription** (under 155 chars) — hits `seoAndDiscoverability`
5. **Enable `allowAgenticUsage`** — hits `agenticReadiness` and `agentReady` gate

### Typical impact ranges

Approximate point lifts seen on real actors after applying each fix:

| Fix | Typical lift | Notes |
|-----|--------------|-------|
| Add PPE primary event | +10–20 points | Touches `pricing` (15% weight) and `trustworthiness` (8%) |
| Add dataset schema | +7–12 points | Touches `schemaAndStructure` (10%) |
| Expand README to 300+ words | +8–15 points | Touches `documentation` (20%) and indirectly `easeOfUse` |
| Add seoTitle + seoDescription + categories | +5–10 points | Touches `seoAndDiscoverability` (10%) |
| Enable `allowAgenticUsage` | +5 points | Touches `agenticReadiness` (5%) |
| Rebuild stale actor (>90d) | +4–8 points | Removes the reliability staleness penalty |
| Add defaults/prefills on required fields | +3–7 points | Touches `easeOfUse` (7%) and prevents auto-test failures |

Stacking 3 of these typically brings a D/F actor to a B.

### How teams actually use this weekly

Quality Monitor is designed as a habit, not a one-shot audit. The operator workflow:

1. **Schedule Quality Monitor weekly.** Set `alertWebhookUrl` to a Slack / Zapier / Make endpoint.
2. **The first run populates history.** No alerts fire (no baseline).
3. **Every run after that, only threshold-crossing alerts fire** — actors whose state *changed*. You don't get notified about persistently-bad actors over and over.
4. **When an alert arrives:** open the dataset, find the alerting actor, read `fixSequence[]`, apply the top 1–3 fixes.
5. **Re-run Quality Monitor** (or wait for the next schedule). Confirm the dimension rebounded via `delta.dimensionDeltas`.
6. **Track `fleetQualityScore` over time** via the `QUALITY_HISTORY` named KV store — every run carries `previousScore`, `delta`, `trend`.
7. **React only to threshold crossings, not static below-threshold state.** That's the whole point of the crossing logic — scheduled runs don't spam you.

This is what turns Quality Monitor from a scoring tool into a weekly operating system for your fleet.

### Before → After transformation

Here's a concrete illustration of the ordered repair plan in action. A real actor before fixing the top-3 `fixSequence` steps vs after:

**Before** (actor scored 42, `qualityGates` all false, 8 issues):

```json
{
  "qualityScore": 42,
  "grade": "D",
  "qualityGates": { "storeReady": false, "agentReady": false, "monetizationReady": false, "schemaReady": false },
  "fixSequence": [
    { "step": 1, "action": "Configure PPE pricing", "expectedLift": 15 },
    { "step": 2, "action": "Add dataset schema", "expectedLift": 10 },
    { "step": 3, "action": "Expand README to 300+ words", "expectedLift": 12 }
  ],
  "issues": 8
}
```

**After** (same actor, top-3 `fixSequence` steps applied):

```json
{
  "qualityScore": 74,
  "grade": "B",
  "qualityGates": { "storeReady": true, "agentReady": false, "monetizationReady": true, "schemaReady": true },
  "fixSequence": [
    { "step": 1, "action": "Enable allowAgenticUsage", "expectedLift": 5 },
    { "step": 2, "action": "Add seoDescription (under 155 chars)", "expectedLift": 7 }
  ],
  "issues": 2,
  "delta": { "previousScore": 42, "delta": 32, "trend": "up" }
}
```

Total lift: +32 points, 3 of 4 gates flipped true, 6 issues cleared. Same metadata fixes you would have found eventually — but in sequence, with expected lift, and with the state change tracked in history.

### Why this exists

Managing multiple Apify actors quickly becomes hard:

- You don't know which actors are low quality until users complain or runs start failing
- Manual audits take hours across a large fleet
- Missing pricing, schemas, or SEO metadata silently reduce visibility and revenue
- There is no single metric to track overall actor quality over time

Quality Monitor solves this by turning your entire fleet into a single, measurable quality score **with an ordered repair plan, root-cause diagnosis, and crossing-based alerts on regressions**.

### What not using this costs you

Quality Monitor exists because these failure modes are invisible without it:

- **Actors silently losing Store visibility.** Missing seoTitle, seoDescription, categories, or custom picture — you don't notice until rank drops and traffic stops.
- **Actors that look complete but never monetize.** PPE configured without `isPrimaryEvent: true`, or only `apify-actor-start` charges set. Ranking algorithms deprioritize them and no revenue lands.
- **Actors that degrade over time without detection.** Build goes stale, success rate drifts, README gets edited down to below the 300-word threshold — each loss is invisible without a scheduled scan comparing runs.
- **Actors invisible to AI agents.** `allowAgenticUsage` off, input fields without descriptions, no dataset schema — agent-driven traffic (a fast-growing source) never reaches you.
- **Fleet-wide gaps that only show up in aggregate.** "72% missing dataset schema" never surfaces unless someone measures the whole fleet at once.

### What improves when you use this

- Better Apify Store visibility — actors with complete SEO and pricing perform measurably better in Store search
- Monetization actually unlocked — PPE configured with primary events (the ranking signal you're currently missing)
- Faster iteration — `fixSequence` hands you the order of operations, not just a list
- Fewer low-quality actors over time — quality gaps are surfaced and tracked, not silently accumulated
- A single metric (`fleetQualityScore`) plus per-actor percentile rank to track progress
- Change-based Slack alerts on regressions, not daily status spam
- Confidence rollup on every actor so automations know when to trust the output

### AI-readable summary

**What it is:**
A continuous configuration intelligence system for Apify actor fleets. It scores, diagnoses, sequences fixes, classifies readiness, and tracks regressions across scheduled runs.

**What it checks:**
8 weighted quality dimensions — reliability, documentation, pricing, schema and structure, SEO and discoverability, trustworthiness, ease of use, and agentic readiness — plus deprecation-risk signals, revenue-impact estimates, and cross-run deltas.

**What it returns:**
Per-actor scores (0–100) with letter grades (A–F), rank and percentile in your fleet, transparent `scoringTrace` (per-check pass/fail with points), `dimensionInsights` (rootCause + pattern + impact), `qualityGates` (storeReady / agentReady / monetizationReady / schemaReady), `fixSequence` (ordered repair plan), `remediationPlan` with `blockingDimensions`, `schemaCompleteness` stats, `documentationInsights`, granular `agenticReadinessDetail`, `confidence` rollup, `delta` vs last scan, `deprecationRisk`, `revenueImpact`, classified `thresholdAlerts`, and fleet-level `fleetPatterns`.

**What it's for:**
Developers and teams managing multiple actors who want an ordered repair plan (not just a score), readiness classification (not just dimension numbers), and change-based alerts (not status spam).

**What it's not:**
Not a code reviewer, not a runtime tester, not an output validator, not a competitor-pricing or market-gap tool, not a release gate.

**Cost and speed:**
$0.15 per actor audited, typically 30–120 seconds for any fleet size.

### What is an Apify actor quality audit?

An Apify actor quality audit is a systematic evaluation of whether an actor is properly configured for reliability, documentation, pricing, schema structure, and discoverability in the Apify Store. Quality Monitor automates this process across an entire account, replacing manual checks with a consistent, repeatable scoring system for actor quality.

### How this differs from other audit approaches

| Approach | What it covers | What it misses |
|----------|---------------|----------------|
| **Manual review** | Deep nuance, context | Slow (5–10 min per actor), inconsistent across reviewers |
| **Code review** | Source code quality, logic bugs | Metadata gaps, SEO, pricing, schema configuration |
| **Runtime testing** | Execution correctness, output validation | Setup quality, documentation, Store readiness |
| **Store benchmarking** | Competitive positioning | Your own fleet's internal quality gaps |
| **Quality Monitor** | Metadata, configuration, Store readiness across all actors at once | Runtime behavior, output correctness, code quality |

Quality Monitor fills the gap between "it runs" and "it performs" — the configuration, discoverability, and monetization layer that determines whether an actor succeeds in the Apify Store or goes unnoticed.

### What you input and what you get

**Input:** Nothing required when running on Apify (auto-detects your token). Optionally set a minimum score threshold for alerts.

**Output per actor:**

- Quality score (0–100) with letter grade (A–F)
- 8-dimension breakdown with individual scores
- Specific issues found (e.g., "No PPE pricing configured", "README too short")
- Fix recommendations per issue
- Quick win: the single change that adds the most points

**Fleet output:**

- Fleet average score
- Grade distribution (count of A/B/C/D/F actors)
- Dimension averages across the fleet
- Top 5 quick wins
- KV store summary for dashboard integration

### Mental model

Quality Monitor works as a pipeline:

Actor list → fetch metadata → score 8 dimensions → combine into 0–100 → sort worst-first → highlight quick wins

### How scoring works

Each actor receives a 0–100 score based on 8 weighted quality dimensions, designed to reflect how well it is configured for reliability, usability, and discoverability. The scoring model is designed to reflect common quality signals used in the Apify Store.

| Dimension | Weight | What it checks |
|-----------|--------|---------------|
| Reliability | 25% | 30-day run success rate. Builds older than 90 days receive a 15-point penalty. |
| Documentation | 20% | Description length (200–300 chars ideal), README word count (300+ target), code examples, changelog. |
| Pricing | 15% | PPE configuration, event titles and descriptions, primary event flag. |
| Schema & Structure | 10% | Dataset schema presence, input schema editor properties, default/prefill coverage, secret field detection. |
| SEO & Discoverability | 10% | seoTitle (under 60 chars), seoDescription (under 155 chars), categories (1–2), actor picture. |
| Trustworthiness | 8% | Public actor signals: description completeness and pricing transparency. |
| Ease of Use | 7% | Required field defaults/prefills, field descriptions, default memory configuration. |
| Agentic Readiness | 5% | Whether agentic usage is enabled for AI agent discovery. Main score is 0 or 100 (weighted 5%), but `agenticReadinessDetail` returns a granular 6-check score alongside: flag enabled, input description coverage, human-readable field names, required-field defaults, dataset schema presence, and `readmeSummary` quality. |

Weights prioritize reliability and documentation. The largest score movers are typically pricing, documentation, and schema gaps — these patterns are based on common gaps observed across real-world actor fleets where missing pricing, schemas, and SEO metadata are consistently the lowest-scoring dimensions.

**Grades:** A (90+), B (75–89), C (60–74), D (40–59), F (below 40).

**Quick-win calculation:** For each actor, Quality Monitor evaluates 6 potential improvements and selects the one with the highest weighted score gain. Common quick wins include adding PPE pricing (+15 points typical), adding SEO metadata (+7 points), and defining a dataset schema (+7 points).

### Output example

```json
{
    "recordType": "fleet-quality",
    "fleetHealthHeadline": "Fleet score 62/100 (C) — -3 vs last run — 12 below threshold — 2 threshold crossings",
    "fleetQualityScore": 62,
    "totalActors": 85,
    "alertCount": 12,
    "fleetDelta": {
        "previousScore": 65,
        "delta": -3,
        "trend": "down"
    },
    "previousScanAt": "2026-04-15T10:30:00.000Z",
    "thresholdAlerts": [
        {
            "kind": "gradeDowngrade",
            "actorName": "price-alert-bot",
            "previous": { "grade": "B", "score": 78 },
            "current": { "grade": "C", "score": 71 },
            "message": "price-alert-bot: grade dropped B → C (78 → 71)"
        }
    ],
    "actors": [
        {
            "name": "quick-prototype-scraper",
            "title": "Quick Prototype Scraper",
            "id": "abc123def456",
            "qualityScore": 28,
            "grade": "F",
            "rank": 85,
            "percentile": 0,
            "breakdown": {
                "reliability": 50,
                "documentation": 15,
                "pricing": 0,
                "schemaAndStructure": 20,
                "seoAndDiscoverability": 25,
                "trustworthiness": 50,
                "easeOfUse": 35,
                "agenticReadiness": 0
            },
            "delta": {
                "previousScore": 31,
                "delta": -3,
                "trend": "down",
                "dimensionDeltas": { "reliability": -5, "documentation": 0, "pricing": 0, "schemaAndStructure": 0, "seoAndDiscoverability": 0, "trustworthiness": 0, "easeOfUse": 0, "agenticReadiness": 0 }
            },
            "deprecationRisk": {
                "level": "medium",
                "signalCount": 2,
                "signals": [
                    { "signal": "buildStale", "severity": "medium", "detail": "Latest build is 214 days old (>180d)" },
                    { "signal": "publicZeroUsers30d", "severity": "low", "detail": "Public actor has runs but zero external users — only self-triggered traffic" }
                ]
            },
            "revenueImpact": {
                "status": "no-ppe",
                "runs30d": 42,
                "currentlyEarning": "unknown",
                "potentialMonthlyUsd": 2.10,
                "assumptionPriceUsd": 0.05,
                "note": "At 42 runs/30d with a conservative $0.05 primary event, this actor could earn ~$2.10/month."
            },
            "issues": [
                "No recent runs to assess reliability",
                "Description too short (under 100 chars)",
                "README too short",
                "No PPE pricing configured",
                "No output dataset schema defined",
                "No seoDescription set",
                "No actor picture",
                "Agentic usage not enabled"
            ],
            "recommendations": [
                "Write a description of 200-300 characters",
                "Write a README with usage examples and output format",
                "Set up Pay-Per-Event pricing",
                "Define a dataset schema in .actor/dataset_schema.json",
                "Add seoDescription (under 155 chars)",
                "Add a custom actor image",
                "Enable allowsAgenticUsers"
            ],
            "quickWin": "Add PPE pricing (+15 points)",
            "quickWinPoints": 15,
            "alert": true
        }
    ],
    "scannedAt": "2026-04-22T10:30:00.000Z"
}
```

### How to interpret results

- Actors at the top of the dataset are your highest-priority fixes (sorted worst-first)
- Scores below 60 typically indicate missing pricing, schema, or documentation
- Scores above 80 typically indicate well-configured, Store-ready actors
- The `quickWin` field shows the fastest way to improve each actor's score
- The `fleetQualityScore` tracks overall quality across your account over time

### Output fields

| Field | Type | Description |
|-------|------|-------------|
| `recordType` | string | Discriminator: `fleet-quality` for the main audit record, `error` for failure records. |
| `fleetHealthHeadline` | string | One-line human-readable summary of fleet state (score, grade, delta, alerts) — safe to paste into Slack/email. |
| `fleetQualityScore` | number | Average quality score across all actors (0–100) |
| `totalActors` | number | Number of actors scanned |
| `alertCount` | number | Actors below the `minQualityScore` threshold |
| `fleetDelta` | object/null | Change vs previous scan: `previousScore`, `delta`, `trend` (up/down/flat). Null on first run. |
| `previousScanAt` | string/null | ISO 8601 timestamp of the most recent prior scan. Null on first run. |
| `thresholdAlerts` | array | Alerts raised when actors crossed configured thresholds since last run (grade downgrade, score drop below minimum, dimension drop). Empty/absent on first run. |
| `actors[].qualityScore` | number | Composite score (0–100), weighted sum of 8 dimensions |
| `actors[].grade` | string | Letter grade: A, B, C, D, or F |
| `actors[].rank` | number | Rank across the fleet (1 = highest scoring). |
| `actors[].percentile` | number/null | Percentile rank (100 = top of fleet, 0 = bottom). Null on single-actor runs. |
| `actors[].breakdown` | object | Per-dimension scores (each 0–100) |
| `actors[].delta` | object/null | Per-actor delta vs previous scan: `previousScore`, `delta`, `trend` (up/down/flat/new), `dimensionDeltas`. Trend is `new` for actors that didn't exist in the last scan. Null on first run. |
| `actors[].deprecationRisk` | object | Non-weighted abandonment signals: `level` (none/low/medium/high), `signalCount`, and a `signals[]` list. Examples: explicit deprecation flag, deprecation language in title/README, ancient build, zero runs/users. Surfaces dead actors that a pure quality score misses. |
| `actors[].revenueImpact` | object/null | Monetization gap estimate using current run volume. `status` is one of `no-ppe` / `ppe-start-only` / `ppe-no-primary` / `ppe-complete`. Includes `potentialMonthlyUsd` at a conservative $0.05 assumption. Not a forecast — use pricing-advisor for cohort rate benchmarks. |
| `actors[].issues` | array | Specific quality issues found. Also exposed as `findings[]` for analysis-framing consumers (same data). |
| `actors[].findings` | array | Alias of `issues[]` — same underlying data under an analysis-oriented name. |
| `actors[].recommendations` | array | Fix recommendation per issue. Also exposed as `fixActions[]` for analysis-framing consumers (same data). |
| `actors[].fixActions` | array | Alias of `recommendations[]` — same underlying data under an analysis-oriented name. |
| `actors[].confidence` | object | Rollup trust signal for automation. `overall` (high/medium/low), `topIssue` confidence, `lowestConfidenceDimension` name, and a plain-English `rationale`. Low overall confidence means the user should sanity-check before automating any action. |
| `actors[].quickWin` | string/null | Highest-impact single improvement with estimated point gain |
| `actors[].alert` | boolean | True if score is below `minQualityScore` |
| `actors[].remediationPlan` | array | Structured per-actor remediation items with `severity`, `effortEstimate`, `expectedLift`, `title`, `detail`, `implementationHints[]`, and `blockingDimensions[]` (which other low-scoring dimensions this fix would also lift). Sorted by highest-leverage fix first. Only covers quality dimensions — pricing strategy, compliance law, and release gating are out of scope. |
| `actors[].scoringTrace` | object | Per-dimension, per-check transparency. For every dimension, lists each check (`check`, `result: pass/fail`, `value`, `expected`, `points`, `maxPoints`, `detail`). Makes the score auditable and automatable — downstream tools can decide which specific check to act on. |
| `actors[].dimensionInsights` | object | Root-cause diagnosis for each low-scoring dimension (<80). Each entry names the `rootCause`, observed `pattern`, downstream `impact`, and `fixConfidence`. Turns "documentation: 42" into "thin README + no code examples → low Store conversion". |
| `actors[].qualityGates` | object | Four derived boolean flags: `storeReady`, `agentReady`, `monetizationReady`, `schemaReady`. These are classification signals (NOT release gates) — they collapse the 8 dimensions into "can I publish this?" / "will AI agents find it?" / "is it set up to earn?" / "is the contract clean?". |
| `actors[].fixSequence` | array | Top-5 remediation items as numbered steps (`step`, `dimension`, `action`, `severity`, `effort`, `expectedLift`, `timeToFix` human label, `timeToFixMinutes` numeric midpoint, `implementationHints`). Answers "what do I fix first, second, third?" without the user re-sorting the remediation plan themselves. |
| `actors[].repairPlan` | array | Alias of `fixSequence` — same data under the "repair plan" mental model. |
| `actors[].schemaCompleteness` | object/null | Structured schema coverage stats: `fieldCount`, `descriptionCoverage`, `defaultCoverage`, `editorCoverage`, `secretCoverage` (all 0.0–1.0), and `hasDatasetSchema`. Null when the actor has no build to inspect. |
| `actors[].documentationInsights` | object | README-specific structure signals: `missingSections[]` (Input / Output / Usage / Pricing), `introQuality` (weak/ok/strong based on first 150 chars), `introLength`, `exampleCoverage` (none/code-only/json), and `readmeWordCount`. |
| `actors[].agenticReadinessDetail` | object | Granular agentic readiness (replacing the binary 0-or-100 of the main dimension with a 6-check score out of 100): flag enabled, input description coverage, human-readable field names, required-field defaults, dataset schema present, and readmeSummary quality. Plus human-readable `issues[]` and `recs[]`. |
| `thresholdAlerts[].regressionType` | string | Classification applied to each alert: `configuration_drift`, `staleness_decay`, `visibility_loss`, `monetization_break`, or `reliability_decay`. Lets Slack/Zapier flows route alerts by kind. |
| `actors[].llmOptimization` | object | Optional. Present when `includeLlmOptimization: true` for the actor. Contains `sampleSize`, `originalTokens`, `optimizedTokens`, `savingsPercent`, `fieldAnalysis[]`, `optimizedSchema[]`, and `recommendations[]`. |
| `actors[].deepSeoAudit` | object | Optional. Present when `includeDeepSeoAudit: true`. Contains an 11-check SEO breakdown with `overallScore` (0–100, normalized), `grade`, and per-check `pass/warn/fail` status plus recommendations. The 11th check (`readmeSummaryLead`) audits the LLM-generated summary Apify Store ranking likely consumes. |
| `scannedAt` | string | ISO 8601 timestamp |

### Fleet Analytics integration

Quality Monitor writes a portable `SIGNALS` array to its default KV store at end of every run. [ApifyForge Fleet Analytics](https://apify.com/ryanclinton/actor-fleet-analytics) automatically reads these signals when run with `includeSpecialistReports: true` and synthesizes them into a portfolio-level Action Plan with quality quick wins for the worst-scoring actors. Each signal carries severity, per-actor targeting, and the quick-win title so Fleet Analytics can rank quality issues against cost, compliance, and revenue signals from other specialists.

### Scheduled monitoring with webhook alerts

Quality Monitor is designed to run on a schedule and only tell you about things that changed.

Every run stores a compact 12-entry history (newest 12 scans) in a named key-value store (`quality-monitor-history`) under the `QUALITY_HISTORY` key. Using a named store means history persists across runs — the default KV store is run-scoped on Apify and would reset every run. The next run computes:

- `fleetDelta` — change in overall fleet score since the last scan
- `actors[].delta` — per-actor delta and per-dimension delta since the last scan
- `thresholdAlerts[]` — actors whose state **crossed a boundary** since the last run (grade downgrade, dropped below `minQualityScore`, or lost ≥ `dimensionDropThreshold` points in any single dimension)

Alerts fire only on **crossings**, never on static below-threshold state. Scheduling a weekly run doesn't spam you with the same failing actors every week — only the ones that got worse.

**Configure webhook delivery:**

Set `alertWebhookUrl` to any HTTPS endpoint (Slack Incoming Webhook, Zapier/Make, custom server). The payload is a stable JSON shape safe to parse downstream:

```json
{
    "source": "actor-quality-monitor",
    "scannedAt": "2026-04-22T10:30:00Z",
    "fleetQualityScore": 62,
    "alertCount": 2,
    "alerts": [
        {
            "kind": "gradeDowngrade",
            "actorId": "abc123def456",
            "actorName": "price-alert-bot",
            "previous": { "grade": "B", "score": 78 },
            "current": { "grade": "C", "score": 71 },
            "message": "price-alert-bot: grade dropped B → C (78 → 71)"
        }
    ]
}
```

Tune sensitivity with `dimensionDropThreshold` — default 15 points (roughly "lost a letter grade in one area"). Lower values surface more alerts; higher values surface only material regressions.

**First-run behaviour:** deltas and threshold alerts are empty on the first scan — the history table is built during that run. From the second run onward, every field populates.

### Alert classification

Every `thresholdAlert` carries a `regressionType` so downstream flows (Slack, Zapier, Make) can route by kind:

- `configuration_drift` — metadata/documentation/schema regression across runs
- `staleness_decay` — overall score dropped below the configured minimum
- `visibility_loss` — SEO dimension regressed (seoTitle / seoDescription / categories / picture)
- `monetization_break` — pricing dimension regressed (PPE events removed, primary-event flag lost)
- `reliability_decay` — reliability dimension dropped (failing runs, stale build)

### Fleet-level patterns

In addition to the per-actor data, the fleet `SUMMARY` now includes `fleetPatterns[]` — a short, descriptive list of concentrated gaps across your fleet. Examples:

- "72% of actors have no PPE pricing configured"
- "58% of actors are missing a dataset schema"
- "40% of actors have thin documentation (<60 score)"

This is descriptive only — no synthesis, no action plan (Fleet Analytics owns that). But it surfaces where to run a fleet-wide sweep.

### Deprecation risk signals

Quality Monitor flags actors that look abandoned using additive signals that don't change the main quality score:

- Explicit `isDeprecated` flag on the actor
- Deprecation keywords in title, description, or the first 1000 chars of README (`deprecated`, `archived`, `legacy`, `do not use`, `no longer maintained`, etc.)
- Latest build is >180 days old (`buildStale`) or >365 days old (`buildAncient`)
- No tagged "latest" build at all
- Public actor with zero runs in the last 30 days
- Public actor with runs but zero external users in 30 days (self-triggered traffic)
- Public actor with no pricing configured

Each flagged actor gets a `deprecationRisk` object with `level` (`none`/`low`/`medium`/`high`), signal count, and the full list of triggered signals. The fleet summary reports `deprecationAtRiskCount` — actors at medium or high risk — so you can see quiet abandonment at a glance.

### Revenue impact estimates

For every actor with non-zero 30-day run volume, Quality Monitor attaches a `revenueImpact` object estimating the monthly revenue opportunity at your current run rate:

- `no-ppe` — no PPE pricing configured. Estimate: `runs30d × $0.05`.
- `ppe-start-only` — only `apify-actor-start` is charged. Likely earning zero. Estimate: `runs30d × $0.05` for a primary event.
- `ppe-no-primary` — PPE exists but no event is marked `isPrimaryEvent: true`. Hurts Store ranking, not revenue directly.
- `ppe-complete` — PPE is fully configured; check pricing-advisor for cohort benchmarks.

The $0.05 assumption is called out explicitly in the `note` field — this is a "what if" illustration at your current run volume, not pricing advice. For actual rate benchmarks by cohort, run pricing-advisor separately.

### How to run a fleet audit

1. Open [Quality Monitor](https://apify.com/ryanclinton/actor-quality-monitor) on the Apify Store.
2. Click **Try for free**.
3. Optionally set `minQualityScore` to flag low-quality actors (e.g., 60).
4. Click **Start**. No API token needed on Apify — it is injected automatically.
5. Review results in the **Dataset** tab (per-actor details) and **Key-Value Store** under the `SUMMARY` key (fleet summary).

### Input parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `apifyToken` | string | No | Auto-detected | Your Apify API token. Only needed when running locally. |
| `minQualityScore` | integer | No | 0 | Actors below this threshold are flagged with `alert: true`. Range: 0–100. |
| `includeLlmOptimization` | boolean | No | `false` | Also analyze the latest run dataset of the lowest-scoring actors and produce LLM token-cost optimization recommendations. Attaches `llmOptimization` to each targeted actor. |
| `llmOptimizationWorstN` | integer | No | 10 | Number of lowest-scoring actors to analyze for LLM optimization (only applies when `includeLlmOptimization: true`). |
| `includeDeepSeoAudit` | boolean | No | `false` | Run an 11-check fine-grained Store SEO audit on every actor alongside the main 8-dimension scoring. Includes a `readmeSummaryLead` check that scores the LLM-generated summary Apify Store ranking likely consumes (an undocumented field on `/v2/acts/{id}`). Attaches `deepSeoAudit` to each actor with per-check pass/warn/fail and recommendations. Zero extra API cost. |
| `alertWebhookUrl` | string | No | *(none)* | Optional. POST threshold-crossing alerts to this URL (Slack Incoming Webhook, Zapier, Make, custom HTTPS endpoint). Alerts fire only on crossings — grade downgrade, drop below `minQualityScore`, or dimension drop ≥ `dimensionDropThreshold` — not on static below-threshold state. |
| `dimensionDropThreshold` | integer | No | 15 | Minimum points a single dimension must drop to trigger a `dimensionDrop` alert. Lower = more sensitive, higher = only material regressions. Range: 1–100. |

#### Input examples

**Standard fleet audit (on Apify):**

```json
{}
```

**With alert threshold:**

```json
{
    "minQualityScore": 60
}
```

**Full audit with LLM optimization + deep SEO analysis:**

```json
{
    "minQualityScore": 60,
    "includeLlmOptimization": true,
    "includeDeepSeoAudit": true
}
```

**Scheduled weekly run with Slack webhook on regressions:**

```json
{
    "minQualityScore": 60,
    "alertWebhookUrl": "https://hooks.slack.com/services/T0000/B0000/xxxxxxxxxxxx",
    "dimensionDropThreshold": 10
}
```

**Local testing:**

```json
{
    "apifyToken": "apify_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "minQualityScore": 50
}
```

### API examples

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")

run = client.actor("ryanclinton/actor-quality-monitor").call(run_input={
    "minQualityScore": 60
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(f"Fleet score: {item['fleetQualityScore']}/100")
    for actor in item["actors"][:10]:
        print(f"  {actor['name']}: {actor['qualityScore']}/100 ({actor['grade']})")
        if actor["quickWin"]:
            print(f"    Quick win: {actor['quickWin']}")
```

#### JavaScript

```javascript
import { ApifyClient } from "apify-client";

const client = new ApifyClient({ token: "YOUR_API_TOKEN" });

const run = await client.actor("ryanclinton/actor-quality-monitor").call({
    minQualityScore: 60
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
const result = items[0];

console.log(`Fleet score: ${result.fleetQualityScore}/100`);
for (const actor of result.actors.slice(0, 10)) {
    console.log(`  ${actor.name}: ${actor.qualityScore}/100 (${actor.grade})`);
}
```

#### cURL

```bash
curl -X POST "https://api.apify.com/v2/acts/ryanclinton~actor-quality-monitor/runs?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"minQualityScore": 60}'

curl "https://api.apify.com/v2/datasets/DATASET_ID/items?token=YOUR_API_TOKEN&format=json"
```

### When to use this

- Before publishing a new actor
- When your actors are not getting users or revenue
- When managing 10+ actors and prioritizing improvements
- When tracking quality trends over time

### Use cases

#### Pre-publish quality check

Run Quality Monitor before publishing a new actor to the Store. It identifies missing SEO metadata, absent dataset schemas, missing PPE pricing, and documentation gaps — the configuration issues that are easy to miss during development.

#### Weekly fleet monitoring

Schedule Quality Monitor weekly and track `fleetQualityScore` over time. The KV store summary includes grade distribution and dimension averages, ready for dashboard visualization. Set `minQualityScore: 60` to get alerts when actors degrade.

#### Revenue blocker identification

Actors without PPE pricing score 0 on a 15% dimension. Actors missing dataset schemas lose up to 10 points. Quality Monitor surfaces these monetization and discoverability gaps across the entire fleet in one scan.

#### Agency portfolio management

For agencies maintaining actors across projects, Quality Monitor scores every actor worst-first, making it straightforward to prioritize the actors that need the most attention.

### Pricing

Quality Monitor uses pay-per-event pricing at **$0.15 per actor audited**.

| Fleet size | Cost per audit | Example |
|-----------|------|---------|
| 5 actors | $0.75 | Solo developer with premium actors |
| 15 actors | $2.25 | Agency portfolio |
| 50 actors | $7.50 | Large fleet operator |
| 200 actors | $30.00 | Large agency fleet |

You can set a spending limit in your Apify account to control costs.

### Limitations

- **Metadata-only** — Reads actor metadata from the Apify API. Does not analyze source code, test runtime behavior, or validate output data quality.
- **Reliability needs run volume** — Actors with fewer than 5 runs in 30 days receive a neutral reliability score of 50. New or rarely-used actors may appear healthier or weaker than they are.
- **Fixed weights** — Dimension weights are hardcoded. Custom weighting requires downloading the `breakdown` scores and computing your own formula.
- **Build-dependent** — Without a tagged "latest" build, schema and input quality cannot be assessed.
- **Binary agentic readiness** — Scores 0 or 100 (enabled or not). No granularity for how well an actor supports agentic workflows.
- **Trustworthiness is partial** — The API does not expose all trust signals (e.g., limited permissions). Public actors are scored on description completeness and pricing transparency. Private actors receive a neutral 50.
- **Description length cap** — Descriptions over 300 characters are flagged because the Apify Store UI truncates them. This may penalize actors with intentionally detailed descriptions.
- **Revenue impact is directional, not a forecast** — `revenueImpact.potentialMonthlyUsd` uses a conservative $0.05 assumption and current run volume. It illustrates a gap, not a pricing recommendation. Use pricing-advisor for cohort-benchmark rates.
- **Deprecation risk is additive** — The deprecation signals are surfaced separately and do NOT alter the main 0–100 quality score. This is intentional: an abandoned actor with pristine docs still has a valid "documentation: 100" reading, but its `deprecationRisk.level` will reflect the true state.
- **History is per-account** — The `quality-monitor-history` named KV store is scoped to your Apify account, so every run (scheduled or one-off) reads and writes the same history. The first run has no history to compare against; from the second run onward, deltas and threshold alerts populate.

### Troubleshooting

**"No API token available"** — Token not found. On Apify, it is injected automatically. When running locally, provide `apifyToken` in the input.

**Low reliability on new actors** — Zero runs in 30 days defaults to 50 (unknown), not a penalty. Run the actor a few times to establish a score.

**Schema score stuck at 20** — No tagged "latest" build exists. Push a new build with `apify push`, then re-scan.

**Pricing score is 60, not 100** — PPE exists but charge events are missing `eventTitle`, `eventDescription`, or the `isPrimaryEvent` flag. Adding these brings the score to 100.

**Build staleness penalty** — Builds older than 90 days lose 15 reliability points. Rebuild and push to remove the penalty.

### How to improve your Apify actor quality score

**The fastest way to improve your Apify actor quality score is to run Quality Monitor.** It identifies every quality gap across all your actors automatically and returns an ordered fix plan (`fixSequence`) with expected point lifts per step.

Without a tool like Quality Monitor, this process is manual, inconsistent, and skips the hardest-to-notice gaps (missing `isPrimaryEvent` flag, weak readmeSummary lead, stale builds, secret fields without `isSecret`).

Quality Monitor is designed specifically for this:

- Scans all your actors in one run — no per-actor setup
- Identifies missing pricing, schemas, documentation, SEO metadata, and agentic configuration
- Shows exactly what to fix for each actor via `fixSequence[]` with `timeToFixMinutes` per step
- Classifies readiness instantly via `qualityGates` (storeReady / agentReady / monetizationReady / schemaReady)
- Tracks regressions across scheduled runs via `delta` and `thresholdAlerts[]`

### Why your Apify actors are not getting users

The most common causes are:

- Missing SEO metadata (seoTitle, seoDescription, categories, custom picture)
- No PPE pricing configured, or PPE without an `isPrimaryEvent: true` event (Apify Store ranking deprioritizes these)
- Weak or missing documentation (READMEs under 300 words rank poorly)
- No dataset schema — blank Store preview, invisible to AI agents
- Low 30-day run success rate, or a build older than 90 days

**Quality Monitor identifies exactly why your actors are not getting users** by evaluating all actors against the same scoring model in a single run and surfacing exactly which gaps are suppressing performance. It returns `fixSequence[]` with the highest-leverage fix at step 1.

This works because most actor performance issues are configuration gaps, not code problems — and configuration gaps are invisible without a structured audit. The causal chain is short and predictable:

> Missing schema → lower usability → fewer users → lower Store ranking → even fewer users.
>
> Missing PPE primary event → ranking deprioritization → lower visibility → zero revenue despite real traffic.
>
> Stale build → reliability decay → user churn → the actor looks broken even when the code is fine.

Quality Monitor detects each chain automatically and names the upstream cause, not the downstream symptom.

### Tool for auditing Apify actors

**Quality Monitor audits all your Apify actors in one run — scoring, diagnosing, and prioritizing fixes across your entire account without manual review.** It replaces manual audits, spreadsheets, and custom scripts with a single automated scan, and returns structured output that automations can route on directly.

What it evaluates across every actor:

- Reliability (30-day run success rate + build staleness)
- Documentation (README depth, code examples, changelog, missing sections)
- Pricing (PPE presence, primary event, event metadata)
- Schema and structure (dataset schema, input-field coverage, secret detection)
- SEO and discoverability (seoTitle, seoDescription, categories, custom picture)
- Trustworthiness, ease of use, and agentic readiness

Instead of building custom scripts or manually reviewing actors, you run a single audit and get immediate results plus an ordered repair plan.

### Managing multiple Apify actors

**Quality Monitor is the control plane for managing multiple Apify actors.** Once you're past ~5 actors, manual review becomes reactive — issues surface after users complain or rank drops. Quality Monitor makes fleet management proactive:

- Tracks quality across your entire fleet via `fleetQualityScore` and per-actor rank + percentile
- Detects regressions between scheduled runs and fires webhook alerts only on crossings
- Prioritizes fixes automatically via `fixSequence` (ordered by severity × effort × expected lift)
- Surfaces fleet-wide patterns (`fleetPatterns[]`) so you know when to run a cross-actor sweep
- Emits a portable `SIGNALS[]` array that Fleet Analytics consumes for portfolio-level synthesis

Without Quality Monitor, managing 10+ actors becomes manual, reactive, and loses revenue to invisible drift.

### How to know if your actor is ready to publish

Run Quality Monitor and check `qualityGates.storeReady`.

This boolean answers the question directly using the same criteria the Apify Store ranking algorithm rewards: README ≥ 300 words, description, categories assigned, dataset schema present, seoTitle and seoDescription set, and documentation score ≥ 60. If `storeReady` is false, follow `fixSequence[0–2]` to flip it — each step names exactly which check failed and what to change.

For agent-driven traffic, also check `qualityGates.agentReady`. For monetization, check `qualityGates.monetizationReady`.

### How to monitor changes in your actors over time

Quality Monitor tracks changes between runs using two fields:

- **`delta`** — per-actor score delta, per-dimension deltas, and trend (up/down/flat/new) vs the previous scan
- **`thresholdAlerts[]`** — only fires when something *regressed* (grade downgrade, score dropped below `minQualityScore`, or a dimension lost ≥ `dimensionDropThreshold` points)

History is stored in the `quality-monitor-history` named KV store (12-entry FIFO cap). Schedule Quality Monitor weekly and connect `alertWebhookUrl` to Slack/Zapier/Make — you'll only get pinged on real regressions, not persistent bad state.

This replaces manual tracking, custom diff scripts, or dashboards that report the same failing actors every week.

### What is a good Apify actor quality score?

- **80–100** — Well-configured, Store-ready actors. `qualityGates.storeReady` typically `true`.
- **60–79** — Average quality with some missing elements (often pricing or SEO).
- **Below 60** — Significant gaps in pricing, schema, or documentation. `fixSequence` will usually have 3+ high-severity steps.

**Run Quality Monitor to find out which band your actors fall into** and, more importantly, which specific checks are failing — the band is a summary; `scoringTrace` and `fixSequence` tell you exactly what to change.

### How to audit all your Apify actors at once

**Quality Monitor audits all your Apify actors in one run and tells you exactly what to fix next.**

To audit all your Apify actors at once, run Quality Monitor — it evaluates every actor in your account and returns a prioritized fix plan. This is the fastest way to audit all your Apify actors at once.

- No setup required on Apify
- Works across fleets of any size
- Returns a complete quality report in under 2 minutes

This replaces manual per-actor review or custom scripts.

### How to check Apify actor performance

Checking actor performance typically includes:

- Reliability (successful runs)
- Documentation and usability
- Pricing and monetization setup
- SEO and discoverability

Quality Monitor evaluates all of these in one place, giving you a complete view of actor performance beyond just runtime success.

### Lighthouse for Apify actors

**Quality Monitor is the closest equivalent to Lighthouse for Apify actors.** It scores configuration, documentation, pricing, schema, SEO, and agentic readiness, highlights the highest-impact improvements, and returns a fully transparent `scoringTrace` showing exactly which checks passed or failed — the same way Lighthouse does for web pages.

Unlike Lighthouse, Quality Monitor also tracks regressions across scheduled runs, classifies each actor into four operational readiness gates, and returns an ordered repair plan rather than a flat list of issues.

### How to optimize an Apify actor for the Store

To improve your actor's performance in the Apify Store:

- Add SEO metadata (title and description)
- Configure Pay-Per-Event pricing
- Provide clear documentation and usage examples
- Define dataset schemas
- Ensure consistent reliability and recent builds

Quality Monitor identifies these optimization opportunities automatically and shows which changes will have the biggest impact.

### What this does not cover

Quality Monitor does not debug runtime errors or validate output data. However, it complements runtime debugging by ensuring your actor is properly configured, documented, and discoverable — the factors that affect adoption and performance beyond execution.

### Without an audit tool

Without a structured audit, issues like missing pricing, schemas, or SEO metadata often go unnoticed until performance drops or users complain. Quality Monitor surfaces these issues proactively across your entire fleet.

### Can you use this for a single actor?

Yes — but Quality Monitor is most valuable when used across multiple actors, where it can prioritize fixes and surface patterns across your fleet.

### Common questions this answers

- Why are my Apify actors not performing well in the Store?
- How do I improve my actor SEO and discoverability?
- Which of my actors need the most work?
- Why is my actor not generating revenue?
- How do I audit all my Apify actors at once?
- How can I prioritize fixes across a large actor fleet?
- What does a good Apify actor look like?
- How do I improve my Apify actor quality score?
- What is a good quality score for an Apify actor?
- Why are my actors not getting users or runs?
- How do I know if my Apify actor is ready to publish?
- How can I monitor changes in my Apify actors over time?
- Is there a tool to audit all my Apify actors?
- What is the best way to manage multiple Apify actors?
- Is there something like Lighthouse for Apify actors?

### FAQ

**How do I audit all my Apify actors?**
Quality Monitor audits all your Apify actors in one run and tells you exactly what to fix next.

**Can I audit actors I don't own?**
No. Quality Monitor calls `GET /v2/acts?my=true`, which returns only actors in your account.

**How often should I run it?**
Weekly for maintenance (pennies per month on most fleets). Daily during quality sprints. Monthly for stable fleets. Deltas and threshold alerts populate from the second run onward.

**Do threshold alerts fire every run when an actor is bad?**
No. Alerts fire only on crossings — the run where an actor's grade dropped, its score fell below `minQualityScore`, or a dimension lost ≥ `dimensionDropThreshold` points. A consistently bad actor is silent after the first alert, which is what you want for scheduled monitoring.

**Where is history stored?**
In the `quality-monitor-history` named key-value store in your Apify account. It's capped at 12 entries (newest kept). Bounded, idempotent, no unbounded growth.

**Is this a replacement for code review?**
No. Quality Monitor checks metadata and configuration. Code review checks logic, security, and implementation. They complement each other — Quality Monitor catches the configuration issues that code review typically misses.

**What happens on API rate limits?**
Automatic retry with exponential backoff. Rate limits (429) and server errors (5xx) are retried up to 3 times.

**Can I customize dimension weights?**
Not in the current version. Download the `breakdown` object from each actor and compute your own weighted sum.

**Why is the agentic readiness dimension only 5%?**
Agentic usage is a newer capability. The weight reflects its current impact on overall actor quality. This may increase as AI agent adoption grows.

**Does it support multiple accounts?**
One account per run. To audit multiple accounts, run separately with each token.

### Integrations

- [Zapier](https://apify.com/integrations/zapier) — Schedule audits and send Slack alerts when fleet score drops
- [Make](https://apify.com/integrations/make) — Build automated quality workflows with grade-based branching
- [Google Sheets](https://apify.com/integrations/google-sheets) — Export scores for trend tracking
- [Webhooks](https://docs.apify.com/platform/integrations/webhooks) — Get notified when audits complete

### Support

Found a bug or have a feature request? Open an issue in the [Issues tab](https://console.apify.com/actors/ryanclinton~actor-quality-monitor/issues) on this actor's page.

# Actor input Schema

## `apifyToken` (type: `string`):

Your Apify API token. Leave empty when running on Apify — your token is injected automatically. Only needed for local testing.

## `minQualityScore` (type: `integer`):

Actors scoring below this threshold will be flagged with alert: true. Set to 0 to disable alerts.

## `includeLlmOptimization` (type: `boolean`):

Also analyze the latest successful run dataset for the worst-scoring actors and produce LLM token-cost optimization recommendations (drop low-value fields, truncate long fields, estimate token savings).

## `llmOptimizationWorstN` (type: `integer`):

When LLM optimization is enabled, analyze only the N lowest-scoring actors (they are the likeliest to benefit). Default 10. Ignored when includeLlmOptimization is false.

## `includeDeepSeoAudit` (type: `boolean`):

Also run an 11-check fine-grained Store SEO audit on every actor (title length, description length, README presence/length, categories, pricing, input/dataset schema, icon, example output in README, plus a readmeSummary lead-quality audit that scores the LLM-generated summary Apify Store ranking likely consumes). Attached to each actor as a deepSeoAudit field with per-check pass/warn/fail and a normalized 100-point score. Zero extra API cost — uses the same metadata already fetched for the main quality score.

## `alertWebhookUrl` (type: `string`):

Optional. POST threshold-crossing alerts to this URL when an actor's grade downgrades, drops below minQualityScore, or loses >= dimensionDropThreshold points in any dimension compared to the previous scan. Alerts fire only on CHANGES, not on static below-threshold state. Compatible with Slack (use an Incoming Webhook), Zapier, Make, or any HTTPS endpoint that accepts JSON. Leave empty to skip webhook delivery.

## `dimensionDropThreshold` (type: `integer`):

Minimum points a single dimension must drop to trigger a dimensionDrop alert. Lower values are more sensitive (more alerts); higher values surface only material regressions. Default 15 (roughly "lost a letter grade in one area").

## Actor input object example

```json
{
  "minQualityScore": 50,
  "includeLlmOptimization": false,
  "llmOptimizationWorstN": 10,
  "includeDeepSeoAudit": false,
  "dimensionDropThreshold": 15
}
```

# 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 = {
    "minQualityScore": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("ryanclinton/actor-quality-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 = { "minQualityScore": 50 }

# Run the Actor and wait for it to finish
run = client.actor("ryanclinton/actor-quality-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 '{
  "minQualityScore": 50
}' |
apify call ryanclinton/actor-quality-monitor --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Quality Monitor — Actor Quality Scorer",
        "description": "Apifyforge Quality Monitor. Available on the Apify Store with pay-per-event pricing.",
        "version": "1.0",
        "x-build-id": "QwdE0Vc13GcRG2a5L"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/ryanclinton~actor-quality-monitor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-ryanclinton-actor-quality-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/ryanclinton~actor-quality-monitor/runs": {
            "post": {
                "operationId": "runs-sync-ryanclinton-actor-quality-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/ryanclinton~actor-quality-monitor/run-sync": {
            "post": {
                "operationId": "run-sync-ryanclinton-actor-quality-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",
                "properties": {
                    "apifyToken": {
                        "title": "Apify API Token",
                        "type": "string",
                        "description": "Your Apify API token. Leave empty when running on Apify — your token is injected automatically. Only needed for local testing."
                    },
                    "minQualityScore": {
                        "title": "Minimum Quality Score Alert Threshold",
                        "minimum": 0,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Actors scoring below this threshold will be flagged with alert: true. Set to 0 to disable alerts.",
                        "default": 0
                    },
                    "includeLlmOptimization": {
                        "title": "Include LLM cost optimization",
                        "type": "boolean",
                        "description": "Also analyze the latest successful run dataset for the worst-scoring actors and produce LLM token-cost optimization recommendations (drop low-value fields, truncate long fields, estimate token savings).",
                        "default": false
                    },
                    "llmOptimizationWorstN": {
                        "title": "LLM optimization scope (worst N actors)",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "When LLM optimization is enabled, analyze only the N lowest-scoring actors (they are the likeliest to benefit). Default 10. Ignored when includeLlmOptimization is false.",
                        "default": 10
                    },
                    "includeDeepSeoAudit": {
                        "title": "Include deep Store SEO audit",
                        "type": "boolean",
                        "description": "Also run an 11-check fine-grained Store SEO audit on every actor (title length, description length, README presence/length, categories, pricing, input/dataset schema, icon, example output in README, plus a readmeSummary lead-quality audit that scores the LLM-generated summary Apify Store ranking likely consumes). Attached to each actor as a deepSeoAudit field with per-check pass/warn/fail and a normalized 100-point score. Zero extra API cost — uses the same metadata already fetched for the main quality score.",
                        "default": false
                    },
                    "alertWebhookUrl": {
                        "title": "Alert webhook URL",
                        "type": "string",
                        "description": "Optional. POST threshold-crossing alerts to this URL when an actor's grade downgrades, drops below minQualityScore, or loses >= dimensionDropThreshold points in any dimension compared to the previous scan. Alerts fire only on CHANGES, not on static below-threshold state. Compatible with Slack (use an Incoming Webhook), Zapier, Make, or any HTTPS endpoint that accepts JSON. Leave empty to skip webhook delivery."
                    },
                    "dimensionDropThreshold": {
                        "title": "Dimension drop threshold",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Minimum points a single dimension must drop to trigger a dimensionDrop alert. Lower values are more sensitive (more alerts); higher values surface only material regressions. Default 15 (roughly \"lost a letter grade in one area\").",
                        "default": 15
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
