A PDF is still a PDF. It opens in Acrobat, Bluebeam, or any viewer. The BIM data layer is the escalator: optional, invisible to tools that don’t know it’s there, essential to tools that do.
bim-pdf embeds structured BIM data as JSON file attachments inside a standard PDF. No new container format. No viewer lock-in. The PDF travels as-is; agents and tools that understand bim-pdf ride the escalator.
Every element carries a class field drawn from the v1.0 registry. Use other with a required class_hint for anything outside the registry.
wallcurtain-wallslabfloorcolumnbeambracefooting
slab = structural deck or slab-on-grade. floor = interior finish assembly.
roofdoorwindowcurtain-panelcurtain-mullion
ceilingroomstairramp
furniturecaseworkequipment
other
Requires class_hint: the producer’s native category name. MEP excluded from v1.0.
Sidecars are JSON files embedded as PDF attachments. elements.json is the anchor; all other sidecars are optional and listed in dependency order.
| Filename | Purpose | Key fields |
|---|---|---|
elements.json | BIM element list + document metadata. Anchor for all other sidecars. | bim-pdf, meta (project_id, document_id, exported_at, producer), source (format, version, id_strategy), class_registry, elements[] |
marks.json | Spatial overlay linking elements to page regions. Requires elements.json. | coordinate_space, marks[] (element_id, page, bbox [x0 y0 x1 y1 in PDF points], view_type) |
scales.json | Per-page calibration. Maps PDF points to real-world units. | Keyed by 1-indexed page number. Each entry is a CalibrationScale (pixel-distance + real-distance + unit) or RatioScale (ratio + unit). |
levels.json | Building level definitions with elevation. | levels[] (id [UUID v5], name, elevation [Quantity]) |
titleblock.json | Sheet metadata extracted from title block fields. | sheets[] (sheet_number, sheet_name, project_name, project_number, date, scale, drawn_by, checked_by, revision) |
annotations.json | Human and agent markup. Requires elements.json. | annotations[] (id, page, type [polygon/rectangle/text/callout/cloud/stamp/...], author [human|agent], created_at, element_id, style, measurement) |
ifc-subset.json | IFC data subset for cross-tool interop. Optional; omit if not available. | Raw IFC entity subset keyed by element id. Schema is open in v1.0. |
To produce a bim-pdf, embed sidecars as standard PDF file attachments using the PDF EmbeddedFiles names tree. Any PDF library that supports /EmbeddedFile streams works.
// Minimal elements.json
{
"bim-pdf": "1.0",
"meta": {
"project_id": "uuid-v4",
"document_id": "uuid-v4",
"exported_at": "2026-01-01T00:00:00Z",
"producer": "my-tool/1.0"
},
"source": {
"format": "revit",
"version": "2024",
"id_strategy": "revit-stable-element-id"
},
"class_registry": "1.0",
"elements": [
{ "id": "1234", "class": "wall", "label": "Exterior CMU 8\"", "level": "Level 1" }
]
}
Embed the JSON as a file attachment named exactly elements.json. Add additional sidecar files as needed. The attachment name is the sidecar identifier — do not rename.
To read a bim-pdf, extract file attachments by name. No special PDF structure required beyond standard EmbeddedFiles support.
Tools in the bim-cli ecosystem produce and consume bim-pdf files:
| Tool | Description |
|---|---|
bim revit export | Export a Revit sheet to bim-pdf — produces a PDF with 6 BIM sidecars embedded |
bim pdf pack | Embed sidecar JSON files into an existing PDF |
bim pdf extract | Extract sidecar JSON files from a bim-pdf |
bim pdf list | List embedded attachments in a PDF |
bim pdf validate | Validate a bim-pdf: schema correctness, cross-references, class registry |
bim pdfv open | Open in pdfv viewer: BIM element overlay, element panel, marks filtered by class |
Install via bimcli.com. No account required.
elements.json is required. Implement one sidecar at a time.