{
  "openapi": "3.0.1",
  "info": {
    "title": "Broken Link Checker & Sitemap Validator (Monitor Mode)",
    "description": "Find broken links, 404s, redirects and sitemap errors on your site. A 4xx is confirmed with GET, temporary errors are retried and bot-blocked links are re-checked in a real browser. Optional monitor mode flags only new issues. No subscription: pay per page and per link.",
    "version": "0.1",
    "x-build-id": "hFcyFjessuJ4wVSWT"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/mrdexter4~broken-link-monitor/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-mrdexter4-broken-link-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/mrdexter4~broken-link-monitor/runs": {
      "post": {
        "operationId": "runs-sync-mrdexter4-broken-link-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/mrdexter4~broken-link-monitor/run-sync": {
      "post": {
        "operationId": "run-sync-mrdexter4-broken-link-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": [
          "startUrls"
        ],
        "properties": {
          "startUrls": {
            "title": "Website(s) to check",
            "type": "array",
            "description": "Start page(s), usually the homepage. Pages on the same domain are crawled; links to other domains are checked but not crawled. Several start URLs share one page and link budget, so use one run or Task per site.",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "maxPagesToCrawl": {
            "title": "Max pages to crawl",
            "minimum": 1,
            "maximum": 50000,
            "type": "integer",
            "description": "Internal HTML pages to crawl for links. Internal links beyond this limit are still status-checked, just not crawled.",
            "default": 100
          },
          "maxLinksToCheck": {
            "title": "Max link checks",
            "minimum": 1,
            "maximum": 500000,
            "type": "integer",
            "description": "Safety cap on unique link/resource/sitemap URL checks per run.",
            "default": 2000
          },
          "checkExternalLinks": {
            "title": "Check external links",
            "type": "boolean",
            "description": "Also check links to other websites (not crawled, only checked).",
            "default": true
          },
          "checkResources": {
            "title": "Check images, scripts and stylesheets",
            "type": "boolean",
            "description": "Check <img>, srcset, <script>, stylesheet and icon URLs too.",
            "default": true
          },
          "validateSitemap": {
            "title": "Validate XML sitemap",
            "type": "boolean",
            "description": "Find the sitemap (robots.txt, /sitemap.xml, sitemap indexes, .gz) and check every listed URL: broken, redirecting, noindex, canonicalised elsewhere, blocked by robots.txt. Also reports crawled pages missing from the sitemap and orphan sitemap pages.",
            "default": true
          },
          "sitemapUrls": {
            "title": "Sitemap URLs (optional)",
            "type": "array",
            "description": "Only needed if your sitemap is not listed in robots.txt or at /sitemap.xml.",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "maxSitemapUrls": {
            "title": "Max sitemap URLs to validate",
            "minimum": 0,
            "maximum": 100000,
            "type": "integer",
            "description": "Sitemap reading stops after this many URLs. Crawled pages and URLs already checked as links are reused; the rest are fetched once each (counted as link checks).",
            "default": 500
          },
          "verifyBlockedInBrowser": {
            "title": "Re-check bot-blocked links in a real browser",
            "type": "boolean",
            "description": "Links that answer 403/429/999 or a Cloudflare challenge are opened in real Chrome before anything is reported. Working links are dropped; the rest are reported as 'blocked-unverified', never as broken. No extra charge.",
            "default": true
          },
          "maxBrowserChecks": {
            "title": "Max browser re-checks",
            "minimum": 0,
            "maximum": 500,
            "type": "integer",
            "description": "Upper limit for real-browser re-checks per run.",
            "default": 25
          },
          "renderJavaScript": {
            "title": "Render JavaScript (for JS-built menus / SPAs)",
            "type": "boolean",
            "description": "Load each crawled page in Chrome and collect links from the rendered DOM too. Slower; use 2048 MB+ memory.",
            "default": false
          },
          "reportRedirects": {
            "title": "Report redirects",
            "enum": [
              "internal",
              "all",
              "none"
            ],
            "type": "string",
            "description": "Which redirecting links to report. Redirects are never errors; internal redirect chains are warnings.",
            "default": "internal"
          },
          "excludeUrlPatterns": {
            "title": "Exclude URLs (regex or text)",
            "type": "array",
            "description": "URLs matching any pattern are neither crawled nor checked, e.g. \"/wp-admin/\", \"linkedin\\\\.com\", \"\\\\?add-to-cart=\", \"\\\\?sort=\". Shops: query-string variants are separate URLs and are charged separately.",
            "items": {
              "type": "string"
            }
          },
          "requestTimeoutSecs": {
            "title": "Request timeout (seconds)",
            "minimum": 5,
            "maximum": 120,
            "type": "integer",
            "description": "Per-request timeout. Timeouts are retried with backoff before a link is reported.",
            "default": 20
          },
          "monitorMode": {
            "title": "Monitor mode (compare with previous run)",
            "type": "boolean",
            "description": "Remember issues between runs (same start URLs + store name). Each issue gets isNew and firstSeenAt; fixed issues are listed as resolved. Schedule the Actor daily or weekly. Set 'Max pages to crawl' above your site's page count, otherwise issues can flip between new and resolved.",
            "default": false
          },
          "monitorStoreName": {
            "title": "History store name",
            "type": "string",
            "description": "Named key-value store that keeps the history. Use different names for separate monitors of the same site.",
            "default": "broken-link-monitor-history"
          },
          "outputOnlyNewIssues": {
            "title": "Dataset: only new issues",
            "type": "boolean",
            "description": "In monitor mode, put only new issues in the dataset (the summary row is always added).",
            "default": false
          },
          "alertOn": {
            "title": "Alert on",
            "enum": [
              "new-errors",
              "new-issues",
              "all-errors"
            ],
            "type": "string",
            "description": "What triggers the webhook/email. Alerts are also sent when an earlier issue is resolved. In monitor mode the first run is the baseline, so every error on it counts as new. Without monitor mode, 'new' means all current issues.",
            "default": "new-errors"
          },
          "webhookUrl": {
            "title": "Webhook URL (Slack, Discord, n8n, Make, Zapier)",
            "type": "string",
            "description": "POSTs JSON with a 'text' field (Slack, n8n, Make, Zapier), a 'content' field (Discord) and the full issue list, only when there is something to report."
          },
          "notificationEmail": {
            "title": "Email for alerts (optional)",
            "type": "string",
            "description": "Optional. Sends a short HTML report when there is something to report, using the apify/send-mail Actor on your account (uses a little platform credit)."
          },
          "maxConcurrency": {
            "title": "Max concurrency",
            "minimum": 1,
            "maximum": 32,
            "type": "integer",
            "description": "Parallel requests overall. Per host it is always limited (4 for your site, 2 for each external site) to avoid rate limits and server load.",
            "default": 16
          },
          "proxyConfiguration": {
            "title": "Proxy",
            "type": "object",
            "description": "Not needed for most sites. Use it if your own site's firewall blocks data-centre IPs."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}