{
  "openapi": "3.0.1",
  "info": {
    "title": "SiteVerdict — Website Change & Uptime Monitor",
    "description": "Schedule it to watch pages for downtime, slow responses, TLS expiry and redirects, plus real content changes: text or CSS/XPath regions, prices, keywords, SEO tags, robots.txt, sitemaps and screenshots. Noise-filtered diffs, Slack/webhook/e-mail alerts.",
    "version": "1.0",
    "x-build-id": "aAy3He3sY4W1EDohS"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/siteverdict~siteverdict-change-uptime-monitor/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-siteverdict-siteverdict-change-uptime-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/siteverdict~siteverdict-change-uptime-monitor/runs": {
      "post": {
        "operationId": "runs-sync-siteverdict-siteverdict-change-uptime-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/siteverdict~siteverdict-change-uptime-monitor/run-sync": {
      "post": {
        "operationId": "run-sync-siteverdict-siteverdict-change-uptime-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",
        "properties": {
          "urls": {
            "title": "URLs to monitor",
            "type": "array",
            "description": "Pages to check on every run. All settings below apply to each of them. For per-page settings (different selector, keywords, browser mode) use 'Advanced monitors'.",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "monitors": {
            "title": "Advanced monitors (per-page settings)",
            "type": "array",
            "description": "Optional JSON list of monitors with their own settings, which override the global ones. Fields: url (required), name, id, mode (http|browser), selector, xpath, excludeSelectors, ignorePatterns, useDefaultIgnorePatterns, minChangePercent, keywords, keywordAlertOn, extractSelector, extractAttribute, trackPrices, seoChecks, checkRobotsTxt, checkSitemap, sitemapUrl, visualDiff, visualThresholdPercent, visualMaskSelectors, fullPageScreenshot, waitForSelector, waitAfterLoadMs, slowResponseMs, tlsWarnDays, alertOn. Example: [{\"url\": \"https://shop.example/pricing\", \"name\": \"Pricing\", \"selector\": \"#pricing-table\", \"trackPrices\": true, \"keywords\": [\"sold out\"]}]"
          },
          "mode": {
            "title": "Check mode",
            "enum": [
              "http",
              "browser"
            ],
            "type": "string",
            "description": "'http' fetches the HTML directly (fast, cheapest, works for most sites). 'browser' renders the page in headless Chromium (needed for JavaScript-built content and screenshot diffs) and is billed as a browser check.",
            "default": "http"
          },
          "contentSelector": {
            "title": "Region: CSS selector",
            "type": "string",
            "description": "Only compare the text inside elements matching this CSS selector, e.g. '#pricing', 'main article', '.product-price'. Empty = the whole page body."
          },
          "contentXPath": {
            "title": "Region: XPath",
            "type": "string",
            "description": "Alternative to the CSS selector, e.g. //table[@id='pricing'] or //div[contains(@class,'status')]. Attribute and text() results are supported. Ignored when a CSS selector is set."
          },
          "excludeSelectors": {
            "title": "Ignore elements (CSS selectors)",
            "type": "array",
            "description": "Elements removed before comparing, e.g. nav, footer, .cookie-banner, .ad, #live-chat. Great for menus, carousels and counters.",
            "items": {
              "type": "string"
            }
          },
          "ignorePatterns": {
            "title": "Ignore text patterns (regex)",
            "type": "array",
            "description": "Text matching these regular expressions is masked before comparing, e.g. 'Visitors today: \\d+' or '/order #\\d+/i'. Invalid regular expressions are treated as plain text.",
            "items": {
              "type": "string"
            }
          },
          "useDefaultIgnorePatterns": {
            "title": "Ignore dates, times and random tokens",
            "type": "boolean",
            "description": "Built-in noise filter: dates, times, '5 minutes ago', Unix timestamps, UUIDs, long random tokens and copyright years are masked so they never trigger an alert.",
            "default": true
          },
          "minChangePercent": {
            "title": "Minimum text change (%)",
            "minimum": 0,
            "maximum": 100,
            "type": "number",
            "description": "Ignore text changes smaller than this share of lines (0 = any change counts). Example: 5 ignores small edits on long pages.",
            "default": 0
          },
          "keywords": {
            "title": "Keywords to watch",
            "type": "array",
            "description": "Alert when these words appear or disappear in the monitored region, e.g. 'sold out', 'in stock', 'discontinued'. Case-insensitive; '/regex/i' is also accepted.",
            "items": {
              "type": "string"
            }
          },
          "keywordAlertOn": {
            "title": "Keyword alert when",
            "enum": [
              "both",
              "appear",
              "disappear"
            ],
            "type": "string",
            "description": "Alert when a keyword appears, disappears, or both.",
            "default": "both"
          },
          "trackPrices": {
            "title": "Track prices",
            "type": "boolean",
            "description": "Extract price-like values (£19, $1,299.99, EUR 45, 30 €) from the region and report each price change ('£49 -> £59').",
            "default": false
          },
          "extractSelector": {
            "title": "Structured list: CSS selector",
            "type": "string",
            "description": "Extract one item per matching element (e.g. '.product-card', 'table#plans tr') and report items added or removed. Good for product lists, job lists, plans."
          },
          "extractAttribute": {
            "title": "Structured list: attribute",
            "type": "string",
            "description": "Use this attribute instead of the element text, e.g. 'href', 'data-sku', 'content'."
          },
          "seoChecks": {
            "title": "SEO-critical changes",
            "type": "boolean",
            "description": "Track title, meta description, canonical, H1, lang, final URL and robots directives (meta robots + X-Robots-Tag). 'noindex' appearing is flagged as critical.",
            "default": true
          },
          "checkRobotsTxt": {
            "title": "Watch robots.txt",
            "type": "boolean",
            "description": "Alert when the site's robots.txt rules change (comments and whitespace are ignored).",
            "default": false
          },
          "checkSitemap": {
            "title": "Watch sitemap",
            "type": "boolean",
            "description": "Alert when URLs are added to or removed from the sitemap (from robots.txt 'Sitemap:' or /sitemap.xml). lastmod-only changes are ignored.",
            "default": false
          },
          "sitemapUrl": {
            "title": "Sitemap URL (optional)",
            "type": "string",
            "description": "Override the sitemap location, e.g. https://example.com/sitemap_index.xml. .gz sitemaps are supported."
          },
          "visualDiff": {
            "title": "Screenshot (visual) diff",
            "type": "boolean",
            "description": "Take a screenshot each run (of the CSS selector region if set, otherwise the viewport or full page) and compare pixels with the previous one. Turns on browser mode.",
            "default": false
          },
          "visualThresholdPercent": {
            "title": "Visual change threshold (% of pixels)",
            "minimum": 0,
            "maximum": 100,
            "type": "number",
            "description": "Alert only when at least this share of pixels differs.",
            "default": 1
          },
          "visualMaskSelectors": {
            "title": "Mask in screenshots (CSS selectors)",
            "type": "array",
            "description": "Areas painted over before the screenshot is compared, e.g. carousels, ads, live chat, clocks.",
            "items": {
              "type": "string"
            }
          },
          "fullPageScreenshot": {
            "title": "Full-page screenshot",
            "type": "boolean",
            "description": "Capture the whole page instead of the first screen (capped at 'Max screenshot height').",
            "default": false
          },
          "viewportWidth": {
            "title": "Viewport width (px)",
            "minimum": 320,
            "maximum": 3840,
            "type": "integer",
            "description": "Browser window width. Use 390 for a phone-sized check.",
            "default": 1366
          },
          "viewportHeight": {
            "title": "Viewport height (px)",
            "minimum": 320,
            "maximum": 4000,
            "type": "integer",
            "description": "Browser window height.",
            "default": 900
          },
          "maxScreenshotHeight": {
            "title": "Max screenshot height (px)",
            "minimum": 500,
            "maximum": 20000,
            "type": "integer",
            "description": "Full-page screenshots are cut at this height to keep runs fast.",
            "default": 8000
          },
          "waitForSelector": {
            "title": "Wait for selector (browser mode)",
            "type": "string",
            "description": "Wait until this element exists before reading the page, e.g. '.price' on JavaScript-built pages."
          },
          "waitAfterLoadMs": {
            "title": "Extra wait after load (ms, browser mode)",
            "minimum": 0,
            "maximum": 30000,
            "type": "integer",
            "description": "Additional settle time after the page has loaded.",
            "default": 1000
          },
          "slowResponseMs": {
            "title": "Slow response threshold (ms)",
            "minimum": 100,
            "maximum": 120000,
            "type": "integer",
            "description": "Responses slower than this are flagged as 'slow' (alerted only if 'slow' is selected in 'Alert on').",
            "default": 3000
          },
          "tlsWarnDays": {
            "title": "TLS certificate warning (days)",
            "minimum": 0,
            "maximum": 365,
            "type": "integer",
            "description": "Alert when the HTTPS certificate expires within this many days (again at 7, 3, 1 and 0 days), or when it is not trusted.",
            "default": 14
          },
          "retryOnFailure": {
            "title": "Confirm failures with retries",
            "minimum": 0,
            "maximum": 3,
            "type": "integer",
            "description": "Re-check a URL this many times (2 s, 4 s apart) before reporting it down, to avoid false downtime alerts. Blocks are never retried.",
            "default": 1
          },
          "timeoutSecs": {
            "title": "Request timeout (seconds)",
            "minimum": 5,
            "maximum": 120,
            "type": "integer",
            "description": "A page that does not respond within this time is reported as down (TIMEOUT).",
            "default": 30
          },
          "alertOn": {
            "title": "Alert on",
            "type": "array",
            "description": "Which kinds of change send an alert (and are billed as a change alert). All changes are still listed in the dataset.",
            "items": {
              "type": "string",
              "enum": [
                "content",
                "seo",
                "keywords",
                "extraction",
                "visual",
                "robots",
                "sitemap",
                "downtime",
                "recovery",
                "tls",
                "slow"
              ],
              "enumTitles": [
                "Text / region changed",
                "SEO tags changed",
                "Keyword appeared / disappeared",
                "Prices / list items changed",
                "Screenshot changed",
                "robots.txt changed",
                "Sitemap URLs changed",
                "Site went down",
                "Site recovered",
                "TLS certificate expiring / invalid",
                "Slow response"
              ]
            },
            "default": [
              "content",
              "seo",
              "keywords",
              "extraction",
              "visual",
              "robots",
              "sitemap",
              "downtime",
              "recovery",
              "tls"
            ]
          },
          "webhookUrl": {
            "title": "Webhook URL",
            "type": "string",
            "description": "We POST a JSON alert (summary, diff excerpt, change details) here for every alert, e.g. a Zapier/Make/n8n hook or your own endpoint. Stored encrypted."
          },
          "slackWebhookUrl": {
            "title": "Slack incoming webhook URL",
            "type": "string",
            "description": "https://hooks.slack.com/services/... — posts a short message with the change summary and diff excerpt. Stored encrypted."
          },
          "emailTo": {
            "title": "E-mail alerts to",
            "type": "string",
            "description": "One digest e-mail per run with all alerts, sent through Apify's official 'apify/send-mail' Actor in your account (it uses a few seconds of your platform usage). Leave empty to disable."
          },
          "stateStoreName": {
            "title": "State store name",
            "type": "string",
            "description": "Named key-value store that keeps the last snapshot and change history of each monitor between runs. Use a different name per project/client to keep histories apart.",
            "default": "siteverdict-monitor"
          },
          "historySize": {
            "title": "Changes kept in history",
            "minimum": 1,
            "maximum": 500,
            "type": "integer",
            "description": "How many past changes are kept per monitor in the state store.",
            "default": 20
          },
          "resetBaseline": {
            "title": "Reset baseline",
            "type": "boolean",
            "description": "Ignore saved snapshots and start fresh this run (history is cleared for the monitors in this run).",
            "default": false
          },
          "respectRobotsTxt": {
            "title": "Respect robots.txt",
            "type": "boolean",
            "description": "Skip (and do not charge for) URLs that robots.txt disallows for 'SiteVerdict' or '*'. Only turn off for sites you own or are authorised to monitor.",
            "default": true
          },
          "maxConcurrency": {
            "title": "Max parallel checks",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "Checks run in parallel across different sites; requests to the same site are always sequential with a 1 s gap.",
            "default": 3
          },
          "maxUrls": {
            "title": "Max URLs per run",
            "minimum": 1,
            "maximum": 5000,
            "type": "integer",
            "description": "Safety cap on monitors checked in one run. The run also never exceeds your 'Max total charge'.",
            "default": 500
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}