Template — Instance-Level Rule
Use this template as a starting point for rules that validate data on FamilyInstance objects: Mark, Level, Comments, and shared parameters that may live on either the instance or the type.
Copy the template, then adapt the configuration section at the top.
Template
(
/* ── Configuration ─────────────────────────────────────── */
$CategoryInclusion := ["OST_Doors", "OST_Windows"];
$paramGuids := {
"FireRating": "8fe8f5ce-4979-4679-b5e0-ccfb362b9059"
};
/* ── Parameter metadata index ───────────────────────────── */
$paramMetaByGuid := $merge(
$[type = "Parameter" and values.guid in $paramGuids.*].{
$string(values.guid): {
"guid": values.guid,
"name": values.name
}
}
);
/* ── Shared parameter helper ────────────────────────────── */
$getSharedParam := function($object, $logicalName) {(
$guid := $lookup($paramGuids, $logicalName);
$meta := $guid ? $lookup($paramMetaByGuid, $string($guid)) : undefined;
$sp := $guid and $exists($object.values)
? $lookup($object.values, "p_" & $guid)
: undefined;
{
"paramExist": $exists($sp),
"value": $exists($sp) ? $sp.value : null,
"hasValue": $exists($sp) ? $sp.hasValue : false,
"guid": $meta ? $meta.guid : $guid,
"name": $meta ? $meta.name : $logicalName
}
)};
/* ── Scope: loadable, non-in-place, model families ─────── */
$familyIds := $[
type = "Family"
and values.isEditable = true
and values.isInPlace = false
].id;
/* ── Symbol scope ───────────────────────────────────────── */
$symbolIds := $[
type = "FamilySymbol"
and parent.id in $familyIds
and values.category.type = "Model"
and values.category.label in $CategoryInclusion
].id;
/* ── Build symbol lookup index ──────────────────────────── */
$symIndex := $merge(
$[type = "FamilySymbol" and id in $symbolIds].{
$string(id): $
}
);
/* ── Main query: FamilyInstances ────────────────────────── */
$[type = "FamilyInstance" and parent.id in $symbolIds].(
$sym := $lookup($symIndex, $string(parent.id));
$sym ? {
"id": id,
"type": type,
"name": name,
"mark": values.mark,
"assemblyCode": $sym.values.assemblyCode,
"FireRating": $getSharedParam($, "FireRating")
} : ()
)
)
What to adapt
| Part | What to change |
|---|---|
$CategoryInclusion |
The categories this rule applies to |
$paramGuids |
Add or remove shared parameters by logical name and GUID |
| Output fields | Replace mark, assemblyCode, parameter calls with what the validator needs |
What not to change
- The Family scope conditions — correct defaults for all loadable family rules
- The symbol index pattern (
$symIndex) — this is the performant way to resolve type data per instance - The
$sym ? { ... } : ()guard — this skips instances whose type was not in scope, avoiding noise
If you do not need shared parameters
Remove $paramGuids, $paramMetaByGuid, and $getSharedParam. Keep the rest of the structure intact.
If you need Assembly Code scoping
Add to the FamilySymbol filter:
and $string(values.assemblyCode) ~> /^32\./
The symbol index will automatically carry only the in-scope symbols to the instance step.