{
  "openapi": "3.0.3",
  "info": {
    "title": "RankNibbler API",
    "version": "1.0.0",
    "description": "Free on-page SEO audit API. Submit any public URL and get a scored audit (title, meta, headings, images, schema, links and more) as JSON. Get a free key at https://www.ranknibbler.com/api."
  },
  "servers": [
    {
      "url": "https://www.ranknibbler.com"
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key"
      }
    }
  },
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "paths": {
    "/api/v1/audit": {
      "get": {
        "summary": "Full on-page SEO audit (score, issues, all checks)",
        "operationId": "auditUrl",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The public URL to analyse."
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "API key (or send the X-API-Key header)."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "URL blocked (SSRF / private address)"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          },
          "502": {
            "description": "Upstream fetch/render failed"
          }
        }
      }
    },
    "/api/v1/links": {
      "get": {
        "summary": "All links on a page (internal/external, dofollow, canonical, hreflang)",
        "operationId": "getLinks",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The public URL to analyse."
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "API key (or send the X-API-Key header)."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "URL blocked (SSRF / private address)"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          },
          "502": {
            "description": "Upstream fetch/render failed"
          }
        }
      }
    },
    "/api/v1/keyword-density": {
      "get": {
        "summary": "Word & phrase frequency / density (1–5-gram)",
        "operationId": "getKeywordDensity",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The public URL to analyse."
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "API key (or send the X-API-Key header)."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "URL blocked (SSRF / private address)"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          },
          "502": {
            "description": "Upstream fetch/render failed"
          }
        }
      }
    },
    "/api/v1/structured-data": {
      "get": {
        "summary": "Extract JSON-LD / microdata structured data",
        "operationId": "getStructuredData",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The public URL to analyse."
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "API key (or send the X-API-Key header)."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "URL blocked (SSRF / private address)"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          },
          "502": {
            "description": "Upstream fetch/render failed"
          }
        }
      }
    },
    "/api/v1/content": {
      "get": {
        "summary": "Readability, word count, heading outline",
        "operationId": "getContent",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The public URL to analyse."
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "API key (or send the X-API-Key header)."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "URL blocked (SSRF / private address)"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          },
          "502": {
            "description": "Upstream fetch/render failed"
          }
        }
      }
    },
    "/api/v1/indexability": {
      "get": {
        "summary": "Robots, canonical, noindex and crawl directives",
        "operationId": "getIndexability",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The public URL to analyse."
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "API key (or send the X-API-Key header)."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "URL blocked (SSRF / private address)"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          },
          "502": {
            "description": "Upstream fetch/render failed"
          }
        }
      }
    },
    "/api/v1/redirect-chains": {
      "get": {
        "summary": "Trace the full redirect chain for a URL",
        "operationId": "getRedirectChains",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The public URL to analyse."
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "API key (or send the X-API-Key header)."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "URL blocked (SSRF / private address)"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          },
          "502": {
            "description": "Upstream fetch/render failed"
          }
        }
      }
    },
    "/api/v1/resources": {
      "get": {
        "summary": "Page resources (images/scripts/styles) with status & size",
        "operationId": "getResources",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The public URL to analyse."
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "API key (or send the X-API-Key header)."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "URL blocked (SSRF / private address)"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          },
          "502": {
            "description": "Upstream fetch/render failed"
          }
        }
      }
    },
    "/api/v1/raw-html": {
      "get": {
        "summary": "Raw fetched HTML with status and headers",
        "operationId": "getRawHtml",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The public URL to analyse."
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "API key (or send the X-API-Key header)."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "URL blocked (SSRF / private address)"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          },
          "502": {
            "description": "Upstream fetch/render failed"
          }
        }
      }
    },
    "/api/v1/meta-tags": {
      "get": {
        "summary": "Full head-metadata dump (title, meta, Open Graph, Twitter, link rels)",
        "operationId": "getMetaTags",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The public URL to analyse."
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "API key (or send the X-API-Key header)."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "URL blocked (SSRF / private address)"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          },
          "502": {
            "description": "Upstream fetch/render failed"
          }
        }
      }
    },
    "/api/v1/page-timing": {
      "get": {
        "summary": "DNS/TCP/TLS/TTFB/download timing + transfer size",
        "operationId": "getPageTiming",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The public URL to analyse."
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "API key (or send the X-API-Key header)."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "URL blocked (SSRF / private address)"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          },
          "502": {
            "description": "Upstream fetch/render failed"
          }
        }
      }
    },
    "/api/v1/ai-readiness": {
      "get": {
        "summary": "AI & agent readiness — agent-discovery standards + AI-search content checks",
        "operationId": "getAiReadiness",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The public URL to analyse."
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "API key (or send the X-API-Key header)."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "URL blocked (SSRF / private address)"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          },
          "502": {
            "description": "Upstream fetch/render failed"
          }
        }
      }
    },
    "/api/v1/security-headers": {
      "get": {
        "summary": "Security-header grade (HSTS/CSP/etc) + mixed content + cache/compression",
        "operationId": "getSecurityHeaders",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The public URL to analyse."
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "API key (or send the X-API-Key header)."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "URL blocked (SSRF / private address)"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          },
          "502": {
            "description": "Upstream fetch/render failed"
          }
        }
      }
    },
    "/api/v1/accessibility": {
      "get": {
        "summary": "Static WCAG/axe accessibility audit",
        "operationId": "getAccessibility",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The public URL to analyse."
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "API key (or send the X-API-Key header)."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "URL blocked (SSRF / private address)"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          },
          "502": {
            "description": "Upstream fetch/render failed"
          }
        }
      }
    },
    "/api/v1/robots-txt": {
      "get": {
        "summary": "robots.txt parse + AI-bot rules + content-signals",
        "operationId": "getRobotsTxt",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The public URL to analyse."
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "API key (or send the X-API-Key header)."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "URL blocked (SSRF / private address)"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          },
          "502": {
            "description": "Upstream fetch/render failed"
          }
        }
      }
    },
    "/api/v1/sitemap": {
      "get": {
        "summary": "XML sitemap discovery + parse + stats",
        "operationId": "getSitemap",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The public URL to analyse."
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "API key (or send the X-API-Key header)."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "URL blocked (SSRF / private address)"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          },
          "502": {
            "description": "Upstream fetch/render failed"
          }
        }
      }
    },
    "/api/v1/lighthouse": {
      "get": {
        "summary": "Lighthouse scores + Core Web Vitals (rendered)",
        "operationId": "getLighthouse",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The public URL to analyse."
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "API key (or send the X-API-Key header)."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "URL blocked (SSRF / private address)"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          },
          "502": {
            "description": "Upstream fetch/render failed"
          }
        }
      }
    },
    "/api/v1/screenshot": {
      "get": {
        "summary": "Rendered full-page screenshot",
        "operationId": "getScreenshot",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The public URL to analyse."
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "API key (or send the X-API-Key header)."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "URL blocked (SSRF / private address)"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          },
          "502": {
            "description": "Upstream fetch/render failed"
          }
        }
      }
    },
    "/api/v1/waterfall": {
      "get": {
        "summary": "Network request waterfall (rendered)",
        "operationId": "getWaterfall",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The public URL to analyse."
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "API key (or send the X-API-Key header)."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "URL blocked (SSRF / private address)"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          },
          "502": {
            "description": "Upstream fetch/render failed"
          }
        }
      }
    },
    "/api/v1/crawl": {
      "post": {
        "summary": "Start a site crawl (async). Returns a job id; poll the summary endpoint.",
        "operationId": "startCrawl",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The public URL to analyse."
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "API key (or send the X-API-Key header)."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "maxPages": {
                    "type": "integer",
                    "default": 50,
                    "maximum": 200
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "202": {
            "description": "Crawl queued",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "URL blocked (SSRF / private address)"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          },
          "502": {
            "description": "Upstream fetch/render failed"
          }
        }
      }
    },
    "/api/v1/crawl/{jobId}/summary": {
      "get": {
        "summary": "Crawl summary",
        "operationId": "getCrawlSummary",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "API key (or send the X-API-Key header)."
          }
        ],
        "responses": {
          "200": {
            "description": "Crawl results",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Crawl belongs to another key"
          },
          "404": {
            "description": "Job not found"
          }
        }
      }
    },
    "/api/v1/crawl/{jobId}/pages": {
      "get": {
        "summary": "Crawl pages",
        "operationId": "getCrawlPages",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "API key (or send the X-API-Key header)."
          }
        ],
        "responses": {
          "200": {
            "description": "Crawl results",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Crawl belongs to another key"
          },
          "404": {
            "description": "Job not found"
          }
        }
      }
    },
    "/api/v1/crawl/{jobId}/duplicate-tags": {
      "get": {
        "summary": "Crawl duplicate tags",
        "operationId": "getCrawlDuplicateTags",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "API key (or send the X-API-Key header)."
          }
        ],
        "responses": {
          "200": {
            "description": "Crawl results",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Crawl belongs to another key"
          },
          "404": {
            "description": "Job not found"
          }
        }
      }
    },
    "/api/v1/crawl/{jobId}/duplicate-content": {
      "get": {
        "summary": "Crawl duplicate content",
        "operationId": "getCrawlDuplicateContent",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "API key (or send the X-API-Key header)."
          }
        ],
        "responses": {
          "200": {
            "description": "Crawl results",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Crawl belongs to another key"
          },
          "404": {
            "description": "Job not found"
          }
        }
      }
    },
    "/api/v1/crawl/{jobId}/links": {
      "get": {
        "summary": "Crawl links",
        "operationId": "getCrawlLinks",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "API key (or send the X-API-Key header)."
          }
        ],
        "responses": {
          "200": {
            "description": "Crawl results",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Crawl belongs to another key"
          },
          "404": {
            "description": "Job not found"
          }
        }
      }
    },
    "/api/v1/crawl/{jobId}/orphans": {
      "get": {
        "summary": "Crawl orphans",
        "operationId": "getCrawlOrphans",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "API key (or send the X-API-Key header)."
          }
        ],
        "responses": {
          "200": {
            "description": "Crawl results",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Crawl belongs to another key"
          },
          "404": {
            "description": "Job not found"
          }
        }
      }
    },
    "/api/v1/crawl/{jobId}/broken-links": {
      "get": {
        "summary": "Crawl broken links",
        "operationId": "getCrawlBrokenLinks",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "API key (or send the X-API-Key header)."
          }
        ],
        "responses": {
          "200": {
            "description": "Crawl results",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Crawl belongs to another key"
          },
          "404": {
            "description": "Job not found"
          }
        }
      }
    },
    "/api/v1/key": {
      "post": {
        "summary": "Retired — create API keys from your account dashboard instead",
        "description": "Anonymous key creation is no longer available. Sign up at /register and create a key in your dashboard at /app/api. This endpoint returns 403 with a pointer to sign-up.",
        "operationId": "createKey",
        "security": [],
        "responses": {
          "403": {
            "description": "Keys are account-only — sign up and create one in the dashboard"
          }
        }
      }
    }
  }
}