{
  "openapi": "3.0.1",
  "info": {
    "title": "SEO Audit Crawler - Find What Broke Since Last Crawl",
    "description": "Find what broke on your site since the last crawl: pages that now 404, new noindex, changed canonicals, titles, H1s and schema, redirect chains and broken internal links, ranked by severity with a plain-English summary and Slack/Discord alert. Re-run after every release.",
    "version": "2.0",
    "x-build-id": "L6VLizUscItyD8j4R"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/that_red_bird~seo-audit-regression-crawler/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-that_red_bird-seo-audit-regression-crawler",
        "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/that_red_bird~seo-audit-regression-crawler/runs": {
      "post": {
        "operationId": "runs-sync-that_red_bird-seo-audit-regression-crawler",
        "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/that_red_bird~seo-audit-regression-crawler/run-sync": {
      "post": {
        "operationId": "run-sync-that_red_bird-seo-audit-regression-crawler",
        "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": {
          "startUrls": {
            "title": "Sites to audit",
            "type": "array",
            "description": "Full site URLs to crawl and audit, e.g. https://example.com. Each site is audited on its own and stored under its own baseline, so the second run of the same URL shows what broke since the first.",
            "default": [
              "https://example.com"
            ],
            "items": {
              "type": "string"
            }
          },
          "maxPages": {
            "title": "Max pages to crawl",
            "minimum": 1,
            "maximum": 2000,
            "type": "integer",
            "description": "How many pages get fetched and audited in full (titles, canonicals, headings, schema, indexability, content). Prefers sitemap.xml URLs and tops up from internal links.",
            "default": 40
          },
          "useSitemap": {
            "title": "Use sitemap.xml",
            "type": "boolean",
            "description": "Discover pages from sitemap.xml (and sitemap indexes, one level deep) first. Also used for orphan-page detection under Indexability.",
            "default": true
          },
          "maxLinksChecked": {
            "title": "Max extra links to status-check",
            "minimum": 0,
            "maximum": 5000,
            "type": "integer",
            "description": "On top of the crawled pages, this many additional internal links found on those pages get a status-only request for the broken-link and redirect-chain audits (no content is stored for these).",
            "default": 150
          },
          "includePatterns": {
            "title": "Only URLs containing",
            "type": "array",
            "description": "Crawl and link-check only internal URLs containing one of these substrings, e.g. /blog/, /products/. Empty means the whole site. The start URL is always crawled.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "excludePatterns": {
            "title": "Skip URLs containing",
            "type": "array",
            "description": "Skip internal URLs containing any of these substrings, e.g. /cart, ?sort=, /tag/.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "detectContentChanges": {
            "title": "Detect body text changes",
            "type": "boolean",
            "description": "Compare each page's visible text with the last crawl and report pages whose text was largely rewritten or shrank by half (type change, kind content-changed or content-shrunk). Digits are ignored so clocks and counters do not trigger it.",
            "default": true
          },
          "contentChangePercent": {
            "title": "Body text change threshold (%)",
            "minimum": 5,
            "maximum": 100,
            "type": "integer",
            "description": "Report a content-changed row when roughly this percentage of a page's text differs from the last crawl. Uses a compact similarity sketch, so it is an estimate.",
            "default": 25
          },
          "onlyRegressions": {
            "title": "Only output new and fixed issues",
            "type": "boolean",
            "description": "After the baseline run, output only what changed since last time (page changes plus NEW and FIXED issues) and skip issues that were already there. The baseline run always outputs everything found.",
            "default": false
          },
          "resetBaseline": {
            "title": "Reset baseline",
            "type": "boolean",
            "description": "Forget the stored audit for these sites and start fresh — this run becomes the new baseline with no regressions reported.",
            "default": false
          },
          "webhookUrl": {
            "title": "Alert webhook URL",
            "type": "string",
            "description": "Slack, Discord or any webhook that accepts JSON. Receives one message per site, only when a later run finds regressions at or above the alert severity. Never fires on the baseline run. Empty disables it.",
            "default": ""
          },
          "alertMinSeverity": {
            "title": "Alert severity",
            "enum": [
              "critical",
              "high",
              "medium",
              "low"
            ],
            "type": "string",
            "description": "Lowest severity that triggers the webhook. critical: lost indexability or a page that now errors. high: removed H1, title, canonical or structured data, broken links. medium and low are smaller changes.",
            "default": "high"
          },
          "titleMinLength": {
            "title": "Title too-short threshold (characters)",
            "minimum": 1,
            "maximum": 200,
            "type": "integer",
            "description": "A <title> shorter than this is flagged as too short.",
            "default": 15
          },
          "titleMaxLength": {
            "title": "Title too-long threshold (characters)",
            "minimum": 1,
            "maximum": 300,
            "type": "integer",
            "description": "A <title> longer than this is flagged as too long (roughly where Google starts truncating it in results).",
            "default": 60
          },
          "descMinLength": {
            "title": "Meta description too-short threshold (characters)",
            "minimum": 1,
            "maximum": 400,
            "type": "integer",
            "description": "A meta description shorter than this is flagged as too short.",
            "default": 50
          },
          "descMaxLength": {
            "title": "Meta description too-long threshold (characters)",
            "minimum": 1,
            "maximum": 500,
            "type": "integer",
            "description": "A meta description longer than this is flagged as too long.",
            "default": 160
          },
          "maxItems": {
            "title": "Max issue rows per site",
            "minimum": 0,
            "type": "integer",
            "description": "Hard cap on issue/fixed rows pushed per site. 0 = no cap.",
            "default": 0
          },
          "concurrency": {
            "title": "Concurrency",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "How many requests to run in parallel while crawling and link-checking.",
            "default": 5
          },
          "timeoutMs": {
            "title": "Request timeout (ms)",
            "minimum": 1000,
            "maximum": 60000,
            "type": "integer",
            "description": "Per-request timeout for every crawl, link-check and redirect hop.",
            "default": 15000
          },
          "stateStoreName": {
            "title": "State store name",
            "type": "string",
            "description": "Named key-value store holding the last crawl of each site (the baseline). Use a different name per client to keep their baselines separate. The default is kept from the earlier version of this Actor so existing baselines still work.",
            "default": "seo-regression-auditor-state"
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}