The exact shapes: every configuration field with its JSON, the REST endpoints and the MCP tools. For what the product does and why — and the component reference — read the documentation.
The fields that need more than a tooltip, with the complete syntax where a JSON shape applies. Every field below is reachable three ways — the builder's sidebar, a supplier listing in the portal, and the MCP tools (solve_system, save_system, import_catalog_items) — and it is the same field in all three; the shapes here are what the API stores and returns. Defaults are the conservative reading of an unknown machine, never a placeholder: a compressor is fixed-speed until you say otherwise, a fan bank is independent sections, a tower is a fixed approach.
How a machine meets a part load, saved with the system (Design tab → Control strategy) and inherited by every building block that uses it. The demand side — setpoints, loads, occupancy — comes from the rooms a simulation serves; what you declare here is what the machine is.
A chiller's pipeInPipe evaporator may declare freezeCutoutC, its low-limit stat on the leaving water (3 °C is typical for plain water). On a trickle of flow a chiller cycling at its floor would otherwise be modelled from an on-state that leaves water far below zero; with the cutout the on-state is the capacity that lands the water on the cutout, at an evaporating temperature the machine can run at.
{
"roomSetpointC": 24,
"load": { "baseKw": 0, "slopeKwPerK": 0, "balanceTempC": 18 },
"supplyComponentId": "fan-1",
"modulate": true,
"selection": "minPower",
"stages": [
{ "name": "ventilation", "enabled": ["fan-1"] },
{ "name": "evaporative", "enabled": ["fan-1", "pack-1", "pump-1"] },
{ "name": "mechanical", "enabled": ["fan-1", "pack-1", "pump-1", "comp-1"] }
],
"supplyControl": { "type": "szvav", "supplySetpointC": 13, "minFlowRatio": 0.4, "resetMaxC": 18 },
"heating": {
"roomSetpointC": 20,
"load": { "baseKw": 0, "slopeKwPerK": 0, "balanceTempC": 16 },
"stages": [
{ "name": "ventilation", "enabled": ["fan-1"] },
{ "name": "heatPump", "enabled": ["fan-1", "comp-1"] },
{ "name": "heating", "enabled": ["fan-1", "comp-1", "heater-1"] }
]
},
"unoccupiedSetpointC": 28,
"occupiedHours": [false,false,false,false,false,false,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false]
}
| Field | Meaning |
|---|---|
stages | Ordered enable-sets; the first stage whose supply temperature reaches the requirement runs the hour, the last runs with met:false when none does. Omitted = derived from the graph: ventilation (fans) → evaporative (+ wet packs, pumps, water coils) → mechanical (+ compressors); heating: ventilation → heat pump (+ compressors) → heating (+ heaters). A cooling-only design must exclude its compressors from the heating stages — every air-coil circuit is heat-pump capable by default. |
selection | ordered (default): first stage that meets. minPower: the lowest electrical power among the stages that meet. |
modulate | Inverters ride their capacity down to the setpoint by bisection; fixed-speed machines cycle at full-load saturation temperatures and pay the AHRI 340/360 cycling degradation. Which one a compressor is comes from its own variableSpeed. |
supplyControl | {"type":"constantVolume"} (default) or {"type":"szvav", …}: single-zone VAV — the supply fan throttles toward minFlowRatio before the coil unloads, and resetMaxC (above the setpoint) lets the supply temperature float up as load falls. The measured worth on the example AHU: constant volume 12 841 kWh, SZVAV 7 773, SZVAV with reset 9 414. |
unoccupiedSetpointC + occupiedHours | Outside occupancy the machine starts from off, drops the air-only stages, and steers to the relaxed setpoint. Both halves or neither: relaxing the room's load while the control still holds the occupied setpoint costs 50 % more heating, measured. In a building run these come from the rooms' schedules and you do not set them. |
fanAuto | The thermostat's fan switch. true is AUTO: on an hour with no cooling or heating call the machine starts from off, fans included, the way an unoccupied hour already does. false (default) is ON: the ventilation stage runs through occupancy whether or not there is a call — right for a machine that is the rooms' outside air, wrong for one that is not (an evaporative cooler beside a rooftop that ventilates). A building block can override it (fanAuto on the block). |
hourlyLoadsKw | One value per weather hour, +cooling / −heating; overrides the modelled load for every hour the array covers. The zone editor's CSV import writes it. |
A compressor is an AHRI 540 / EN 12900 rating: two (optionally three) ten-coefficient polynomials in evaporating and condensing temperature, published in watts (mass flow in kg/s), of the form
X = C1 + C2·te + C3·tc + C4·te² + C5·te·tc + C6·tc² + C7·te³ + C8·te²·tc + C9·te·tc² + C10·tc³
— the order selection software exports. The catalog carries some 4 800 manufacturer maps already; paste your own only for a machine that is not there.
{
"model": "Danfoss VZH088CJ (R410A scroll, 50 Hz)",
"refrigerant": "R410A",
"capacityCoefficients": [49941.1, 1720.81, -63.2423, 26.7946, 0.00183626, -4.70348, 0.114679, -0.184863, -0.188105, -0.00503575],
"powerCoefficients": [5508.63, 168.934, 49.9583, 6.42313, -8.88073, 3.39995, 0.0898196, -0.158666, 0.0967435, -0.0140492],
"massFlowCoefficients": [0.2413, 0.00812, -0.00031, 0.000131, 0.0000041, -0.0000228, 0.00000053, -0.00000091, -0.00000092, -0.000000024],
"superheatRef": 10, "subcoolRef": 0,
"superheat": 10, "subcool": 5,
"heatRejectionFactor": 0.95,
"variableSpeed": true, "minSpeedRatio": 0.25, "maxSpeedRatio": 1.2,
"minCondensingC": 30,
"operatingEnvelope": { "vertices": [[-25,10],[-5,10],[25,40],[25,55],[15,68.5],[3.5,68.5],[-10,61],[-20,50],[-25,37.5]] },
"steps": [
{ "speedRps": 25, "capacityCoefficients": [ /* 10 */ ], "powerCoefficients": [ /* 10 */ ], "massFlowCoefficients": [ /* 10 */ ] },
{ "speedRps": 50, "capacityCoefficients": [ /* 10 */ ], "powerCoefficients": [ /* 10 */ ] },
{ "speedRps": 100, "capacityCoefficients": [ /* 10 */ ], "powerCoefficients": [ /* 10 */ ] }
]
}
| Field | Meaning |
|---|---|
superheatRef / subcoolRef | The superheat and subcooling the map was rated at (EN 12900: 10 K / 0 K; the old ARI point: 20 °F superheat, 15 °F subcooling). Every solve corrects the map from there to the operating superheat/subcool through the refrigerant's properties. |
variableSpeed | An inverter. Default false, which costs real energy — a fixed-speed machine cycles and pays the degradation; an inverter modulates and earns a part-load COP hump. Set it only for a genuine variable-speed machine. |
minSpeedRatio / maxSpeedRatio | Turndown and boost as fractions of the rating point (25–100 rps is 0.25). Below the minimum the machine cycles at that speed; above 1 the machine can be driven past its rating, which changes sizing. |
steps | AHRI 540 §5.3.3's published part-load ratings, each a full coefficient set at a speed. With three or more, power is read off the published curve between steps — interpolated against capacity, since that is what the control asks for. Fewer than three are ignored: a chord between a maximum and a minimum is worse than the flat scaling it would replace. Without steps a part load scales one map, which holds COP flat and over-states power by 7.5 % on average and 46 % at worst on the catalog's Danfoss VZH088. The fit_compressor_map MCP tool returns a ready steps[] from a rating table carrying speedRps. |
operatingEnvelope | Where the map may be trusted (AHRI 540 §3.15 forbids extrapolating past it). Either a rectangle {"teMin":-25,"teMax":25,"tcMin":10,"tcMax":68.5} or the polygon a datasheet actually draws, as [te, tc] vertices in either winding. A rectangle over-claims: the VZH088's bounding box asserts 68 °C condensing at −25 °C evaporating, a corner no scroll reaches, and an envelope that over-claims is a warning switched off exactly where extrapolating is most dangerous. A solve landing outside returns a warning, never a refusal. |
minCondensingC | Head-pressure control: the condensing temperature the condenser section is held at or above by staging its airflow down. A constraint, not an economy — it costs the compressor more than it saves the fans, and without it a model reports a mild-weather efficiency the controller never allows. |
reversible | true (default): the circuit runs backwards on heating hours — heat-pump heating on the same map, with the frost derate below 5 °C outside. false: a cooling-only circuit; heating stages leave it out and the heaters carry the heating, which is what a rooftop with a gas furnace does. Config, not catalog — a reversing valve is the system's. |
cyclingDegradation | A measured CD; omit to use the AHRI 340/360-2022 Eq. 5 correlation. |
capacityFactor | The one field that is yours rather than the map's: a multiplier for N identical machines on one circuit, or a derate. |
A fan's power is a curve, not an efficiency. With both curves present the operating point is found the way a selection program finds it — the published curve is one speed, a duty off it is reached by changing speed, and the fan laws give the power. The priority is powerCurve → efficiency → nameplate powerKw; a listing carrying only the last behaves as a fixed-power fan.
{
"airFlowM3s": 3.75, "powerKw": 5.9, "heatToAirFraction": 1.0,
"externalStaticPa": 950,
"curve": [[1.254, 1100], [1.877, 950], [2.542, 500], [3.043, 0]],
"powerCurve": [[1.254, 2.604], [1.877, 2.950], [2.542, 2.585], [3.043, 1.868]],
"stages": 2,
"arrangement": "sharedFace"
}
| Field | Meaning |
|---|---|
curve | The manufacturer's pressure curve, [flow m³/s, static Pa] ascending, per fan. With stages > 1 every curve read divides the bank's flow by the count — a listing is one machine, the count is your installation. |
powerCurve | Input power along the same curve at the same speed, [flow, kW]. A constant efficiency mis-states ebm-papst's own published points by 19–100 %, and reads zero at free delivery where the fan draws 1.87 kW. |
stages | How many equal fans this is. A staged bank's power falls linearly with the air it moves (each running fan is still at full speed); only a single throttled fan gets the cube law. Airflow quantises to whole fans. |
arrangement | independentSections (default; each fan its own coil section — AHRI 340/360 Example 8's measured arrangement) or sharedFace (one coil face, so a survivor rides out along its pressure curve when a neighbour stops: on two catalog RadiPacs the survivor delivers 69 % of the pair's air, not 50 %, and draws 2.52 kW against the staircase's 2.95). Needs curve; declared without one it keeps the staircase. |
Pump curve / powerCurve / externalHeadKpa | The water-side twins: [kg/s, kPa] and [kg/s, kW] at one speed, plus the pipework head the model cannot see. The loop's head is summed from its coils' tube and header drops and reported as headKpa; a curve that cannot cover the loop warns rather than silently shifting the flow. |
staticSetpointPa | Duct static-pressure setpoint, Pa. A VAV handler holds a static at its duct sensor as the boxes throttle, so the fan does not ride the square law down: Δp is p_set + (Δp_design − p_set)·s² and power P_design·s·Δp/Δp_design (a power curve is read at that point through the fan laws). At a third of design air a fan holding half its design Δp draws about a fifth of design power rather than a twenty-seventh. Absent = square-law system; a static-pressure reset (90.1 §6.5.3.2.3) is a lower setpoint. |
fuel (heater) | electric (default) or gas. A heater delivers duty capped at capacityKw and draws duty ÷ efficiency as input; electric books that as electricity, gas as fuel — totals.fuelKw on a solve, fuelKw hourly and totalFuelKwh on a run, never inside the electricity. A gas furnace at 0.8 is the catalog's Reznor class. |
Fin-and-tube geometry in catalog millimetres; the tube pattern is a preset and the fin form rides on it.
{ "faceHeightMm": 1473, "faceLengthMm": 1100, "rows": 4, "fpi": 12, "circuits": 12, "airFlowM3s": 4.0,
"pattern": { "type": "threeEighthsIn", "finEnhancement": 1.2 } }
{ "pattern": { "type": "custom", "tubeInnerDiameterMm": 8.7, "tubeOuterDiameterMm": 9.52,
"pitchLongitudinalMm": 22.0, "pitchTransverseMm": 25.4, "finThicknessMm": 0.115, "finAreaFactor": 1.0, "finEnhancement": 1.0 } }
finEnhancement multiplies the air-side coefficient: 1.0 plain (absent = plain, so every stored coil is unchanged), wavy/"configured" conventionally 1.1–1.3 (the sidebar's wavy is 1.2, the value that reconciles Colmac's and Carrier's published selections), louvered about 1.75. The model itself is anchored on Carrier's 36-point rating matrix within 1.03 % RMS and a measured dry coil within 0.14 % on UA; geometry stops discriminating as the air reaches saturation, so rows and fin spacing matter and the tube preset barely does (0.1 % of duty).
{ "faceHeightMm": 1200, "faceLengthMm": 1200, "depthM": 0.15, "airFlowM3s": 4.0,
"effectivenessCurve": [[1.0, 0.92], [2.0, 0.87], [3.0, 0.81]],
"waterFlowKgs": 4.0, "waterSideEffectiveness": 0.7,
"rated": { "hotWaterC": 35, "coldWaterC": 29.4, "wetBulbC": 25.6 } }
| Field | Meaning |
|---|---|
effectivenessCurve | The media's saturation effectiveness against face velocity, [m/s, ε]; absent = the EnergyPlus CelDek polynomial, which under-reads real media by 3–13 points against Munters' own sheets. A named catalog pad carries its maker's curve. |
| Water ports open | Adiabatic: constant wet bulb, the dry bulb approaches it with the effectiveness. No water fields matter. |
In a water loop, no rated | The legacy water cooler: the loop water approaches the entering wet bulb by the fixed waterSideEffectiveness, blind to airflow and L/G. |
rated | The tower's certified point — hot water, cold water, wet bulb — at this spec's own water and air flows. Present, the loop pass becomes Braun's enthalpy-basis ε-NTU model with the NTU derived once from this point and following water loading by (ṁw/ṁa)^0.4; anchored on Marley's 615-point and EVAPCO's 856-point performance tables within 0.27 and 0.11 K RMS. An impossible rating (cold at or under the wet bulb, hot not above cold, or beyond what an infinite tower could do at these flows) is ignored and the legacy model stands. |
{ "waterFlowKgs": 26, "waterFlowSecondaryKgs": 35, "economizer": true,
"rated": { "primaryInC": 12, "primaryOutC": 7.5, "secondaryInC": 6, "secondaryOutC": 9.35 } }
| Field | Meaning |
|---|---|
| Ports | waterIn/waterOut is the primary stream, waterInSecondary/waterOutSecondary the secondary — two water streams and no air. Counterflow; heat flows from the warmer stream to the colder, whichever side it is on. An open waterInSecondary takes its boundary as waterInlets["id:waterInSecondary"]. |
rated | The datasheet's four temperatures at this spec's own flows; the UA is derived from them through the counterflow LMTD. A point whose two sides do not balance within 10 %, or whose streams cross, is no rating and uaKwK answers instead. A plate with neither is refused. |
uaKwK | The conductance a listing would carry, used without a rating. |
economizer | The changeover valves of a free-cooling plant: transfer only when the secondary is colder than the primary. Off (the default, a plain exchanger) the plate exchanges either way — which on a summer day warms the chilled return with tower water. |
| In a building run | A block holding a leaving-water setpoint whose graph carries a plate gets a free cooling stage — everything but the compressors — ahead of its chiller stage; the first that meets the setpoint runs the hour. The example campus plant (New York) is arranged this way: the plate ahead of the evaporator on the chilled side and ahead of the condenser on the tower side, so it sees the coldest water and the chiller trims what is left. |
{ "airFlowM3s": 4.0, "airFlowSecondaryM3s": 1.0,
"role": "outsideAir",
"economizer": true, "economizerHighLimitC": 24, "economizerEnthalpy": false,
"occupiedFromHour": 7, "occupiedToHour": 21,
"dcv": true, "dcvBaseFraction": 0.33 }
| Field | Meaning |
|---|---|
| The two flows | Primary (outside air on an outside-air box) and secondary (return). These are the damper's minimum position, never a starting point — free cooling is not a reason to stop ventilating. |
role | outsideAir (default: the box with a damper somebody drives) or bypass (the downstream half of a face-and-bypass pair — no damper; scheduling it shut would send every kilogram across an idle coil). |
economizer | Cooling hours only: the damper is placed by solving the ventilation stage shut and wide open and interpolating to the required supply temperature (mixing is exactly linear in position). Opens only when outside is below the changeover economizerHighLimitC (90.1 Table 6.5.1.1.3; default 24 °C) and better than the return — by dry bulb, or by total heat with economizerEnthalpy, the device for a humid climate (22 °C at 95 % RH is cooler than a 26 °C room and carries more heat). |
occupiedFromHour / occupiedToHour | Inclusive, wrapping. Outside the window the outside-air damper's minimum is zero (90.1 §6.4.3.4.1); an economiser can still open it, so a night purge is free. Default 0–23 is the damper that never shut. Note a room's dayEnd is exclusive, so the same closing time is written one hour apart in the two places. |
dcv + dcvBaseFraction | Demand-controlled ventilation: the minimum position follows how full the served rooms are (90.1 §6.4.3.9, shaped by 62.1's Vbz = Rp·Pz + Ra·Az), falling to the per-area share dcvBaseFraction and no further. Compute the fraction from 62.1 Table 6.2.2.1 over the rooms this box's machine serves: Σ Ra·Az / Σ (Rp·Pz + Ra·Az) — 0.33 for a dining-plus-retail mix, 0.12 for an auditorium. Worth 6.5 MWh of heating a year on the example mall. |
Heat pipes and sensible cores carry minExhaustC: frost control as the lowest temperature the cooled side may leave at. The device derates — as a real core does, by bypassing part of itself — rather than blocking solid. Absent = unrestricted. It costs recovery (0.7 / 2.1 / 5.3 % of a Helsinki year's heating at 1 / 3 / 5 °C) and never binds in London.
{ "id": "food-court", "name": "Food court", "areaM2": 900, "heightM": 4.5, "envelopeUaKwK": 1.8,
"solarApertureM2": 40, "coolingSetC": 24, "heatingSetC": 20,
"setbackCoolingC": 28, "setbackHeatingC": 15, "recoveryKPerHour": 1.5,
"outdoorAirAch": 0.1, "moistureCapacityMultiplier": 15, "humidityLimitKgkg": 0.012,
"gains": { "dayKw": 45, "nightKw": 4, "latentDayKw": 12, "latentNightKw": 1, "dayStart": 7, "dayEnd": 21,
"occupancy": [0,0,0,0,0,0,0,0.1,0.2,0.4,0.6,0.7,0.8,0.8,0.8,0.8,0.7,0.6,0.5,0.4,0.2,0,0,0] } }
| Field | Meaning |
|---|---|
gains.occupancy | 24 fractions. Present, it replaces the day window: dayKw/latentDayKw are the gains at full occupancy, nightKw at none, each hour lands between, and "occupied" means the fraction is above zero. Any length but 24 is refused. Shape alone moves annual cooling +21 % on the example mall against a step schedule. |
setbackHeatingC / setbackCoolingC | The unoccupied band; absent = held to the occupied band around the clock. Worth a quarter of the example mall's heating. |
recoveryKPerHour | Optimum start: a ramp that reaches the setpoint exactly at opening, spreading recovery over ΔT/gradient hours. 1.5 K/h costs 18 % of the mall's heating for 369 → 42 unmet hours; assuming 3 K/h is cheaper and far less comfortable because a ramp that believes the machines recover twice as fast starts half as early. |
outdoorAirAch | The room's own leakage, moisture only (the sensible side is inside envelopeUaKwK). Outside air a mixing box brings in is already in the supply — counting it here too ventilates the room twice. |
moistureCapacityMultiplier | How much more vapour the room holds than its air (EnergyPlus's humidity capacity multiplier; NREL's effective moisture capacitance is 15). It moves no energy — buffering stores vapour and returns it — but hours above ASHRAE 55's 0.012 kg/kg collapse: 73 at ×1, 1 at ×8, 0 at ×15 on the example food court. |
humidityLimitKgkg | The room's humidity ceiling, kg/kg (ASHRAE 55's 0.012 is the usual figure, the same bound the humid-hours count uses). When the room would end the hour above it, its machine is asked for a supply dry enough as well as cool enough: the stage is judged and modulated on both, a fixed-speed machine cycles to the drier of the two, and a heater downstream of the cooling coil is enabled as reheat with the sensible requirement as its target. Without a reheat heater the room over-cools within its band. Absent = no humidity control. |
humidityFloorKgkg | The room's humidity floor, kg/kg (an operating suite's 30 % RH at 20 °C is 0.0044). When the room would end the hour under it, its machine's steam humidifier (the humidifier kind: capacityKgH, efficiency, fuel, and a design-point targetWKgkg the run overrides hourly) is steered to the supply humidity that lands the room on the bound, up to its capacity; the steam's energy is booked as electricity or gas. dryHours on the room counts the hours under the floor. Must sit under the ceiling. Absent = no floor. |
A VAV box per room, on the block that serves it (Simulate tab → select the block → VAV boxes, then a room's supply link under Connections to set its box). The box is not part of the machine's graph — the graph is one machine with one supply state, and the rooms and their boxes are the building's. Declaring any box makes the block a multi-zone VAV handler: every served room gets one (an undeclared room a default box — its area share of the fan, 30 % minimum, no reheat), and each room is handed what its own box delivered instead of a demand-proportional share of the block's supply.
{ "id": "s1", "label": "AHU-1", "serves": ["food-court", "retail", "concourse"],
"couplings": [{ "port": "fan:airOut", "role": "supplyAir" }],
"supplyControl": { "type": "szvav", "supplySetpointC": 13, "minFlowRatio": 0.3, "resetMaxC": 18 },
"terminals": [
{ "zone": "food-court", "maxFlowM3s": 1.6, "minFraction": 0.3, "reheat": { "kind": "hotWater", "maxKw": 12 } },
{ "zone": "retail", "minFraction": 0.3, "reheat": { "kind": "hotWater", "maxKw": 8 } },
{ "zone": "concourse", "minFraction": 0.3 } ] }
| Field | Meaning |
|---|---|
supplyControl | The handler's air-side strategy for this block, overriding the saved system's. Boxes need szvav: supplySetpointC is the coldest leaving air, resetMaxC the warmest the controller may reset to, minFlowRatio the fan's floor. The setpoint is reset from the critical zone (90.1 §6.5.3.5): as warm as the ceiling allows while the box that needs the most air still fits under its maximum — every degree warmer costs fan energy in that one room and saves reheat in all the others. |
maxFlowM3s | The box's maximum. A room whose load needs more than this at the coldest setpoint is unmet by air, whatever the coil could do. Absent: the room's area share of the fan's design flow. |
minFraction | Minimum damper position as a fraction of the maximum — ventilation (90.1 Appendix G's 30 %). It holds while the building is occupied and on heating hours; an empty building's boxes shut. |
reheat | When the minimum carries more cooling than the room wants — or the room wants heat on a cooling hour — the box reheats the excess up to maxKw, and it counts as heat delivered either way; electric counts as the block's electricity as well (the way its duct heater does), hotWater does not. Absent = a cooling-only box, which over-cools at its minimum and reports the room below its band. |
| heating hours | A VAV handler heats through its boxes: every box at its minimum, the handler at a neutral supply (the reset ceiling), each box reheating its own room. A room whose box cannot reheat is carried by the handler instead — its supply rises to what that room needs at its minimum, and the other rooms over-heat, which is what a reheat-less terminal on a warm deck does. |
| what you get back | Per room, reheatKwh; per block, an hourly reheatKw series and totalReheatKwh (inside the heating total as well, and the electricity total when electric). With one room and no reset ceiling the block reproduces single-zone VAV exactly. |
| the example | Riverside Mall's AHU-1 runs boxes on its three rooms — 15 % minimums, a 13 °C deck reset to 16 °C, electric reheat, the fan holding 125 Pa of duct static — the configuration a sweep picked: a warmer reset gave the food court's humid hours back, a colder deck cost a third more electricity, higher minimums cost reheat on every count. Open it on the Simulate tab to see the fields filled in. |
What a supplier fills in, and what each field does on the public page and in quote routing. A component listing is one catalog item — its spec is exactly the component spec above for its kind — plus the fields below; a system offering is a snapshot of one of your saved systems, taken at publish (editing the saved system later does not move the offering; republish to refresh it).
Category. Every system offering carries a category — one of the fixed set (air handler, rooftop / packaged, split / VRF, chiller, condensing unit, fan coil / terminal, evaporative cooler, heat recovery / DOAS, plant / tower, unit cooler / refrigeration) or a label of your own, up to 40 characters. It is what the systems directory facets on and what the Design tab's sources list filters by; an offering without one shows as unassigned until you set it. Saved systems carry the same field (category on POST /api/systems and in the MCP save_system / update_saved_system tools).
Reuse. A saved system may nest other systems (a system of systems: a published offering or one of your own as a node whose open ports connect like a component's). Publishing such a design flattens it into the offering's snapshot — and a nested offering of another supplier's is only flattened in if that supplier has ticked allowReuse on it (default off; the platform's examples allow it). A design that references an offering without it is refused by the offering's name.
// import_catalog_items — one fan and one compressor
{ "items": [
{ "kind": "fan", "name": "RadiPac K3G450-AQ24-90", "published": true, "regions": ["EU"], "tags": ["EC", "plug fan"],
"certification": "", "productUrl": "https://www.ebmpapst.com/…",
"spec": { "airFlowM3s": 1.877, "powerKw": 2.95, "heatToAirFraction": 1.0, "externalStaticPa": 950,
"curve": [[1.254, 1100], [1.877, 950], [2.542, 500], [3.043, 0]],
"powerCurve": [[1.254, 2.604], [1.877, 2.950], [2.542, 2.585], [3.043, 1.868]] } },
{ "kind": "compressor", "published": true, "regions": [], "certification": "AHRI 540",
"spec": { "model": "…", "refrigerant": "R32", "capacityCoefficients": [ /* 10 */ ], "powerCoefficients": [ /* 10 */ ],
"superheatRef": 10, "subcoolRef": 0, "variableSpeed": false,
"operatingEnvelope": { "teMin": -20, "teMax": 15, "tcMin": 20, "tcMax": 65 } } }
] }
| Field | What it does |
|---|---|
published | Draft or live. The free supplier tier keeps at most three listings live at once; the paid tier lifts the cap. Publishing an identical payload twice is refused as a duplicate. |
regions | Markets served, as region codes (EU, UK, NA, LATAM, MEA, CN, IN, APAC, or your own). Empty means worldwide. They are the directory's market facet, they route a lead to the territory rep you named for that region, and they are one of the four things a fan-out quote request matches on. |
tags | Free text for the directory's search; no other effect. |
certification | The programme the item is certified under (AHRI 540, Eurovent, CTI…), shown on the listing. Verified is a separate flag only a platform admin can set after checking the programme's public directory; the import tool refuses to set it. |
productUrl | Your own product page, linked from the listing. Carries rel="nofollow" until the supplier tier is paid. |
imageDataUri | A product photo; the portal downscales to 1600 px before upload, 2 MB after. The company logo lives on the profile, not per item. |
refrigerant (compressors) | Chosen from what the property backend serves — every fluid CoolProp loads on the live deploy. A listing naming anything else cannot be solved, and is flagged as such. |
spec.refrigerant (compressor) | One of the refrigerants this deployment's property backend can solve — GET /api/catalog/refrigerants lists them (R410A, R32, R454B, R454C, R290, R1234ze(E)… under CoolProp; R410A alone without it). A listing naming anything else is refused, in the portal and through import_catalog_items alike: a map nobody can run is not a listing. The map is corrected from superheatRef/subcoolRef to the operating superheat and subcooling on that fluid. |
A system offering adds:
| Field | What it does |
|---|---|
name, blurb | The public page's title and text. An empty blurb keeps the page out of search engines (noindex) — indexing is earned by a complete profile and a description. |
capacityMinKw / capacityMaxKw, heatingCapacityMinKw / heatingCapacityMaxKw, showCooling / showHeating | The range the offering is built for, per mode, and which modes the tile shows. They feed the directory's capacity bands, and the builder's "supplier systems that cover this duty" hint after a solve. |
| The snapshot | Graph and boundary as saved at publish. Engineers open it in their builder as a local copy — your components stay attached by their catalog references, so a later data correction on a listing reaches every design that picked it (see strict resolution). |
What routes a quote request to you (capability-routed RFQ): your declared capability kinds must cover the request's kinds; regions must overlap (empty on either side = worldwide; capability regions fall back to your listings' regions); the request's duty must fall inside your capacity envelope with a 20 % margin; refrigerants must overlap only when both sides declare any. Leads arrive by email instantly on the paid tier and after 24 hours on the free tier, which also caps at 20 leads per rolling month; delivery mode (instant / daily digest / none) is yours to set.