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.
| Field | Type | Unit | Description |
|---|---|---|---|
building_year | string | — | Construction year, e.g. "1978" |
building_height | string | m | Total building height, e.g. "6.2" |
building_layers | array of strings | m² | Gebruiksoppervlak per bouwlaag (floor area per storey), e.g. ["48.0", "44.0"] |
front_facade_orientation | string | — | Front-facade orientation ("Oriëntatie voorgevel") for every zone in the file — see Cardinal Points. Preferred. |
cardinal_point | string | — | Accepted alias for front_facade_orientation |
childrenGroups | array | — | Either building elements (single-zone) or zone entries (multi-zone) — see Rekenzones |
All numeric values must be strings, e.g.
"28.0"not28.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-levelbuilding_layersbecomes that zone's floor areas per storey. - Multi-zone: the entries are
rekenzoneentries. Each becomes its own rekenzone. If any top-level entry is arekenzone, the file is treated as multi-zone and all top-level entries must berekenzoneentries. (zoneis accepted as an alias forrekenzone.)
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 */ ]
}
| Field | Required | Type | Description |
|---|---|---|---|
type | Yes | "rekenzone" | Marks this entry as a rekenzone ("zone" also accepted) |
name | No | string | Zone name. Defaults to "Rekenzone" (auto-numbered) when omitted. |
building_layers | No | array of strings | Floor area per storey (m²) for this zone |
cardinal_point | No | string | Orientation 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. |
childrenGroups | No | array | Building 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
rekenzoneentry. 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
| Field | Required | Type | Description |
|---|---|---|---|
type | Yes | string (enum) | Element type — see Element Types |
name | No | string | Display label in the intake form. Defaults to the Dutch element type name if omitted ("Gevel", "Vloer", "Dak", "Dakkapel", "Raam", "Deur", "Paneel"). |
additionalFields | No | object | Geometry properties — all values must be strings. Omit the key entirely if no geometry is provided. |
childrenGroups | No | array | Child 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.
| Field | Unit | Applies to | Description |
|---|---|---|---|
surface_area | m² | All types | Measured 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. |
height | m | All types | Element height |
width | m | All types | Element width |
cardinal_point | — | walls, roof, window | Orientation — see Cardinal Points. Defaults to s. |
inclination | ° | walls, floor, roof, dakkapel | Tilt 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. |
adjacency | — | walls, floor, roof | Adjoining space — see Adjacency Types. Defaults to buitenlucht when omitted. |
perimeter | m | floor | Perimeter of the floor element |
glass_insulation | — | window | Glass type — see Glass Types |
windowFrameKind | — | window, panel | Frame material — see Frame Types |
insulation | object | walls, floor, roof, panel | Insulation and cavity data — see Isolation. Preferred over the flat keys below. isolation is accepted as a legacy alias. |
rc_value | m²K/W | walls, floor, roof, panel | Insulation Rc value. Leading — when present, insulation is set to "yes (Rc value)". |
insulation_thickness | mm | walls, floor, roof, panel | Insulation thickness. Used only when rc_value is absent; insulation is then set to "yes (known insulation)". |
has_cavity | bool | walls, panel | Whether a cavity (spouw) is present. Overrides the year-based default. |
cavity_depth | mm | walls, panel | Cavity (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.
| Field | Type | Effect |
|---|---|---|
spouw_aanwezig | bool | Sets 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_onbekend | bool | Marks the thickness as unknown. Only takes effect when no usable isolatiedikte_mm is given — see below. |
isolatiedikte_mm | number | Insulation thickness in mm. |
bouwjaar | number | Not 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:
isolatie_aanwezig: "Nee"→ no insulation.isolatiedikte_mm> 0 → insulation present with that thickness.isolatie_aanwezig: "Ja"→ insulation present, thickness unknown.- 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_valueis leading: if present, it is used andinsulation_thicknessis ignored.- otherwise
insulation_thicknessis used. has_cavity/cavity_depthset 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
| Value | Default name | Description |
|---|---|---|
walls | Gevel | Facade / exterior wall |
floor | Vloer | Ground floor or intermediate floor |
roof | Dak | Sloped or flat roof |
dakkapel | Dakkapel | Dormer (child of roof) — see Dakkapellen |
window | Raam | Window (child of walls or roof) |
door | Deur | Door (child of walls) |
panel | Paneel | Opaque 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
dakkapelitself is a container: send itssurface_area(the area it takes out of the parent roof) and dimensions, but noadjacencyand noinsulation— those belong on its walls and roof. - Its
inclinationis 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
inclination0 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:
| Field | Derived 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
| Value | Dutch | Dutch abbr. | English |
|---|---|---|---|
n | Noord | N | North |
ne | Noord-Oost | NO | North-East |
e | Oost | O | East |
se | Zuid-Oost | ZO | South-East |
s | Zuid (default) | Z | South |
sw | Zuid-West | ZW | South-West |
w | West | W | West |
nw | Noord-West | NW | North-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.
| Value | Description |
|---|---|
enkelGlas | Enkel glas |
dubbelGlas | Dubbel glas |
hrGlasdubbelGlasMetCoating | HR glas |
hrPlusGlas | HR+ glas |
hrPlusPlusGlas | HR++ glas |
tripleHrGlas | Driedubbel 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.
| Value | Description |
|---|---|
buitenlucht | Outside air (default) |
water | Water |
grond | Ground |
kruipruimte | Crawl space |
aangrenzendeOnverwarmdeRuimte | Adjacent unheated space |
aangrenzendeOnverwarmdeSerre | Adjacent unheated conservatory |
aangrenzendeSterkGeventileerdeRuimte | Adjacent strongly ventilated space |
aangrenzendeOnverwarmdeKelder | Adjacent unheated basement |
aangrenzendeVerwarmdeRuimte | Adjacent 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:
| Abbreviation | Maps to |
|---|---|
AOR | aangrenzendeOnverwarmdeRuimte |
ASGR | aangrenzendeSterkGeventileerdeRuimte |
AVR | aangrenzendeVerwarmdeRuimte |
AOS | aangrenzendeOnverwarmdeSerre |
AOK | aangrenzendeOnverwarmdeKelder |
Each abbreviation maps to what it stands for.
AORandASGRare different spaces with different temperature factors in the calculation, so useAORfor an adjacent unheated space andASGRonly 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.
| Value | Description |
|---|---|
woodOrPlastic | Wood or plastic frame |
metalThermallyBroken | Metal, thermally broken |
metalNonThermallyBroken | Metal, not thermally broken |
Validation Rules
typeis the only required field per element; all other fields are optional- If
nameis omitted, the import assigns the Dutch default for the element type - If
childrenGroupsis omitted, it defaults to an empty list - All
additionalFieldsvalues must be strings, not numbers glass_insulationonly applies towindowelementswindowFrameKindapplies towindowandpanelelementsinclinationapplies towalls,floor,roofanddakkapel; subgeometries inherit from parentadjacencyapplies towalls,floorandroof; defaults tobuitenluchtwhen omitted. Not on adakkapel— put it on its walls and roof.perimeteronly applies tofloorelementscardinal_pointdefaults toswhen omitted on walls and roofswindow,doorandpanelmay appear as children ofwallsorroofwindowandpanelmay also appear as children of adoor— an opening inside a doorfront_facade_orientationat the top level, orcardinal_pointon arekenzone, sets the front-facade orientationinsulation(or itsisolationalias) applies towalls,floor,roofandpanel; its values may be booleans or numbers- a
dakkapelmay appear as a child of aroof, and carries its ownwallsandroof - a
door'ssurface_areais its opaque area, with any glass already subtracted