# Competitor Change Intelligence Monitor (`fascinating_lentil/competitor-change-intelligence-monitor`) Actor

Monitor authorized public competitor, pricing, product, terms, and changelog pages for material changes with bounded evidence, confidence, severity, and action-focused reports.

- **URL**: https://apify.com/fascinating\_lentil/competitor-change-intelligence-monitor.md
- **Developed by:** [Md Jakaria Mirza](https://apify.com/fascinating_lentil) (community)
- **Categories:** Automation, E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 page 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

## Competitor Change Intelligence Monitor

Monitor authorized public competitor pages for meaningful pricing, product,
availability, plan, policy, and changelog changes. The Actor compares each page
with a trusted baseline and returns concise evidence, confidence, severity, and a
recommended human review action.

Use it for competitor pricing intelligence, product launch monitoring, SaaS plan
tracking, public terms updates, and release-note alerts without building a custom
monitoring pipeline.

### What You Get

- Structured before-and-after changes instead of raw page diffs
- Price deltas and percentage changes when values can be normalized safely
- Categories for price, availability, product features, pricing plans,
  terms/policies, launches/changelogs, and general content
- Confidence scores, severity, bounded evidence, and suggested review actions
- Stable change IDs for deduplication and downstream automation
- JSON Dataset output plus JSON and Markdown digests
- Optional immediate or weekly HTTPS webhook delivery
- Persistent trusted baselines with explicit candidate review and promotion

### Quick Start

#### 1. Initialize a trusted baseline

Run once with a page you are authorized to monitor:

```json
{
  "targets": [
    {
      "name": "Acme pricing",
      "url": "https://example.org/pricing",
      "changeTypes": ["price", "pricing_plan", "product_feature"]
    }
  ],
  "confirmAuthorizedUse": true,
  "baselineAction": "initialize_trusted",
  "notificationMode": "none",
  "dryRun": false
}
````

#### 2. Compare later runs

Keep the target name, URL, selected change types, selectors, and product identifiers
consistent, then change `baselineAction` to `compare_only`. Schedule the Actor in
Apify Console for recurring checks.

```json
{
  "targets": [
    {
      "name": "Acme pricing",
      "url": "https://example.org/pricing",
      "changeTypes": ["price", "pricing_plan", "product_feature"]
    }
  ],
  "confirmAuthorizedUse": true,
  "baselineAction": "compare_only",
  "minimumMateriality": "low",
  "notificationMode": "none",
  "dryRun": false
}
```

The prefilled `example.com` input is a safe dry run. It does not mutate a baseline,
send a webhook, or charge a `page-checked` event.

### Output

Each target produces one Dataset report with fields such as:

```json
{
  "targetName": "Acme pricing",
  "status": "success_changed",
  "baselineFound": true,
  "changeDetected": true,
  "materialChangeCount": 2,
  "overallSeverity": "high",
  "overallConfidence": 91,
  "changes": [
    {
      "category": "price",
      "field": "product.pro.price",
      "previousValue": 29,
      "currentValue": 35,
      "delta": 6,
      "deltaPercent": 20.6897,
      "severity": "medium",
      "confidence": "high",
      "recommendedAction": "Review pricing, margin, and positioning before changing your offer."
    }
  ]
}
```

The default Key-Value Store also exposes:

- `RUN_SUMMARY`: counts, statuses, delivery result, and page-event assessment
- `DIGEST_JSON`: bounded machine-readable changes
- `DIGEST_MARKDOWN`: concise human-readable digest

### Baseline Actions

- `compare_only`: compare with the trusted baseline without changing it
- `initialize_trusted`: create the first trusted baseline; refuses overwrite
- `store_candidate`: save a candidate snapshot for review
- `promote_candidate`: promote only an exact reviewed candidate and parent hash

Use candidate promotion when a detected page revision should become the new trusted
reference. This prevents an unexpected change from silently replacing the baseline.

### Better Signal With Selectors

For noisy pages, add `includeSelectors` for the sections you care about and
`excludeSelectors` for banners, timestamps, rotating recommendations, or other
volatile content. `ignoreTextPatterns` accepts only bounded literal or simple glob
patterns, not arbitrary regular expressions.

Known SKU, GTIN, MPN, brand, model, variant, and pack quantity values can improve
product-change confidence. The Actor does not discover competitor products
automatically or claim uncertain products are equivalent.

### Webhook Alerts

Set `notificationMode` to `immediate` or `weekly_digest`, provide a secret public
HTTPS `alertWebhookUrl`, and choose `minimumAlertSeverity`. Delivery happens only
after the Dataset report is persisted. Payloads are deduplicated, redacted, bounded,
and contain at most ten material changes per delivery.

The webhook URL is secret input and is never logged, returned, or stored in reports
or digests.

### Pricing

This Actor uses pay per event:

- `page-checked`: **$0.003** for each successfully inspected page report persisted
  to the Dataset
- Actor start: Apify's small synthetic start event

Dry runs, invalid input, unauthorized targets, blocked or robots-disallowed pages,
failed inspections, and failed Dataset persistence do not charge `page-checked`.

### Safety And Limits

- One to 25 explicitly configured public HTTPS pages per run
- One document per target; no recursive crawling
- Public-IP DNS validation and rebinding protection
- Same-origin redirects unless another public HTTPS origin is explicitly authorized
- Robots.txt enforcement, bounded responses, timeouts, and retries
- No login, cookie acceptance, CAPTCHA solving, access-control bypass, or repricing
- Secret, credential, email, and phone-number redaction from retained evidence

`confirmAuthorizedUse` records that you already have permission; it does not create
permission. Use the Actor only on pages that belong to you, intentionally expose
content for this use, or that you are otherwise permitted to monitor. Follow source
terms and applicable laws.

### Common Statuses

- `success_no_change`: the trusted baseline matches
- `success_changed`: material changes were detected
- `baseline_missing`: initialize or review a candidate first
- `robots_disallowed`: source policy blocked inspection
- `blocked_target`: URL or network safety validation stopped the request
- `http_error`, `unsupported_content`, or `internal_error`: inspect the report

### Support

When reporting an issue, include the public target type, selected change types, run
ID, and redacted log excerpt. Never share credentials, private URLs, or webhook
secrets.

Source and issue tracker:
[GitHub repository](https://github.com/erenmyeager15/competitor-change-intelligence-monitor)

# Actor input Schema

## `targets` (type: `array`):

One to 25 public HTTPS pages that intentionally expose public content, belong to you, or that you have permission to monitor. V1 checks one document per target and does not crawl recursively.

## `confirmAuthorizedUse` (type: `boolean`):

Required for every non-demo target. Set true only when the public target belongs to you, intentionally exposes content for this use, or you have explicit permission to monitor it. This confirmation records existing authorization; it does not create permission.

## `baselineAction` (type: `string`):

The safe default compare\_only never creates or changes a trusted baseline. Mutating actions require explicit selection and runtime lineage checks.

## `candidateId` (type: `string`):

Required only for exact candidate promotion. Obtain this value from a prior candidate report.

## `expectedCandidateHash` (type: `string`):

Required only for promotion. Exact lowercase SHA-256 hash of the reviewed candidate snapshot.

## `expectedTrustedParentHash` (type: `string`):

Required only for promotion. Exact lowercase SHA-256 trusted-parent hash, or NO\_PARENT when the candidate was created without a trusted baseline.

## `includeUnchanged` (type: `boolean`):

When false, unchanged successful checks produce only the minimal auditable Dataset record needed for atomic pay-per-event charging.

## `minimumMateriality` (type: `string`):

Lowest deterministic severity retained as a material change in the concise report.

## `notificationMode` (type: `string`):

Optional post-persistence delivery. Weekly mode accumulates deduplicated redacted changes for the selected weekly window.

## `minimumAlertSeverity` (type: `string`):

Lowest change severity eligible for optional webhook delivery.

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

Optional authorized public HTTPS webhook. Stored as secret input and never logged, persisted, or returned.

## `weeklyDigestDay` (type: `integer`):

Delivery day from one (Monday) through seven (Sunday). Used only in weekly digest mode.

## `timezone` (type: `string`):

IANA timezone used only to determine the weekly delivery window.

## `requestTimeoutSeconds` (type: `integer`):

Per-request timeout from 3 to 30 seconds.

## `maxResponseBytes` (type: `integer`):

Maximum accepted response body from 64 KiB to 5 MiB.

## `maxRetries` (type: `integer`):

Bounded retry count for transient network, 408, 429, and 5xx failures only.

## `dryRun` (type: `boolean`):

Fetch and classify without baseline mutation, webhook delivery, or pay-per-event charging.

## Actor input object example

```json
{
  "targets": [
    {
      "name": "Example.com public demo",
      "url": "https://example.com/",
      "changeTypes": [
        "general_content"
      ]
    }
  ],
  "confirmAuthorizedUse": false,
  "baselineAction": "compare_only",
  "includeUnchanged": false,
  "minimumMateriality": "low",
  "notificationMode": "none",
  "minimumAlertSeverity": "medium",
  "weeklyDigestDay": 1,
  "timezone": "UTC",
  "requestTimeoutSeconds": 10,
  "maxResponseBytes": 262144,
  "maxRetries": 1,
  "dryRun": true
}
```

# Actor output Schema

## `reports` (type: `string`):

One structured monitoring or safety-stop report per processed target.

## `runSummary` (type: `string`):

Machine-readable run counts, severity totals, baseline outcomes, and delivery status.

## `digestMarkdown` (type: `string`):

Concise Markdown digest of material changes and recommended review actions.

## `digestJson` (type: `string`):

Structured digest for downstream automation and AI-agent workflows.

# 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 = {
    "targets": [
        {
            "name": "Example.com public demo",
            "url": "https://example.com/",
            "changeTypes": [
                "general_content"
            ]
        }
    ],
    "confirmAuthorizedUse": false,
    "baselineAction": "compare_only",
    "includeUnchanged": false,
    "minimumMateriality": "low",
    "notificationMode": "none",
    "minimumAlertSeverity": "medium",
    "weeklyDigestDay": 1,
    "timezone": "UTC",
    "requestTimeoutSeconds": 10,
    "maxResponseBytes": 262144,
    "maxRetries": 0,
    "dryRun": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("fascinating_lentil/competitor-change-intelligence-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 = {
    "targets": [{
            "name": "Example.com public demo",
            "url": "https://example.com/",
            "changeTypes": ["general_content"],
        }],
    "confirmAuthorizedUse": False,
    "baselineAction": "compare_only",
    "includeUnchanged": False,
    "minimumMateriality": "low",
    "notificationMode": "none",
    "minimumAlertSeverity": "medium",
    "weeklyDigestDay": 1,
    "timezone": "UTC",
    "requestTimeoutSeconds": 10,
    "maxResponseBytes": 262144,
    "maxRetries": 0,
    "dryRun": True,
}

# Run the Actor and wait for it to finish
run = client.actor("fascinating_lentil/competitor-change-intelligence-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 '{
  "targets": [
    {
      "name": "Example.com public demo",
      "url": "https://example.com/",
      "changeTypes": [
        "general_content"
      ]
    }
  ],
  "confirmAuthorizedUse": false,
  "baselineAction": "compare_only",
  "includeUnchanged": false,
  "minimumMateriality": "low",
  "notificationMode": "none",
  "minimumAlertSeverity": "medium",
  "weeklyDigestDay": 1,
  "timezone": "UTC",
  "requestTimeoutSeconds": 10,
  "maxResponseBytes": 262144,
  "maxRetries": 0,
  "dryRun": true
}' |
apify call fascinating_lentil/competitor-change-intelligence-monitor --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Competitor Change Intelligence Monitor",
        "description": "Monitor authorized public competitor, pricing, product, terms, and changelog pages for material changes with bounded evidence, confidence, severity, and action-focused reports.",
        "version": "0.1",
        "x-build-id": "caZ8ctQQXlundxru6"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/fascinating_lentil~competitor-change-intelligence-monitor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-fascinating_lentil-competitor-change-intelligence-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/fascinating_lentil~competitor-change-intelligence-monitor/runs": {
            "post": {
                "operationId": "runs-sync-fascinating_lentil-competitor-change-intelligence-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/fascinating_lentil~competitor-change-intelligence-monitor/run-sync": {
            "post": {
                "operationId": "run-sync-fascinating_lentil-competitor-change-intelligence-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": [
                    "targets",
                    "confirmAuthorizedUse"
                ],
                "properties": {
                    "targets": {
                        "title": "Authorized target pages",
                        "minItems": 1,
                        "maxItems": 25,
                        "type": "array",
                        "description": "One to 25 public HTTPS pages that intentionally expose public content, belong to you, or that you have permission to monitor. V1 checks one document per target and does not crawl recursively.",
                        "items": {
                            "type": "object",
                            "additionalProperties": false,
                            "properties": {
                                "name": {
                                    "title": "Target name",
                                    "type": "string",
                                    "description": "Unique human-readable target name used to organize reports and baseline identity.",
                                    "minLength": 1,
                                    "maxLength": 100,
                                    "pattern": ".*\\S.*"
                                },
                                "url": {
                                    "title": "Target URL",
                                    "type": "string",
                                    "description": "Absolute public HTTPS URL without URL credentials or a fragment.",
                                    "minLength": 9,
                                    "maxLength": 2048,
                                    "pattern": "^https:\\/\\/[^\\s]+$"
                                },
                                "changeTypes": {
                                    "title": "Change types",
                                    "type": "array",
                                    "description": "Business changes to extract and classify for this target.",
                                    "editor": "stringList",
                                    "minItems": 1,
                                    "maxItems": 7,
                                    "uniqueItems": true,
                                    "items": {
                                        "type": "string",
                                        "pattern": "^(?:price|availability|product_feature|pricing_plan|terms_policy|launch_changelog|general_content)$"
                                    }
                                },
                                "includeSelectors": {
                                    "title": "Include CSS selectors",
                                    "type": "array",
                                    "description": "Optional bounded CSS selectors whose matched content is eligible for monitoring. Selector safety is validated at runtime.",
                                    "editor": "stringList",
                                    "maxItems": 10,
                                    "uniqueItems": true,
                                    "items": {
                                        "type": "string",
                                        "minLength": 1,
                                        "maxLength": 256,
                                        "pattern": ".*\\S.*"
                                    }
                                },
                                "excludeSelectors": {
                                    "title": "Exclude CSS selectors",
                                    "type": "array",
                                    "description": "Optional bounded CSS selectors for volatile or irrelevant content that should be removed before comparison.",
                                    "editor": "stringList",
                                    "maxItems": 20,
                                    "uniqueItems": true,
                                    "items": {
                                        "type": "string",
                                        "minLength": 1,
                                        "maxLength": 256,
                                        "pattern": ".*\\S.*"
                                    }
                                },
                                "ignoreTextPatterns": {
                                    "title": "Ignored text patterns",
                                    "type": "array",
                                    "description": "Optional literal or simple glob patterns for known volatile text. User-provided regular expressions are not accepted in v1.",
                                    "editor": "stringList",
                                    "maxItems": 10,
                                    "uniqueItems": true,
                                    "items": {
                                        "type": "string",
                                        "minLength": 1,
                                        "maxLength": 128,
                                        "pattern": ".*\\S.*"
                                    }
                                },
                                "currency": {
                                    "title": "Currency hint",
                                    "type": "string",
                                    "description": "Optional three-letter ISO 4217 currency hint. The Actor never performs currency conversion.",
                                    "minLength": 3,
                                    "maxLength": 3,
                                    "pattern": "^[A-Za-z]{3}$"
                                },
                                "productIdentifiers": {
                                    "title": "Known product identifiers",
                                    "type": "object",
                                    "description": "Optional identifiers that improve product-change confidence without enabling automatic product discovery.",
                                    "editor": "json",
                                    "additionalProperties": false,
                                    "properties": {
                                        "sku": {
                                            "title": "SKU",
                                            "type": "string",
                                            "description": "Known seller or manufacturer stock-keeping unit.",
                                            "minLength": 1,
                                            "maxLength": 128
                                        },
                                        "gtin": {
                                            "title": "GTIN",
                                            "type": "string",
                                            "description": "Known 8-14 digit Global Trade Item Number.",
                                            "minLength": 8,
                                            "maxLength": 14,
                                            "pattern": "^[0-9]+$"
                                        },
                                        "mpn": {
                                            "title": "MPN",
                                            "type": "string",
                                            "description": "Known manufacturer part number.",
                                            "minLength": 1,
                                            "maxLength": 128
                                        },
                                        "brand": {
                                            "title": "Brand",
                                            "type": "string",
                                            "description": "Known product brand.",
                                            "minLength": 1,
                                            "maxLength": 128
                                        },
                                        "model": {
                                            "title": "Model",
                                            "type": "string",
                                            "description": "Known product model identifier.",
                                            "minLength": 1,
                                            "maxLength": 128
                                        },
                                        "variant": {
                                            "title": "Variant",
                                            "type": "string",
                                            "description": "Known size, color, or other product variant.",
                                            "minLength": 1,
                                            "maxLength": 128
                                        },
                                        "packQuantity": {
                                            "title": "Pack quantity",
                                            "type": "string",
                                            "description": "Known pack count or unit quantity retained as source text.",
                                            "minLength": 1,
                                            "maxLength": 64
                                        }
                                    }
                                },
                                "authorizedRedirectOrigins": {
                                    "title": "Authorized redirect origins",
                                    "type": "array",
                                    "description": "Optional public HTTPS origins that are separately authorized as cross-origin redirect destinations. Every origin is independently safety-checked.",
                                    "editor": "stringList",
                                    "maxItems": 3,
                                    "uniqueItems": true,
                                    "items": {
                                        "type": "string",
                                        "minLength": 9,
                                        "maxLength": 512,
                                        "pattern": "^https:\\/\\/[^\\s/]+(?::[0-9]+)?$"
                                    }
                                }
                            },
                            "required": [
                                "name",
                                "url",
                                "changeTypes"
                            ]
                        }
                    },
                    "confirmAuthorizedUse": {
                        "title": "Confirm authorized use",
                        "type": "boolean",
                        "description": "Required for every non-demo target. Set true only when the public target belongs to you, intentionally exposes content for this use, or you have explicit permission to monitor it. This confirmation records existing authorization; it does not create permission.",
                        "default": false
                    },
                    "baselineAction": {
                        "title": "Baseline action",
                        "enum": [
                            "compare_only",
                            "initialize_trusted",
                            "store_candidate",
                            "promote_candidate"
                        ],
                        "type": "string",
                        "description": "The safe default compare_only never creates or changes a trusted baseline. Mutating actions require explicit selection and runtime lineage checks.",
                        "default": "compare_only"
                    },
                    "candidateId": {
                        "title": "Candidate ID",
                        "pattern": "^[A-Za-z0-9_-]+$",
                        "minLength": 1,
                        "maxLength": 128,
                        "type": "string",
                        "description": "Required only for exact candidate promotion. Obtain this value from a prior candidate report."
                    },
                    "expectedCandidateHash": {
                        "title": "Expected candidate hash",
                        "pattern": "^[a-f0-9]{64}$",
                        "type": "string",
                        "description": "Required only for promotion. Exact lowercase SHA-256 hash of the reviewed candidate snapshot."
                    },
                    "expectedTrustedParentHash": {
                        "title": "Expected trusted parent hash",
                        "pattern": "^(?:[a-f0-9]{64}|NO_PARENT)$",
                        "type": "string",
                        "description": "Required only for promotion. Exact lowercase SHA-256 trusted-parent hash, or NO_PARENT when the candidate was created without a trusted baseline."
                    },
                    "includeUnchanged": {
                        "title": "Include full unchanged reports",
                        "type": "boolean",
                        "description": "When false, unchanged successful checks produce only the minimal auditable Dataset record needed for atomic pay-per-event charging.",
                        "default": false
                    },
                    "minimumMateriality": {
                        "title": "Minimum materiality",
                        "enum": [
                            "informational",
                            "low",
                            "medium",
                            "high",
                            "critical"
                        ],
                        "type": "string",
                        "description": "Lowest deterministic severity retained as a material change in the concise report.",
                        "default": "low"
                    },
                    "notificationMode": {
                        "title": "Notification mode",
                        "enum": [
                            "none",
                            "immediate",
                            "weekly_digest"
                        ],
                        "type": "string",
                        "description": "Optional post-persistence delivery. Weekly mode accumulates deduplicated redacted changes for the selected weekly window.",
                        "default": "none"
                    },
                    "minimumAlertSeverity": {
                        "title": "Minimum alert severity",
                        "enum": [
                            "low",
                            "medium",
                            "high",
                            "critical"
                        ],
                        "type": "string",
                        "description": "Lowest change severity eligible for optional webhook delivery.",
                        "default": "medium"
                    },
                    "alertWebhookUrl": {
                        "title": "Secret alert webhook URL",
                        "type": "string",
                        "description": "Optional authorized public HTTPS webhook. Stored as secret input and never logged, persisted, or returned."
                    },
                    "weeklyDigestDay": {
                        "title": "Weekly digest day",
                        "minimum": 1,
                        "maximum": 7,
                        "type": "integer",
                        "description": "Delivery day from one (Monday) through seven (Sunday). Used only in weekly digest mode.",
                        "default": 1
                    },
                    "timezone": {
                        "title": "Digest timezone",
                        "pattern": "^[A-Za-z0-9_+\\-/]+$",
                        "minLength": 1,
                        "maxLength": 64,
                        "type": "string",
                        "description": "IANA timezone used only to determine the weekly delivery window.",
                        "default": "UTC"
                    },
                    "requestTimeoutSeconds": {
                        "title": "Request timeout",
                        "minimum": 3,
                        "maximum": 30,
                        "type": "integer",
                        "description": "Per-request timeout from 3 to 30 seconds.",
                        "default": 15
                    },
                    "maxResponseBytes": {
                        "title": "Maximum response size",
                        "minimum": 65536,
                        "maximum": 5242880,
                        "type": "integer",
                        "description": "Maximum accepted response body from 64 KiB to 5 MiB.",
                        "default": 2097152
                    },
                    "maxRetries": {
                        "title": "Maximum retries",
                        "minimum": 0,
                        "maximum": 2,
                        "type": "integer",
                        "description": "Bounded retry count for transient network, 408, 429, and 5xx failures only.",
                        "default": 1
                    },
                    "dryRun": {
                        "title": "Dry run",
                        "type": "boolean",
                        "description": "Fetch and classify without baseline mutation, webhook delivery, or pay-per-event charging.",
                        "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
