{
  "openapi": "3.0.1",
  "info": {
    "title": "SEO Page Audit — Sitemap Crawl & On-Page Checker",
    "description": "Point it at a domain. It reads robots.txt, walks the sitemap or crawls the site, then audits every page: title, description, H1s, canonical, hreflang, schema, images, links and speed. 23 issue codes, a transparent 0-100 score, and an optional broken-link check.",
    "version": "0.1",
    "x-build-id": "Rs16hk2iXdOZNgyxB"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/insight.solutions~seo-page-audit/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-insight.solutions-seo-page-audit",
        "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/insight.solutions~seo-page-audit/runs": {
      "post": {
        "operationId": "runs-sync-insight.solutions-seo-page-audit",
        "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/insight.solutions~seo-page-audit/run-sync": {
      "post": {
        "operationId": "run-sync-insight.solutions-seo-page-audit",
        "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": {
          "websites": {
            "title": "Websites",
            "type": "array",
            "description": "One entry per site to audit. A bare domain is enough — `basecamp.com` — and so is a full URL. Each domain is tried on `https://`, then `https://www.`, then plain `http://`, so a host that only answers on one of them still gets read. For each site the Actor reads `robots.txt`, follows the `Sitemap:` lines it finds (or tries `/sitemap.xml` and three other usual locations), and audits up to **Maximum pages per website** URLs. A site that publishes no sitemap at all is crawled breadth-first from its home page instead. Email addresses and IP addresses are rejected for free.",
            "items": {
              "type": "string"
            }
          },
          "pageUrls": {
            "title": "Specific page URLs",
            "type": "array",
            "description": "Audit exactly these pages and nothing else — no sitemap, no crawl. Use it when you already know which URLs matter: the twelve landing pages you just shipped, the product pages a client complained about, a list exported from your analytics. URLs on the same host as an entry in **Websites** are folded into that site's audit rather than becoming a second one, so they still count toward its duplicate-title check and its site summary row.",
            "items": {
              "type": "string"
            }
          },
          "maxPages": {
            "title": "Maximum pages per website",
            "minimum": 1,
            "maximum": 5000,
            "type": "integer",
            "description": "How many pages to audit per website. This is the number that sets the price of a run: every audited page is one `page` event. The default of 100 is a useful sample of a mid-size site; raise it to cover a site completely, lower it to spot-check. Sitemap URLs are taken in the order the sitemap lists them; a crawl takes them breadth-first from the home page, shallowest links first.",
            "default": 100
          },
          "checkLinks": {
            "title": "Check internal links",
            "type": "boolean",
            "description": "Off by default. Turn it on and every unique internal link found on the audited pages is fetched once (a plain `GET` — `HEAD` stalls on some CDNs), and anything answering 4xx, 5xx or nothing at all gets a `broken-link` row naming the pages that link to it. Links are deduplicated across the whole site — a bad link in the footer of 400 pages is one check and one row — and pages that were audited anyway are skipped, because their status is already known. Billed at $0.0002 per link that turns out to be broken; checking costs nothing.",
            "default": false
          },
          "maxLinksToCheck": {
            "title": "Maximum links to check",
            "minimum": 1,
            "maximum": 5000,
            "type": "integer",
            "description": "The ceiling on the link check, per website. Only used when **Check internal links** is on. Unique internal links are collected across every audited page and then cut to this number.",
            "default": 500
          },
          "respectRobots": {
            "title": "Respect robots.txt",
            "type": "boolean",
            "description": "On by default, and worth leaving on. The Actor reads the `User-agent: *` group of each site's `robots.txt` and skips any URL it disallows, using the same longest-match-wins rule search engines use, with `*` and `$` patterns supported. Skipped URLs are counted on the `site` row as `robotsBlocked` and are never fetched or billed. Turn it off only for a site you own or have permission to crawl — for example to audit a staging site that blocks everything.",
            "default": true
          },
          "maxSitemapUrls": {
            "title": "Maximum sitemap URLs to collect",
            "minimum": 1,
            "maximum": 5000,
            "type": "integer",
            "description": "How many URLs to read out of a site's sitemaps before stopping. A large news site's sitemap tree runs to millions of entries and reading all of it to audit 100 pages would be rude as well as slow, so collection also stops as soon as there are enough URLs to fill **Maximum pages per website**. Sitemap indexes are followed three levels deep and at most 50 sitemap files are fetched per website.",
            "default": 5000
          },
          "maxConcurrency": {
            "title": "Pages in parallel",
            "minimum": 1,
            "maximum": 16,
            "type": "integer",
            "description": "How many pages of one website are fetched at once. Each parallel worker keeps its own proxy session, so a page that refuses one exit IP does not burn the address the others are using. Requests to a single host are spaced 150–400 ms apart whatever this is set to, so raising it buys parallel parsing rather than a burst of simultaneous requests. Websites themselves are always audited one at a time.",
            "default": 8
          },
          "maxRunSecs": {
            "title": "Maximum run time (seconds)",
            "minimum": 30,
            "maximum": 3600,
            "type": "integer",
            "description": "Wall-clock budget for the whole run. When it is reached the Actor stops fetching, keeps and bills for every row it already wrote, and files a free diagnostic row saying how many URLs it never reached. Nothing is charged for work that did not happen.",
            "default": 240
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Ordinary websites do not refuse datacenter address ranges the way the big platforms do, so the default is Apify's datacenter proxy and its cost is already inside the per-page price. If you are auditing a site behind an aggressive bot wall, switch the group to RESIDENTIAL here and nothing else changes — sessions still rotate automatically when an exit IP is refused. Clearing the field sends requests from the run's own address.",
            "default": {
              "useApifyProxy": 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
                  }
                }
              },
              "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}