{
  "openapi": "3.1.0",
  "info": {
    "title": "Lightmark Audit API",
    "version": "1.0.0",
    "description": "Read stored agent reports or explicitly request a bounded public site crawl."
  },
  "servers": [
    {
      "url": "https://www.lightmark.app"
    }
  ],
  "paths": {
    "/api/v1/agentic/report": {
      "get": {
        "operationId": "getAgenticReport",
        "summary": "Read a stored domain-level agent audit",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Public domain or URL. Paths and queries are removed."
          }
        ],
        "responses": {
          "200": {
            "description": "Latest provider report, possibly with partial analysis",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Report"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "headers": {
              "RateLimit": {
                "description": "Remaining requests and reset delay.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Local report-read quota policy.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Problem"
          },
          "404": {
            "$ref": "#/components/responses/Problem"
          },
          "429": {
            "description": "Provider rate limit; honor Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Remaining requests and reset delay.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Local report-read quota policy.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/Problem"
          },
          "405": {
            "$ref": "#/components/responses/Problem"
          }
        },
        "description": "Read the latest stored Ora Essentials report for a public domain. Does not start a scan. Public and keyless; provider quotas apply. Results may be partial and retain their scan timestamp. Report reads allow 120 requests per IP per 60-second fixed window. RateLimit headers describe the local quota; upstream provider quotas remain separate."
      }
    },
    "/api/site-audit": {
      "post": {
        "operationId": "crawlPublicSite",
        "summary": "Crawl a bounded sample of public pages",
        "description": "Explicitly starts a read-only HTTP crawl. Same-origin, default-port, query-free IPv4 URLs only. Respects robots.txt; no browser rendering. At most 25 pages, 3 sitemap files and 40 seconds. Returns coverage and findings, not a search ranking score.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "description": "Public HTTP(S) site URL without query or credentials."
                  },
                  "maxPages": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 25,
                    "default": 25
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Crawl sample, possibly limited by time, page count or fetch failures. Inspect coverage, warnings and per-page errors.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "version": {
                      "type": "integer"
                    },
                    "origin": {
                      "type": "string"
                    },
                    "scannedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "pages": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "findings": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "coverage": {
                      "type": "object"
                    },
                    "warnings": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "skipped": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "limitations": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input"
          },
          "403": {
            "description": "Browser origin rejected"
          },
          "422": {
            "description": "Could not establish crawl permission or fetch site"
          }
        }
      }
    }
  },
  "components": {
    "responses": {
      "Problem": {
        "description": "Report unavailable",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      }
    },
    "schemas": {
      "Problem": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "detail": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "resolution": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          }
        },
        "required": [
          "type",
          "title",
          "status",
          "code",
          "detail",
          "resolution"
        ]
      },
      "Bucket": {
        "type": "object",
        "properties": {
          "earned": {
            "type": "number"
          },
          "available": {
            "type": "number"
          },
          "passing": {
            "type": "integer"
          },
          "total": {
            "type": "integer"
          }
        }
      },
      "Check": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "group": {
            "enum": [
              "essential",
              "recommended",
              "bonus"
            ],
            "type": "string"
          },
          "status": {
            "enum": [
              "pass",
              "partial",
              "fail",
              "na"
            ],
            "type": "string"
          },
          "fraction": {
            "type": [
              "number",
              "null"
            ]
          },
          "gain": {
            "type": [
              "number",
              "null"
            ]
          },
          "evidence": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "layer": {
                  "type": "string"
                },
                "status": {
                  "type": "string"
                },
                "details": {
                  "type": "string"
                },
                "recommendation": {
                  "type": "string"
                }
              }
            }
          }
        },
        "required": [
          "id",
          "title",
          "group",
          "status",
          "evidence"
        ]
      },
      "Report": {
        "type": "object",
        "required": [
          "version",
          "provider",
          "domain",
          "url",
          "score",
          "analysisStatus",
          "checks",
          "issues",
          "limitations"
        ],
        "properties": {
          "version": {
            "const": 1,
            "type": "integer"
          },
          "provider": {
            "const": "Ora",
            "type": "string"
          },
          "contractVersion": {
            "type": [
              "string",
              "null"
            ]
          },
          "domain": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "reportUrl": {
            "type": "string"
          },
          "fetchedAt": {
            "type": "string"
          },
          "scannedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "score": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 100
          },
          "label": {
            "type": "string"
          },
          "analysisStatus": {
            "type": "string"
          },
          "pendingChecks": {
            "type": "array",
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "object",
                  "additionalProperties": true
                }
              ]
            }
          },
          "servedFromCache": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "essential": {
            "$ref": "#/components/schemas/Bucket"
          },
          "recommended": {
            "$ref": "#/components/schemas/Bucket"
          },
          "bonusPoints": {
            "type": "number"
          },
          "activeSurfaces": {
            "type": "array",
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "object",
                  "additionalProperties": true
                }
              ]
            }
          },
          "checks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Check"
            }
          },
          "issues": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Check"
            }
          },
          "limitations": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      }
    }
  }
}
