{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/andrewsfreebies-com/json-schema/andrewsfreebies-com-freshness-response-schema.json",
  "title": "FreshnessResponse",
  "description": "Latest official verification event per actionable candidate, on-schedule coverage, explicit evidence resolution, and observed scheduler heartbeat recency. Record catalog status remains separate from audit outcome.",
  "x-generated": "2026-11-01",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/andrewsfreebies-com-openapi.json#/components/schemas/FreshnessResponse",
  "type": "object",
  "required": [
    "api_version",
    "catalog_scope",
    "filters",
    "totals",
    "by_freshness",
    "by_evidence_resolution",
    "by_outcome",
    "evidence_resolution_interpretation",
    "operations",
    "items",
    "policy"
  ],
  "properties": {
    "api_version": {
      "type": "string",
      "const": "2.1"
    },
    "catalog_scope": {
      "type": "string",
      "description": "Non-directory trials and redeemable savings with incorporated first-party catalog evidence; directory-only leads and public-service records are excluded."
    },
    "filters": {
      "type": "object"
    },
    "totals": {
      "type": "object",
      "properties": {
        "catalog_records": {
          "type": "integer",
          "description": "Backward-compatible count of records inside catalog_scope, not the complete public catalog."
        },
        "records_checked": {
          "type": "integer",
          "description": "Records with at least one accepted official verification event."
        },
        "records_current": {
          "type": "integer",
          "description": "Records still inside their published verification cadence; current does not mean confirmed."
        },
        "records_overdue": {
          "type": "integer"
        },
        "records_unchecked": {
          "type": "integer"
        },
        "records_with_supporting_evidence": {
          "type": "integer",
          "description": "Records whose latest official outcome is confirmed-exact or confirmed-partial."
        },
        "coverage_percent": {
          "type": "number",
          "minimum": 0,
          "maximum": 100,
          "description": "Current records divided by catalog records; this is cadence coverage, not a confirmation rate."
        },
        "attempted_coverage_percent": {
          "type": "number",
          "minimum": 0,
          "maximum": 100,
          "description": "Records checked at least once divided by catalog records."
        },
        "supporting_evidence_percent": {
          "type": "number",
          "minimum": 0,
          "maximum": 100,
          "description": "Records with confirmed-exact or confirmed-partial latest evidence divided by catalog records."
        }
      }
    },
    "by_freshness": {
      "type": "object",
      "properties": {
        "current": {
          "type": "integer"
        },
        "overdue": {
          "type": "integer"
        },
        "unchecked": {
          "type": "integer"
        }
      }
    },
    "by_evidence_resolution": {
      "type": "object",
      "description": "Mutually exclusive evidence groups across the current actionable catalog.",
      "properties": {
        "supporting": {
          "type": "integer",
          "description": "confirmed-exact plus confirmed-partial."
        },
        "review_alert": {
          "type": "integer",
          "description": "terms-changed, explicitly-expired, moved, or not-found; requires review and never automatically rewrites the catalog."
        },
        "inconclusive": {
          "type": "integer",
          "description": "blocked, fetch-error, or unknown; establishes neither validity nor expiration."
        },
        "unchecked": {
          "type": "integer"
        }
      }
    },
    "by_outcome": {
      "type": "object",
      "description": "Counts for all nine conservative outcomes.",
      "additionalProperties": {
        "type": "integer"
      }
    },
    "evidence_resolution_interpretation": {
      "type": "string"
    },
    "oldest_checked_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    },
    "newest_checked_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    },
    "operations": {
      "type": "object",
      "properties": {
        "policy_version": {
          "type": "string"
        },
        "heartbeat_target_hours": {
          "type": "number"
        },
        "heartbeat_alert_after_hours": {
          "type": "number"
        },
        "latest_run_completed_at": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time"
        },
        "latest_heartbeat_completed_at": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time",
          "description": "Latest heartbeat of any origin, including manual checks."
        },
        "latest_scheduled_heartbeat_completed_at": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time",
          "description": "Latest heartbeat produced by the configured scheduler."
        },
        "heartbeat_basis": {
          "type": "string",
          "const": "scheduled"
        },
        "heartbeat_age_hours": {
          "type": [
            "number",
            "null"
          ],
          "description": "Age of the latest scheduler-origin heartbeat."
        },
        "heartbeat_status": {
          "type": "string",
          "enum": [
            "awaiting-first-run",
            "on-schedule",
            "late"
          ],
          "description": "Scheduler liveness; manual heartbeats cannot make this on-schedule."
        }
      }
    },
    "items": {
      "type": "array",
      "description": "Verification events include a schedule object with status, cadence_days, and due_at.",
      "items": {
        "$ref": "#/$defs/VerificationEvent"
      }
    },
    "policy": {
      "type": "string",
      "description": "The latest-state projection is review evidence and never automatically changes the catalog."
    }
  },
  "$defs": {
    "VerificationEvent": {
      "allOf": [
        {
          "$ref": "#/$defs/VerificationEventInput"
        },
        {
          "type": "object",
          "properties": {
            "id": {
              "type": "string",
              "format": "uuid"
            },
            "run_id": {
              "type": "string",
              "format": "uuid"
            },
            "created_at": {
              "type": "string",
              "format": "date-time"
            },
            "run": {
              "type": "object",
              "properties": {
                "schema_version": {
                  "type": "string"
                },
                "generated_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "method": {
                  "type": "string"
                },
                "verifier": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "started_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "completed_at": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          }
        }
      ]
    },
    "VerificationEventInput": {
      "type": "object",
      "required": [
        "record_id",
        "record_type",
        "url",
        "url_role",
        "outcome",
        "url_health",
        "offer_existence",
        "terms_match",
        "redemption_path",
        "evidence_quality",
        "freshness"
      ],
      "properties": {
        "record_id": {
          "type": "string",
          "maxLength": 200
        },
        "record_type": {
          "type": "string",
          "enum": [
            "trial",
            "entitlement"
          ]
        },
        "category": {
          "type": "string",
          "maxLength": 120,
          "description": "Optional; when present it must match the canonical record category."
        },
        "url": {
          "type": "string",
          "format": "uri",
          "maxLength": 2048
        },
        "url_role": {
          "type": "string",
          "maxLength": 80
        },
        "checked_at": {
          "type": "string",
          "format": "date-time",
          "description": "Defaults to generated_at."
        },
        "method": {
          "type": "string",
          "maxLength": 100,
          "description": "Defaults to run.method."
        },
        "outcome": {
          "$ref": "#/$defs/VerificationOutcome"
        },
        "content_hash": {
          "type": "string",
          "maxLength": 256
        },
        "evidence_excerpt": {
          "type": "string",
          "maxLength": 2000
        },
        "matched_fields": {
          "type": "array",
          "maxItems": 100,
          "items": {
            "type": "string",
            "maxLength": 100
          }
        },
        "unmatched_fields": {
          "type": "array",
          "maxItems": 100,
          "items": {
            "type": "string",
            "maxLength": 100
          }
        },
        "url_health": {
          "type": "object",
          "description": "Structured status, redirect, and reachability observations.",
          "additionalProperties": true
        },
        "offer_existence": {
          "type": "object",
          "description": "Structured evidence for whether the provider currently describes the offer.",
          "additionalProperties": true
        },
        "terms_match": {
          "type": "object",
          "description": "Matched, unmatched, and contradicted normalized fields.",
          "additionalProperties": true
        },
        "redemption_path": {
          "type": "object",
          "description": "Structured activation, application, or claim-path result.",
          "additionalProperties": true
        },
        "evidence_quality": {
          "type": "object",
          "description": "Evidence ownership, authority, and sufficiency.",
          "additionalProperties": true
        },
        "freshness": {
          "type": "object",
          "description": "Audit age and next-check scheduling fields.",
          "additionalProperties": true
        }
      }
    },
    "VerificationOutcome": {
      "type": "string",
      "enum": [
        "confirmed-exact",
        "confirmed-partial",
        "terms-changed",
        "explicitly-expired",
        "moved",
        "blocked",
        "fetch-error",
        "not-found",
        "unknown"
      ],
      "description": "Conservative field-level audit result. blocked, fetch-error, not-found, and unknown do not establish expiration."
    }
  }
}