{
  "openapi": "3.1.0",
  "info": {
    "title": "Plek in de Veste API",
    "version": "1.0.0",
    "description": "Publieke alleen-lezen API voor opgeslagen FC Twente beschikbaarheid. Geen API-key nodig. Iedere wedstrijd wordt ongeveer eens per zes uur bijgewerkt. Dit is een onafhankelijke tool, geen officiële FC Twente API. De documentversie is geen URL-versie."
  },
  "servers": [
    {
      "url": "https://plekindeveste.net/local-api"
    }
  ],
  "security": [],
  "paths": {
    "/season-history": {
      "get": {
        "operationId": "season_history",
        "summary": "Verloop van alle wedstrijden",
        "description": "Alle opgeslagen wedstrijden met hun volledige metingen in history. Filter op de wedstrijddatum voor het gewenste seizoen. Bevat alleen tellingen, geen stoelen.",
        "responses": {
          "200": {
            "description": "Geslaagd. Voorbeeldgegevens zijn illustratief.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "allOf": [
                      {
                        "$ref": "#/components/schemas/Event"
                      },
                      {
                        "type": "object",
                        "properties": {
                          "history": {
                            "type": "array",
                            "items": {
                              "$ref": "#/components/schemas/Measurement"
                            }
                          }
                        },
                        "required": [
                          "history"
                        ]
                      }
                    ]
                  }
                },
                "example": [
                  {
                    "EventId": 371,
                    "Name": "FC Twente - PSV",
                    "EventStartDateTime": "2026-09-20T12:30:00",
                    "isCurrent": true,
                    "firstSeen": "2026-09-15T01:00:00.000Z",
                    "lastSeen": "2026-09-16T10:00:00.000Z",
                    "removedAt": null,
                    "lastCapturedAt": "2026-09-16T10:01:00.000Z",
                    "measurementCount": 12,
                    "history": [
                      {
                        "id": 123,
                        "started_at": "2026-09-16T10:00:00.000Z",
                        "captured_at": "2026-09-16T10:01:00.000Z",
                        "complete": 1,
                        "marketplace_status": "loaded",
                        "interval_minutes": 360,
                        "total_count": 28292,
                        "available_count": 120,
                        "regular_count": 80,
                        "marketplace_count": 45,
                        "marketplace_extra_count": 40
                      }
                    ]
                  }
                ]
              }
            }
          },
          "400": {
            "description": "Ongeldige vakselectie",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Niet gevonden of nog geen meting",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Gegevens tijdelijk niet beschikbaar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Database of hosting tijdelijk niet beschikbaar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/events": {
      "get": {
        "operationId": "events",
        "summary": "Wedstrijden",
        "description": "Alle opgeslagen wedstrijden, inclusief archief. Filter zelf op isCurrent voor het huidige aanbod. Activiteiten en vrouwenwedstrijden zijn uitgesloten. Er is geen paginering.",
        "responses": {
          "200": {
            "description": "Geslaagd. Voorbeeldgegevens zijn illustratief.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Event"
                  }
                },
                "example": [
                  {
                    "EventId": 371,
                    "Name": "FC Twente - PSV",
                    "EventStartDateTime": "2026-09-20T12:30:00",
                    "isCurrent": true,
                    "firstSeen": "2026-09-15T01:00:00.000Z",
                    "lastSeen": "2026-09-16T10:00:00.000Z",
                    "removedAt": null,
                    "lastCapturedAt": "2026-09-16T10:01:00.000Z",
                    "measurementCount": 12
                  }
                ]
              }
            }
          },
          "400": {
            "description": "Ongeldige vakselectie",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Niet gevonden of nog geen meting",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Gegevens tijdelijk niet beschikbaar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Database of hosting tijdelijk niet beschikbaar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/season-availability": {
      "get": {
        "operationId": "season",
        "summary": "Beschikbaarheid van alle wedstrijden",
        "description": "De lichtste keuze voor een overzicht met actuele aantallen. Eén antwoord met de wedstrijden en hun laatst bewaarde stand. Bevat ook archiefwedstrijden. Een seizoen loopt van juli tot en met juni; groepeer zelf op de Nederlandse aftrapdatum. Er is geen season-parameter.",
        "responses": {
          "200": {
            "description": "Geslaagd. Voorbeeldgegevens zijn illustratief.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SeasonEvent"
                  }
                },
                "example": [
                  {
                    "EventId": 371,
                    "Name": "FC Twente - PSV",
                    "EventStartDateTime": "2026-09-20T12:30:00",
                    "isCurrent": true,
                    "firstSeen": "2026-09-15T01:00:00.000Z",
                    "lastSeen": "2026-09-16T10:00:00.000Z",
                    "removedAt": null,
                    "lastCapturedAt": "2026-09-16T10:01:00.000Z",
                    "measurementCount": 12,
                    "availability": {
                      "capturedAt": "2026-09-16T10:01:00.000Z",
                      "complete": true,
                      "marketplaceStatus": "loaded",
                      "marketplaceInferredZero": false,
                      "totalCount": 28292,
                      "availableCount": 120,
                      "regularCount": 80,
                      "marketplaceExtraCount": 40
                    }
                  }
                ]
              }
            }
          },
          "400": {
            "description": "Ongeldige vakselectie",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Niet gevonden of nog geen meting",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Gegevens tijdelijk niet beschikbaar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Database of hosting tijdelijk niet beschikbaar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/events/{eventId}/dashboard": {
      "get": {
        "operationId": "dashboard",
        "summary": "Vakken en stoelen",
        "description": "Uitgebreid antwoord met stadionindeling, vakken, stoelen en tellingen. Gebruik dit alleen als je die details nodig hebt. Geeft bij voorkeur de laatste volledige meting; zonder volledige meting de laatste onvolledige. HTTP 404 als er geen opgeslagen meting is.",
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "description": "EventId uit GET /events. Het voorbeeld 371 is geen vaste standaard."
          },
          {
            "name": "snapshotId",
            "in": "query",
            "required": false,
            "description": "ID van een eerdere meting uit de history-route van deze wedstrijd. Zonder deze parameter krijg je de laatste beschikbare stand.",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Geslaagd. Voorbeeld is een verkort antwoord.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Dashboard"
                },
                "example": {
                  "snapshot": {
                    "id": 123,
                    "startedAt": "2026-09-16T10:00:00.000Z",
                    "capturedAt": "2026-09-16T10:01:00.000Z",
                    "complete": true
                  },
                  "latestAttempt": {
                    "capturedAt": "2026-09-16T10:01:00.000Z",
                    "complete": true
                  },
                  "data": {
                    "eventMeta": {
                      "EventId": 371,
                      "Name": "FC Twente - PSV",
                      "EventStartDateTime": "2026-09-20T12:30:00"
                    },
                    "totals": {
                      "availableCount": 120,
                      "regularAvailableCount": 80,
                      "marketplaceAvailableCount": 45,
                      "marketplaceExtraCount": 40
                    },
                    "marketplace": {
                      "status": "loaded",
                      "channelId": 7,
                      "message": "Beide bronnen geladen"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ongeldige vakselectie",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Niet gevonden of nog geen meting",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Gegevens tijdelijk niet beschikbaar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Database of hosting tijdelijk niet beschikbaar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/events/{eventId}/history-sections": {
      "get": {
        "operationId": "history_sections",
        "summary": "Vak-ID’s voor historie",
        "description": "De beschikbare vakken voor historische selectie, met naam en tribune. Gebruik id als sectionId of in sectionIds. Geeft [] als er geen vakgegevens zijn.",
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "description": "EventId uit GET /events. Het voorbeeld 371 is geen vaste standaard."
          }
        ],
        "responses": {
          "200": {
            "description": "Geslaagd. Voorbeeldgegevens zijn illustratief.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/HistorySection"
                  }
                },
                "example": [
                  {
                    "id": 391427,
                    "name": "Vak 134",
                    "tribune": "Lange zijde"
                  }
                ]
              }
            }
          },
          "400": {
            "description": "Ongeldige vakselectie",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Niet gevonden of nog geen meting",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Gegevens tijdelijk niet beschikbaar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Database of hosting tijdelijk niet beschikbaar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/events/{eventId}/history": {
      "get": {
        "operationId": "history",
        "summary": "Historische metingen",
        "description": "Chronologisch gesorteerde metingen, oudste eerst. Zonder parameters: het hele stadion, alleen volledige metingen. Geeft [] bij ontbrekende historie. Geen datumfilter of paginering; filter en bewaar het resultaat zelf.",
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "description": "EventId uit GET /events. Het voorbeeld 371 is geen vaste standaard."
          },
          {
            "name": "includeIncomplete",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            },
            "description": "Gebruik 1 om ook onvolledige metingen te ontvangen. Standaard uitgesloten, behalve bij sectionIds."
          },
          {
            "name": "sectionId",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0
            },
            "description": "Eén vak-ID. Bevat ook section_id, snapshot_id, name en aanvullende tellingen. Niet combineren met sectionIds."
          },
          {
            "name": "sectionIds",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^\\d+(,\\d+)*$"
            },
            "description": "Maximaal 200 komma-gescheiden vak-ID’s. Dubbele ID’s tellen eenmaal. Geeft opgetelde tellingen per meting. Bevat altijd ook onvolledige metingen, ongeacht includeIncomplete. complete=1 alleen als alle geselecteerde vakken aanwezig zijn en de snapshot volledig is. Niet combineren met sectionId."
          }
        ],
        "responses": {
          "200": {
            "description": "Geslaagd. Voorbeeldgegevens zijn illustratief.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Measurement"
                  }
                },
                "example": [
                  {
                    "id": 123,
                    "started_at": "2026-09-16T10:00:00.000Z",
                    "captured_at": "2026-09-16T10:01:00.000Z",
                    "complete": 1,
                    "marketplace_status": "loaded",
                    "interval_minutes": 360,
                    "total_count": 28292,
                    "available_count": 120,
                    "regular_count": 80,
                    "marketplace_count": 45,
                    "marketplace_extra_count": 40
                  }
                ]
              }
            }
          },
          "400": {
            "description": "Ongeldige vakselectie",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Niet gevonden of nog geen meting",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Gegevens tijdelijk niet beschikbaar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Database of hosting tijdelijk niet beschikbaar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/status": {
      "get": {
        "operationId": "status",
        "summary": "Status van het ophalen",
        "description": "Informatie over de automatische ophaalplanning. Een GET start nooit een nieuwe ophaalronde. De publieke API kan alleen opgeslagen gegevens lezen.",
        "responses": {
          "200": {
            "description": "Geslaagd. Voorbeeldgegevens zijn illustratief.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Status"
                },
                "example": {
                  "running": false,
                  "nextRunAt": "2026-09-16T11:00:00.000Z",
                  "intervalMinutes": 360,
                  "snapshotCount": 120,
                  "cooldownUntil": null,
                  "manualSyncAllowed": false,
                  "progress": null,
                  "lastRun": null
                }
              }
            }
          },
          "400": {
            "description": "Ongeldige vakselectie",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Niet gevonden of nog geen meting",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Gegevens tijdelijk niet beschikbaar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Database of hosting tijdelijk niet beschikbaar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "EventMetadata": {
        "type": "object",
        "properties": {
          "EventId": {
            "type": "integer"
          },
          "Name": {
            "type": "string"
          },
          "EventStartDateTime": {
            "type": "string",
            "description": "UTC. Als de tijdzone ontbreekt, behandel de waarde als UTC en voeg voor parsing Z toe."
          },
          "HomeImageUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "AwayImageUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "EventTypeName": {
            "type": [
              "string",
              "null"
            ]
          },
          "EventTypeLogoUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "HasTicketsAvailable": {
            "type": "boolean"
          },
          "CurrentlyOnSaleForUser": {
            "type": "boolean"
          },
          "VisibleInShop": {
            "type": "boolean"
          },
          "ShowMarketplaceForEvent": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Actuele vlag uit de wedstrijdlijst: false = kaartenmarkt nog niet beschikbaar, true = beschikbaar. Ontbrekend/null betekent onbekend. Geen historische openingsdatum."
          }
        },
        "required": [
          "EventId",
          "Name",
          "EventStartDateTime"
        ]
      },
      "Event": {
        "type": "object",
        "properties": {
          "EventId": {
            "type": "integer"
          },
          "Name": {
            "type": "string"
          },
          "EventStartDateTime": {
            "type": "string",
            "description": "UTC. Als de tijdzone ontbreekt, behandel de waarde als UTC en voeg voor parsing Z toe."
          },
          "HomeImageUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "AwayImageUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "EventTypeName": {
            "type": [
              "string",
              "null"
            ]
          },
          "EventTypeLogoUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "HasTicketsAvailable": {
            "type": "boolean"
          },
          "CurrentlyOnSaleForUser": {
            "type": "boolean"
          },
          "VisibleInShop": {
            "type": "boolean"
          },
          "ShowMarketplaceForEvent": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Actuele vlag uit de wedstrijdlijst: false = kaartenmarkt nog niet beschikbaar, true = beschikbaar. Ontbrekend/null betekent onbekend. Geen historische openingsdatum."
          },
          "isCurrent": {
            "type": "boolean"
          },
          "firstSeen": {
            "type": "string",
            "format": "date-time"
          },
          "lastSeen": {
            "type": "string",
            "format": "date-time"
          },
          "removedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "lastCapturedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "measurementCount": {
            "type": "integer"
          }
        },
        "required": [
          "EventId",
          "Name",
          "EventStartDateTime",
          "isCurrent",
          "lastCapturedAt",
          "measurementCount"
        ]
      },
      "SeasonEvent": {
        "type": "object",
        "properties": {
          "EventId": {
            "type": "integer"
          },
          "Name": {
            "type": "string"
          },
          "EventStartDateTime": {
            "type": "string",
            "description": "UTC. Als de tijdzone ontbreekt, behandel de waarde als UTC en voeg voor parsing Z toe."
          },
          "HomeImageUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "AwayImageUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "EventTypeName": {
            "type": [
              "string",
              "null"
            ]
          },
          "EventTypeLogoUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "HasTicketsAvailable": {
            "type": "boolean"
          },
          "CurrentlyOnSaleForUser": {
            "type": "boolean"
          },
          "VisibleInShop": {
            "type": "boolean"
          },
          "ShowMarketplaceForEvent": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Actuele vlag uit de wedstrijdlijst: false = kaartenmarkt nog niet beschikbaar, true = beschikbaar. Ontbrekend/null betekent onbekend. Geen historische openingsdatum."
          },
          "isCurrent": {
            "type": "boolean"
          },
          "firstSeen": {
            "type": "string",
            "format": "date-time"
          },
          "lastSeen": {
            "type": "string",
            "format": "date-time"
          },
          "removedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "lastCapturedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "measurementCount": {
            "type": "integer"
          },
          "availability": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Availability"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "EventId",
          "Name",
          "availability"
        ]
      },
      "Availability": {
        "type": "object",
        "properties": {
          "capturedAt": {
            "type": "string",
            "format": "date-time"
          },
          "complete": {
            "type": "boolean"
          },
          "marketplaceStatus": {
            "type": "string",
            "enum": [
              "loaded",
              "closed",
              "unavailable",
              "unknown"
            ],
            "description": "loaded = kaartenmarkt geladen, closed = expliciet niet beschikbaar en niet opgehaald, unavailable = ophalen mislukt, unknown = openingsstatus niet vastgelegd bij een oudere meting."
          },
          "marketplaceInferredZero": {
            "type": "boolean",
            "description": "true bij een volledige gesloten-marktmeting met nul aanbod na een eerdere waargenomen opening. Een afgeleide nul, geen gemeten kaartenmarktaanbod of gemeten verandering."
          },
          "totalCount": {
            "type": "integer"
          },
          "availableCount": {
            "type": "integer"
          },
          "regularCount": {
            "type": "integer"
          },
          "marketplaceExtraCount": {
            "type": "integer"
          }
        },
        "required": [
          "capturedAt",
          "complete",
          "availableCount",
          "regularCount",
          "marketplaceExtraCount"
        ]
      },
      "HistorySection": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "tribune": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "tribune"
        ]
      },
      "Measurement": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "started_at": {
            "type": "string",
            "format": "date-time"
          },
          "captured_at": {
            "type": "string",
            "format": "date-time"
          },
          "complete": {
            "type": "integer",
            "enum": [
              0,
              1
            ]
          },
          "marketplace_status": {
            "type": "string",
            "enum": [
              "loaded",
              "closed",
              "unavailable",
              "unknown"
            ],
            "description": "loaded = kaartenmarkt geladen, closed = expliciet niet beschikbaar en niet opgehaald, unavailable = ophalen mislukt, unknown = openingsstatus niet vastgelegd bij een oudere meting."
          },
          "interval_minutes": {
            "type": "integer",
            "description": "Geplande tussenpoos, geen ophaalduur. Nieuwe hostingmetingen: 360. Oudere waarden kunnen afwijken."
          },
          "total_count": {
            "type": "integer"
          },
          "available_count": {
            "type": "integer"
          },
          "regular_count": {
            "type": "integer"
          },
          "marketplace_count": {
            "type": "integer"
          },
          "marketplace_extra_count": {
            "type": "integer"
          },
          "snapshot_id": {
            "type": "integer",
            "description": "Alleen bij sectionId."
          },
          "section_id": {
            "type": "integer",
            "description": "Alleen bij sectionId."
          },
          "name": {
            "type": "string",
            "description": "Alleen bij sectionId."
          },
          "sold_count": {
            "type": "integer"
          },
          "reserved_count": {
            "type": "integer"
          },
          "unavailable_count": {
            "type": "integer"
          },
          "not_for_sale_count": {
            "type": "integer"
          }
        },
        "required": [
          "id",
          "started_at",
          "captured_at",
          "complete",
          "interval_minutes",
          "total_count",
          "available_count",
          "regular_count",
          "marketplace_extra_count"
        ]
      },
      "Counts": {
        "type": "object",
        "properties": {
          "rawTotalCount": {
            "type": "integer"
          },
          "rawAvailableCount": {
            "type": "integer"
          },
          "totalCount": {
            "type": "integer"
          },
          "availableCount": {
            "type": "integer"
          },
          "regularAvailableCount": {
            "type": "integer"
          },
          "marketplaceAvailableCount": {
            "type": "integer"
          },
          "marketplaceExtraCount": {
            "type": "integer"
          },
          "soldCount": {
            "type": "integer"
          },
          "reservedCount": {
            "type": "integer"
          },
          "unavailableCount": {
            "type": "integer"
          },
          "notForSaleCount": {
            "type": "integer"
          },
          "availabilityRate": {
            "type": "number",
            "description": "Percentage beschikbare standaardplaatsen: 0–100. Alleen bruikbaar bij bekende capaciteit."
          }
        }
      },
      "Seat": {
        "type": "object",
        "properties": {
          "Id": {
            "type": "integer"
          },
          "Column": {
            "type": "integer"
          },
          "Row": {
            "type": "integer"
          },
          "RowNumber": {
            "type": "string"
          },
          "SeatNumber": {
            "type": "string"
          },
          "PlacementTypeId": {
            "type": [
              "integer",
              "null"
            ]
          },
          "IsAvailableForSale": {
            "type": "boolean"
          },
          "IsUnavailable": {
            "type": "boolean"
          },
          "IsReserved": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "IsSold": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "RegularAvailable": {
            "type": "boolean"
          },
          "MarketplaceAvailable": {
            "type": "boolean"
          },
          "AvailableForSecondary": {
            "type": "boolean"
          },
          "MarketplacePrice": {
            "type": [
              "number",
              "null"
            ]
          },
          "MarketplaceBundled": {
            "type": "boolean"
          }
        }
      },
      "Section": {
        "type": "object",
        "properties": {
          "VenueBuildingBlockId": {
            "type": "integer"
          },
          "EventId": {
            "type": "integer"
          },
          "EventPlacementId": {
            "type": "integer"
          },
          "Name": {
            "type": "string"
          },
          "ShortName": {
            "type": "string"
          },
          "SectionNumber": {
            "type": "string"
          },
          "ParentVenueBuildingBlockName": {
            "type": [
              "string",
              "null"
            ]
          },
          "SectionSVG": {
            "type": "string"
          },
          "HasTicketsAvailable": {
            "type": "boolean"
          },
          "HasMarketplaceTicketsAvailable": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "AvailableSeats": {
            "type": [
              "integer",
              "null"
            ]
          },
          "HasPriceVariations": {
            "type": "boolean"
          }
        }
      },
      "SectionAvailability": {
        "type": "object",
        "properties": {
          "rawTotalCount": {
            "type": "integer"
          },
          "rawAvailableCount": {
            "type": "integer"
          },
          "totalCount": {
            "type": "integer"
          },
          "availableCount": {
            "type": "integer"
          },
          "regularAvailableCount": {
            "type": "integer"
          },
          "marketplaceAvailableCount": {
            "type": "integer"
          },
          "marketplaceExtraCount": {
            "type": "integer"
          },
          "soldCount": {
            "type": "integer"
          },
          "reservedCount": {
            "type": "integer"
          },
          "unavailableCount": {
            "type": "integer"
          },
          "notForSaleCount": {
            "type": "integer"
          },
          "availabilityRate": {
            "type": "number",
            "description": "Percentage beschikbare standaardplaatsen: 0–100. Alleen bruikbaar bij bekende capaciteit."
          },
          "capacityKnown": {
            "type": "boolean"
          },
          "section": {
            "$ref": "#/components/schemas/Section"
          },
          "ticketTypes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "Id": {
                  "type": "integer"
                },
                "Name": {
                  "type": "string"
                }
              }
            },
            "description": "Compatibiliteitsveld; nieuwe opgeslagen antwoorden bevatten een lege lijst."
          },
          "categoryPrices": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "PriceTotal": {
                  "type": "number"
                },
                "VariationName": {
                  "type": "string"
                }
              }
            },
            "description": "Compatibiliteitsveld; nieuwe opgeslagen antwoorden bevatten een lege lijst."
          },
          "seatMap": {
            "type": "object",
            "properties": {
              "capacityKnown": {
                "type": "boolean"
              },
              "Details": {
                "$ref": "#/components/schemas/Section"
              },
              "CategoryPrices": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "PriceTotal": {
                      "type": "number"
                    },
                    "VariationName": {
                      "type": "string"
                    }
                  }
                },
                "description": "Compatibiliteitsveld; nieuwe opgeslagen antwoorden bevatten een lege lijst."
              },
              "Rows": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "Columns": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Seat"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "Dashboard": {
        "type": "object",
        "properties": {
          "snapshot": {
            "type": "object",
            "properties": {
              "id": {
                "type": "integer"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time"
              },
              "capturedAt": {
                "type": "string",
                "format": "date-time"
              },
              "complete": {
                "type": "boolean"
              }
            },
            "required": [
              "id",
              "startedAt",
              "capturedAt",
              "complete"
            ]
          },
          "latestAttempt": {
            "type": "object",
            "properties": {
              "capturedAt": {
                "type": "string",
                "format": "date-time"
              },
              "complete": {
                "type": "boolean"
              }
            },
            "required": [
              "capturedAt",
              "complete"
            ]
          },
          "data": {
            "type": "object",
            "properties": {
              "eventMeta": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/EventMetadata"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "events": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/EventMetadata"
                },
                "description": "Compatibiliteitsveld; nieuwe opgeslagen antwoorden bevatten een lege lijst. Gebruik GET /events."
              },
              "salesChannels": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {}
                },
                "description": "Compatibiliteitsveld; nieuwe opgeslagen antwoorden bevatten een lege lijst."
              },
              "salesPeriods": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {}
                },
                "description": "Compatibiliteitsveld; nieuwe opgeslagen antwoorden bevatten een lege lijst."
              },
              "filters": {
                "type": "object",
                "properties": {},
                "description": "Compatibiliteitsveld; nieuwe opgeslagen antwoorden bevatten een leeg object."
              },
              "collection": {
                "type": "object",
                "properties": {
                  "sectionRequests": {
                    "type": "integer"
                  },
                  "skippedSections": {
                    "type": "integer"
                  }
                }
              },
              "totals": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/Counts"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "sectionsWithAvailability": {
                        "type": "integer"
                      }
                    }
                  }
                ]
              },
              "capacityKnown": {
                "type": "boolean"
              },
              "displayCapacity": {
                "type": "integer"
              },
              "basePlanSvg": {
                "type": "string"
              },
              "sections": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Section"
                }
              },
              "marketplace": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "loaded",
                      "closed",
                      "unavailable"
                    ]
                  },
                  "channelId": {
                    "type": "integer"
                  },
                  "message": {
                    "type": "string"
                  }
                }
              },
              "sectionAvailability": {
                "type": "object",
                "additionalProperties": {
                  "$ref": "#/components/schemas/SectionAvailability"
                }
              }
            }
          }
        },
        "required": [
          "snapshot",
          "latestAttempt",
          "data"
        ]
      },
      "Status": {
        "type": "object",
        "properties": {
          "running": {
            "type": "boolean"
          },
          "nextRunAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "intervalMinutes": {
            "type": "integer"
          },
          "snapshotCount": {
            "type": "integer"
          },
          "cooldownUntil": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "manualSyncAllowed": {
            "type": "boolean",
            "const": false
          },
          "progress": {
            "type": [
              "object",
              "null"
            ]
          },
          "lastRun": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "integer"
                  },
                  "startedAt": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "finishedAt": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date-time"
                  },
                  "status": {
                    "type": "string"
                  },
                  "result": {
                    "type": [
                      "object",
                      "null"
                    ]
                  }
                }
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "running",
          "nextRunAt",
          "intervalMinutes",
          "manualSyncAllowed"
        ]
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          }
        },
        "required": [
          "error"
        ]
      }
    }
  }
}
