{
  "openapi": "3.0.1",
  "info": {
    "title": "Website Change Monitor — Sitemap Monitor & Page Diff",
    "description": "Track website changes via sitemaps: finds new, removed and updated pages (lastmod) and detects page content changes with normalized hashes and word-level diff previews. Pay per page checked ($0.0005) and per change detected ($0.002).",
    "version": "0.1",
    "x-build-id": "qtukQPlZXVJRg2QG0"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/owlabee~website-change-monitor/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-owlabee-website-change-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/owlabee~website-change-monitor/runs": {
      "post": {
        "operationId": "runs-sync-owlabee-website-change-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/owlabee~website-change-monitor/run-sync": {
      "post": {
        "operationId": "run-sync-owlabee-website-change-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": [
          "sites"
        ],
        "properties": {
          "sites": {
            "title": "Sites or sitemap URLs",
            "minItems": 1,
            "type": "array",
            "description": "One entry per line. A site URL (https://example.com) is resolved through robots.txt `Sitemap:` lines, then /sitemap.xml and /sitemap_index.xml. A direct sitemap URL (.xml, .xml.gz, .txt, sitemap indexes) is used as-is. The prefilled value is the cheap, always-available example used by Apify's daily automated test.",
            "items": {
              "type": "string"
            }
          },
          "mode": {
            "title": "Mode",
            "enum": [
              "discover",
              "monitor"
            ],
            "type": "string",
            "description": "`discover` lists every page URL found in the sitemaps with lastmod/changefreq/priority (no page fetches, no state). `monitor` compares this run with the previous snapshot and emits change records; the first monitor run writes baseline records.",
            "default": "monitor"
          },
          "discovery": {
            "title": "Discovery sources",
            "uniqueItems": true,
            "type": "array",
            "description": "Where page URLs come from. `sitemap` (the default) reads robots.txt Sitemap lines, sitemap indexes and /sitemap.xml. `feed` reads the RSS, Atom or JSON feed of the site: the URL itself when it is a feed, the feeds its page advertises (`<link rel=\"alternate\">`), or /feed, /rss.xml and /atom.xml; entries that roll off a feed are not reported as removed. `wordpress` lists posts and pages with their modification dates from the WordPress REST API (`/wp-json/wp/v2/`). URLs found by several sources are checked once; `maxPages` caps the total. Each URL is charged as one checked page, as for sitemaps; reading the feeds and the API is not charged separately.",
            "items": {
              "type": "string",
              "enum": [
                "sitemap",
                "feed",
                "wordpress"
              ],
              "enumTitles": [
                "Sitemaps",
                "RSS / Atom / JSON feeds",
                "WordPress REST API"
              ]
            },
            "default": [
              "sitemap"
            ]
          },
          "checkContent": {
            "title": "Check page content",
            "type": "boolean",
            "description": "Monitor mode only. Fetch each HTML page (max 1 MB, 20 s timeout), normalize its text and hash it, so `content-changed` and `status-changed` records are produced in addition to sitemap-level changes. Turn off to compare sitemap data only (much faster, no page requests).",
            "default": true
          },
          "contentSelector": {
            "title": "Content CSS selector",
            "type": "string",
            "description": "Comma-separated CSS selectors; the first one that matches a non-empty element is hashed. Default `main, article, body`. Use it to ignore headers, footers and sidebars, e.g. `#content, .post-body`."
          },
          "ignoreNumbers": {
            "title": "Ignore numbers and dates",
            "type": "boolean",
            "description": "Strip digits, dates and times before hashing so view counters, timestamps and prices do not count as content changes.",
            "default": false
          },
          "trackStructuredData": {
            "title": "Track structured data (JSON-LD)",
            "type": "boolean",
            "description": "Monitor mode with page content on. Also compare each page's schema.org JSON-LD (Product price and availability, JobPosting, Event, Organization, FAQ and others) field by field. A change in it alone produces a `structured-data-changed` record listing the changed paths, e.g. `jsonld.Product.offers.price`; a price or availability change is high severity.",
            "default": false
          },
          "checkDocuments": {
            "title": "Check PDFs and other documents",
            "type": "boolean",
            "description": "Monitor mode with page content on. Non-HTML URLs (PDF, CSV, JSON, plain text and others) are checked instead of being skipped. PDFs and text files up to 512 KB are compared by their text, with the same word-level preview as pages; larger or binary files are compared by Last-Modified and size (or ETag, or a hash of the first 512 KB).",
            "default": false
          },
          "conditionalRequests": {
            "title": "Conditional requests (ETag / Last-Modified)",
            "type": "boolean",
            "description": "Monitor mode with page content on. Keep each page's ETag and Last-Modified and send them on the next run; a page the server answers with 304 Not Modified is not downloaded again and keeps its previous fingerprint (marked `notModified`). Saves transfer and time on large sites. A server with unreliable validators can hide a change, which is why this is off by default.",
            "default": false
          },
          "watchFiles": {
            "title": "Watch site files",
            "uniqueItems": true,
            "type": "array",
            "description": "Monitor mode. Also watch these files at the root of each site's origin and report `file-changed` records with the added and removed lines: robots.txt (crawler and AI-crawler rules), llms.txt and llms-full.txt (LLM-oriented site summaries), /.well-known/security.txt. The first run writes one baseline record per file. Each file check is charged as one checked page; files are read up to 512 KB.",
            "items": {
              "type": "string",
              "enum": [
                "robots.txt",
                "llms.txt",
                "llms-full.txt",
                "security.txt"
              ],
              "enumTitles": [
                "robots.txt",
                "llms.txt",
                "llms-full.txt",
                "security.txt"
              ]
            },
            "default": []
          },
          "maxPages": {
            "title": "Max pages per site",
            "minimum": 1,
            "maximum": 50000,
            "type": "integer",
            "description": "Upper bound on page URLs taken from the sitemaps of each site (after include/exclude filtering, in sitemap order). In monitor mode set it above the site's real page count so removals are detected correctly.",
            "default": 500
          },
          "includePatterns": {
            "title": "Include URL patterns",
            "type": "array",
            "description": "Only keep page URLs matching at least one pattern. Globs (`https://example.com/blog/*`), regular expressions (`/\\/docs\\/v\\d+\\//`) or plain substrings (`/pricing`). Empty = keep all.",
            "items": {
              "type": "string"
            }
          },
          "excludePatterns": {
            "title": "Exclude URL patterns",
            "type": "array",
            "description": "Drop page URLs matching any pattern (same syntax as include patterns), e.g. `*/tag/*`, `/\\.pdf$/`.",
            "items": {
              "type": "string"
            }
          },
          "maxConcurrency": {
            "title": "Max concurrency",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "Parallel page fetches. Requests to the same host are additionally spaced at least 500 ms apart to stay polite (about 2 requests per second per host).",
            "default": 5
          },
          "maxSecondsPerSite": {
            "title": "Max seconds per site",
            "minimum": 60,
            "maximum": 21600,
            "type": "integer",
            "description": "Time budget for one site: reading its sitemaps and checking its pages. When it runs out, or when nothing useful came back for 60 seconds (pages or sitemaps timing out, or sitemaps yielding no URLs that match your patterns), the site stops there. Pages already checked are kept and charged; pages not reached keep their previous record, so nothing is reported as removed, and a first (baseline) run that did not finish is not saved. At about 2 requests per second per host, 1,800 seconds cover roughly 3,600 pages; raise it for larger sites.",
            "default": 1800
          },
          "stateStoreName": {
            "title": "State key-value store",
            "pattern": "^[a-zA-Z0-9-]{3,63}$",
            "type": "string",
            "description": "Named key-value store that keeps one snapshot per site between monitor runs. Use a different name to keep independent baselines (e.g. per client or per schedule).",
            "default": "website-change-monitor-state"
          },
          "resetBaseline": {
            "title": "Reset baseline",
            "type": "boolean",
            "description": "Ignore the stored snapshot and write a fresh baseline for every site in this run.",
            "default": false
          },
          "webhookUrl": {
            "title": "Webhook URL (optional)",
            "pattern": "^https?://.+",
            "type": "string",
            "description": "If set, the Actor POSTs a JSON summary of the run and the list of change records to this URL (10 s timeout, 2 retries). Failures are logged, never fatal."
          },
          "notifyOnlyOnChanges": {
            "title": "Notify only on changes",
            "type": "boolean",
            "description": "Monitor mode: call the webhook only when at least one change record was produced. Turn off to receive a webhook after every run.",
            "default": true
          }
        }
      },
      "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}