Ga naar hoofdinhoud

weScan JSON Schema — Nijbegun Isolatieplan

This document describes the JSON format exported by weScan and imported into the Nijbegun insulation plan intake form.

Purpose

Once an advisor has created a customer and a building (with its rekenzone) in Nij Begun, they can upload a JSON file exported from weScan. This automatically fills in building elements, dimensions, and orientations in the intake form — removing the need to enter this data twice.

The import covers building geometry. Insulation values and installations still need to be filled in manually by the advisor. Adjacency defaults to outside air and should be verified per element.

Top-Level Fields

All top-level fields are optional. When present, they are applied to the existing building object/zone.

FieldTypeUnitDescription
building_yearstringConstruction year, e.g. "1978"
building_heightstringmTotal building height, e.g. "6.2"
building_layersarray of stringsGebruiksoppervlak per bouwlaag (floor area per storey), e.g. ["48.0", "44.0"]
front_facade_orientationstringFront-facade orientation ("Oriëntatie voorgevel") for every zone in the file — see Cardinal Points. Preferred.
cardinal_pointstringAccepted alias for front_facade_orientation
childrenGroupsarrayEither building elements (single-zone) or zone entries (multi-zone) — see Rekenzones

All numeric values must be strings, e.g. "28.0" not 28.0.

Rekenzones

The top-level childrenGroups supports two shapes:

  • Single-zone (default): the entries are building elements directly (walls, floor, roof, …). On import they are placed into one rekenzone. The top-level building_layers becomes that zone's floor areas per storey.
  • Multi-zone: the entries are rekenzone entries. Each becomes its own rekenzone. If any top-level entry is a rekenzone, the file is treated as multi-zone and all top-level entries must be rekenzone entries. (zone is accepted as an alias for rekenzone.)

A rekenzone entry has the following structure:

{
"type": "rekenzone",
"name": "Rekenzone A",
"building_layers": ["1.38", "13.9", "24.74", "2.72"],
"cardinal_point": "ne",
"childrenGroups": [ /* building elements for this zone */ ]
}
FieldRequiredTypeDescription
typeYes"rekenzone"Marks this entry as a rekenzone ("zone" also accepted)
nameNostringZone name. Defaults to "Rekenzone" (auto-numbered) when omitted.
building_layersNoarray of stringsFloor area per storey (m²) for this zone
cardinal_pointNostringOrientation of this zone's front facade ("Oriëntatie voorgevel") — see Cardinal Points. Overrides the top-level front_facade_orientation; left blank when neither is given, and the advisor has to fill it in by hand.
childrenGroupsNoarrayBuilding elements in this zone — same structure as below

The front-facade orientation is never guessed from the geometry: each wall's orientation in the calculation is derived relative to it, so an inferred value would skew every wall in the zone.

When importing a multi-zone file, one new rekenzone is created per rekenzone entry. Multi-zone files always create new zones (they are never merged into an existing zone).

Building Elements (childrenGroups)

Each element in childrenGroups has the following structure:

{
"type": "walls",
"name": "Voorgevel",
"additionalFields": { ... },
"childrenGroups": [ ... ]
}

Common Fields

FieldRequiredTypeDescription
typeYesstring (enum)Element type — see Element Types
nameNostringDisplay label in the intake form. Defaults to the Dutch element type name if omitted ("Gevel", "Vloer", "Dak", "Dakkapel", "Raam", "Deur", "Paneel").
additionalFieldsNoobjectGeometry properties — all values must be strings. Omit the key entirely if no geometry is provided.
childrenGroupsNoarrayChild elements (openings inside this element). Defaults to [] if omitted.

additionalFields per Element Type

All fields inside additionalFields are optional. Omitted fields are left blank in the intake form and must be filled in manually.

FieldUnitApplies toDescription
surface_areaAll typesMeasured area. Gross, including any openings, for walls, floors and roofs; for a door it is the opaque area with any glass already subtracted — see Doors with glass in them.
heightmAll typesElement height
widthmAll typesElement width
cardinal_pointwalls, roof, windowOrientation — see Cardinal Points. Defaults to s.
inclination°walls, floor, roof, dakkapelTilt angle: 0 = flat, 90 = vertical. Decimal values ("52.0") are accepted and rounded to whole degrees. A roof with inclination 0 is imported as a flat roof. Subgeometries inherit the parent value when omitted. Defaults: wall=90, sloped roof=45, floor/flat roof=0.
adjacencywalls, floor, roofAdjoining space — see Adjacency Types. Defaults to buitenlucht when omitted.
perimetermfloorPerimeter of the floor element
glass_insulationwindowGlass type — see Glass Types
windowFrameKindwindow, panelFrame material — see Frame Types
insulationobjectwalls, floor, roof, panelInsulation and cavity data — see Isolation. Preferred over the flat keys below. isolation is accepted as a legacy alias.
rc_valuem²K/Wwalls, floor, roof, panelInsulation Rc value. Leading — when present, insulation is set to "yes (Rc value)".
insulation_thicknessmmwalls, floor, roof, panelInsulation thickness. Used only when rc_value is absent; insulation is then set to "yes (known insulation)".
has_cavityboolwalls, panelWhether a cavity (spouw) is present. Overrides the year-based default.
cavity_depthmmwalls, panelCavity (spouw) depth. Optional; only applied when has_cavity is true.

