# Static Website Content, Metadata & Structured-Data Delta (`ursog/static-website-content-delta`) Actor

- **URL**: https://apify.com/ursog/static-website-content-delta.md
- **Developed by:** [andre donda de sa](https://apify.com/ursog) (community)
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 page checkeds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Static Website Content, Metadata & Structured-Data Delta

Monitor a bounded list of explicit public pages for meaningful visible-content, title, canonical, status, redirect, robots, and optional JSON-LD changes. The first successful observation is a free baseline.

### Buyers and use cases

Automation teams, researchers, compliance operators, SEO teams, and analysts tracking selected public policy, documentation, company, publication, product, or evidence pages.

This is not a universal crawler, browser scraper, uptime SLA, WAF bypass, or sitemap inventory product. Dynamic/challenge-protected pages may be unsupported. Sitemap URL Inventory & Change remains the product for large URL membership, sitemap structure, and `lastmod` monitoring.

### Input

`explicitUrls` accepts URL strings or objects with `url`, optional `label`, optional CSS `selector`, and metadata/structured-data toggles. Missing selectors return `selector_not_found`; they never silently fall back to the full page.

Only public HTTP(S) is allowed. Initial and redirected destinations receive DNS-based SSRF validation against credentials, localhost, private/reserved IPv4/IPv6, link-local, internal names, and cloud metadata. Requests have redirect, timeout, concurrency, retry, and streamed-size limits.

### Events

`CONTENT_CHANGED`, `TITLE_CHANGED`, `CANONICAL_CHANGED`, `STATUS_CHANGED`, `REDIRECT_CHANGED`, `ROBOTS_CHANGED`, `STRUCTURED_DATA_ADDED`, `STRUCTURED_DATA_REMOVED`, and `STRUCTURED_FIELD_CHANGED`. Structured-data events expose entity identities, schema types, and one-way hashes only; raw JSON-LD values are neither retained nor emitted.

Raw HTML, ETag, Last-Modified, content length, request IDs, dates, cookies, and CDN headers never independently create billable changes. Normalization removes non-content markup, prefers `main`/`article`, normalizes whitespace, and preserves visible punctuation, numbers, and dates.

JSON-LD supports multiple blocks, arrays, `@graph`, nested nodes, key canonicalization, preserved `@list` order, deterministic set ordering, and entity identity through `@id`, URL, or deterministic node identity. Field events return entity, schema types, path, and previous/current values.

### Baseline, billing, and failures

Baseline rows are free. Proposed PPE: **$0.001 per successful recurring page check**, whether or not the page changed. A canonical page is charged at most once per completed observation. Unsupported pages, failures, retries, diagnostics, duplicate inputs, and first baselines are free.

Whole-page monitoring intentionally reflects visible text returned to the Actor. Pages with rotating, localized, personalized, or live content can therefore change frequently; use a strict CSS selector when only one stable region matters.

HTTP 404/410 are observable availability evidence. HTTP 403/429 and challenge HTML are blocked, never successful empty pages. State stores compact normalized evidence, not raw HTML.

```json
{"explicitUrls":["https://example.com/",{"url":"https://example.com/product","selector":".price"}],"monitorKey":"daily-pages"}
```

### Who this Actor is for

Operations, monitoring, research, and data teams that need monitor allowed public static pages for content, metadata and structured-data changes. It is designed for scheduled Apify, API, webhook, integration, and MCP-compatible workflowsÃƒÂ¢Ã¢â€šÂ¬Ã¢â‚¬Ânot for unsupported professional conclusions.

### Input reference

- `explicitUrls` (required): Add each page as an object. Only url is required; label, selector, includeMetadata, and includeStructuredData are optional.
- `monitorKey`: Separates this persistent baseline from other monitors.
- `maxUrls`: Hard page limit for one run.
- `maxConcurrency`: Maximum simultaneous page requests.
- `requestTimeoutSecs`: Covers headers and complete response streaming.
- `maxRequestRetries`: Retries transient failures only.
- `maxWireBytes`: Rejects declared or streamed oversized bodies.
- `maxDecodedBytes`: Rejects oversized decoded HTML.
- `maxRedirects`: Every redirect destination is revalidated against SSRF rules.

Representative input (replace placeholders and use only sources you are authorized to access):

```json
{
  "explicitUrls": [
    {
      "url": "https://example.com/"
    }
  ],
  "monitorKey": "default",
  "maxUrls": 200,
  "maxConcurrency": 10,
  "requestTimeoutSecs": 12,
  "maxRequestRetries": 1,
  "maxWireBytes": 3000000,
  "maxDecodedBytes": 3000000,
  "maxRedirects": 5
}
```

### Output reference

- `recordType`: Structured output field.
- `eventId`: Structured output field.
- `stableId`: Structured output field.
- `pageId`: Structured output field.
- `label`: Structured output field.
- `sourceUrl`: Structured output field.
- `status`: Structured output field.
- `message`: Structured output field.
- `changeType`: Structured output field.
- `fieldPath`: Structured output field.
- `entityIdentity`: Structured output field.
- `schemaTypes`: Structured output field.
- `previousValue`: Structured output field.
- `currentValue`: Structured output field.
- `previousEvidence`: Structured output field.
- `currentEvidence`: Structured output field.
- `code`: Structured output field.
- `retryable`: Structured output field.
- `observedAt`: Structured output field.

The first complete run creates an expected baseline where the product uses state. Later comparable runs emit only the documented observations or changes. Dataset records retain deterministic identity and source evidence where the contract requires it.

### Limitations and known semantics

- Only the documented source, input forms, fields, identities, and completeness rules are supported.
- An empty, partial, blocked, timed-out, or malformed upstream response is never silently reported as a successful empty result.
- Absence or removal is reported only with the exact observational wording and completeness evidence documented by this Actor; it is not proof of a real-world deletion or status unless the source explicitly says so.
- Upstream publication schedules, schemas, coverage, terms, and availability can change.

### Errors and troubleshooting

Check the run status and OUTPUT summary before consuming Dataset rows. For invalid input, correct the named field. For retryable source failures, preserve the monitor key/state and retry later. For schema or completeness failures, do not reset state or infer changes; report the run ID and non-secret diagnostics to support.

### API, integrations, and MCP

Run the Actor through the Apify API, Schedule, webhook, or supported integration. Read structured records from the default Dataset and the run summary from the default Key-value store. MCP/agent consumers must preserve source, status, uncertainty, and limitation fields and must not convert observational outputs into unsupported claims.

### Privacy and legal notes

Submit only data necessary for the documented workflow and only sources you are authorized to access. Do not include credentials, sensitive personal data, or private URLs unless the Actor explicitly documents secure support for them. Outputs are factual automation evidence, not legal, financial, safety, employment, regulatory, or compliance advice. You remain responsible for source rights, downstream use, retention, and professional review.

### Supported-use boundary

This Actor accepts only public URLs or caller-controlled Apify data that you own or are authorized to process. `sourceRightsConfirmed` must be `true`. The Actor does not grant rights to source material, bypass authentication or access controls, or make an otherwise prohibited collection lawful. Submit the minimum data needed and comply with source terms, privacy duties, retention rules, and applicable law.

# Changelog

This Actor's version history is a separate document: https://apify.com/ursog/static-website-content-delta/changelog.md

# Actor input Schema

## `explicitUrls` (type: `array`):

Add each page as an object. Only url is required; label, selector, includeMetadata, and includeStructuredData are optional.

## `monitorKey` (type: `string`):

Separates this persistent baseline from other monitors.

## `maxUrls` (type: `integer`):

Hard page limit for one run.

## `maxConcurrency` (type: `integer`):

Maximum simultaneous page requests.

## `requestTimeoutSecs` (type: `integer`):

Covers headers and complete response streaming.

## `maxRequestRetries` (type: `integer`):

Retries transient failures only.

## `maxWireBytes` (type: `integer`):

Rejects declared or streamed oversized bodies.

## `maxDecodedBytes` (type: `integer`):

Rejects oversized decoded HTML.

## `maxRedirects` (type: `integer`):

Every redirect destination is revalidated against SSRF rules.

## `sourceRightsConfirmed` (type: `boolean`):

Required. Confirm that every submitted public URL is owned by you or that you are authorized to automate access and process the resulting metadata under the source terms and applicable law.

## Actor input object example

```json
{
  "explicitUrls": [
    {
      "url": "https://example.com/"
    }
  ],
  "monitorKey": "default",
  "maxUrls": 200,
  "maxConcurrency": 10,
  "requestTimeoutSecs": 12,
  "maxRequestRetries": 1,
  "maxWireBytes": 3000000,
  "maxDecodedBytes": 3000000,
  "maxRedirects": 5
}
```

# Actor output Schema

## `changes` (type: `string`):

No description

## `baselines` (type: `string`):

No description

## `diagnostics` (type: `string`):

No description

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

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

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

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("ursog/static-website-content-delta").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("ursog/static-website-content-delta").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{}' |
apify call ursog/static-website-content-delta --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ursog/static-website-content-delta"
        }
    }
}
```

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/Y9O0WpFJLGZ6rcF9D/builds/M3QzjnD55Dan4cfZB/openapi.json
