{
  "openapi": "3.1.0",
  "info": {
    "title": "Splitify Engine v3",
    "version": "3.0.0",
    "summary": "Stabiel publiek contract voor de Splitify pand-context-engine",
    "description": "Eén-shot pand-context voor heel Nederland. Per BAG-pand-id levert de engine een\ngestructureerde JSON-blob met (1) twaalf scenario-uitkomsten (kansrijk / voorwaardelijk\n/ niet-kansrijk), (2) bron-tracking per veld voor audit-baar advies, (3) procedureel\nadvies per scenario (route, doorlooptijd, kosten, kansrijkheid).\n\nVersioning: `/api/v3/` is een stabiel publiek contract. Breaking changes verhuizen\nnaar `/api/v4/`. Tot dan: alleen additieve wijzigingen (nieuwe optionele velden,\nnieuwe scenarios).\n\nAuth: voor `?detail=full` vereisen we `X-API-Key` (tier-systeem).\nVoor de publieke MVP-context kun je zonder key aanvragen, met rate-limit per IP.",
    "contact": {
      "name": "Splitify",
      "email": "info@splitify.nl",
      "url": "https://splitify.nl"
    },
    "license": {
      "name": "Proprietary — Splitify",
      "url": "https://splitify.nl"
    }
  },
  "servers": [
    {
      "url": "https://splitify.nl",
      "description": "Productie"
    },
    {
      "url": "http://localhost:8000",
      "description": "Lokale dev (dev-server.py)"
    }
  ],
  "tags": [
    {
      "name": "pand",
      "description": "Pand-context per BAG-id"
    },
    {
      "name": "scenarios",
      "description": "Scenario-catalogus"
    },
    {
      "name": "feedback",
      "description": "Gebruikers-feedback (placeholder)"
    },
    {
      "name": "qa",
      "description": "Kwaliteits-indicatoren (regressie-runs, gouden-test)"
    },
    {
      "name": "meta",
      "description": "Spec en docs"
    },
    {
      "name": "vraag",
      "description": "Vraag-ingang: een team van agents beantwoordt een vraag over een pand uit eigen data, met een live-volgbare trace (fase A). Sinds Story 1: meerdere beurten binnen één gesprek, met hergebruik van eerder opgehaalde data en een cumulatief gespreksbudget naast het bestaande beurtbudget."
    }
  ],
  "paths": {
    "/api/v3/pand/{bag_id}": {
      "get": {
        "tags": [
          "pand"
        ],
        "summary": "Volledige pand-context",
        "description": "Levert de volledige `PandContextV3` voor een BAG-pand-id. In MVP-modus zijn niet alle velden ingevuld (zie `meta.ontbrekende_velden`).",
        "operationId": "getPandContextV3",
        "parameters": [
          {
            "name": "bag_id",
            "in": "path",
            "required": true,
            "description": "BAG-pand-id (16 cijfers), of een nummeraanduiding-id.",
            "schema": {
              "type": "string",
              "pattern": "^[0-9A-Za-z_-]+$",
              "minLength": 8,
              "maxLength": 32
            },
            "example": "0518100000123456"
          },
          {
            "name": "detail",
            "in": "query",
            "required": false,
            "description": "Detail-niveau van de response. `full` vereist `X-API-Key`.",
            "schema": {
              "type": "string",
              "enum": [
                "particulier",
                "full"
              ],
              "default": "particulier"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "description": "Forceer cache-bypass (alleen voor admin-tier keys).",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Pand-context succesvol opgehaald.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PandContextV3"
                }
              }
            }
          },
          "400": {
            "description": "Verzoek mist verplichte parameter (bag_id).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Ongeldige X-API-Key (alleen bij `?detail=full`)."
          },
          "404": {
            "description": "Pand niet gevonden.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "429": {
            "description": "Rate-limit overschreden."
          },
          "500": {
            "description": "Interne fout in engine.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v3/scenarios": {
      "get": {
        "tags": [
          "scenarios"
        ],
        "summary": "Scenario-catalogus",
        "description": "Lijst van alle 12 scenarios met decision-tree-versie.",
        "operationId": "getScenarios",
        "responses": {
          "200": {
            "description": "Lijst van scenarios.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "versie": {
                      "type": "string",
                      "example": "v3.0"
                    },
                    "scenarios": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "naam",
                          "versie"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "example": "splitsing_1_naar_2"
                          },
                          "naam": {
                            "type": "string",
                            "example": "Splitsen 1 woning naar 2"
                          },
                          "versie": {
                            "type": "string",
                            "example": "v3.0"
                          },
                          "beschikbaar": {
                            "type": "boolean"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v3/feedback": {
      "post": {
        "tags": [
          "feedback"
        ],
        "summary": "Gebruiker meldt fout (placeholder)",
        "description": "Placeholder-endpoint. Zal in latere fase schrijven naar `feedback_meldingen` (zie `100-procent-architectuur.md` sectie 6.5).",
        "operationId": "postFeedback",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "bag_id"
                ],
                "properties": {
                  "bag_id": {
                    "type": "string"
                  },
                  "scenario": {
                    "type": "string"
                  },
                  "veld_pad": {
                    "type": "string"
                  },
                  "gemelde_waarde": {
                    "type": "string"
                  },
                  "correcte_waarde": {
                    "type": "string"
                  },
                  "toelichting": {
                    "type": "string"
                  },
                  "bron_url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "gebruiker_email": {
                    "type": "string",
                    "format": "email"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Feedback ontvangen."
          },
          "400": {
            "description": "Ongeldige feedback-payload."
          },
          "501": {
            "description": "Endpoint nog niet geïmplementeerd (placeholder)."
          }
        }
      }
    },
    "/api/v3/qa/regressie": {
      "get": {
        "tags": [
          "qa"
        ],
        "summary": "Laatste regressie-runs (gouden-testset CI)",
        "description": "Publieke kwaliteits-indicator: laatste N regressie-runs met match-percentage, verwarringsmatrix-summary en geslaagd-vlag. Iedere PR die de scenario-engine raakt draait een run; CI faalt bij <95% match. Zie `100-procent-architectuur.md` §6.2.",
        "operationId": "getQaRegressie",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 10
            }
          },
          {
            "name": "scenario",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter op scenario-id."
          },
          {
            "name": "alleen_geslaagd",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "1",
                "true"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Lijst regressie-runs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "bron": {
                      "type": "string",
                      "example": "regressie_runs"
                    },
                    "limit": {
                      "type": "integer",
                      "example": 10
                    },
                    "laatste": {
                      "type": "object",
                      "nullable": true
                    },
                    "runs": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "integer"
                          },
                          "scenario": {
                            "type": "string",
                            "nullable": true
                          },
                          "gemeente": {
                            "type": "string",
                            "nullable": true
                          },
                          "scenario_versie": {
                            "type": "string",
                            "nullable": true
                          },
                          "totaal": {
                            "type": "integer"
                          },
                          "match": {
                            "type": "integer"
                          },
                          "match_pct": {
                            "type": "number"
                          },
                          "drempel": {
                            "type": "number",
                            "example": 95
                          },
                          "geslaagd": {
                            "type": "boolean"
                          },
                          "duration_ms": {
                            "type": "integer"
                          },
                          "pr_nummer": {
                            "type": "integer",
                            "nullable": true
                          },
                          "commit_sha": {
                            "type": "string",
                            "nullable": true
                          },
                          "created_at": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v3/vraag": {
      "post": {
        "tags": [
          "vraag"
        ],
        "summary": "Stel een vraag over een pand, of vervolg een gesprek (vraag-ingang + Story 1 gesprekslaag)",
        "description": "Een team van agents (Saar, Bas, optioneel Teun/taxateur en Roos/bouwkundige, Pim, Vera, Noor) beantwoordt een vraag in gewone taal uit eigen data. Teun en Roos spreken alleen als hun vak (resp. waarde, bouwkundige staat) een tool-treffer heeft; Pim, Vera en Noor spreken elke beurt. Zonder `gesprek_id` start dit een nieuw gesprek (`beurt: 1`); met een geldig `gesprek_id` vervolgt het hetzelfde gesprek en hergebruikt het team wat in eerdere beurten al is opgehaald en bevestigd. De run draait binnen deze POST -- er is geen wachtrij. `Accept: text/event-stream` levert een live SSE-trace (200); anders het afgeronde resultaat (202, `status` is dan terminaal: `beantwoord` / `onbeantwoord` / `fout`). Vereist `X-API-Key` (tier `pro`/`admin`), geen `publiek`-endpoint: elke aanroep kan modelkosten maken.",
        "operationId": "postVraag",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "Accept",
            "in": "header",
            "required": false,
            "description": "`text/event-stream` schakelt naar de live SSE-trace.",
            "schema": {
              "type": "string",
              "enum": [
                "application/json",
                "text/event-stream"
              ]
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "vraag"
                ],
                "properties": {
                  "vraag": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 500,
                    "example": "welke gegevens hebben jullie van dit pand"
                  },
                  "gesprek_id": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true,
                    "description": "Story 1. Afwezig of null = start een nieuw gesprek. Een geldig gesprek_id vervolgt dat gesprek met een nieuwe beurt."
                  },
                  "bag_pand_id": {
                    "type": "string",
                    "pattern": "^[0-9]{16}$",
                    "nullable": true,
                    "description": "Bij een vervolgbeurt (beurt >= 2) moet dit gelijk zijn aan het pand van het gesprek, of afwezig blijven -- één gesprek gaat over één pand (D6)."
                  },
                  "adres": {
                    "type": "string",
                    "maxLength": 200,
                    "nullable": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Run afgerond (JSON-pad). `status` is terminaal, niet `\"loopt\"` -- afwijking van de vroege PoC-schets, expliciet in de Technische Eisen (de run draait binnen deze POST en is dan al klaar).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VraagRun"
                }
              }
            }
          },
          "200": {
            "description": "Live trace (SSE-pad, alleen bij `Accept: text/event-stream`). Headers `X-Vraag-Run-Id`, `X-Vraag-Gesprek-Id`, `X-Vraag-Beurt`; elk frame is een `VraagTraceEvent`; sluit altijd af met `run_eind` of `fout`.",
            "content": {
              "text/event-stream": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "`ongeldige_vraag` / `ongeldig_pand_id` / `ongeldig_adres` / `ongeldig_gesprek_id` (Story 1, geen geldige uuid v4) / `ander_pand_in_gesprek` (Story 1, D6: het gesprek gaat al over een ander pand).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "`geen_toegang` -- X-API-Key ontbreekt of onbekend."
          },
          "403": {
            "description": "`tier_onvoldoende` -- geen pro/admin-tier, of (Story 1, besluit 6) een guard zonder key_hash."
          },
          "404": {
            "description": "Story 1. `gesprek_onbekend` -- het gesprek bestaat niet, hoort bij een andere sleutel, of is verlopen. Geen onderscheid tussen die drie."
          },
          "409": {
            "description": "Story 1. `gesprek_beurtplafond` (het gesprek heeft zijn maximale aantal beurten gehad) of `gesprek_gesloten` (het gesprek is al gesloten, of het cumulatieve gespreksbudget is op)."
          },
          "413": {
            "description": "Body groter dan 4 KB."
          },
          "415": {
            "description": "Content-Type is geen application/json."
          },
          "429": {
            "description": "`vraag_dagbudget` -- deze sleutel is over zijn runs-per-dag heen (een beurt telt als run)."
          },
          "503": {
            "description": "`llm_niet_geconfigureerd` (ANTHROPIC_API_KEY ontbreekt, R1) of `persistentie_niet_beschikbaar` (ops.vraag_run/ops.vraag_gesprek bestaan nog niet).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v3/gesprek/{gesprek_id}": {
      "get": {
        "tags": [
          "vraag"
        ],
        "summary": "Haal een heel gesprek terug (Story 1, gesprekslaag)",
        "description": "Levert alle beurten van een gesprek op volgorde -- per beurt vraag, status, reden, antwoord, bronnen en (tenzij `?zonder_trace=1`) de trace-events op `seq`-volgorde. Gescopet op de sleutel die het gesprek begon: een andere sleutel krijgt dezelfde `404 gesprek_onbekend` als een onbekend gesprek.",
        "operationId": "getGesprek",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "gesprek_id",
            "in": "path",
            "required": true,
            "description": "UUID v4.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "zonder_trace",
            "in": "query",
            "required": false,
            "description": "`1` laat `runs[].trace` weg -- een lichte poll voor een chat-UI die alleen de status van elke beurt wil zien.",
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Het volledige gesprek.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VraagGesprek"
                }
              }
            }
          },
          "400": {
            "description": "`ongeldig_gesprek_id` -- geen geldige uuid, geen DB-call gedaan."
          },
          "401": {
            "description": "`geen_toegang` -- X-API-Key ontbreekt of onbekend."
          },
          "403": {
            "description": "`tier_onvoldoende` -- guard zonder key_hash (besluit 6)."
          },
          "404": {
            "description": "`gesprek_onbekend`, zonder detail en zonder onderscheid tussen \"bestaat niet\" en \"van iemand anders\"."
          },
          "503": {
            "description": "`persistentie_niet_beschikbaar` -- ops.vraag_gesprek bestaat nog niet."
          }
        }
      }
    },
    "/api/v3/vraag/{run_id}": {
      "get": {
        "tags": [
          "vraag"
        ],
        "summary": "Haal een vraag-run terug (trace + eindantwoord)",
        "description": "Levert de volledige run: vraag, status, eindantwoord, bronnen, `gesprek_id`/`beurt` (Story 1) en alle trace-events op `seq`-volgorde -- ook nadat de stream gesloten is en ook na een koude start. De terugvalweg als streaming tegenvalt. Gescopet op de sleutel die de run claimde (Story 1, B5): een andere sleutel krijgt dezelfde `404 run_onbekend`.",
        "operationId": "getVraagRun",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "description": "UUID v4.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "De volledige run.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VraagRun"
                }
              }
            }
          },
          "400": {
            "description": "`ongeldig_run_id` -- geen geldige uuid, geen DB-call gedaan."
          },
          "401": {
            "description": "`geen_toegang` -- X-API-Key ontbreekt of onbekend."
          },
          "403": {
            "description": "`tier_onvoldoende` -- guard zonder key_hash (Story 1, besluit 6)."
          },
          "404": {
            "description": "`run_onbekend`, zonder detail en zonder onderscheid tussen \"bestaat niet\" en \"van iemand anders\"."
          },
          "503": {
            "description": "`persistentie_niet_beschikbaar` -- ops.vraag_run bestaat nog niet. Bewust geen 404: dat zou een andere bewering zijn."
          }
        }
      }
    },
    "/api/v3/openapi.yaml": {
      "get": {
        "tags": [
          "meta"
        ],
        "summary": "OpenAPI-spec (YAML)",
        "description": "Levert deze OpenAPI-spec als YAML.",
        "operationId": "getOpenApiYaml",
        "responses": {
          "200": {
            "description": "OpenAPI-spec",
            "content": {
              "application/yaml": {
                "schema": {
                  "type": "string"
                }
              },
              "text/yaml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/api/v3/openapi.json": {
      "get": {
        "tags": [
          "meta"
        ],
        "summary": "OpenAPI-spec (JSON)",
        "description": "Levert deze OpenAPI-spec als JSON.",
        "operationId": "getOpenApiJson",
        "responses": {
          "200": {
            "description": "OpenAPI-spec",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/v3/docs": {
      "get": {
        "tags": [
          "meta"
        ],
        "summary": "Interactieve API-docs (Swagger UI)",
        "description": "HTML-pagina met Swagger UI die `openapi.yaml` rendert.",
        "operationId": "getDocsPage",
        "responses": {
          "200": {
            "description": "HTML-pagina",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "API-key voor `?detail=full` en hogere rate-limits."
      }
    },
    "schemas": {
      "RDCoordinate": {
        "type": "array",
        "minItems": 2,
        "maxItems": 2,
        "items": {
          "type": "number"
        },
        "description": "RD-coördinaat [x, y] in EPSG:28992.",
        "example": [
          121394,
          487383
        ]
      },
      "WGS84Coordinate": {
        "type": "array",
        "minItems": 2,
        "maxItems": 2,
        "items": {
          "type": "number"
        },
        "description": "WGS84 [lon, lat] in EPSG:4326 (GeoJSON-volgorde).",
        "example": [
          4.881,
          52.367
        ]
      },
      "GeoJSONPolygon": {
        "type": "object",
        "required": [
          "type",
          "coordinates"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "Polygon"
            ]
          },
          "coordinates": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "array",
                "items": {
                  "type": "number"
                }
              }
            }
          }
        }
      },
      "BronPad": {
        "type": "object",
        "required": [
          "api",
          "document_id",
          "deeplink",
          "peildatum",
          "extractie_methode",
          "confidence"
        ],
        "properties": {
          "api": {
            "type": "string",
            "example": "rp_v4"
          },
          "document_id": {
            "type": "string",
            "example": "NL.IMRO.0518.BP0123-VG01"
          },
          "artikel_pad": {
            "type": [
              "string",
              "null"
            ],
            "example": "4.2.1"
          },
          "deeplink": {
            "type": "string",
            "format": "uri"
          },
          "peildatum": {
            "type": "string",
            "format": "date"
          },
          "plan_versie": {
            "type": [
              "string",
              "null"
            ]
          },
          "extractie_methode": {
            "type": "string",
            "enum": [
              "native",
              "regex",
              "llm-opus",
              "llm-sonnet",
              "manual"
            ]
          },
          "confidence": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          },
          "hash_payload": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Identificatie": {
        "type": "object",
        "properties": {
          "pand_id": {
            "type": [
              "string",
              "null"
            ],
            "example": "0518100000123456"
          },
          "vbo_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "num_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "coordinaten": {
            "type": "object",
            "properties": {
              "rd": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/RDCoordinate"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "wgs84": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/WGS84Coordinate"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            }
          },
          "gemeente_code": {
            "type": [
              "string",
              "null"
            ],
            "example": "0518"
          },
          "gemeente_naam": {
            "type": [
              "string",
              "null"
            ]
          },
          "buurtcode": {
            "type": [
              "string",
              "null"
            ]
          },
          "wijkcode": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Energielabel": {
        "type": "object",
        "required": [
          "klasse"
        ],
        "properties": {
          "klasse": {
            "type": "string",
            "example": "C"
          },
          "geldig_tot": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          }
        }
      },
      "PandFeiten": {
        "type": "object",
        "properties": {
          "oppervlakte_m2": {
            "type": [
              "number",
              "null"
            ]
          },
          "bouwjaar": {
            "type": [
              "integer",
              "null"
            ]
          },
          "gebruiksdoel": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "aantal_vbos_in_pand": {
            "type": [
              "integer",
              "null"
            ]
          },
          "bouwlagen": {
            "type": [
              "integer",
              "null"
            ]
          },
          "nokhoogte_m": {
            "type": [
              "number",
              "null"
            ]
          },
          "daktype": {
            "type": [
              "string",
              "null"
            ]
          },
          "energielabel": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Energielabel"
              },
              {
                "type": "null"
              }
            ]
          },
          "woz_waarde": {
            "type": [
              "number",
              "null"
            ]
          },
          "fundering_type": {
            "type": [
              "string",
              "null"
            ]
          },
          "monument_status": {
            "type": "string",
            "enum": [
              "rijksmonument",
              "geen",
              "onbekend"
            ],
            "description": "'rijksmonument' = de bron noemt het pand zo; 'geen' = de bron zegt expliciet van niet; 'onbekend' = de bron zwijgt over dit pand (geldt voor het overgrote deel)."
          }
        }
      },
      "LeidendPlan": {
        "type": "object",
        "properties": {
          "identificatie": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "example": "bestemmingsplan"
          },
          "naam": {
            "type": [
              "string",
              "null"
            ]
          },
          "vastgesteld_op": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "status": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Bestemming": {
        "type": "object",
        "properties": {
          "hoofdgroep": {
            "type": "string",
            "example": "Wonen"
          },
          "naam": {
            "type": "string",
            "example": "Wonen-1"
          },
          "bron_artikel": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Dubbelbestemming": {
        "type": "object",
        "properties": {
          "hoofdgroep": {
            "type": "string",
            "enum": [
              "Waarde",
              "Leiding",
              "Waterstaat"
            ]
          },
          "naam": {
            "type": "string"
          },
          "regime": {
            "type": "string"
          },
          "bron_artikel": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Bouwvlak": {
        "type": "object",
        "properties": {
          "aanwezig": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "pand_binnen_bouwvlak": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "polygoon": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/GeoJSONPolygon"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "Maatvoeringen": {
        "type": "object",
        "properties": {
          "max_bouwhoogte_m": {
            "type": [
              "number",
              "null"
            ]
          },
          "max_goothoogte_m": {
            "type": [
              "number",
              "null"
            ]
          },
          "max_aantal_wooneenheden": {
            "type": [
              "integer",
              "null"
            ]
          },
          "max_bebouwingspercentage": {
            "type": [
              "number",
              "null"
            ]
          }
        }
      },
      "Functieaanduiding": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string"
          },
          "kwalificatie": {
            "type": "string",
            "enum": [
              "toelatend",
              "beperkend"
            ]
          },
          "brontekst": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Gebiedsaanduiding": {
        "type": "object",
        "properties": {
          "hoofdgroep": {
            "type": "string"
          },
          "naam": {
            "type": "string"
          },
          "regime_samenvatting": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "BruidsschatRegel": {
        "type": "object",
        "properties": {
          "akn_uri": {
            "type": "string",
            "example": "/akn/nl/act/mnre1034/2020/bruidsschat"
          },
          "onderwerp": {
            "type": "string"
          },
          "brontekst_excerpt": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Juridisch": {
        "type": "object",
        "properties": {
          "regime": {
            "type": "string",
            "enum": [
              "wro",
              "ow",
              "hybride",
              "ow_omgevingsplan",
              "onbekend"
            ]
          },
          "leidend_plan": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/LeidendPlan"
              },
              {
                "type": "null"
              }
            ]
          },
          "bestemming": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Bestemming"
              },
              {
                "type": "null"
              }
            ]
          },
          "dubbelbestemmingen": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Dubbelbestemming"
            }
          },
          "bouwvlak": {
            "$ref": "#/components/schemas/Bouwvlak"
          },
          "maatvoeringen": {
            "$ref": "#/components/schemas/Maatvoeringen"
          },
          "functieaanduidingen": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Functieaanduiding"
            }
          },
          "gebiedsaanduidingen": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Gebiedsaanduiding"
            }
          },
          "bruidsschat_regels": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BruidsschatRegel"
            }
          }
        }
      },
      "VerordeningStatus": {
        "type": "string",
        "enum": [
          "toegestaan",
          "voorwaardelijk",
          "verboden",
          "onbekend"
        ]
      },
      "Huisvestingsverordening": {
        "type": "object",
        "properties": {
          "van_toepassing": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "cvdr_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "splitsing_status": {
            "$ref": "#/components/schemas/VerordeningStatus"
          },
          "kamerverhuur_status": {
            "$ref": "#/components/schemas/VerordeningStatus"
          },
          "min_opp_per_woning_m2": {
            "type": [
              "number",
              "null"
            ]
          },
          "min_opp_pand_m2": {
            "type": [
              "number",
              "null"
            ]
          },
          "min_opp_artikel": {
            "type": [
              "string",
              "null"
            ]
          },
          "min_opp_bron_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "min_opp_confidence": {
            "type": [
              "string",
              "null"
            ]
          },
          "gemeente": {
            "type": [
              "string",
              "null"
            ]
          },
          "verordening_titel": {
            "type": [
              "string",
              "null"
            ]
          },
          "voorwaarden": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "Parkeerverordening": {
        "type": "object",
        "properties": {
          "van_toepassing": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "norm_per_woning": {
            "type": [
              "number",
              "null"
            ]
          },
          "afkoop_mogelijk": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "afkoop_bedrag_per_plaats": {
            "type": [
              "number",
              "null"
            ]
          }
        }
      },
      "Welstandsnota": {
        "type": "object",
        "properties": {
          "van_toepassing": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "gebiedsregime": {
            "type": [
              "string",
              "null"
            ]
          },
          "brontekst_excerpt": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "MonumentenVerordening": {
        "type": "object",
        "properties": {
          "van_toepassing": {
            "type": [
              "boolean",
              "null"
            ]
          }
        }
      },
      "ErfgoedVerordening": {
        "type": "object",
        "properties": {
          "van_toepassing": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "bouwhistorische_waardering": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "SplitsZone": {
        "type": "object",
        "properties": {
          "gemeente_code": {
            "type": "string"
          },
          "regio_naam": {
            "type": "string"
          },
          "zone_type": {
            "type": "string",
            "enum": [
              "verboden",
              "voorwaardelijk",
              "toegestaan",
              "onbekend"
            ]
          },
          "bron_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          }
        },
        "additionalProperties": true
      },
      "Beleid": {
        "type": "object",
        "properties": {
          "huisvestingsverordening": {
            "$ref": "#/components/schemas/Huisvestingsverordening"
          },
          "parkeerverordening": {
            "$ref": "#/components/schemas/Parkeerverordening"
          },
          "welstandsnota": {
            "$ref": "#/components/schemas/Welstandsnota"
          },
          "monumenten_verordening": {
            "$ref": "#/components/schemas/MonumentenVerordening"
          },
          "erfgoed_verordening": {
            "$ref": "#/components/schemas/ErfgoedVerordening"
          },
          "splits_zone": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SplitsZone"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "Geluidzone": {
        "type": "object",
        "properties": {
          "modaliteit": {
            "type": "string"
          },
          "db_klasse": {
            "type": "string"
          },
          "vereist_hwbe": {
            "type": "boolean"
          }
        }
      },
      "ExterneVeiligheid": {
        "type": "object",
        "properties": {
          "binnen_pr10_6": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "binnen_invloedsgebied": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "risicobronnen_nabij": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "Natura2000": {
        "type": "object",
        "properties": {
          "binnen_natura2000": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "stikstofgevoelig_in_omgeving": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "aerius_verplicht": {
            "type": [
              "boolean",
              "null"
            ]
          }
        }
      },
      "Bodem": {
        "type": "object",
        "properties": {
          "verdacht_locatie": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "sanering_uitgevoerd": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "onderzoek_vereist_bij_functiewijziging": {
            "type": [
              "boolean",
              "null"
            ]
          }
        }
      },
      "Fundering": {
        "type": "object",
        "properties": {
          "kwetsbaarheid_klasse": {
            "type": [
              "string",
              "null"
            ]
          },
          "score": {
            "type": [
              "number",
              "null"
            ]
          },
          "perc_voor_1970": {
            "type": [
              "number",
              "null"
            ]
          },
          "fgr": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "ExterneFactoren": {
        "type": "object",
        "properties": {
          "geluidzones": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Geluidzone"
            }
          },
          "externe_veiligheid": {
            "$ref": "#/components/schemas/ExterneVeiligheid"
          },
          "natura2000": {
            "$ref": "#/components/schemas/Natura2000"
          },
          "bodem": {
            "$ref": "#/components/schemas/Bodem"
          },
          "fundering": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Fundering"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "StillePotentie": {
        "type": "object",
        "properties": {
          "extra_lagen": {
            "type": [
              "integer",
              "null"
            ]
          },
          "extra_hoogte_m": {
            "type": [
              "number",
              "null"
            ]
          },
          "nieuwe_functies": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "headroom_score": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 1
          }
        }
      },
      "ScenarioKlasse": {
        "type": "string",
        "enum": [
          "kansrijk",
          "voorwaardelijk",
          "niet_kansrijk",
          "onbekend"
        ]
      },
      "ScenarioOnderbouwingItem": {
        "type": "object",
        "required": [
          "aspect",
          "bevinding",
          "invloed"
        ],
        "properties": {
          "aspect": {
            "type": "string"
          },
          "bevinding": {
            "type": "string"
          },
          "invloed": {
            "type": "string",
            "enum": [
              "positief",
              "voorwaarde",
              "blokkade",
              "neutraal"
            ]
          },
          "bron_pad": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "ProcedurelRoute": {
        "type": "object",
        "required": [
          "type",
          "kansrijkheid",
          "doorlooptijd_weken",
          "kosten_orde"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "bij_recht",
              "binnenplans",
              "bopa_regulier",
              "bopa_uitgebreid",
              "wijziging_omgevingsplan",
              "buitenplans_omgevingsvergunning"
            ]
          },
          "kansrijkheid": {
            "type": "string",
            "enum": [
              "hoog",
              "middel-hoog",
              "middel",
              "middel-laag",
              "laag"
            ]
          },
          "doorlooptijd_weken": {
            "type": "array",
            "minItems": 2,
            "maxItems": 2,
            "items": {
              "type": "integer",
              "minimum": 0
            }
          },
          "kosten_orde": {
            "type": "array",
            "minItems": 2,
            "maxItems": 2,
            "items": {
              "type": "number",
              "minimum": 0
            }
          },
          "onderbouwing_vereist": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "BevoegdGezag": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "example": "gemeente"
          },
          "naam": {
            "type": "string"
          },
          "oin": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "ScenarioProcedureel": {
        "type": "object",
        "properties": {
          "routes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProcedurelRoute"
            }
          },
          "bevoegd_gezag": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/BevoegdGezag"
              },
              {
                "type": "null"
              }
            ]
          },
          "indieningsvereisten": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "ScenarioPresentatie": {
        "type": "object",
        "required": [
          "samenvatting",
          "detail",
          "cta"
        ],
        "properties": {
          "samenvatting": {
            "type": "string"
          },
          "detail": {
            "type": "string"
          },
          "cta": {
            "type": "string"
          }
        }
      },
      "ScenarioOutcome": {
        "type": "object",
        "required": [
          "klasse",
          "vertrouwen",
          "onderbouwing",
          "voorwaarden",
          "blokkades",
          "procedureel",
          "presentatie",
          "versie"
        ],
        "properties": {
          "klasse": {
            "$ref": "#/components/schemas/ScenarioKlasse"
          },
          "vertrouwen": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          },
          "onderbouwing": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ScenarioOnderbouwingItem"
            }
          },
          "voorwaarden": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "blokkades": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "procedureel": {
            "$ref": "#/components/schemas/ScenarioProcedureel"
          },
          "presentatie": {
            "$ref": "#/components/schemas/ScenarioPresentatie"
          },
          "versie": {
            "type": "string",
            "example": "v3.0"
          }
        }
      },
      "ScenariosV3": {
        "type": "object",
        "required": [
          "splitsing_1_naar_2",
          "splitsing_1_naar_3plus",
          "kamerverhuur",
          "optoppen_dakopbouw",
          "bijbehorend_bouwwerk",
          "dakkapel",
          "transformatie_kantoor_naar_wonen",
          "transformatie_winkel_naar_wonen",
          "transformatie_bedrijf_naar_wonen",
          "bed_and_breakfast",
          "beroep_aan_huis",
          "mantelzorgwoning"
        ],
        "properties": {
          "splitsing_1_naar_2": {
            "$ref": "#/components/schemas/ScenarioOutcome"
          },
          "splitsing_1_naar_3plus": {
            "$ref": "#/components/schemas/ScenarioOutcome"
          },
          "kamerverhuur": {
            "$ref": "#/components/schemas/ScenarioOutcome"
          },
          "optoppen_dakopbouw": {
            "$ref": "#/components/schemas/ScenarioOutcome"
          },
          "bijbehorend_bouwwerk": {
            "$ref": "#/components/schemas/ScenarioOutcome"
          },
          "dakkapel": {
            "$ref": "#/components/schemas/ScenarioOutcome"
          },
          "transformatie_kantoor_naar_wonen": {
            "$ref": "#/components/schemas/ScenarioOutcome"
          },
          "transformatie_winkel_naar_wonen": {
            "$ref": "#/components/schemas/ScenarioOutcome"
          },
          "transformatie_bedrijf_naar_wonen": {
            "$ref": "#/components/schemas/ScenarioOutcome"
          },
          "bed_and_breakfast": {
            "$ref": "#/components/schemas/ScenarioOutcome"
          },
          "beroep_aan_huis": {
            "$ref": "#/components/schemas/ScenarioOutcome"
          },
          "mantelzorgwoning": {
            "$ref": "#/components/schemas/ScenarioOutcome"
          }
        }
      },
      "Meta": {
        "type": "object",
        "required": [
          "versie",
          "engine_versie",
          "gegenereerd_op",
          "cache_hit",
          "refresh_strategy",
          "qa_status",
          "privacy_check"
        ],
        "properties": {
          "versie": {
            "type": "string",
            "example": "v3.0"
          },
          "engine_versie": {
            "type": "string",
            "example": "v3.0-mvp"
          },
          "gegenereerd_op": {
            "type": "string",
            "format": "date-time"
          },
          "cache_hit": {
            "type": "boolean"
          },
          "refresh_strategy": {
            "type": "string",
            "enum": [
              "pre_compute",
              "on_demand",
              "hybrid"
            ]
          },
          "qa_status": {
            "type": "string",
            "enum": [
              "green",
              "amber",
              "red"
            ]
          },
          "privacy_check": {
            "type": "string",
            "enum": [
              "passed",
              "flagged"
            ]
          },
          "ontbrekende_velden": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "schema_versie": {
            "type": "string",
            "example": "v3.0"
          },
          "schema_validation": {
            "type": "object",
            "properties": {
              "ok": {
                "type": "boolean"
              },
              "violations": {
                "type": "integer",
                "minimum": 0
              },
              "warnings": {
                "type": "integer",
                "minimum": 0
              }
            }
          }
        }
      },
      "BronPerVeld": {
        "type": "object",
        "additionalProperties": {
          "oneOf": [
            {
              "$ref": "#/components/schemas/BronPad"
            },
            {
              "type": "null"
            }
          ]
        }
      },
      "PandContextV3": {
        "type": "object",
        "required": [
          "identificatie",
          "pand_feiten",
          "juridisch",
          "beleid",
          "externe_factoren",
          "stille_potentie",
          "scenarios",
          "bron_per_veld",
          "meta"
        ],
        "properties": {
          "identificatie": {
            "$ref": "#/components/schemas/Identificatie"
          },
          "pand_feiten": {
            "$ref": "#/components/schemas/PandFeiten"
          },
          "juridisch": {
            "$ref": "#/components/schemas/Juridisch"
          },
          "bp_bestemming": {
            "type": [
              "string",
              "null"
            ]
          },
          "beleid": {
            "$ref": "#/components/schemas/Beleid"
          },
          "externe_factoren": {
            "$ref": "#/components/schemas/ExterneFactoren"
          },
          "stille_potentie": {
            "$ref": "#/components/schemas/StillePotentie"
          },
          "scenarios": {
            "$ref": "#/components/schemas/ScenariosV3"
          },
          "bron_per_veld": {
            "$ref": "#/components/schemas/BronPerVeld"
          },
          "meta": {
            "$ref": "#/components/schemas/Meta"
          }
        }
      },
      "ApiError": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string",
            "example": "pand_niet_gevonden"
          },
          "bag_id": {
            "type": "string"
          },
          "hint": {
            "type": "string"
          },
          "detail": {
            "type": "string"
          }
        }
      },
      "VraagBron": {
        "type": "object",
        "description": "Letterlijk uit TOOL_CATALOGUS (api/v3/tool-detail.js): welke tool, welk systeem, welke deeplink.",
        "required": [
          "tool",
          "systeem",
          "url",
          "niveau",
          "bekende_beperkingen"
        ],
        "properties": {
          "tool": {
            "type": "string",
            "example": "bag-feiten"
          },
          "systeem": {
            "type": "string",
            "example": "BAG (Basisregistratie Adressen en Gebouwen) via Kadaster"
          },
          "url": {
            "type": "string",
            "nullable": true
          },
          "niveau": {
            "type": "integer"
          },
          "bekende_beperkingen": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "VraagTraceEvent": {
        "type": "object",
        "description": "Eén event uit de trace. `schema` versioneert de envelope: `vraag-trace/v1` (fase A, geen gesprek) of `vraag-trace/v2` (Story 1 -- `gesprek_id`/`beurt` verplicht op de envelope; Story 3+4 breidt binnen v2 de `agent`-lijst uit met `taxateur`/`bouwkundige` en levert `overleg` daadwerkelijk uit, zonder een nieuwe schemaversie). De elf `type`-waarden zijn een gesloten lijst (AC3).",
        "required": [
          "schema",
          "run_id",
          "seq",
          "ts",
          "agent",
          "type",
          "data"
        ],
        "properties": {
          "schema": {
            "type": "string",
            "enum": [
              "vraag-trace/v1",
              "vraag-trace/v2"
            ]
          },
          "run_id": {
            "type": "string",
            "format": "uuid"
          },
          "gesprek_id": {
            "type": "string",
            "format": "uuid",
            "description": "Story 1. Verplicht op een `vraag-trace/v2`-event, afwezig op v1."
          },
          "beurt": {
            "type": "integer",
            "minimum": 1,
            "description": "Story 1. Verplicht op een `vraag-trace/v2`-event, afwezig op v1."
          },
          "seq": {
            "type": "integer",
            "minimum": 1,
            "description": "Per run oplopend, geen gaten -- een eigenschap van de schrijver, niet van de aanroeper."
          },
          "ts": {
            "type": "string",
            "format": "date-time"
          },
          "agent": {
            "type": "string",
            "enum": [
              "systeem",
              "intake",
              "data",
              "taxateur",
              "bouwkundige",
              "regels",
              "verificatie",
              "woordvoerder"
            ],
            "description": "`systeem` is de loop zelf, geen persona -- run_start/run_eind/fout zijn geen handeling van een agent, en `systeem` mag ook geen `overleg` sturen. `taxateur` en `bouwkundige` (Story 3+4) claimen alleen als hun vak een tool-treffer heeft deze beurt; zonder treffer verschijnen ze niet in de trace."
          },
          "type": {
            "type": "string",
            "enum": [
              "run_start",
              "agent_start",
              "tool_call",
              "tool_resultaat",
              "claim",
              "verificatie",
              "afkeuring",
              "antwoord",
              "fout",
              "run_eind",
              "overleg"
            ]
          },
          "data": {
            "type": "object",
            "description": "Vorm hangt af van `type`; zie de eventtabel in de Technische Eisen van het werkitem. Bevat NOOIT de vraagtekst -- alleen `vraag_lengte` op `run_start`. Op `tool_resultaat` (Story 1): `hergebruikt_uit_beurt` (integer >= 1 of null) -- null/afwezig betekent deze beurt echt gelezen. Op `afkeuring` (Story 3+4, optioneel): `rol` -- de rol wiens claim afviel. Op `run_eind` (Story 3+4, optioneel): `specialisten_actief` -- array van rol-ids die deze beurt hebben gesproken."
          }
        }
      },
      "VraagRun": {
        "type": "object",
        "required": [
          "run_id",
          "status",
          "bronnen",
          "trace"
        ],
        "properties": {
          "run_id": {
            "type": "string",
            "format": "uuid"
          },
          "gesprek_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Story 1. Het gesprek waar deze beurt bij hoort."
          },
          "beurt": {
            "type": "integer",
            "minimum": 1,
            "nullable": true,
            "description": "Story 1. Het beurtnummer binnen het gesprek."
          },
          "vraag": {
            "type": "string",
            "description": "Alleen aanwezig op GET /api/v3/vraag/{run_id}; de POST-response draagt de vraagtekst niet terug."
          },
          "vraagtype": {
            "type": "string",
            "nullable": true,
            "enum": [
              "objectvraag",
              "mogelijkheidsvraag",
              null
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "beantwoord",
              "onbeantwoord",
              "fout"
            ]
          },
          "reden": {
            "type": "string",
            "nullable": true,
            "enum": [
              "geen_bron",
              "budget",
              "gespreksbudget",
              "tijdslimiet",
              "geen_pand",
              "antwoord_niet_gedekt",
              "verificatie_onbeschikbaar",
              "llm_fout",
              "persistentie_niet_beschikbaar",
              "wedervraag",
              "voorstel",
              null
            ]
          },
          "antwoord": {
            "type": "string",
            "nullable": true
          },
          "voorstellen": {
            "type": "array",
            "description": "#1485: vervolgstappen die de tafel aanbiedt, uit de vaste actiecatalogus (lib/vraag/voorstellen.js). Leeg bij runs zonder voorstellen.",
            "items": {
              "type": "object",
              "required": ["actie"],
              "properties": {
                "actie": {
                  "type": "string",
                  "enum": ["rapport", "bewaren", "monitoren", "zoeken", "huurwaarde"]
                },
                "argumenten": {
                  "type": "object"
                }
              }
            }
          },
          "bronnen": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VraagBron"
            },
            "description": "Nooit gevuld bij status \"beantwoord\" zonder ten minste één bron -- het model mag niet gokken (AC6)."
          },
          "verbruik": {
            "type": "object",
            "properties": {
              "toolcalls": {
                "type": "integer"
              },
              "llm_calls": {
                "type": "integer"
              },
              "input_tokens": {
                "type": "integer"
              },
              "output_tokens": {
                "type": "integer"
              },
              "duur_ms": {
                "type": "integer",
                "nullable": true
              }
            }
          },
          "beurten_resterend": {
            "type": "integer",
            "minimum": 0,
            "description": "Story 1. Alleen aanwezig op POST /api/v3/vraag: VRAAG_MAX_BEURTEN_PER_GESPREK min `beurt`."
          },
          "gesprek_status": {
            "type": "string",
            "enum": [
              "open",
              "gesloten"
            ],
            "description": "Story 1. Alleen aanwezig op POST /api/v3/vraag."
          },
          "trace_url": {
            "type": "string",
            "description": "Alleen aanwezig op POST /api/v3/vraag."
          },
          "gesprek_url": {
            "type": "string",
            "description": "Story 1. Alleen aanwezig op POST /api/v3/vraag: /api/v3/gesprek/{gesprek_id}."
          },
          "trace": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VraagTraceEvent"
            },
            "description": "Alleen aanwezig op GET /api/v3/vraag/{run_id}, op seq-volgorde."
          }
        }
      },
      "VraagGesprek": {
        "type": "object",
        "description": "Story 1. Het hele gesprek: gesprekstoestand plus alle beurten op volgorde (GET /api/v3/gesprek/{gesprek_id}).",
        "required": [
          "gesprek_id",
          "status",
          "beurten",
          "runs"
        ],
        "properties": {
          "gesprek_id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "gesloten"
            ]
          },
          "sluit_reden": {
            "type": "string",
            "nullable": true,
            "enum": [
              "gespreksbudget",
              "beurtplafond",
              null
            ]
          },
          "bag_pand_id": {
            "type": "string",
            "pattern": "^[0-9]{16}$",
            "nullable": true
          },
          "adres": {
            "type": "string",
            "nullable": true,
            "description": "Het adres bij bag_pand_id (#1433), of null bij een losse vraag of een adresloos pand."
          },
          "gestart_op": {
            "type": "string",
            "format": "date-time"
          },
          "laatste_beurt_op": {
            "type": "string",
            "format": "date-time"
          },
          "beurten": {
            "type": "integer",
            "minimum": 0
          },
          "beurten_max": {
            "type": "integer",
            "minimum": 1
          },
          "verbruik": {
            "type": "object",
            "description": "Som van het verbruik over alle beurten.",
            "properties": {
              "toolcalls": {
                "type": "integer"
              },
              "llm_calls": {
                "type": "integer"
              },
              "input_tokens": {
                "type": "integer"
              },
              "output_tokens": {
                "type": "integer"
              },
              "duur_ms": {
                "type": "integer"
              }
            }
          },
          "runs": {
            "type": "array",
            "description": "Op beurt oplopend.",
            "items": {
              "$ref": "#/components/schemas/VraagRun"
            }
          }
        }
      }
    }
  }
}
