{
  "openapi": "3.1.0",
  "info": {
    "title": "LLMready API",
    "version": "1.0.0",
    "summary": "Audit websites for AI search readiness and generate or validate llms.txt files.",
    "description": "The LLMready API runs the same crawler and scoring as the web app: it fetches a site's homepage, robots.txt, /llms.txt, /llms-full.txt, sitemap and a sample of key pages, then scores bot access, content extractability, semantic metadata and citation readiness (0–100, graded A+ to F).\n\nAccess is included with LLMready Pro: 1,000 credits per calendar month (UTC). Crawling operations cost credits; reads and validation are free. Failed calls never use credits. Rate limit: 30 requests per minute per key.\n\nFree tool without a key: GET /quick-check?url=example.com returns a site's score, grade, category scores and top fixes (10 per minute, 100 per day per IP).\n\nThe same tools are available to AI agents through the remote MCP server at https://answer-engine-ready.lovable.app/mcp (server card: https://answer-engine-ready.lovable.app/mcp/server-card). Every API is listed in the RFC 9727 catalog at https://answer-engine-ready.lovable.app/.well-known/api-catalog.\n\nA score measures how readable a site is for AI crawlers. It does not guarantee that any AI engine will cite the site.",
    "contact": {
      "name": "LLMready",
      "url": "https://answer-engine-ready.lovable.app/docs"
    }
  },
  "externalDocs": {
    "description": "Developer and agent docs",
    "url": "https://answer-engine-ready.lovable.app/docs"
  },
  "servers": [
    {
      "url": "https://answer-engine-ready.lovable.app/api/public/v1"
    }
  ],
  "security": [
    {
      "apiKey": []
    }
  ],
  "tags": [
    {
      "name": "Free",
      "description": "No API key needed"
    },
    {
      "name": "Audits",
      "description": "Run and read AI readiness audits"
    },
    {
      "name": "llms.txt",
      "description": "Generate and validate llms.txt files"
    },
    {
      "name": "Account",
      "description": "Usage and credits"
    }
  ],
  "paths": {
    "/quick-check": {
      "get": {
        "tags": [
          "Free"
        ],
        "operationId": "quickCheck",
        "summary": "Free quick AI search readiness check",
        "description": "Free, no API key. Runs the same live crawl and scoring as a full audit and returns the 0–100 score, grade, category scores, AI crawler access from robots.txt, llms.txt status and the top 3 fixes. Nothing is saved to an account and no report page is created — links.fullAudit opens the full audit. Limits per IP: 10 per minute and 100 per rolling day; repeat checks of the same URL within 10 minutes reuse the last result (cached: true).",
        "security": [],
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 2048,
              "examples": [
                "example.com"
              ]
            },
            "description": "Any public http(s) URL or bare domain"
          }
        ],
        "responses": {
          "200": {
            "description": "Quick check result",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Free quick checks allowed per rolling day (100)",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Quick checks left in the rolling day for this caller",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Policy": {
                "description": "Windows in seconds, e.g. `10;w=60, 100;w=86400`",
                "schema": {
                  "type": "string"
                }
              },
              "X-Quick-Check-Cached": {
                "description": "true when the same URL was checked in the last 10 minutes and that result was reused",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true",
                    "false"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuickCheck"
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid URL",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The site could not be fetched (blocked, timed out or not HTML)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "More than 10 quick checks a minute or 100 a day from this caller. Honor Retry-After.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "The free quick check is at capacity. Honor Retry-After.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Free"
        ],
        "operationId": "quickCheckPost",
        "summary": "Free quick AI search readiness check (JSON body)",
        "description": "Free, no API key. Runs the same live crawl and scoring as a full audit and returns the 0–100 score, grade, category scores, AI crawler access from robots.txt, llms.txt status and the top 3 fixes. Nothing is saved to an account and no report page is created — links.fullAudit opens the full audit. Limits per IP: 10 per minute and 100 per rolling day; repeat checks of the same URL within 10 minutes reuse the last result (cached: true).",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "maxLength": 2048,
                    "examples": [
                      "https://example.com"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Quick check result",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Free quick checks allowed per rolling day (100)",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Quick checks left in the rolling day for this caller",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Policy": {
                "description": "Windows in seconds, e.g. `10;w=60, 100;w=86400`",
                "schema": {
                  "type": "string"
                }
              },
              "X-Quick-Check-Cached": {
                "description": "true when the same URL was checked in the last 10 minutes and that result was reused",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true",
                    "false"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuickCheck"
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid URL",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The site could not be fetched (blocked, timed out or not HTML)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "More than 10 quick checks a minute or 100 a day from this caller. Honor Retry-After.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "The free quick check is at capacity. Honor Retry-After.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/status": {
      "get": {
        "tags": [
          "Free"
        ],
        "operationId": "getStatus",
        "summary": "API status",
        "description": "Liveness check with the API and MCP server versions. No key needed.",
        "security": [],
        "responses": {
          "200": {
            "description": "The API is up",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "status",
                    "time"
                  ],
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "ok"
                      ]
                    },
                    "time": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "api": {
                      "type": "object",
                      "properties": {
                        "version": {
                          "type": "string"
                        },
                        "baseUrl": {
                          "type": "string"
                        },
                        "openapi": {
                          "type": "string"
                        }
                      }
                    },
                    "mcp": {
                      "type": "object",
                      "properties": {
                        "version": {
                          "type": "string",
                          "examples": [
                            "1.2.0"
                          ]
                        },
                        "url": {
                          "type": "string"
                        },
                        "serverCard": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/audits": {
      "post": {
        "tags": [
          "Audits"
        ],
        "operationId": "createAudit",
        "summary": "Audit a URL",
        "description": "Crawls the site live (usually 5–20 seconds) and returns the score, grade, category scores, prioritized fixes and failing checks. The audit is saved to your account and gets a public report URL and badge. Costs 1 credit.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "examples": [
                      "https://example.com"
                    ],
                    "description": "Any public http(s) URL or bare domain"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Audit completed",
            "headers": {
              "X-Credits-Remaining": {
                "description": "Credits left in the current month after this call",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Credits-Included": {
                "description": "Credits included per month",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute per key",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuditSummary"
                }
              }
            }
          },
          "400": {
            "description": "Invalid URL or body",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The key's account is not on Pro",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The site could not be fetched (blocked, timed out or not HTML)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (30/min) or monthly credits exhausted. Honor Retry-After when present.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Audits"
        ],
        "operationId": "listAudits",
        "summary": "List your audits",
        "description": "Most recent first. Costs 0 credits.",
        "parameters": [
          {
            "name": "domain",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter by domain, e.g. example.com"
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Audits",
            "headers": {
              "X-Credits-Remaining": {
                "description": "Credits left in the current month after this call",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Credits-Included": {
                "description": "Credits included per month",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute per key",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "audits"
                  ],
                  "properties": {
                    "audits": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AuditListItem"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The key's account is not on Pro",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (30/min) or monthly credits exhausted. Honor Retry-After when present.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/audits/{id}": {
      "get": {
        "tags": [
          "Audits"
        ],
        "operationId": "getAudit",
        "summary": "Get an audit",
        "description": "Returns a stored audit from your account. Costs 0 credits.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Audit",
            "headers": {
              "X-Credits-Remaining": {
                "description": "Credits left in the current month after this call",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Credits-Included": {
                "description": "Credits included per month",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute per key",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuditSummary"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The key's account is not on Pro",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No audit with that id on your account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (30/min) or monthly credits exhausted. Honor Retry-After when present.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/llms-txt/generate": {
      "post": {
        "tags": [
          "llms.txt"
        ],
        "operationId": "generateLlmsTxt",
        "summary": "Generate llms.txt and llms-full.txt",
        "description": "Crawls the site (up to 14 key pages), then returns a spec-compliant llms.txt and an llms-full.txt with page content as Markdown, plus validation of the generated file. Also stores an audit. Costs 1 credit.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "examples": [
                      "https://example.com"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Generated files",
            "headers": {
              "X-Credits-Remaining": {
                "description": "Credits left in the current month after this call",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Credits-Included": {
                "description": "Credits included per month",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute per key",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GeneratedFiles"
                }
              }
            }
          },
          "400": {
            "description": "Invalid URL or body",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The key's account is not on Pro",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The site could not be fetched",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (30/min) or monthly credits exhausted. Honor Retry-After when present.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/llms-txt/validate": {
      "post": {
        "tags": [
          "llms.txt"
        ],
        "operationId": "validateLlmsTxt",
        "summary": "Validate llms.txt",
        "description": "Validate raw content against the llmstxt.org proposal, or pass a site URL to fetch and validate its live /llms.txt. Costs 0 credits.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "required": [
                      "content"
                    ],
                    "properties": {
                      "content": {
                        "type": "string",
                        "maxLength": 400000
                      }
                    }
                  },
                  {
                    "type": "object",
                    "required": [
                      "url"
                    ],
                    "properties": {
                      "url": {
                        "type": "string",
                        "examples": [
                          "https://example.com"
                        ]
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Validation result",
            "headers": {
              "X-Credits-Remaining": {
                "description": "Credits left in the current month after this call",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Credits-Included": {
                "description": "Credits included per month",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute per key",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Validation"
                }
              }
            }
          },
          "400": {
            "description": "Missing content or url",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The key's account is not on Pro",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Content larger than 400 KB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The live file could not be fetched",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (30/min) or monthly credits exhausted. Honor Retry-After when present.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/usage": {
      "get": {
        "tags": [
          "Account"
        ],
        "operationId": "getUsage",
        "summary": "Credits used this month",
        "description": "Costs 0 credits.",
        "responses": {
          "200": {
            "description": "Usage",
            "headers": {
              "X-Credits-Remaining": {
                "description": "Credits left in the current month after this call",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Credits-Included": {
                "description": "Credits included per month",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute per key",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Usage"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The key's account is not on Pro",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (30/min) or monthly credits exhausted. Honor Retry-After when present.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "lr_…",
        "description": "Create keys at https://answer-engine-ready.lovable.app/dashboard/api (Pro)."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error",
          "message"
        ],
        "properties": {
          "error": {
            "type": "string",
            "description": "Stable error code",
            "enum": [
              "missing_api_key",
              "invalid_api_key",
              "pro_required",
              "rate_limited",
              "quota_exceeded",
              "invalid_request",
              "invalid_json",
              "invalid_url",
              "invalid_id",
              "not_found",
              "site_unreachable",
              "fetch_failed",
              "empty_content",
              "too_large",
              "audit_failed",
              "storage_failed",
              "usage_unavailable",
              "busy",
              "internal_error"
            ]
          },
          "message": {
            "type": "string",
            "description": "Human-readable explanation, safe to show to users"
          }
        }
      },
      "AuditListItem": {
        "type": "object",
        "required": [
          "id",
          "domain",
          "score",
          "grade",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "domain": {
            "type": "string"
          },
          "score": {
            "type": "integer"
          },
          "grade": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "AuditSummary": {
        "type": "object",
        "required": [
          "id",
          "url",
          "domain",
          "score",
          "grade",
          "verified",
          "measuredAt",
          "categories",
          "fixes",
          "failingChecks",
          "bots",
          "llmsTxt",
          "llmsFullTxt",
          "links"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "url": {
            "type": "string",
            "description": "Final URL after redirects"
          },
          "domain": {
            "type": "string"
          },
          "score": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "grade": {
            "type": "string",
            "enum": [
              "A+",
              "A",
              "A-",
              "B+",
              "B",
              "B-",
              "C+",
              "C",
              "C-",
              "D",
              "F"
            ]
          },
          "verified": {
            "type": "boolean",
            "description": "Score is 80 or higher — eligible for the Verified AI-Ready badge"
          },
          "measuredAt": {
            "type": "string",
            "format": "date-time"
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string",
                  "enum": [
                    "bot_access",
                    "extractability",
                    "metadata",
                    "citation"
                  ]
                },
                "label": {
                  "type": "string"
                },
                "score": {
                  "type": "integer"
                },
                "weight": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 1,
                  "description": "Share of the overall score, e.g. 0.3 for 30%"
                }
              }
            }
          },
          "fixes": {
            "type": "array",
            "description": "Highest-impact fixes first",
            "items": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string"
                },
                "category": {
                  "type": "string"
                },
                "impact": {
                  "type": "integer",
                  "description": "Estimated score points gained"
                },
                "fix": {
                  "type": "string"
                }
              }
            }
          },
          "failingChecks": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "category": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "warn",
                    "fail",
                    "info"
                  ]
                },
                "detail": {
                  "type": "string"
                },
                "fix": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              }
            }
          },
          "bots": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "operator": {
                  "type": "string"
                },
                "purpose": {
                  "type": "string"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "allowed",
                    "partial",
                    "blocked",
                    "unknown"
                  ]
                }
              }
            }
          },
          "llmsTxt": {
            "type": "object",
            "properties": {
              "found": {
                "type": "boolean"
              },
              "url": {
                "type": "string"
              },
              "valid": {
                "type": [
                  "boolean",
                  "null"
                ]
              },
              "errors": {
                "type": "integer"
              },
              "warnings": {
                "type": "integer"
              }
            }
          },
          "llmsFullTxt": {
            "type": "object",
            "properties": {
              "found": {
                "type": "boolean"
              },
              "url": {
                "type": "string"
              }
            }
          },
          "links": {
            "type": "object",
            "properties": {
              "report": {
                "type": "string",
                "description": "Public, shareable report page"
              },
              "badge": {
                "type": "string",
                "description": "SVG badge with the live score"
              },
              "badgeEmbedHtml": {
                "type": "string",
                "description": "Copy-paste HTML linking the badge to the report"
              },
              "scorecardImage": {
                "type": "string",
                "description": "1200×630 social scorecard image"
              }
            }
          }
        }
      },
      "Validation": {
        "type": "object",
        "required": [
          "valid",
          "linkCount",
          "errorCount",
          "warningCount",
          "issues"
        ],
        "properties": {
          "url": {
            "type": "string",
            "description": "Present when a live file was fetched"
          },
          "valid": {
            "type": "boolean"
          },
          "title": {
            "type": [
              "string",
              "null"
            ]
          },
          "summary": {
            "type": [
              "string",
              "null"
            ]
          },
          "sections": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "links": {
                  "type": "integer"
                }
              }
            }
          },
          "linkCount": {
            "type": "integer"
          },
          "errorCount": {
            "type": "integer"
          },
          "warningCount": {
            "type": "integer"
          },
          "bytes": {
            "type": "integer"
          },
          "issues": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "line": {
                  "type": "integer"
                },
                "severity": {
                  "type": "string",
                  "enum": [
                    "error",
                    "warning",
                    "info"
                  ]
                },
                "code": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "GeneratedFiles": {
        "type": "object",
        "required": [
          "auditId",
          "domain",
          "llmsTxt",
          "llmsFullTxt",
          "pagesUsed",
          "validation"
        ],
        "properties": {
          "auditId": {
            "type": "string",
            "format": "uuid"
          },
          "domain": {
            "type": "string"
          },
          "llmsTxt": {
            "type": "string"
          },
          "llmsFullTxt": {
            "type": "string"
          },
          "pagesUsed": {
            "type": "integer"
          },
          "validation": {
            "$ref": "#/components/schemas/Validation"
          }
        }
      },
      "QuickCheck": {
        "type": "object",
        "required": [
          "url",
          "finalUrl",
          "domain",
          "score",
          "grade",
          "verified",
          "measuredAt",
          "cached",
          "categories",
          "topFixes",
          "bots",
          "llmsTxt",
          "llmsFullTxt",
          "links",
          "limits",
          "note"
        ],
        "properties": {
          "url": {
            "type": "string",
            "description": "Normalized URL that was checked"
          },
          "finalUrl": {
            "type": "string",
            "description": "URL after redirects"
          },
          "domain": {
            "type": "string"
          },
          "score": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "grade": {
            "type": "string",
            "examples": [
              "A+",
              "B",
              "F"
            ]
          },
          "verified": {
            "type": "boolean",
            "description": "Score is high enough for the Verified AI-Ready badge"
          },
          "measuredAt": {
            "type": "string",
            "format": "date-time"
          },
          "cached": {
            "type": "boolean",
            "description": "Result reused from a check of the same URL in the last 10 minutes"
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string",
                  "enum": [
                    "bot_access",
                    "extractability",
                    "metadata",
                    "citation"
                  ]
                },
                "label": {
                  "type": "string"
                },
                "score": {
                  "type": "integer"
                },
                "weight": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 1,
                  "description": "Share of the overall score, e.g. 0.3 for 30%"
                }
              }
            }
          },
          "topFixes": {
            "type": "array",
            "maxItems": 3,
            "items": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string"
                },
                "category": {
                  "type": "string"
                },
                "impact": {
                  "type": "integer",
                  "description": "Estimated score points gained"
                },
                "fix": {
                  "type": "string"
                }
              }
            }
          },
          "bots": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "operator": {
                  "type": "string"
                },
                "purpose": {
                  "type": "string"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "allowed",
                    "partial",
                    "blocked",
                    "unknown"
                  ]
                }
              }
            }
          },
          "llmsTxt": {
            "type": "object",
            "properties": {
              "found": {
                "type": "boolean"
              },
              "url": {
                "type": "string"
              },
              "valid": {
                "type": [
                  "boolean",
                  "null"
                ]
              }
            }
          },
          "llmsFullTxt": {
            "type": "object",
            "properties": {
              "found": {
                "type": "boolean"
              },
              "url": {
                "type": "string"
              }
            }
          },
          "links": {
            "type": "object",
            "properties": {
              "fullAudit": {
                "type": "string",
                "description": "Opens the full audit (every check, shareable report, generated llms.txt) on LLMready"
              },
              "docs": {
                "type": "string"
              }
            }
          },
          "limits": {
            "type": "object",
            "properties": {
              "perMinute": {
                "type": "integer"
              },
              "perDay": {
                "type": "integer"
              },
              "remainingToday": {
                "type": "integer"
              }
            }
          },
          "note": {
            "type": "string",
            "description": "A score measures readability for AI crawlers; it does not guarantee citations"
          }
        }
      },
      "Usage": {
        "type": "object",
        "required": [
          "periodStart",
          "periodEnd",
          "creditsIncluded",
          "creditsUsed",
          "creditsRemaining",
          "rateLimitPerMinute"
        ],
        "properties": {
          "periodStart": {
            "type": "string",
            "format": "date-time"
          },
          "periodEnd": {
            "type": "string",
            "format": "date-time"
          },
          "creditsIncluded": {
            "type": "integer"
          },
          "creditsUsed": {
            "type": "integer"
          },
          "creditsRemaining": {
            "type": "integer"
          },
          "rateLimitPerMinute": {
            "type": "integer"
          }
        }
      }
    }
  }
}