Object Shape Overview
Every Speckle object has a consistent shape, regardless of type. Conceptually, an object looks like this: This structure applies to all objects, though not all fields are present on all object types. Geometry objects have geometry-specific fields instead ofproperties and displayValue. Instance objects have a definitionId and transform instead.
Base Object Fields
All Speckle objects inherit fromBase and have these core fields:
id
The id is a content-based hash that uniquely identifies the object’s data. If two objects have the same content, they have the same id. This enables efficient deduplication and version control.
speckle_type
The speckle_type identifies what kind of object this is. Examples:
"Objects.Geometry.Point""Objects.Geometry.Mesh""Objects.Data.DataObject""Objects.Data.DataObject:Objects.Data.RevitObject"
applicationId
The applicationId is the identifier from the source application (e.g., a Revit element ID, a Rhino object GUID). This is how proxies reference objects.
DataObject Structure
DataObject is the most common object type for BIM elements. It extendsBase with these fields:
name
A human-readable name for the object (e.g., “Basic Wall - 200mm”, “Column A1”).
properties
A dictionary of key-value pairs containing all metadata about the object. This is where connector-specific data lives:
- Revit: Instance parameters, type parameters, material quantities
- Rhino: User strings, user dictionaries
- AutoCAD: Extension dictionaries, XData
properties dictionary can contain nested structures, but the values are always JSON-serializable.
Role of properties: Properties store semantic data—the “what” and “how” of an object (material, dimensions, classifications). They complement geometry stored in displayValue, which represents the “where” and “shape” of an object.
displayValue
An array of geometry objects that represent the visual appearance of this DataObject. Geometry objects (Point, Line, Mesh, Brep, etc.) are stored here, not as direct children.
Role of displayValue: The displayValue array contains the geometric representation—the visual shape of the object. This is distinct from the semantic meaning stored in properties. A wall DataObject has properties describing it as a wall (material, dimensions, type), while displayValue contains the mesh geometry showing where and how it appears in 3D space.
Distinction between DataObject, Semantic Object, and DisplayValue:
- DataObject is the container—it combines semantic data (
properties) with geometric representation (displayValue) - Semantic Object refers to the domain meaning encoded in
properties(e.g., “this is a wall with concrete material”) - DisplayValue is the geometric representation—the actual 3D geometry primitives that can be rendered
displayValue? This keeps DataObjects flat as a best practice—geometry is stored separately in an array, allowing multiple representations (mesh + curves + points) while maintaining a simple object structure. More importantly, displayValue uses minimum viable interoperable primitives (Meshes, Lines, Points) that almost all AEC and 3D software can ingest, even if they have no concept of higher-level objects like “Wall” or “TopologicalSurface”. This ensures maximum interoperability across different applications. Note that some DataObjects (like Revit curtain walls) may also have an elements property containing child DataObjects when required by the source application.
units
The unit system used for this object’s geometry (e.g., "m", "ft", "mm", "in").
Geometry Object Structure
Geometry objects are simpler—they represent pure geometric primitives:properties or displayValue—they are the geometry themselves.
Instance Structure
Instance objects represent block references or instanced geometry:definitionId references a Definition proxy that contains the actual geometry.
Interpreting Absent or Optional Fields
When processing objects, you may encounter missing or optional fields. Here’s how to interpret them:-
Missing
displayValue: The object has no geometric representation—it’s data-only (e.g., classification, metadata, analytical data). The object still has semantic meaning throughproperties. -
Empty
displayValuearray: Similar to missing—the object is intentionally data-only. Some connectors create objects for organizational or analytical purposes without geometry. -
Missing
properties: Only applies to Geometry objects, which don’t have apropertiesfield. DataObjects always haveproperties, though it may be an empty dictionary. -
Missing
applicationId: Some Geometry objects may not have anapplicationIdif they were created during conversion or processing. DataObjects should always have anapplicationId. -
Optional connector-specific fields: Fields like
type,family,category(on RevitObject) are connector-specific extensions. Their absence doesn’t indicate an error—they’re only present when the connector adds them.
Global Invariants
These rules apply to all objects:-
No nested DataObjects (guideline) - As a best practice, DataObjects should not contain other DataObjects as direct children. Use
displayValuefor geometry, and use proxies for relationships. However, some connectors (e.g., Revit curtain walls, IFC data) may use anelementsproperty to contain child DataObjects when the source application’s structure requires it. Traversal code should anticipate and handle both patterns. -
Geometry always in
displayValue- All visual geometry for a DataObject must be in thedisplayValuearray, not as direct properties. -
Objects always have core fields - Every object has
id,speckle_type,applicationId,units, and (for DataObjects)properties. -
Proxies reference by
applicationId- Proxies link to objects usingapplicationId, notid. - Hierarchy is Speckle-imposed - The collection hierarchy is created by Speckle connectors, not necessarily matching the source application’s structure exactly.
Why avoid nested DataObjects?
Why avoid nested DataObjects?
As a best practice, DataObjects should not contain other DataObjects to prevent deep nesting and keep the data model flat and predictable. The tree structure works best with a clear parent-child relationship through collections. For most hierarchical relationships (like a wall containing studs), use:
- Separate DataObjects in collections (spatial/categorical organization)
- Proxies to encode the relationship (functional/material relationships)
- Properties to store references (data-level relationships)
elements property on DataObjects when the source application’s structure requires it. Your traversal code should handle both patterns—check for elements properties on both Collections and DataObjects to ensure robust data processing.What's the difference between `id` and `applicationId`?
What's the difference between `id` and `applicationId`?
id: Speckle’s content-based hash. Same content = sameid. Used for deduplication and content-based versioning.applicationId: The source application’s identifier (Revit element ID, Rhino GUID, etc.). Used for references, proxies, and tracking objects across versions.
applicationId to track objects across versions (it’s more stable—the same logical element keeps the same applicationId even if its content changes). You use id for deduplication and content-based lookups. Proxies reference objects by applicationId.Connector-Specific Extensions
Some connectors extend DataObject with additional fields. For example:- RevitObject: Adds
type,family,category,level,location - NavisworksObject: Minimal extension (just inherits DataObject)
- Civil3dObject: Adds
baseCurves
Example: Complete DataObject
Here’s a realistic example of a Revit wall object:Conceptual Capability
After reading this page, you understand the structure of Speckle objects: how all objects inherit from Base with core identity fields, how DataObjects combine semantic data (properties) with geometric representation (displayValue), how Geometry objects represent pure primitives, and how Instance objects reference Definition proxies. You can interpret absent or optional fields and understand the distinction between semantic meaning and geometric representation. You’re ready to explore how geometry is structured within displayValue.
Next Steps
- Geometry Schema - How geometry objects are structured
- Proxy Schema - How proxies encode relationships