{
  "openapi": "3.0.1",
  "info": {
    "title": "Website Audit: SEO, GEO, Security, WordPress & Speed",
    "description": "Passive website audit for humans and AI agents: page-by-page SEO, AI visibility (GEO), HTTPS & security headers, SPF/DMARC/DKIM, broken links, PageSpeed, accessibility, WordPress/Shopify/CMS vulnerabilities. JSON + HTML/PDF report, EN/FR.",
    "version": "0.8",
    "x-build-id": "PQxipU07uCzGEe7kY"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/neocraft~website-audit-all-in-one/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-neocraft-website-audit-all-in-one",
        "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/neocraft~website-audit-all-in-one/runs": {
      "post": {
        "operationId": "runs-sync-neocraft-website-audit-all-in-one",
        "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/neocraft~website-audit-all-in-one/run-sync": {
      "post": {
        "operationId": "run-sync-neocraft-website-audit-all-in-one",
        "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": "Websites to audit",
            "type": "array",
            "description": "Websites to audit, one entry per site (home page URL, e.g. https://www.example.com). A sub-path such as https://site.com/blog/ limits the crawl to that section. Duplicated hosts are audited once. Output: one dataset item per site.",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "language": {
            "title": "Report language",
            "enum": [
              "en",
              "fr"
            ],
            "type": "string",
            "description": "Language of all human-readable texts (titles, explanations, fix steps, HTML report). Field names, ids and enum values are always English.",
            "default": "en"
          },
          "maxPagesPerSite": {
            "title": "Max pages per site",
            "minimum": 1,
            "maximum": 200,
            "type": "integer",
            "description": "Maximum pages crawled per site (1-200). The first 10 are included in the 'site-audit' price; further pages are billed as 'extra-page'. 5-20 is enough for most audits. On Shopify stores a few product and collection pages are crawled first.",
            "default": 20
          },
          "maxLinkChecks": {
            "title": "Max links checked per site",
            "minimum": 0,
            "maximum": 300,
            "type": "integer",
            "description": "Links found on crawled pages (but not crawled) that are checked for errors (HEAD/GET, internal links first). 0 disables extra link checks.",
            "default": 30
          },
          "pagespeed": {
            "title": "Run Google PageSpeed Insights",
            "type": "boolean",
            "description": "Query Google PageSpeed Insights (Lighthouse lab test + Chrome real-user Core Web Vitals) for the home page. Adds 20-60 s per site. Without an API key Google may refuse (quota); the audit continues anyway and performance is then not scored.",
            "default": true
          },
          "pagespeedStrategies": {
            "title": "PageSpeed devices",
            "type": "array",
            "description": "Devices tested by PageSpeed Insights, in parallel. Default both. The performance category score is weighted 60% mobile + 40% desktop (or uses the only device available).",
            "items": {
              "type": "string",
              "enum": [
                "mobile",
                "desktop"
              ],
              "enumTitles": [
                "Mobile",
                "Desktop"
              ]
            },
            "default": [
              "mobile",
              "desktop"
            ]
          },
          "pagespeedApiKey": {
            "title": "Google API key for PageSpeed (optional)",
            "type": "string",
            "description": "Your own free Google API key (Google Cloud > APIs & Services > enable 'PageSpeed Insights API' > Credentials > API key). Used first when given. Without it, the Actor's shared key is used for up to 50 sites per run; further sites skip PageSpeed with a note. Stored encrypted, never logged or output."
          },
          "pagespeedPages": {
            "title": "PageSpeed: number of pages",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "Run Google PageSpeed Insights on the first N crawled pages (home page first). 1 = home page only. Each extra page adds 20-60 s and uses PageSpeed quota; with the shared key of this Actor extra pages count against the same per-run cap as sites.",
            "default": 1
          },
          "checkSecurity": {
            "title": "HTTPS, certificate & security headers",
            "type": "boolean",
            "description": "HTTPS availability and redirect, SSL/TLS certificate, security headers, cookie flags (Secure, HttpOnly, SameSite) on every crawled response, mixed content (active/passive) and forms posting to http://, security.txt (info), server/PHP version exposure, outdated JavaScript libraries with known vulnerabilities (OSV.dev).",
            "default": true
          },
          "checkDomain": {
            "title": "Domain registration (RDAP: expiry, registrar, transfer lock, DNSSEC)",
            "type": "boolean",
            "description": "Reads public registry data via RDAP (no personal data is kept). Runs only when the security checks are enabled.",
            "default": true
          },
          "checkEmail": {
            "title": "E-mail DNS (SPF, DMARC, DKIM, MX, MTA-STS, TLS-RPT, BIMI)",
            "type": "boolean",
            "description": "DNS checks of the domain's e-mail authentication: MX, SPF (multiple records, +all/?all, 10-DNS-lookup limit = permerror, broken includes), DMARC, DKIM (common selectors), MTA-STS policy + TLS-RPT, BIMI (info).",
            "default": true
          },
          "checkSeo": {
            "title": "SEO (titles, descriptions, headings, robots.txt, sitemap...)",
            "type": "boolean",
            "description": "Titles, meta descriptions, H1/headings, canonical, noindex, language, viewport, image alt texts, OpenGraph, hreflang, robots.txt, XML sitemap, error pages.",
            "default": true
          },
          "checkGeo": {
            "title": "AI visibility / GEO (llms.txt, AI crawlers, structured data)",
            "type": "boolean",
            "description": "AI visibility (GEO): AI crawler rules in robots.txt, Cloudflare Content Signals, CDN AI-blocking advice, snippet controls (nosnippet, max-snippet, data-nosnippet), JSON-LD quality per type, trust signals, freshness, answer-friendly structure, Bing signals, llms.txt. Scored with a pillar breakdown.",
            "default": true
          },
          "checkLinks": {
            "title": "Broken links",
            "type": "boolean",
            "description": "Broken internal and external links (anti-bot answers are reported as inconclusive, not broken).",
            "default": true
          },
          "checkPerformance": {
            "title": "Performance",
            "type": "boolean",
            "description": "Server response time, compression and (if 'pagespeed' is on) PageSpeed Insights mobile + desktop.",
            "default": true
          },
          "checkTechnologies": {
            "title": "Technology detection",
            "type": "boolean",
            "description": "Detect CMS, e-commerce platform, frameworks, analytics, consent tools, CDN/hosting (own rule list).",
            "default": true
          },
          "checkWordpress": {
            "title": "WordPress (version, plugins, themes, known vulnerabilities)",
            "type": "boolean",
            "description": "WordPress core/plugin/theme versions and known vulnerabilities with CVE ids, CVSS score/severity, fixed-in version and CISA KEV 'actively exploited' flag (escalated to critical, 'fix today'); premium components flagged as 'latest version unknown'; closed plugins; version-hiding (hardening) advice. Only applies to WordPress sites.",
            "default": true
          },
          "checkShopify": {
            "title": "Shopify store checks (theme, apps, product data, consent, app speed impact)",
            "type": "boolean",
            "description": "Shopify stores: theme, apps detected from scripts, Product/Offer structured data on product pages, product/collection SEO basics, cookie consent, speed impact of apps. Only applies to Shopify sites.",
            "default": true
          },
          "checkPlatforms": {
            "title": "CMS / framework checks (Drupal, Joomla, PrestaShop, Magento, TYPO3, Symfony, Laravel, Next.js, Nuxt, Wix...)",
            "type": "boolean",
            "description": "Passive detection of Drupal, Joomla, PrestaShop (+ modules), Magento 1/2 (Adobe Commerce), TYPO3, Symfony, Laravel, Next.js, Nuxt and hosted builders (Wix, Squarespace, Webflow); version only when the platform itself shows it; end-of-life (endoflife.date) and known vulnerabilities (OSV/GitHub Advisory Database, Drupal advisories, NVD, Friends-of-Presta, CISA KEV); framework debug exposure seen during the normal crawl (Symfony profiler / X-Debug-Token, Laravel Ignition/Whoops/Debugbar, Magento developer mode). At most one extra request per platform for its well-known version file, only if robots.txt allows it.",
            "default": true
          },
          "checkAccessibility": {
            "title": "Accessibility (lightweight, passive + Lighthouse)",
            "type": "boolean",
            "description": "Passive HTML accessibility checks on crawled pages (form labels, empty links/buttons, vague link texts like 'click here', iframe titles, skip link / main landmark, zoom blocked, page language) plus Lighthouse accessibility audits (axe-core, incl. colour contrast) when PageSpeed runs. Scored as category 'accessibility'. Not a WCAG conformity audit. Mentions the European Accessibility Act for online shops (information, not legal advice).",
            "default": true
          },
          "pageRecords": {
            "title": "Per-page records",
            "type": "boolean",
            "description": "Push one dataset item of type 'page' per crawled page (score 0-100, category scores, issues with fix hints) and add page aggregates (average score, top issues, duplicates, crawl coverage) to the site item.",
            "default": true
          },
          "renderJs": {
            "title": "JavaScript rendering",
            "enum": [
              "auto",
              "always",
              "never"
            ],
            "type": "string",
            "description": "Render pages in headless Chromium to audit what users see on JavaScript sites (React, Vue, Next.js...). Compares rendered vs raw HTML (content invisible to most AI crawlers), adds rendered links/images to the page checks, lab LCP/CLS and consent-banner detection. 'auto' renders only pages with almost no text, an empty app root or a framework shell. Rendering uses more memory and time; 2048 MB is recommended for 'always'.",
            "default": "auto"
          },
          "maxRenderedPages": {
            "title": "Max rendered pages per site",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "Upper limit of pages rendered in the browser per site (home first).",
            "default": 5
          },
          "screenshots": {
            "title": "Screenshots of rendered pages",
            "type": "boolean",
            "description": "Store a full-page PNG (max 8000 px high) of each rendered page in the key-value store; linked from the report.",
            "default": false
          },
          "auditMetaTags": {
            "title": "Page module: Meta tags",
            "type": "boolean",
            "description": "Per-page records: score the Meta tags (title, description, pixel width, Open Graph, Twitter card, charset) category. Off = category not scored (null) and its issues not reported.",
            "default": true
          },
          "auditHeadings": {
            "title": "Page module: Headings",
            "type": "boolean",
            "description": "Per-page records: score the Headings (H1-H6 tree, missing/multiple H1, skipped levels) category. Off = category not scored (null) and its issues not reported.",
            "default": true
          },
          "auditContent": {
            "title": "Page module: Content",
            "type": "boolean",
            "description": "Per-page records: score the Content (word count, readability per language, keywords) category. Off = category not scored (null) and its issues not reported.",
            "default": true
          },
          "auditTechnical": {
            "title": "Page module: Technical",
            "type": "boolean",
            "description": "Per-page records: score the Technical (robots, canonical, head closed early, lang, viewport, HTTPS) category. Off = category not scored (null) and its issues not reported.",
            "default": true
          },
          "auditPerformance": {
            "title": "Page module: Performance",
            "type": "boolean",
            "description": "Per-page records: score the Performance (PageSpeed or response time / HTML size) category. Off = category not scored (null) and its issues not reported.",
            "default": true
          },
          "auditSchema": {
            "title": "Page module: Structured data",
            "type": "boolean",
            "description": "Per-page records: score the Structured data (JSON-LD, microdata, RDFa) category. Off = category not scored (null) and its issues not reported.",
            "default": true
          },
          "auditLinks": {
            "title": "Page module: Links",
            "type": "boolean",
            "description": "Per-page records: score the Links (counts, nav/content/footer, nofollow, first 10 links checked) category. Off = category not scored (null) and its issues not reported.",
            "default": true
          },
          "auditImages": {
            "title": "Page module: Images",
            "type": "boolean",
            "description": "Per-page records: score the Images (alt, real file size, format, broken) category. Off = category not scored (null) and its issues not reported.",
            "default": true
          },
          "auditAccessibility": {
            "title": "Page module: Accessibility",
            "type": "boolean",
            "description": "Per-page records: score the Accessibility (labels, accessible names, zoom) category. Off = category not scored (null) and its issues not reported.",
            "default": true
          },
          "exposedFilesCheck": {
            "title": "Exposed sensitive files check (OPT-IN, only for sites you own or are authorized to test)",
            "type": "boolean",
            "description": "OFF by default. Only enable it for websites you own or are explicitly authorized to test. Makes a short fixed list of single requests for files that must never be public (/.git/HEAD, /.env, /wp-config.php.bak, /backup.zip as HEAD only, /.DS_Store, /phpinfo.php, /wp-content/debug.log on WordPress), at the same polite rate. Each hit is validated by a content signature to avoid false positives; file contents are never stored or output (only a redacted one-line proof). Your explicit opt-in takes precedence over robots.txt for these few files. Needs 'checkSecurity'.",
            "default": false
          },
          "wpReadmeLookup": {
            "title": "Read plugin readme.txt files",
            "type": "boolean",
            "description": "For plugins already referenced by the site's pages, read their public readme.txt to identify the version more reliably (max 15 requests).",
            "default": true
          },
          "liveVulnLookup": {
            "title": "Live lookup for components missing from the nightly database",
            "type": "boolean",
            "description": "Query api.wordpress.org and wpvulnerability.net for plugins/themes not in the bundled database, OSV.dev for front-end JavaScript library vulnerabilities, and the CISA KEV feed if the database has no KEV data.",
            "default": true
          },
          "requestIntervalSecs": {
            "title": "Seconds between requests to the same site",
            "minimum": 0.5,
            "maximum": 10,
            "type": "number",
            "description": "Politeness delay (minimum 0.5).",
            "default": 1
          },
          "maxConcurrentSites": {
            "title": "Sites audited in parallel",
            "minimum": 1,
            "maximum": 5,
            "type": "integer",
            "description": "Number of sites audited in parallel (1-5). Each site is still fetched politely (one request per interval).",
            "default": 2
          },
          "compareWithPrevious": {
            "title": "Compare with the previous audit (history / monitoring)",
            "type": "boolean",
            "description": "Keep a compact snapshot of each audit in the named key-value store 'site-audit-history' of YOUR Apify account and add a 'changes' block (new / fixed / worse / improved findings, score deltas) plus a 'What changed since <date>' section to the report. Schedule the Actor (Apify Schedules) to turn this into monitoring. Off = no history is read or written.",
            "default": true
          },
          "monitorId": {
            "title": "Monitor / client id",
            "type": "string",
            "description": "Optional label that keeps a separate history per client or project (agencies: one id per customer). Letters, digits, '-', '_', '.' only. Histories are also always separated by Apify account."
          },
          "historyStoreName": {
            "title": "History store name",
            "type": "string",
            "description": "Name of the named key-value store used for the history (in the account that runs the Actor). Change it only to keep fully separate histories.",
            "default": "site-audit-history"
          },
          "reportDetail": {
            "title": "Report detail level",
            "enum": [
              "simple",
              "technical"
            ],
            "type": "string",
            "description": "'simple' hides raw technical JSON in the HTML/PDF report but keeps, for each finding, a short line 'how it was found + confidence + sources'. 'technical' also shows the raw evidence. The dataset always contains everything.",
            "default": "simple"
          },
          "pdf": {
            "title": "Also export a PDF report",
            "type": "boolean",
            "description": "Save a PDF version of the report as 'OUTPUT.pdf' in the key-value store (drawn without a browser with fpdf2; plain layout; Latin characters only, others are transliterated). Off by default because most callers are programs: it adds about 0.5 s and up to ~50 MB of memory for 10 sites.",
            "default": false
          },
          "agencyName": {
            "title": "Agency name (white-label)",
            "type": "string",
            "description": "Shown at the top of the HTML/PDF reports. Setting any white-label field removes our 'generated by' branding."
          },
          "agencyLogoUrl": {
            "title": "Agency logo URL",
            "type": "string",
            "description": "HTTPS URL of your logo (PNG or JPEG, max 1 MB for the PDF). Displayed in the reports."
          },
          "brandColor": {
            "title": "Brand colour",
            "type": "string",
            "description": "Hex colour for titles and links, e.g. '#0b5394'."
          },
          "contactEmail": {
            "title": "Contact e-mail",
            "type": "string",
            "description": "Shown in the report footer (e.g. your support address)."
          },
          "footerText": {
            "title": "Footer text",
            "type": "string",
            "description": "Free text in the report footer (e.g. 'Prepared by Example Agency - www.example.com')."
          },
          "alerts": {
            "title": "Alerts (webhook / Slack)",
            "type": "object",
            "description": "Optional. {\"webhookUrl\": \"https://...\", \"slackWebhookUrl\": \"https://hooks.slack.com/services/...\", \"minSeverity\": \"high\", \"onlyNew\": true, \"domainExpiryDays\": 30, \"sslExpiryDays\": 14}. One message per destination per run when a site has findings >= minSeverity (only NEW or WORSE ones since the previous audit when onlyNew is true; all of them on a first audit) or a domain/SSL expiry within the thresholds. Messages go only to the URLs you give (no redirects followed). For e-mail, use an Apify integration on the run (see README)."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}