GUIDs and index values are auto-generated on import — do not include them in the JSON.

Isolation mapping

Isolation data is optional per element and may be given in either form. When both are present the flat keys win, as they are the more specific.

Preferred: the nested insulation object

"insulation": {
"bouwjaar": 1964,
"spouw_aanwezig": false,
"isolatie_aanwezig": "Onbekend",
"isolatiedikte_onbekend": true,
"isolatiedikte_mm": 60
}

Both insulation (preferred) and the original isolation spelling are read, and either one is consumed on import. Sending both — as the current export does — is harmless; they must then hold the same data, because insulation wins.

FieldTypeEffect
spouw_aanwezigboolSets the cavity (spouw) for walls and panels. Send this explicitly. When it is absent the intake form falls back to a year-based default that assumes a cavity is present, which changes the calculation.
isolatie_aanwezig"Ja" / "Nee" / "Onbekend"Whether insulation is present. Matched case-insensitively.
isolatiedikte_onbekendboolMarks the thickness as unknown. Only takes effect when no usable isolatiedikte_mm is given — see below.
isolatiedikte_mmnumberInsulation thickness in mm.
bouwjaarnumberNot imported. The form's construction-year field is a year bracket, not a year. Set the construction year once at the top level via building_year.

Unlike the rest of additionalFields, the values inside insulation may be real JSON booleans and numbers; strings are accepted too.

A measured thickness wins. When isolatiedikte_mm is greater than 0 it is imported as a known thickness, even if isolatiedikte_onbekend is true or isolatie_aanwezig is "Onbekend" — both combinations occur in practice, and discarding a real measurement only forces the advisor to re-enter it. The resolution order is:

  1. isolatie_aanwezig: "Nee" → no insulation.
  2. isolatiedikte_mm > 0 → insulation present with that thickness.
  3. isolatie_aanwezig: "Ja" → insulation present, thickness unknown.
  4. anything else → unknown.

The object is read on walls, floor, roof and panel. A paneel is an opaque part of a facade with its own insulation and cavity in the intake form, so both are imported for it. It is ignored on windows and doors, whose thermal properties come from glass_insulation and windowFrameKind, and on a dakkapel, which has no insulation of its own — send it on the dakkapel's walls and roof instead.

Alternative: flat keys

  • rc_value is leading: if present, it is used and insulation_thickness is ignored.
  • otherwise insulation_thickness is used.
  • has_cavity / cavity_depth set the cavity (spouw) for walls.

When neither form is present, the element keeps the form's default isolation (no insulation + a year-based cavity depth) for the advisor to complete.

Element Types

ValueDefault nameDescription
wallsGevelFacade / exterior wall
floorVloerGround floor or intermediate floor
roofDakSloped or flat roof
dakkapelDakkapelDormer (child of roof) — see Dakkapellen
windowRaamWindow (child of walls or roof)
doorDeurDoor (child of walls)
panelPaneelOpaque panel in a facade (child of walls)

Windows, doors and panels are nested as childrenGroups inside their parent wall or roof element.

Dakkapellen

A dormer is a dakkapel element nested inside the roof it sits on, carrying its own walls and roof:

