{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://toolbelt.utlyze.com/data/dataset-options.schema.json",
  "title": "Toolbelt datasets: provider content, catalog counts and public access conditions",
  "description": "Public reference data. The feed describes providers and their published terms; it carries no account, key or test state.",
  "type": "object",
  "required": ["schema_version", "updated_at", "access_reviewed_on", "scope", "summary", "provider_groups", "access_types", "count_basis", "listed_scope", "providers", "service_apis"],
  "properties": {
    "$schema": {"type": "string", "format": "uri"},
    "schema_version": {"const": "2.0"},
    "updated_at": {"type": "string", "format": "date-time"},
    "access_reviewed_on": {"type": "string", "format": "date", "description": "Date the access terms were last read from official provider pages."},
    "scope": {"type": "string", "minLength": 1},
    "summary": {
      "type": "object",
      "required": ["data_providers", "providers_by_group", "datasets_listed", "providers_with_catalog_total", "providers_single_source", "providers_catalog_not_counted", "providers_by_access_type", "datasets_with_own_conditions", "service_apis"],
      "properties": {
        "data_providers": {"type": "integer", "minimum": 0},
        "providers_by_group": {
          "type": "object",
          "required": ["public_data", "platform_data"],
          "properties": {
            "public_data": {"type": "integer", "minimum": 0},
            "platform_data": {"type": "integer", "minimum": 0}
          },
          "additionalProperties": false
        },
        "datasets_listed": {"type": "integer", "minimum": 0, "description": "Dataset families listed in this feed. Not a total of what the providers publish."},
        "providers_with_catalog_total": {"type": "integer", "minimum": 0},
        "providers_single_source": {"type": "integer", "minimum": 0},
        "providers_catalog_not_counted": {"type": "integer", "minimum": 0},
        "providers_by_access_type": {
          "type": "object",
          "required": ["open", "free_key", "application", "paid"],
          "properties": {
            "open": {"type": "integer", "minimum": 0},
            "free_key": {"type": "integer", "minimum": 0},
            "application": {"type": "integer", "minimum": 0},
            "paid": {"type": "integer", "minimum": 0}
          },
          "additionalProperties": false
        },
        "datasets_with_own_conditions": {"type": "integer", "minimum": 0},
        "service_apis": {"type": "integer", "minimum": 0}
      },
      "additionalProperties": false
    },
    "provider_groups": {
      "type": "object",
      "required": ["public_data", "platform_data"],
      "additionalProperties": {"$ref": "#/$defs/term"}
    },
    "access_types": {
      "type": "object",
      "required": ["open", "free_key", "application", "paid"],
      "additionalProperties": {"$ref": "#/$defs/term"}
    },
    "count_basis": {
      "type": "object",
      "required": ["official_count", "single_source", "not_counted"],
      "additionalProperties": {"type": "string", "minLength": 1}
    },
    "listed_scope": {
      "type": "object",
      "required": ["complete", "grouped", "selected"],
      "additionalProperties": {"type": "string", "minLength": 1}
    },
    "providers": {"type": "array", "items": {"$ref": "#/$defs/provider"}},
    "service_apis": {
      "type": "object",
      "required": ["note", "apis"],
      "properties": {
        "note": {"type": "string", "minLength": 1},
        "apis": {"type": "array", "items": {"$ref": "#/$defs/service"}}
      },
      "additionalProperties": false
    }
  },
  "additionalProperties": false,
  "$defs": {
    "geography": {
      "type": "object",
      "description": "Evidence-based declared geographic scope, not tested row coverage. Missing or empty detail remains unconfirmed. National/global coverage can include subdivisions; local areas never imply complete state or country coverage. Countries and subdivisions constrain the declared scope when present. Provider metadata is not inherited by dataset families.",
      "required": ["scope"],
      "properties": {
        "scope": {"enum": ["global", "national", "regional", "local", "unknown"]},
        "countries": {"type": "array", "items": {"type": "string", "pattern": "^[A-Z]{2}$"}, "description": "Covered ISO 3166-1 alpha-2 countries. Empty is unknown unless scope explicitly declares global coverage."},
        "subdivisions": {"type": "array", "items": {"type": "string", "pattern": "^[A-Z]{2}-[A-Z0-9]{1,3}$"}, "description": "Covered ISO 3166-2 subdivisions. A local area's parent subdivision identifies its location, not statewide coverage."},
        "areas": {"type": "array", "items": {"type": "string"}, "description": "Named covered areas interpreted with country/subdivision context; bare names do not establish identity."},
        "summary": {"type": "string"},
        "source_urls": {"type": "array", "items": {"type": "string", "format": "uri"}, "description": "Public source evidence for this coverage; never account or query receipts."}
      },
      "additionalProperties": false
    },
    "strings": {"type": "array", "minItems": 1, "items": {"type": "string", "minLength": 1}},
    "term": {
      "type": "object",
      "required": ["label", "meaning"],
      "properties": {"label": {"type": "string", "minLength": 1}, "meaning": {"type": "string", "minLength": 1}},
      "additionalProperties": false
    },
    "access_type": {"enum": ["open", "free_key", "application", "paid"]},
    "link": {
      "type": "object",
      "required": ["label", "url"],
      "properties": {"label": {"type": "string", "minLength": 1}, "url": {"type": "string", "format": "uri"}},
      "additionalProperties": false
    },
    "access": {
      "type": "object",
      "description": "The provider's published access conditions, read from the official sources listed.",
      "required": ["types", "summary", "steps", "restrictions", "links", "sources", "checked_on"],
      "properties": {
        "types": {"type": "array", "minItems": 1, "uniqueItems": true, "items": {"$ref": "#/$defs/access_type"}},
        "summary": {"type": "string", "minLength": 1},
        "cost": {"type": "string", "minLength": 1},
        "steps": {"$ref": "#/$defs/strings"},
        "restrictions": {"type": "array", "items": {"type": "string", "minLength": 1}},
        "links": {"type": "array", "minItems": 1, "items": {"$ref": "#/$defs/link"}},
        "sources": {"type": "array", "minItems": 1, "items": {"type": "string", "format": "uri"}},
        "checked_on": {"type": "string", "format": "date"}
      },
      "additionalProperties": false
    },
    "catalog": {
      "type": "object",
      "required": ["url", "total", "unit", "basis", "note", "listed", "listed_note", "checked_on"],
      "properties": {
        "url": {"type": "string", "format": "uri", "description": "The provider's own full catalog."},
        "total": {"type": ["integer", "null"], "minimum": 1, "description": "Items in the provider's catalog, in the unit given. Null when the provider states no total and it has not been counted."},
        "unit": {"type": "string", "minLength": 1},
        "basis": {"enum": ["official_count", "single_source", "not_counted"]},
        "note": {"type": "string", "minLength": 1},
        "listed": {"enum": ["complete", "grouped", "selected"], "description": "How the datasets listed here relate to the provider's catalog."},
        "listed_note": {"type": "string", "minLength": 1},
        "checked_on": {"type": "string", "format": "date"},
        "source_url": {"type": "string", "format": "uri"},
        "scale": {
          "type": "object",
          "required": ["text", "source_url", "checked_on"],
          "properties": {
            "text": {"type": "string", "minLength": 1},
            "source_url": {"type": "string", "format": "uri"},
            "checked_on": {"type": "string", "format": "date"}
          },
          "additionalProperties": false
        }
      },
      "additionalProperties": false
    },
    "dataset": {
      "type": "object",
      "required": ["id", "name", "description", "use_cases", "industries", "docs"],
      "properties": {
        "id": {"type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$"},
        "name": {"type": "string", "minLength": 1},
        "description": {"type": "string", "minLength": 1},
        "use_cases": {"$ref": "#/$defs/strings"},
        "industries": {"$ref": "#/$defs/strings"},
        "docs": {"type": "string", "format": "uri"},
        "geography": {"$ref": "#/$defs/geography"},
        "aliases": {"type": "array", "items": {"type": "string"}},
        "field_names": {"type": "array", "items": {"type": "string"}},
        "coverage_notes": {"type": "array", "items": {"type": "string"}},
        "time_coverage": {"type": "string", "description": "Published period or update scope; empty is unconfirmed."},
        "access": {"$ref": "#/$defs/access", "description": "Present only when this dataset's conditions differ from its provider's."}
      },
      "additionalProperties": false
    },
    "provider": {
      "type": "object",
      "required": ["id", "name", "group", "summary", "industries", "docs", "listed_count", "catalog", "access", "datasets"],
      "properties": {
        "id": {"type": "string", "minLength": 1},
        "name": {"type": "string", "minLength": 1},
        "group": {"enum": ["public_data", "platform_data"], "description": "public_data: government, institutional, nonprofit and community sources. platform_data: data a platform or vendor holds or sells access to."},
        "summary": {"type": "string", "minLength": 1},
        "industries": {"$ref": "#/$defs/strings"},
        "docs": {"type": "string", "format": "uri"},
        "geography": {"$ref": "#/$defs/geography"},
        "aliases": {"type": "array", "items": {"type": "string"}},
        "field_names": {"type": "array", "items": {"type": "string"}},
        "coverage_notes": {"type": "array", "items": {"type": "string"}},
        "time_coverage": {"type": "string", "description": "Provider scope is not inherited by dataset families."},
        "listed_count": {"type": "integer", "minimum": 1, "description": "Dataset families listed here for this provider. Compare with catalog.total; it is not the provider's total."},
        "catalog": {"$ref": "#/$defs/catalog"},
        "access": {"allOf": [{"$ref": "#/$defs/access"}, {"required": ["cost"]}]},
        "datasets": {"type": "array", "minItems": 1, "items": {"$ref": "#/$defs/dataset"}}
      },
      "additionalProperties": false
    },
    "service": {
      "type": "object",
      "description": "A service API. Not a dataset and not counted as one.",
      "required": ["id", "name", "docs", "capabilities"],
      "properties": {
        "id": {"type": "string", "minLength": 1},
        "name": {"type": "string", "minLength": 1},
        "docs": {"type": "string", "format": "uri"},
        "geography": {"$ref": "#/$defs/geography"},
        "aliases": {"type": "array", "items": {"type": "string"}},
        "field_names": {"type": "array", "items": {"type": "string"}},
        "coverage_notes": {"type": "array", "items": {"type": "string"}},
        "time_coverage": {"type": "string"},
        "capabilities": {"$ref": "#/$defs/strings"}
      },
      "additionalProperties": false
    }
  }
}
