| name | ifcos-syntax-api |
| description | Use when writing IfcOpenShell Python code that creates, modifies, or deletes IFC entities. Prevents the #1 AI mistake: using create_entity() or direct attribute assignment instead of ifcopenshell.api.run(). Covers all 30+ API modules, invocation patterns, parameter conventions, and the difference between api.run() and direct module calls. Keywords: ifcopenshell.api, api.run, create_entity, IFC, BIM, IfcWall, IfcSlab, API modules, ifcopenshell Python, how to use api.run, ifcopenshell tutorial.
|
| license | MIT |
| compatibility | Designed for Claude Code. Requires IfcOpenShell Python library. |
| metadata | {"author":"OpenAEC-Foundation","version":"1.0"} |
IfcOpenShell API Module System
Quick Reference
Critical Warnings
- ALWAYS use
ifcopenshell.api.run() or direct module calls for IFC mutations. NEVER modify entity attributes directly (e.g., wall.Name = "X") — use api.run("attribute.edit_attributes", ...) instead.
- ALWAYS import
ifcopenshell.api before calling any API function. The module uses lazy loading; functions are NOT available without this import.
- ALWAYS pass the
file (model) object as the first positional argument after the function name in api.run().
- NEVER invent API module or function names. There are exactly 35 modules — see the module table below. Hallucinated calls like
api.run("element.create", ...) or api.run("wall.add", ...) do NOT exist.
- ALWAYS use keyword arguments for all parameters after the model. Positional arguments beyond the model are NOT supported.
- NEVER use
model.create_entity() for production code. Use api.run("root.create_entity", ...) — it generates GlobalIds, sets ownership, and validates predefined types automatically.
- ALWAYS set up a complete project before creating elements: IfcProject → units → contexts → spatial hierarchy. See the bootstrap pattern below.
- NEVER assume
products parameters accept single elements. Since IfcOpenShell v0.8+, most relationship functions expect products as a list, not a single entity.
Decision Tree: Which API Module to Use
What do you need to do?
├── Create/remove/copy IFC entities?
│ └── root (create_entity, remove_product, copy_class, reassign_class)
│
├── Build spatial hierarchy?
│ ├── Project → Site → Building → Storey → Space?
│ │ └── aggregate (assign_object, unassign_object)
│ ├── Place elements in a storey/space?
│ │ └── spatial (assign_container, unassign_container)
│ └── Reference element in multiple spaces?
│ └── spatial (reference_structure, dereference_structure)
│
├── Add geometry to elements?
│ ├── Set up representation contexts first?
│ │ └── context (add_context — root context, then subcontexts)
│ ├── Parametric wall/slab/beam geometry?
│ │ └── geometry (add_wall_representation, add_slab_representation,
│ │ add_profile_representation)
│ ├── Custom mesh geometry?
│ │ └── geometry (add_mesh_representation)
│ ├── Position element in 3D space?
│ │ └── geometry (edit_object_placement)
│ └── Connect geometry to element?
│ └── geometry (assign_representation)
│
├── Set properties on elements?
│ ├── Key-value metadata (name, fire rating, etc.)?
│ │ └── pset (add_pset, edit_pset)
│ └── Measurable quantities (length, area, volume)?
│ └── pset (add_qto, edit_qto)
│
├── Assign materials?
│ ├── Simple single material?
│ │ └── material (add_material, assign_material)
│ ├── Layered construction (walls, slabs)?
│ │ └── material (add_material_set with IfcMaterialLayerSet, add_layer)
│ ├── Profiled sections (beams, columns)?
│ │ └── material (add_material_set with IfcMaterialProfileSet, add_profile)
│ └── Composite (windows, doors)?
│ └── material (add_material_set with IfcMaterialConstituentSet)
│
├── Assign/manage types?
│ └── type (assign_type, unassign_type, map_type_representations)
│
├── Edit entity attributes directly?
│ └── attribute (edit_attributes)
│
├── Create openings/voids?
│ └── void (add_opening, add_filling)
│
├── Set up units?
│ └── unit (assign_unit — defaults to SI)
│
├── Manage project file?
│ └── project (create_file)
│
└── Other domains?
├── Classification → classification
├── Groups → group
├── Layers (CAD) → layer
├── Visual styles → style
├── Cost management → cost
├── Scheduling (4D) → sequence
├── MEP systems → system
├── Structural analysis → structural
├── Documents → document
├── Constraints → constraint
├── Resources → resource
├── Owner/actors → owner
├── Profiles → profile
├── Nesting → nest
├── Boundaries → boundary
├── Libraries → library
├── Drawing/annotations → drawing
├── Georeference → georeference
├── Grid → grid
├── Infrastructure alignment → alignment
├── Coordinate geometry → cogo
├── Features → feature
└── Property set templates → pset_template
Essential Patterns
Pattern 1: Two Equivalent Invocation Styles
import ifcopenshell
import ifcopenshell.api
model = ifcopenshell.file(schema="IFC4")
wall = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWall", name="Wall 1")
wall = ifcopenshell.api.root.create_entity(model, ifc_class="IfcWall", name="Wall 1")
ALWAYS use one style consistently within a project. Both are correct. api.run() is more common in documentation and tutorials.
Pattern 2: Complete Project Bootstrap
import ifcopenshell
import ifcopenshell.api
model = ifcopenshell.api.run("project.create_file", version="IFC4")
project = ifcopenshell.api.run("root.create_entity", model,
ifc_class="IfcProject", name="My Project")
ifcopenshell.api.run("unit.assign_unit", model)
model3d = ifcopenshell.api.run("context.add_context", model, context_type="Model")
body = ifcopenshell.api.run("context.add_context", model,
context_type="Model", context_identifier="Body",
target_view="MODEL_VIEW", parent=model3d)
site = ifcopenshell.api.run("root.create_entity", model,
ifc_class="IfcSite", name="Default Site")
building = ifcopenshell.api.run("root.create_entity", model,
ifc_class="IfcBuilding", name="Building A")
storey = ifcopenshell.api.run("root.create_entity", model,
ifc_class="IfcBuildingStorey", name="Ground Floor")
ifcopenshell.api.run("aggregate.assign_object", model,
products=[site], relating_object=project)
ifcopenshell.api.run("aggregate.assign_object", model,
products=[building], relating_object=site)
ifcopenshell.api.run("aggregate.assign_object", model,
products=[storey], relating_object=building)
ALWAYS follow this sequence: file → project → units → contexts → spatial hierarchy. Skipping steps produces invalid IFC files.
Pattern 3: Create Element with Full Data
wall_type = ifcopenshell.api.run("root.create_entity", model,
ifc_class="IfcWallType", name="Standard Wall 200mm")
concrete = ifcopenshell.api.run("material.add_material", model,
name="Concrete C30/37", category="concrete")
ifcopenshell.api.run("material.assign_material", model,
products=[wall_type], material=concrete)
wall = ifcopenshell.api.run("root.create_entity", model,
ifc_class="IfcWall", name="Wall 001")
ifcopenshell.api.run("type.assign_type", model,
related_objects=[wall], relating_type=wall_type)
representation = ifcopenshell.api.run("geometry.add_wall_representation", model,
context=body, length=5.0, height=3.0, thickness=0.2)
ifcopenshell.api.run("geometry.assign_representation", model,
product=wall, representation=representation)
ifcopenshell.api.run("geometry.edit_object_placement", model, product=wall)
ifcopenshell.api.run("spatial.assign_container", model,
products=[wall], relating_structure=storey)
pset = ifcopenshell.api.run("pset.add_pset", model,
product=wall, name="Pset_WallCommon")
ifcopenshell.api.run("pset.edit_pset", model, pset=pset, properties={
"IsExternal": True,
"LoadBearing": True,
"FireRating": "REI90",
"ThermalTransmittance": ,
})
Complete API Module Table (35 Modules)
| Module | Category | Purpose | Key Functions |
|---|
root | Core | Create/remove/copy entities | create_entity, remove_product, copy_class, reassign_class |
spatial | Spatial | Containment and referencing | assign_container, unassign_container, reference_structure |
aggregate | Spatial | Hierarchical decomposition | assign_object, unassign_object |
geometry | Geometry | Representations and placement | add_wall_representation, add_mesh_representation, add_profile_representation, assign_representation, edit_object_placement |
context | Geometry | Representation contexts | add_context, edit_context, remove_context |
pset | Properties | Property and quantity sets | add_pset, edit_pset, add_qto, edit_qto |
material | Materials | Material definitions and sets | add_material, assign_material, add_material_set, add_layer |
type | Types | Type definitions | assign_type, unassign_type, map_type_representations |
attribute | Data | Direct attribute editing | edit_attributes |
unit | Setup | Measurement units |
Common Operations
Edit Attributes Directly
ifcopenshell.api.run("attribute.edit_attributes", model,
product=wall, attributes={"Name": "Wall 001", "Description": "External bearing wall"})
Create and Assign Opening
opening = ifcopenshell.api.run("root.create_entity", model,
ifc_class="IfcOpeningElement", name="Door Opening")
ifcopenshell.api.run("void.add_opening", model, opening=opening, element=wall)
door = ifcopenshell.api.run("root.create_entity", model,
ifc_class="IfcDoor", name="Door 001")
ifcopenshell.api.run("void.add_filling", model, opening=opening, element=door)
Assign Classification
classification = ifcopenshell.api.run("classification.add_classification", model,
classification="Uniclass 2015")
ifcopenshell.api.run("classification.add_reference", model,
products=[wall], identification="Ss_20_10_30",
name="Walls", classification=classification)
Add Visual Style
style = ifcopenshell.api.run("style.add_style", model, name="Concrete Grey")
ifcopenshell.api.run("style.add_surface_style", model, style=style,
attributes={"SurfaceColour": {"Red": 0.7, "Green": 0.7, "Blue": 0.7}})
ifcopenshell.api.run("style.assign_representation_styles", model,
shape_representation=representation, styles=[style])
Safe Element Removal
ifcopenshell.api.run("root.remove_product", model, product=wall)
Parameter Conventions
List Parameters (v0.8+ Breaking Change)
Since IfcOpenShell v0.8, relationship functions use list parameters:
ifcopenshell.api.run("spatial.assign_container", model,
products=[wall], relating_structure=storey)
ifcopenshell.api.run("spatial.assign_container", model,
product=wall, relating_structure=storey)
Functions affected: spatial.assign_container, aggregate.assign_object, type.assign_type, material.assign_material, group.assign_group, classification.add_reference, nest.assign_object, and others.
Property Type Mapping (pset.edit_pset)
Python types map automatically to IFC property types:
| Python Type | IFC Type | Example |
|---|
str | IfcLabel | "REI60" |
float | IfcReal | 0.24 |
int | IfcInteger | 3 |
bool | IfcBoolean | True |
None | (deletes property) | None |
Matrix Convention (geometry.edit_object_placement)
Placement uses a 4x4 NumPy transformation matrix:
import numpy
ifcopenshell.api.run("geometry.edit_object_placement", model,
product=wall, matrix=numpy.eye(4))
ALWAYS set is_si=True (default) when providing coordinates in meters. Set is_si=False only when coordinates match the file's native unit system.
Version Notes
Schema-Specific Entities
| Entity | IFC2X3 | IFC4 | IFC4X3 |
|---|
| IfcBuildingStorey | Yes | Yes | Yes |
| IfcSpace | Yes | Yes | Yes |
| IfcFacility | No | No | Yes |
| IfcFacilityPart | No | No | Yes |
| IfcAlignment | No | No | Yes |
| IfcBridge | No | No | Yes |
| IfcRoad | No | No | Yes |
api.run() handles most schema differences internally. When creating IFC4X3 infrastructure models, use the infrastructure-specific entity classes.
project.create_file Parameter
model = ifcopenshell.api.run("project.create_file", version="IFC4")
model = ifcopenshell.api.run("project.create_file", schema="IFC4")
Dependency
This skill depends on ifcos-syntax-fileio for file creation, opening, writing, and transaction management patterns. Use ifcos-syntax-fileio for:
ifcopenshell.open() / ifcopenshell.file()
model.write() / model.to_string()
- Transaction management (
begin_transaction / end_transaction / undo / redo)
Reference Links