{
"type": "roof",
"name": "Hellend dak voor",
"additionalFields": { "surface_area": "30.0", "inclination": "52.0", "cardinal_point": "ne" },
"childrenGroups": [
{
"type": "dakkapel",
"additionalFields": { "surface_area": "4.2", "width": "2.4", "height": "1.75" },
"childrenGroups": [
{
"type": "walls",
"name": "Dakkapel voorzijde",
"additionalFields": {
"surface_area": "2.4", "width": "2.4", "height": "1.0",
"cardinal_point": "ne", "inclination": "90",
"insulation": { "spouw_aanwezig": false, "isolatie_aanwezig": "Ja",
"isolatiedikte_onbekend": false, "isolatiedikte_mm": 60 }
},
"childrenGroups": [
{ "type": "window", "additionalFields": { "surface_area": "1.2", "glass_insulation": "hrPlusPlusGlas" } }
]
},
{
"type": "roof",
"name": "Dakkapel dak",
"additionalFields": {
"surface_area": "1.8", "inclination": "0.0",
"insulation": { "isolatie_aanwezig": "Ja", "isolatiedikte_onbekend": false, "isolatiedikte_mm": 80 }
}
}
]
}
]
}
  • The dakkapel itself is a container: send its surface_area (the area it takes out of the parent roof) and dimensions, but no adjacency and no insulation — those belong on its walls and roof.
  • Its inclination is inherited from the parent roof when omitted, falling back to 45.
  • Its walls and roof behave exactly like any other gevel or dak: adjacency, insulation, cavity, flat-roof detection and openings all apply. A dakkapel roof with inclination 0 is imported as a flat roof.
  • The dakkapel's roofs count towards the object's "Type dak", so a sloped main roof plus a flat dakkapel roof yields deels plat dak.

Doors with glass in them

surface_area on a door is the opaque area — the door leaf with any glass already subtracted. weScan sends it that way, and the import keeps it: a door whose surface_area is smaller than width × height is imported as a polygon so the measured value is authoritative and the form will not recalculate it from the bounding box. Without that, a 0.9 × 2.35 door reported as 1.27 m² would be inflated to 2.12 m².

The glazed part is emitted as a window alongside the door, under the same parent wall, carrying its own glass_insulation.

Nesting the window inside the door is also supported: the import then subtracts each nested opening from the door itself, so in that shape the door's surface_area should be the full leaf area including the glass. Only send one of the two shapes — sending the glass area both inside the door's area and as a nested window would subtract it twice.

Derived on import

These are computed from the geometry — do not send them:

FieldDerived from
Object "Type dak"The imported roofs: all flat → plat dak, none flat → hellend dak, a mix → deels plat dak
Element "Plat dak"A roof whose inclination is 0, including a dakkapel roof
Shape ("Rechthoek" / "Overig")Whether width × height matches surface_area; applies to walls, roofs, doors, panels and dakkapellen

Cardinal Points

ValueDutchDutch abbr.English
nNoordNNorth
neNoord-OostNONorth-East
eOostOEast
seZuid-OostZOSouth-East
sZuid (default)ZSouth
swZuid-WestZWSouth-West
wWestWWest
nwNoord-WestNWNorth-West

Any column is accepted, in any casing, with or without spaces/hyphens — so ne, NO, NE, Noord-Oost, noordoost and North East all mean the same thing. The Dutch and English abbreviations never conflict: Dutch O and Z only occur where English uses E and S, and N, W and NW mean the same in both languages.

On walls, roofs and windows (cardinal_point) an unrecognised value falls back to s. For the front-facade orientation an unrecognised value is left blank instead, so the advisor fills it in rather than the calculation silently using a wrong reference.

Glass Types

Applies to window elements only via glass_insulation.

ValueDescription
enkelGlasEnkel glas
dubbelGlasDubbel glas
hrGlasdubbelGlasMetCoatingHR glas
hrPlusGlasHR+ glas
hrPlusPlusGlasHR++ glas
tripleHrGlasDriedubbel glas

Full Example

A single-zone file in the current format: a front-facade orientation, nested isolation objects, a decimal roof inclination, and a window nested inside a door.

