{
  "openapi": "3.0.3",
  "info": {
    "title": "CourtScan public read-only data",
    "version": "1.0.0",
    "description": "Public research data, not legal advice. SafeLegalAI adaptations under CC BY 4.0; retain record attribution and describe changes. Monitor package initially PENDING; check actual status. No authentication, write routes or payment API.",
    "license": {
      "name": "SafeLegalAI adapted data: CC BY 4.0; original documents retain own rights",
      "url": "https://creativecommons.org/licenses/by/4.0/"
    }
  },
  "servers": [
    {
      "url": "/"
    }
  ],
  "security": [],
  "paths": {
    "/data/court-rules.json": {
      "get": {
        "operationId": "court_rules",
        "summary": "Read court-rules",
        "description": "Revalidate once per visit or daily batch. Honor conditional responses and Retry-After. Never infer freshness from HTTP 200 alone. No guaranteed rate quota.",
        "responses": {
          "200": {
            "description": "Public JSON. Validate schema, freshness and matching run IDs before filing use.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string"
                },
                "description": "public, max-age=0, must-revalidate"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CourtRules"
                }
              }
            }
          },
          "304": {
            "description": "Not modified if conditional requests are supported by the host."
          },
          "404": {
            "description": "Unavailable file; may be HTML."
          },
          "429": {
            "description": "Host throttling; honor Retry-After and back off."
          },
          "503": {
            "description": "Host/upstream failure; may be HTML. Use fallback only for research."
          }
        }
      }
    },
    "/data/source-status.json": {
      "get": {
        "operationId": "source_status",
        "summary": "Read source-status",
        "description": "Revalidate once per visit or daily batch. Honor conditional responses and Retry-After. Never infer freshness from HTTP 200 alone. No guaranteed rate quota.",
        "responses": {
          "200": {
            "description": "Public JSON. Validate schema, freshness and matching run IDs before filing use.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string"
                },
                "description": "public, max-age=0, must-revalidate"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SourceStatus"
                }
              }
            }
          },
          "304": {
            "description": "Not modified if conditional requests are supported by the host."
          },
          "404": {
            "description": "Unavailable file; may be HTML."
          },
          "429": {
            "description": "Host throttling; honor Retry-After and back off."
          },
          "503": {
            "description": "Host/upstream failure; may be HTML. Use fallback only for research."
          }
        }
      }
    },
    "/data/source-changelog.json": {
      "get": {
        "operationId": "source_changelog",
        "summary": "Read source-changelog",
        "description": "Revalidate once per visit or daily batch. Honor conditional responses and Retry-After. Never infer freshness from HTTP 200 alone. No guaranteed rate quota.",
        "responses": {
          "200": {
            "description": "Public JSON. Validate schema, freshness and matching run IDs before filing use.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string"
                },
                "description": "public, max-age=0, must-revalidate"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Changelog"
                }
              }
            }
          },
          "304": {
            "description": "Not modified if conditional requests are supported by the host."
          },
          "404": {
            "description": "Unavailable file; may be HTML."
          },
          "429": {
            "description": "Host throttling; honor Retry-After and back off."
          },
          "503": {
            "description": "Host/upstream failure; may be HTML. Use fallback only for research."
          }
        }
      }
    },
    "/data/practice-guides.json": {
      "get": {
        "operationId": "practice_guides",
        "summary": "Read practice-guides",
        "description": "Revalidate once per visit or daily batch. Honor conditional responses and Retry-After. Never infer freshness from HTTP 200 alone. No guaranteed rate quota.",
        "responses": {
          "200": {
            "description": "Public JSON. Validate schema, freshness and matching run IDs before filing use.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string"
                },
                "description": "public, max-age=0, must-revalidate"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PracticeGuides"
                }
              }
            }
          },
          "304": {
            "description": "Not modified if conditional requests are supported by the host."
          },
          "404": {
            "description": "Unavailable file; may be HTML."
          },
          "429": {
            "description": "Host throttling; honor Retry-After and back off."
          },
          "503": {
            "description": "Host/upstream failure; may be HTML. Use fallback only for research."
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "SourceMonitoring": {
        "type": "object",
        "required": [
          "status",
          "reviewRequired",
          "checkedAt",
          "sourceUrls"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "PENDING",
              "BASELINED",
              "UNCHANGED",
              "CHANGED",
              "ERROR"
            ]
          },
          "reviewRequired": {
            "type": "boolean",
            "description": "Sticky flag. Unchanged checks never clear it."
          },
          "checkedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "sourceUrls": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri"
            }
          },
          "textHashes": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "nullable": true
            }
          }
        }
      },
      "Record": {
        "type": "object",
        "required": [
          "id",
          "title",
          "verificationLabel"
        ],
        "additionalProperties": true,
        "properties": {
          "id": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "summary": {
            "type": "string",
            "nullable": true
          },
          "sourceUrl": {
            "type": "string",
            "nullable": true
          },
          "sourceLinks": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "status": {
            "type": "string",
            "description": "Legal metadata preserved by monitor; not an automated legal conclusion."
          },
          "verificationLabel": {
            "type": "string",
            "enum": [
              "PRIMARY_SOURCE_REVIEWED",
              "PUBLISHER_REPORTED",
              "REVIEW_REQUIRED"
            ]
          },
          "primaryReview": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "Historical review; never automatically renewed."
          },
          "actionProfile": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "properties": {
              "generationEligible": {
                "type": "boolean"
              }
            }
          },
          "sourceMonitoring": {
            "$ref": "#/components/schemas/SourceMonitoring"
          }
        }
      },
      "CourtRules": {
        "type": "object",
        "required": [
          "schema",
          "records",
          "generatedAt",
          "datasetDate",
          "sources"
        ],
        "properties": {
          "schema": {
            "type": "string"
          },
          "generatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "datasetDate": {
            "type": "string",
            "format": "date"
          },
          "monitorRunId": {
            "type": "string",
            "nullable": true
          },
          "offlineFallback": {
            "type": "boolean",
            "description": "If true, new filing language must be disabled."
          },
          "counts": {
            "type": "object",
            "additionalProperties": true
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Record"
            }
          }
        }
      },
      "Source": {
        "type": "object",
        "required": [
          "sourceUrl",
          "status",
          "checkedAt"
        ],
        "properties": {
          "sourceUrl": {
            "type": "string",
            "format": "uri"
          },
          "resolvedUrl": {
            "type": "string",
            "format": "uri"
          },
          "status": {
            "type": "string",
            "enum": [
              "PENDING",
              "BASELINED",
              "UNCHANGED",
              "CHANGED",
              "ERROR"
            ]
          },
          "checkedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "lastSuccessAt": {
            "type": "string",
            "format": "date-time"
          },
          "hash": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$"
          },
          "error": {
            "type": "string"
          },
          "reviewRequired": {
            "type": "boolean"
          }
        }
      },
      "SourceStatus": {
        "type": "object",
        "required": [
          "schema",
          "status",
          "generatedAt",
          "sources",
          "counts"
        ],
        "properties": {
          "schema": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "PENDING",
              "OK",
              "PARTIAL_ERROR"
            ]
          },
          "generatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "runId": {
            "type": "string",
            "nullable": true
          },
          "freshnessHours": {
            "type": "integer",
            "enum": [
              48
            ]
          },
          "counts": {
            "type": "object",
            "required": [
              "allowlisted",
              "monitored",
              "pending",
              "skipped",
              "errors"
            ],
            "properties": {
              "allowlisted": {
                "type": "integer",
                "minimum": 0
              },
              "monitored": {
                "type": "integer",
                "minimum": 0
              },
              "pending": {
                "type": "integer",
                "minimum": 0
              },
              "skipped": {
                "type": "integer",
                "minimum": 0
              },
              "errors": {
                "type": "integer",
                "minimum": 0
              }
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Source"
            }
          },
          "skipped": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "sourceUrl": {
                  "type": "string"
                },
                "reason": {
                  "type": "string"
                }
              }
            }
          },
          "limitations": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "Event": {
        "type": "object",
        "required": [
          "id",
          "sourceUrl",
          "time",
          "status",
          "previousHash",
          "newHash",
          "diff"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "sourceUrl": {
            "type": "string",
            "format": "uri"
          },
          "resolvedUrl": {
            "type": "string",
            "format": "uri"
          },
          "time": {
            "type": "string",
            "format": "date-time"
          },
          "status": {
            "type": "string",
            "enum": [
              "BASELINED",
              "CHANGED"
            ]
          },
          "previousHash": {
            "type": "string",
            "nullable": true
          },
          "newHash": {
            "type": "string"
          },
          "diff": {
            "type": "string",
            "description": "Unified diff of normalized extracted text; untrusted text, escape on display.",
            "nullable": true
          },
          "snapshot": {
            "type": "string",
            "description": "Path in public monitor repository, not in frontend dist.",
            "nullable": true
          },
          "diffPolicy": {
            "type": "string",
            "description": "HASH_ONLY_RIGHTS_UNCLEARED means only hashes are published; null textual diff never means unchanged."
          }
        }
      },
      "Changelog": {
        "type": "object",
        "required": [
          "schema",
          "generatedAt",
          "events"
        ],
        "properties": {
          "schema": {
            "type": "string"
          },
          "generatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "runId": {
            "type": "string",
            "nullable": true
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Event"
            }
          }
        }
      },
      "PracticeGuides": {
        "type": "object",
        "required": [
          "guides"
        ],
        "additionalProperties": true,
        "properties": {
          "guides": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "id",
                "title",
                "summary",
                "steps",
                "sources"
              ],
              "properties": {
                "id": {
                  "type": "string"
                },
                "title": {
                  "type": "string"
                },
                "summary": {
                  "type": "string"
                },
                "steps": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "sources": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "url": {
                        "type": "string",
                        "format": "uri"
                      },
                      "title": {
                        "type": "string"
                      },
                      "checkedAt": {
                        "type": "string",
                        "nullable": true
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
