Qualified Properties
A Qualified Property in Tandem is the internal name used to uniquely identify the property in the database. In the Tandem product UI, each Parameter has a description that gives it a Category, Name, Data Type, etc. These parameters exist in a Facility Template, which can then be applied to many different facilities (each with their own database). In addition, each facility may be composed of many models, where the property must be uniquely defined within each model.
When reading property values via POST scan or writing property values via POST mutate, it is necessary to know information about the property definition. For instance, both endpoints expect properties to be referenced by their internal “qualified” names. As an example, here is the body payload for a call to POST scan to find all elements with the property z:3wc attached to it.
{
"qualifiedColumns": [
"z:3wc"
],
"includeHistory": false
}
Let’s look at a specific example. Here is the definition of a Parameter in the Tandem product.

This is the general definition that exists in the Facility Template and can be used by many Facilities. To find out it’s qualified name for use in a specific Facility/Model, we can call the GET schema endpoint using a specific model URN. We can see the qualified property name highlighted in the return value below.
{
"id": "z:3wc",
"fam": "z",
"col": "3wc",
"name": "Param A",
"category": "JMA Test",
"dataType": 20,
"description": "Test string value A",
"flags": 16,
"context": "e"
},
{
"id": "z:4Ac",
"fam": "z",
"col": "4Ac",
"name": "M&Ms Color",
"category": "JMA Test",
"dataType": 20,
"description": "Test restricted values param",
"flags": 17,
"allowedValues": {
"list": [
"Green",
"Brown",
"Red",
"Yellow"
]
},
"context": "e"
},
{
"id": "z:4Qc",
"fam": "z",
"col": "4Qc",
"name": "Param B",
"category": "JMA Test",
"dataType": 3,
"description": "Test number value",
"flags": 16,
"context": "e"
}
Most API users will need to establish a mapping table to move back and forth between the property’s internal Qualified Name and it’s Display Name. This mapping table can be created using the results of /schema
.
Here are some enum values for internal structures that will help you parse this table.
Data Type enums:
export const AttributeType = {
// Numeric types
Unknown: 0,
Boolean: 1,
Integer: 2,
Double: 3,
Float: 4,
// Special types
BLOB: 10,
DbKey: 11, /* represents a link to another object in the database, using database internal ID */
DbKeyList: 12, /* represents a list of links to other objects within the same model */
ExDbKeyList: 13, /* represents a list of links to other objects in external models */
// String types
String: 20,
LocalizableString: 21,
DateTime: 22, /* ISO 8601 date */
GeoLocation: 23, /* LatLonHeight - ISO6709 Annex H string, e.g: "+27.5916+086.5640+8850/" for Mount Everest */
Position: 24, /* "x y z w" space separated string representing vector with 2,3 or 4 elements*/
Url: 25, /* URL string */
};
Context enums:
// Indicates what objects the attribute applies to. Can be a combination, for example, a setting of "et"
// means that the attribute applies to both elements and types
export const AttributeContext = {
Element: "e",
Type: "t",
Space: "s",
Facility: "f",
DONOTUSE_Logical: "l",
};
Bitmask values for Flags field:
// Bitmask values for boolean attribute options
export const AttributeFlags =
{
afHidden: 1 << 0, /* Attribute will not be displayed in default GUI property views. */
afDontIndex: 1 << 1, /* NOT USED Attribute will not be indexed by the search service. */
afDtHashV2: 1 << 1, /* in DT storage, used for DtParams that use content based hash function rather than UUID. This use overrides AfDontIndex from Forge, which we don't use */
afDirectStorage: 1 << 2, /* NOT USED Attribute is not worth de-duplicating (e.g. vertex data or dbId reference) */
afStream: 1 << 2, /* Actual attribute value on the element would be a stream of values, rather than an individual value */
afReadOnly: 1 << 3, /* Attribute is read-only (used when writing back to the design model, in e.g. Revit) */
afDtParam: 1 << 4, /* Attribute is a native DT parameter (user-defined Parameter) */
afStable: 1 << 5, /* NOT USED Attribute value should be stable between file versions (e.g. Revit Element ID, AutoCAD Entity Handle) */
};
Examples of how to use the dataType of Flags to check various conditions of the Property definition.
export function isAttributeTypeNumeric(type) {
return (
type === AttributeType.Integer ||
type === AttributeType.Double ||
type === AttributeType.Float
);
}
export function isAttributeTypeDateTime(type) {
return Number(type) === AttributeType.DateTime;
}
export function isUserDefinedProperty(flags) {
return (flags & AttributeFlags.afDtParam) !== 0;
}