# Terms, Privacy & Policy Diff Monitor (`gifted_wagon/terms-policy-diff-monitor`) Actor

Track public terms and privacy policies by clause. Find material additions, removals, obligation, entity, effective-date, retention, arbitration, data-sharing, and other risk changes with before/after evidence.

- **URL**: https://apify.com/gifted\_wagon/terms-policy-diff-monitor.md
- **Developed by:** [Michael Olmos](https://apify.com/gifted_wagon) (community)
- **Categories:** Business, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $18.00 / 1,000 policy diff analyzeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Terms, Privacy & Policy Diff Monitor

Track what changed in public terms, privacy policies, cookie policies, and other agreements without rereading entire documents. This Actor deterministically segments text into clauses, compares a supplied or stored baseline, flags additions/removals/modifications, identifies obligation/entity/date/risk changes, and returns bounded before/after evidence. No external AI key is required.

> This Actor provides automated change detection, not legal advice. A qualified lawyer should review material findings and the cited source text.

### What you get

- Clause-level `clause-added`, `clause-removed`, and `clause-modified` records.
- Explicit obligation, named-entity, effective/retention date, and risk signal changes.
- Deterministic signals for arbitration, class-action waivers, data sharing/sale, advertising, retention, precise location, automatic renewal, termination, indemnity, liability, jurisdiction, and unilateral changes.
- Materiality, 0–100 risk score, risk level, confidence, heading, and before/after evidence.
- A persistent baseline in your named key-value store for scheduled monitoring.

### Input options

Use any combination of:

- `documents[].url` for a public HTTP or HTTPS policy.
- `documents[].currentContent` plus optional `previousContent` for private, local, or already-fetched HTML/text.
- `datasetId` for a dataset containing the same document fields.
- No input for the built-in before/after privacy-policy sample.

Use `policyType` to label terms, privacy, cookies, or another policy. `ignoreSelectors` removes site-specific navigation or widgets. `matchThreshold` controls clause pairing. `includeEvidenceText: false` removes the full normalized policy while retaining each change's bounded evidence.

### Stateful behavior

The first successful URL check creates a `baseline`. Later checks return `unchanged` or `changed`. Supplying `previousContent` performs an immediate comparison and overrides stored state. `resetBaseline` replaces state without classifying the replacement as a change. State is updated only after a useful output and successful pay-per-event charge.

### Charging and failure safety

A one-time `$0.0004` Actor-start event covers measured platform startup and URL-safety validation. The primary `policy-diff-analyzed` event is charged only after a document is fetched or accepted inline, segmented, compared, risk-classified, and prepared as a useful result. Invalid URLs, private-network targets, HTTP errors, oversized responses, empty policies, and other failures return dataset diagnostics with no value-event charge. The `OUTPUT` summary—including the not-legal-advice caveat—is separate and uncharged. The Actor checks the PPE budget before work and stops cleanly at the event limit.

### Network, evidence, and privacy safety

HTTP fetching is bounded by time, response size, content type, and five redirects. Every initial URL and redirect is revalidated. Localhost plus private, loopback, link-local, carrier-grade NAT, benchmarking, multicast, reserved IPv4, unique-local IPv6, and link-local IPv6 destinations are rejected. URL mode reads a public policy; inline mode avoids network access. Evidence and snapshots are stored in your Apify storage—use private runs and disable full evidence text for sensitive material.

### Output

Each dataset row contains status, policy identity/type, clause count, fingerprint, `diff`, evidence, warnings, pricing, `valueEvent`, and the legal disclaimer. `diff.changes[].signalChanges` lists added and removed obligation/entity/date/risk signals. `OUTPUT` contains uncharged run counts, material-change totals, budget status, and the same disclaimer.

### Limitations and responsible use

This HTTP-first MVP does not execute JavaScript, log in, bypass access controls, interpret images/PDFs, or determine legal effect. Heuristics may miss unusual drafting or classify benign wording as material. Results do not establish compliance, risk, enforceability, or required action. Verify the source and consult qualified counsel. Monitor only documents you are allowed to access and follow applicable terms, privacy rules, and laws.

### Local verification

```bash
npm install
npm run typecheck
npm test
npm run build
npm run benchmark
npm run launch:verify
```

# Actor input Schema

## `documents` (type: `array`):

Each item needs a public URL or currentContent. Supply previousContent for an immediate diff; otherwise the first successful run creates a baseline.

## `datasetId` (type: `string`):

Optional dataset containing the same fields as each document.

## `maxDocuments` (type: `integer`):

Maximum documents attempted across inline and dataset sources.

## `timeoutSecs` (type: `integer`):

Maximum duration for each HTTP request.

## `maxContentBytes` (type: `integer`):

Maximum downloaded response size per policy.

## `matchThreshold` (type: `number`):

Higher values require stronger similarity before clauses are paired as modifications.

## `stateStoreName` (type: `string`):

Named key-value store that preserves policy baselines across runs.

## `resetBaseline` (type: `boolean`):

Replace existing stored baselines without emitting a material change.

## `includeEvidenceText` (type: `boolean`):

Disable when per-change before/after evidence is enough. Output is automated analysis, not legal advice.

## Actor input object example

```json
{
  "documents": [
    {
      "url": "https://www.example.com/privacy",
      "label": "Example privacy policy",
      "policyType": "privacy"
    }
  ],
  "maxDocuments": 25,
  "timeoutSecs": 20,
  "maxContentBytes": 2000000,
  "matchThreshold": 0.42,
  "stateStoreName": "terms-policy-diff-monitor-state",
  "resetBaseline": false,
  "includeEvidenceText": true
}
```

# Actor output Schema

## `dataset` (type: `string`):

Material additions, removals, modifications, signal changes, and before/after evidence. Not legal advice.

## `summary` (type: `string`):

Uncharged counts, source, state, budget status, and the legal disclaimer. Saving this summary never triggers a value event.

# 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 = {
    "documents": [
        {
            "url": "https://www.example.com/privacy",
            "label": "Example privacy policy",
            "policyType": "privacy"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("gifted_wagon/terms-policy-diff-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 = { "documents": [{
            "url": "https://www.example.com/privacy",
            "label": "Example privacy policy",
            "policyType": "privacy",
        }] }

# Run the Actor and wait for it to finish
run = client.actor("gifted_wagon/terms-policy-diff-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "documents": [
    {
      "url": "https://www.example.com/privacy",
      "label": "Example privacy policy",
      "policyType": "privacy"
    }
  ]
}' |
apify call gifted_wagon/terms-policy-diff-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,gifted_wagon/terms-policy-diff-monitor"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/4XBd7ALmSCmntowqH/builds/amDhOEgpc1AeFPakk/openapi.json
