{
  "openapi": "3.0.1",
  "info": {
    "title": "Change Watcher - Push Events for Web and API Changes",
    "description": "Watches URLs with a CSS/XPath/regex selector or a JSONPath query, filters out timestamps, tokens, counters and other rendering noise, and emits a normalized change event only when the watched block really changed. No change, no event, no charge.",
    "version": "0.1",
    "x-build-id": "zkemszEI4pYTGHJtV"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/ernestmarza~change-watcher/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-ernestmarza-change-watcher",
        "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/ernestmarza~change-watcher/runs": {
      "post": {
        "operationId": "runs-sync-ernestmarza-change-watcher",
        "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/ernestmarza~change-watcher/run-sync": {
      "post": {
        "operationId": "run-sync-ernestmarza-change-watcher",
        "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": [
          "watchers"
        ],
        "properties": {
          "watchers": {
            "title": "Watchers",
            "type": "array",
            "description": "One entry per watched target. Each entry accepts: url (required), selector, selectorType (css | xpath | regex | jsonpath | wholeBody), mode (text | json), extractAs (text | html), label, id, topic, method, headers, body, joinWith. Omit the selector to watch the whole body. A plain URL string is also accepted and means 'watch this whole page'. Maximum 50 entries per run."
          },
          "stabilityChecks": {
            "title": "Stability window (consecutive checks)",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "How many consecutive checks a new value has to survive before it is reported. 1 fires on the first difference. 2 or 3 filters out A/B buckets, staggered cache invalidation and half-deployed clusters, which otherwise produce a change event every time the load balancer picks a different node."
          },
          "checksPerRun": {
            "title": "Checks per run",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "How many times each target is checked within a single run. Set it above 1 to close the stability window inside one run instead of across several scheduled runs. Note that the run stays alive for (checksPerRun - 1) x check interval, which costs compute.",
            "default": 1
          },
          "checkIntervalSeconds": {
            "title": "Seconds between checks in a run",
            "minimum": 1,
            "maximum": 900,
            "type": "integer",
            "description": "Only used when checks per run is greater than 1.",
            "default": 30
          },
          "minChangeRatio": {
            "title": "Minimum change ratio (0-1)",
            "minimum": 0,
            "maximum": 1,
            "type": "number",
            "description": "Ignore differences smaller than this fraction of the block. 0 reports every difference that survives the noise filters. 0.02 means 'at least two percent of the block has to move'. Use it for targets with residual jitter the generic rules cannot catch, such as a rotating advert or a randomised testimonial.",
            "default": 0
          },
          "emitInitialState": {
            "title": "Emit an event for the first observation",
            "type": "boolean",
            "description": "By default the first time a target is seen it only records a baseline: there is nothing to compare against, so calling it a change would be noise. Turn this on to receive a 'created' event carrying the initial value, which is useful when the subscriber wants to seed its own copy.",
            "default": false
          },
          "ignoreRules": {
            "title": "Noise filters to apply",
            "type": "array",
            "description": "Which parts of the anti-noise catalogue to run before hashing. Leave empty for the recommended set (everything except epoch masking). Available ids: unicode, jwt, isoTimestamp, httpDate, epochMillis, dateNumeric, dateTextual, clockTime, relativeTime, uuid, tokenAssignment, hexBlob, base64Blob, cacheBusting, trackingParams, viewCounters, whitespace.",
            "items": {
              "type": "string"
            }
          },
          "customIgnorePatterns": {
            "title": "Extra patterns to ignore",
            "type": "array",
            "description": "Regular expressions applied after the catalogue; every match is replaced with <CUSTOM>. Both 'pattern' and '/pattern/flags' forms are accepted. The global flag is forced on.",
            "items": {
              "type": "string"
            }
          },
          "caseSensitive": {
            "title": "Case sensitive comparison",
            "type": "boolean",
            "description": "Turn off to ignore changes that are only a difference in letter case.",
            "default": true
          },
          "includeDiff": {
            "title": "Include the diff in every event",
            "type": "boolean",
            "description": "Adds added lines, removed lines, a unified diff and a similarity score to each event. Turning it off makes events smaller but leaves the subscriber to work out what moved.",
            "default": true
          },
          "maxValueLength": {
            "title": "Maximum characters per value",
            "minimum": 100,
            "maximum": 200000,
            "type": "integer",
            "description": "Old and new values longer than this are truncated with an explicit marker. Guards against a watcher on a large page filling the dataset.",
            "default": 8000
          },
          "topicPrefix": {
            "title": "Topic prefix",
            "type": "string",
            "description": "Every event carries a topic built as prefix.host.label, for example change.example-com.pricing-table. Subscribers route on it without opening the payload. A per-watcher 'topic' field overrides it entirely.",
            "default": "change"
          },
          "stateStoreName": {
            "title": "State store name",
            "type": "string",
            "description": "Named key-value store that holds the baseline between runs. This is what turns a series of one-shot runs into a watcher with a memory. Use different names to keep unrelated watch sets apart.",
            "default": "change-watcher-state"
          },
          "resetState": {
            "title": "Reset stored state before this run",
            "type": "boolean",
            "description": "Drops the stored baseline for every watcher in this run and starts over. Use after changing the noise filters, since the old baseline was normalized with different rules.",
            "default": false
          },
          "useConditionalRequests": {
            "title": "Use conditional requests (ETag / If-Modified-Since)",
            "type": "boolean",
            "description": "Sends the validators from the previous fetch so a server that supports them can answer 304 with no body at all. Much cheaper on targets that support it. Turn it off for servers that return misleading validators.",
            "default": true
          },
          "requestTimeoutSecs": {
            "title": "Request timeout (seconds)",
            "minimum": 5,
            "maximum": 300,
            "type": "integer",
            "description": "How long a single request may take before it is aborted and retried.",
            "default": 30
          },
          "maxRetries": {
            "title": "Retries per check",
            "minimum": 1,
            "maximum": 6,
            "type": "integer",
            "description": "Attempts before a check is recorded as failed. 5xx and timeouts are retried with backoff; 4xx is not, because it will not get better.",
            "default": 3
          },
          "userAgent": {
            "title": "User agent",
            "type": "string",
            "description": "Sent with every request. Identify yourself honestly; some sites block generic agents.",
            "default": "Mozilla/5.0 (compatible; ApifyChangeWatcher/0.1; +https://apify.com)"
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}