{
  "$ref": "#/definitions/EstimateSnapshots",
  "definitions": {
    "EstimateSnapshots": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "description": "Unique stable identifier, e.g. \"cz-parliament-2025-02-23\"."
          },
          "region": {
            "anyOf": [
              {
                "type": "string",
                "minLength": 1
              },
              {
                "type": "array",
                "items": {
                  "type": "string",
                  "minLength": 1
                }
              }
            ],
            "description": "Region(s) this snapshot covers. ISO 3166-1 alpha-2 or ISO 3166-2 codes."
          },
          "type": {
            "type": "string",
            "description": "Election type being modelled. Canonical values: \"parliamentary\", \"presidential\", \"municipal\", \"regional\", \"european\", \"referendum\"."
          },
          "computed_at": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601 datetime (UTC) when the model was last computed. Format: YYYY-MM-DDTHH:mm:ssZ"
          },
          "model_version": {
            "type": "string",
            "description": "Identifier for the model version that produced this snapshot. Examples: \"v1.2.0\", \"2025-02-01\""
          },
          "estimates": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "choice_id": {
                  "type": "string",
                  "minLength": 1,
                  "description": "ID of the choice (party, coalition) or candidate this estimate covers. References Choice.id or Candidate.id."
                },
                "type": {
                  "type": "string",
                  "minLength": 1,
                  "description": "What quantity is being estimated. Canonical values: \"percents\", \"seats\", \"probability to enter\"."
                },
                "value": {
                  "type": "number",
                  "description": "Point estimate (central value)."
                },
                "lower_value": {
                  "type": "number",
                  "description": "Lower bound of the credible/confidence interval."
                },
                "upper_value": {
                  "type": "number",
                  "description": "Upper bound of the credible/confidence interval."
                },
                "other_values": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": {
                      "type": [
                        "number",
                        "string",
                        "null"
                      ]
                    }
                  },
                  "description": "Additional computed values (median, mode, standard deviation, etc.). Example: [{ \"median_value\": 67 }]"
                },
                "probability_level_percentage": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 100,
                  "default": 95,
                  "description": "Confidence/credibility level for lower_value/upper_value, in percent. Default: 95."
                },
                "distribution": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "type": "string",
                      "minLength": 1,
                      "description": "What quantity the distribution is over. Canonical values: \"seats\", \"percents\". Should match the parent Estimate.type."
                    },
                    "values": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "x": {
                            "type": "string",
                            "minLength": 1,
                            "description": "Bin label — exact value or range. Examples: \"10\" (exact), \"9-10\" (range), \"<5\" (open-ended)."
                          },
                          "value": {
                            "type": "number",
                            "description": "Probability mass or frequency for this bin. Typically a percentage (0–100) summing to ~100 across all bins, or a probability (0–1) summing to ~1."
                          }
                        },
                        "required": [
                          "x",
                          "value"
                        ],
                        "additionalProperties": false,
                        "description": "One bin of a probability or frequency distribution.\n\nLayer: aggregate (embedded in Distribution → Estimate → EstimateSnapshot)"
                      },
                      "minItems": 1,
                      "description": "Ordered array of bins in ascending order of x."
                    }
                  },
                  "required": [
                    "type",
                    "values"
                  ],
                  "additionalProperties": false,
                  "description": "Full probability distribution over discrete bins. Provides the complete shape of uncertainty."
                }
              },
              "required": [
                "choice_id",
                "type",
                "value"
              ],
              "additionalProperties": false,
              "description": "A model-derived estimate for a single choice.\n\nLayer: aggregate (contained in EstimateSnapshot)\n\nThese are outputs of the aggregation pipeline (poll-of-polls, Monte Carlo, etc.) — not raw values reported by any polling agency. For agency-reported values see PollResult (source) or DerivedResult (compute)."
            },
            "minItems": 1,
            "description": "Model estimates for each choice/candidate. Typically contains separate Estimate entries for each type (\"percents\", \"seats\", \"probability to enter\")."
          },
          "extras": {
            "type": "object",
            "additionalProperties": {},
            "description": "Extension point for additional fields (e.g. poll_count, total_seats)."
          }
        },
        "required": [
          "id",
          "region",
          "computed_at",
          "estimates"
        ],
        "additionalProperties": false,
        "description": "The output of a polling aggregation model at one point in time.\n\nLayer: aggregate (final output of the pipeline)\n\nIMPORTANT — scope boundary: EstimateSnapshot is the home for all computed/modelled outputs — poll-of-polls aggregates, seat distributions, entry probabilities, and majority scenario probabilities. It is completely separate from Poll/PollOutput, which store only what polling agencies publish. An EstimateSnapshot is never nested inside a Poll.\n\nData flow: Poll (source) → ScenarioSnapshot (compute) → EstimateSnapshot (this)"
      },
      "description": "Array of EstimateSnapshot objects (time series)."
    }
  },
  "$schema": "http://json-schema.org/draft-07/schema#"
}