{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/africacompliancedata-com/json-schema/africacompliancedata-com-country-bundle-schema.json",
  "title": "CountryBundle",
  "x-generated": "2026-10-30",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/africacompliancedata-com-openapi.json#/components/schemas/CountryBundle",
  "type": "object",
  "required": [
    "bundle",
    "signature",
    "disclaimer"
  ],
  "properties": {
    "bundle": {
      "type": "object",
      "description": "The signed payload",
      "required": [
        "format",
        "kind",
        "country",
        "year",
        "years",
        "parts",
        "dataset_version",
        "issued_at",
        "expires_at",
        "key_id",
        "disclaimer",
        "country_data",
        "calendar"
      ],
      "properties": {
        "format": {
          "type": "integer",
          "enum": [
            1
          ]
        },
        "kind": {
          "type": "string",
          "enum": [
            "country_year"
          ]
        },
        "country": {
          "type": "string"
        },
        "year": {
          "type": "integer"
        },
        "years": {
          "type": "array",
          "items": {
            "type": "integer"
          },
          "description": "First and last year the dataset covers"
        },
        "parts": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "holidays",
              "tax"
            ]
          }
        },
        "dataset_version": {
          "type": "string"
        },
        "data_revision": {
          "$ref": "#/$defs/DataRevision"
        },
        "issued_at": {
          "type": "string",
          "format": "date-time"
        },
        "expires_at": {
          "type": "string",
          "format": "date-time",
          "description": "1 day after issued_at for the current and later years, 30 days for past years: do not use the bundle after this"
        },
        "key_id": {
          "type": "string",
          "description": "First 16 hex digits of the SHA-256 of the signing public key"
        },
        "disclaimer": {
          "type": "string"
        },
        "country_data": {
          "type": "object",
          "description": "The country's fields as the API uses them: iso2, name, weekend (ISO weekday numbers, 1 = Monday), coverage, holidays (source_ref, weekend_rule, notes), holiday_announcements, calendar_incomplete_years, calendar_any (whether any year has a holiday), sources (with confidence); with the tax parts also vat, vat_history, deadlines, currency and payroll (payroll_tax and contributions periods, as in /payroll-tax and /social-security)",
          "properties": {
            "weekend": {
              "type": "array",
              "items": {
                "type": "integer"
              }
            },
            "coverage": {
              "type": "object",
              "additionalProperties": {
                "$ref": "#/$defs/Coverage"
              }
            },
            "sources": {
              "type": "object",
              "additionalProperties": {
                "$ref": "#/$defs/Source"
              }
            },
            "vat_history": {
              "type": "object",
              "properties": {
                "covered_from": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "periods": {
                  "type": "array",
                  "items": {
                    "$ref": "#/$defs/VatPeriod"
                  }
                }
              }
            }
          }
        },
        "calendar": {
          "type": "object",
          "description": "The year's holidays (every scope), keyed by the year",
          "additionalProperties": {
            "type": "array",
            "items": {
              "$ref": "#/$defs/Holiday"
            }
          }
        },
        "not_included": {
          "type": "object",
          "properties": {
            "tax": {
              "type": "string",
              "description": "Why the tax parts are not included (the plan, or a full Pro pack)"
            }
          }
        }
      }
    },
    "signature": {
      "type": "object",
      "properties": {
        "alg": {
          "type": "string",
          "enum": [
            "Ed25519"
          ]
        },
        "key_id": {
          "type": "string"
        },
        "value": {
          "type": "string",
          "description": "Base64 Ed25519 signature of the UTF-8 canonical JSON of 'bundle'"
        }
      }
    },
    "disclaimer": {
      "type": "string",
      "description": "The disclaimer as in every answer for this key (outside the signature)"
    }
  },
  "$defs": {
    "Coverage": {
      "type": "string",
      "enum": [
        "ready",
        "partial",
        "gap"
      ]
    },
    "DataRevision": {
      "type": "string",
      "description": "Short commit id of the data the answer was built from (e.g. 928cb72b). dataset_version is the build date: the daily rebuild changes it with no data change, while data_revision changes only when the data does. Keep it with saved results to know exactly which data you used."
    },
    "Holiday": {
      "type": "object",
      "properties": {
        "date": {
          "type": "string",
          "format": "date"
        },
        "name": {
          "type": "string"
        },
        "rule_id": {
          "type": [
            "string",
            "null"
          ],
          "description": "Absent for ad-hoc days off"
        },
        "status": {
          "type": "string",
          "enum": [
            "rule",
            "confirmed",
            "estimated",
            "observed",
            "bridge"
          ]
        },
        "scope": {
          "type": "string",
          "description": "national, or the group a holiday is limited to"
        },
        "observed_for": {
          "type": "string",
          "format": "date",
          "description": "For a substitute day: the date of the holiday it replaces"
        },
        "moved_from": {
          "type": "string",
          "format": "date",
          "description": "Original date of a holiday officially moved"
        },
        "bridge_for": {
          "type": "string",
          "format": "date",
          "description": "For a bridge day: the holiday it bridges to"
        },
        "estimated": {
          "type": "boolean",
          "description": "true on a weekend substitute of an estimated (moon-sighted) date: it moves with the announced date"
        },
        "source_url": {
          "type": [
            "string",
            "null"
          ],
          "description": "Official announcement (confirmed dates); null when the official text is not online (source_note says where it was published)"
        },
        "source_note": {
          "type": "string",
          "description": "Where the announcement was made when it is not published online, or that the date is known from a press report of the official announcement"
        }
      }
    },
    "Source": {
      "type": "object",
      "properties": {
        "url": {
          "type": [
            "string",
            "null"
          ],
          "description": "null when the official text is not available online; 'note' then explains it"
        },
        "note": {
          "type": "string",
          "description": "Present when url is null"
        },
        "legal_basis": {
          "type": "string"
        },
        "source_type": {
          "type": "string",
          "description": "e.g. statute, gazette, revenue_authority; 'secondary' when no official text has been confirmed"
        },
        "effective_date": {
          "type": [
            "string",
            "null"
          ]
        },
        "confidence": {
          "type": "string",
          "enum": [
            "high",
            "medium",
            "low"
          ]
        },
        "last_verified": {
          "type": "string",
          "format": "date"
        }
      }
    },
    "VatPeriod": {
      "type": "object",
      "properties": {
        "rate": {
          "type": "number"
        },
        "from": {
          "type": [
            "string",
            "null"
          ],
          "format": "date"
        },
        "to": {
          "type": [
            "string",
            "null"
          ],
          "format": "date"
        },
        "from_note": {
          "type": "string",
          "description": "When the period started before the documented history, e.g. 'in force on 2015-01-01 (earlier start not covered)'"
        },
        "legal_basis": {
          "type": "string"
        },
        "source_url": {
          "type": [
            "string",
            "null"
          ]
        },
        "confidence": {
          "type": "string",
          "enum": [
            "high",
            "medium",
            "low"
          ]
        },
        "notes": {
          "type": "string"
        }
      }
    }
  }
}