{
"building_year": "1978",
"building_height": "6.2",
"building_layers": ["48.0", "44.0"],
"front_facade_orientation": "ZW",
"childrenGroups": [
{
"type": "walls",
"name": "Voorgevel",
"additionalFields": {
"surface_area": "28.0",
"height": "5.4",
"width": "5.2",
"cardinal_point": "s",
"adjacency": "buitenlucht",
"insulation": {
"spouw_aanwezig": false,
"isolatie_aanwezig": "Ja",
"isolatiedikte_onbekend": false,
"isolatiedikte_mm": 80
}
},
"childrenGroups": [
{
"type": "window",
"name": "Raam woonkamer",
"additionalFields": {
"surface_area": "3.6",
"height": "1.5",
"width": "2.4",
"glass_insulation": "hrPlusPlusGlas",
"windowFrameKind": "woodOrPlastic"
}
},
{
"type": "door",
"name": "Voordeur",
"additionalFields": {
"surface_area": "1.98",
"height": "2.2",
"width": "0.9"
},
"childrenGroups": [
{
"type": "window",
"name": "Raam voordeur",
"additionalFields": {
"surface_area": "0.33",
"height": "0.44",
"width": "0.76",
"glass_insulation": "enkelGlas",
"windowFrameKind": "woodOrPlastic"
}
}
]
}
]
},
{
"type": "walls",
"additionalFields": {
"surface_area": "38.0",
"height": "5.4",
"width": "7.0",
"cardinal_point": "e",
"adjacency": "aangrenzendeOnverwarmdeRuimte",
"insulation": {
"spouw_aanwezig": false,
"isolatie_aanwezig": "Onbekend",
"isolatiedikte_onbekend": true,
"isolatiedikte_mm": 0
}
}
},
{
"type": "floor",
"name": "Begane grondvloer",
"additionalFields": {
"surface_area": "48.0",
"perimeter": "28.0",
"adjacency": "kruipruimte",
"insulation": {
"spouw_aanwezig": false,
"isolatie_aanwezig": "Nee",
"isolatiedikte_onbekend": false,
"isolatiedikte_mm": 0
}
}
},
{
"type": "roof",
"name": "Hellend dak voor",
"additionalFields": {
"surface_area": "30.0",
"height": "5.0",
"width": "6.0",
"cardinal_point": "s",
"inclination": "52.0",
"insulation": {
"isolatie_aanwezig": "Ja",
"isolatiedikte_onbekend": false,
"isolatiedikte_mm": 200
}
},
"childrenGroups": [
{
"type": "window",
"name": "Dakraam",
"additionalFields": {
"surface_area": "0.9",
"height": "0.9",
"width": "1.0",
"glass_insulation": "dubbelGlas"
}
}
]
},
{
"type": "roof",
"name": "Plat dak achter",
"additionalFields": {
"surface_area": "8.0",
"height": "4.0",
"width": "2.0",
"inclination": "0.0"
}
}
]
}

The roof with inclination "0.0" is imported as a flat roof, and because the file mixes a flat and a sloped roof the object's "Type dak" becomes deels plat dak. The dakraam inherits the 52° of its parent roof.

Adjacency Types

Applies to walls, floor, and roof elements via adjacency. Defaults to buitenlucht when omitted or unrecognised.

ValueDescription
buitenluchtOutside air (default)
waterWater
grondGround
kruipruimteCrawl space
aangrenzendeOnverwarmdeRuimteAdjacent unheated space
aangrenzendeOnverwarmdeSerreAdjacent unheated conservatory
aangrenzendeSterkGeventileerdeRuimteAdjacent strongly ventilated space
aangrenzendeOnverwarmdeKelderAdjacent unheated basement
aangrenzendeVerwarmdeRuimteAdjacent heated space

Matching ignores case, spaces, underscores and hyphens, so the Dutch labels above ("Aangrenzende onverwarmde ruimte") are accepted as well as the exact values. These abbreviations are also recognised:

AbbreviationMaps to
AORaangrenzendeOnverwarmdeRuimte
ASGRaangrenzendeSterkGeventileerdeRuimte
AVRaangrenzendeVerwarmdeRuimte
AOSaangrenzendeOnverwarmdeSerre
AOKaangrenzendeOnverwarmdeKelder

Each abbreviation maps to what it stands for. AOR and ASGR are different spaces with different temperature factors in the calculation, so use AOR for an adjacent unheated space and ASGR only for a strongly ventilated one. Prefer the exact values over abbreviations so there is no ambiguity at all.

Frame Types

Applies to window and panel elements via windowFrameKind.

ValueDescription
woodOrPlasticWood or plastic frame
metalThermallyBrokenMetal, thermally broken
metalNonThermallyBrokenMetal, not thermally broken

Validation Rules

  • type is the only required field per element; all other fields are optional
  • If name is omitted, the import assigns the Dutch default for the element type
  • If childrenGroups is omitted, it defaults to an empty list
  • All additionalFields values must be strings, not numbers
  • glass_insulation only applies to window elements
  • windowFrameKind applies to window and panel elements
  • inclination applies to walls, floor, roof and dakkapel; subgeometries inherit from parent
  • adjacency applies to walls, floor and roof; defaults to buitenlucht when omitted. Not on a dakkapel — put it on its walls and roof.
  • perimeter only applies to floor elements
  • cardinal_point defaults to s when omitted on walls and roofs
  • window, door and panel may appear as children of walls or roof
  • window and panel may also appear as children of a door — an opening inside a door
  • front_facade_orientation at the top level, or cardinal_point on a rekenzone, sets the front-facade orientation
  • insulation (or its isolation alias) applies to walls, floor, roof and panel; its values may be booleans or numbers
  • a dakkapel may appear as a child of a roof, and carries its own walls and roof
  • a door's surface_area is its opaque area, with any glass already subtracted