An open, canonical schema for the built world.
Buildings, spaces, companies, people, leases, and the systems that run them — described once, in a shape everyone can read.
Status: draft. This specification is published for public comment. Nothing here is stable yet, and breaking changes are possible until the first dated release. Build against it to learn from it and to tell us where it is wrong; do not depend on it in production without pinning.
Commercial real estate runs on data that cannot travel. A lease abstracted in one system, an asset register kept in another, and an occupancy figure computed in a third all describe the same building, but nothing in their structure says so. Every integration between them is bespoke, every migration is an archaeology project, and every question that spans two systems gets answered by hand.
The industry has excellent standards for individual concerns — IFC for physical geometry, BOMA for measurement, ASC 842 and IFRS 16 for lease accounting — and no shared shape for the records that sit between them. The Digital Grid is an attempt at that shape: a dictionary of the objects the industry actually keeps, defined precisely enough to interoperate and loosely enough to extend.
It was created by HqO out of the model behind our own platform, and it is developed in the open under Apache 2.0. We publish it because a schema only one company uses is not a schema — it is a database.
An extensible dictionary of typed objects. Ten objects in this draft — building, space, company, person, lease, installed asset, work item, entity event, observation, membership — each defined as a JSON Schema 2020-12 document. They are deliberately few. A specification that names four hundred objects is a data model; one that names ten is a vocabulary other people can learn.
A set of relationships for composing them. Parties are not typed by their relationship to you. The same company is a tenant in one building, a vendor in another, and was a broker on a deal three years ago — all true at once. Rather than a tenant table and a vendor table, the Grid keeps one company object and records what it is to whom, where, and when, in dated membership records. The same principle governs premises, assignment, and ownership: relationships are first-class, dated, and reversible.
An event spine that records what happened. One envelope — entity-event — for every domain, instead of a separate event log per domain. Reverse-domain namespaced event types (ai.digitalgrid.lease.executed), one subject, two timestamps, an idempotency key, and an opaque payload. Alongside it, observation holds facts whose truth changes and whose knowledge arrives late, keeping both when a value was true in the world and when we learned it.
A lease, reduced to its skeleton. The full instance is in examples/lease.example.json.
{
"id": "c47d3e21-9a86-4b0f-8e75-1d2c4a6f8b93",
"organization_id": "3a1c7b90-4e52-4f1a-8d6b-9c2e5f7a1234",
"external_refs": [
{ "system": "yardi", "external_id": "t0004821", "is_primary": true }
],
"status": "ACTIVE",
"currency_code": "USD",
"parties": [
{ "role": "LANDLORD", "company_id": "5e2b8c14-7d39-4a60-b1f8-3c9e07a4d215" },
{ "role": "TENANT", "company_id": "9d40f6a2-3b17-4e58-8c92-6a1f5d7b0e34" }
],
"premises": [
{
"building_id": "8f14e45f-ceea-4d2c-9b1e-2a7c9d0b3f61",
"space_id": "a5c81f36-4b70-4e29-9d83-6f1a2c7e504b",
"rentable_area_sqft": 24180,
"measurement_standard": "BOMA_2017_OFFICE"
}
],
"term": {
"commencement_date": "2024-03-01",
"rent_commencement_date": "2024-09-01",
"expiration_date": "2034-02-28"
},
"rent_schedule": [
{
"period_start": "2024-09-01",
"period_end": "2029-02-28",
"charge_type": "BASE_RENT",
"amount_cents": 14507500,
"currency_code": "USD",
"frequency": "MONTHLY",
"escalation": { "method": "FIXED_PERCENT", "value": 3.0 }
}
],
"options": [
{
"option_type": "RENEWAL",
"holder_role": "TENANT",
"latest_notice_date": "2033-02-28",
"term_months": 60,
"rent_basis": "FAIR_MARKET",
"status": "AVAILABLE"
}
],
"accounting": {
"framework": "ASC_842",
"classification": "OPERATING",
"party_perspective": "LESSOR",
"discount_rate_pct": 6.75
}
}Four things in that fragment are load-bearing, and each is explained in docs/concepts.md:
external_refsmeans the record stays reconcilable with the system it came from. The Grid does not ask anyone to abandon their system of record.amount_centsis an integer in the currency's minor unit, never a decimal. Money represented as a float is money that disagrees with itself.measurement_standardtravels with every area, because 24,180 square feet under BOMA 2017 and 24,180 square feet under a local convention are not the same fact.latest_notice_dateon the renewal option is the date that actually has to be worked. An option is lost by missing the notice, not by missing the expiration.
And the event that put that lease into force — full instance in examples/entity-event.example.json:
{
"id": "1a9e5d78-3c62-4b04-9f81-7d2a0c6e4b35",
"event_type": "ai.digitalgrid.lease.executed",
"subject": { "type": "lease", "id": "c47d3e21-9a86-4b0f-8e75-1d2c4a6f8b93" },
"occurred_at": "2023-11-17T21:48:00Z",
"recorded_at": "2023-11-20T15:04:12Z",
"actor": { "type": "person", "id": "b6f18c40-9a27-4d53-8e16-3c5b7f0a2d98" },
"payload": { "previous_status": "OUT_FOR_SIGNATURE", "new_status": "EXECUTED" },
"idempotency_key": "yardi:t0004821:lease.executed:2023-11-17"
}The lease was signed on the 17th and the Grid learned of it on the 20th. Both times are recorded, because a system that keeps only one of them cannot answer what it knew, and when.
| Path | What is in it |
|---|---|
schema/ |
The JSON Schema documents, one per object, plus common.json for shared definitions |
examples/ |
Realistic instances that validate against the schemas |
docs/concepts.md |
The model behind the files: primitive classes, layers, domains, the event spine, bitemporality, extension rules |
GOVERNANCE.md |
How decisions get made, and who makes them today |
CONTRIBUTING.md |
How to propose a change, and how to validate before you do |
versions.json |
The published versions and their aliases |
Every schema carries an $id of the form https://digitalgrid.ai/schema/draft/<name>.json, and refers to its siblings by relative reference, so the directory resolves the same whether it is served from that host or read from disk.
You do not need our agreement to add something. Extensions are namespaced properties: x- followed by a reverse-domain namespace you control.
{
"id": "8f14e45f-ceea-4d2c-9b1e-2a7c9d0b3f61",
"name": "Northgate Exchange",
"x-com.example.seismic_retrofit_year": 2019
}Implementations that do not understand a namespaced property ignore it. Unnamespaced property names are reserved for this specification, and that is the whole of the bargain: keep your additions in your namespace, and your data stays valid Grid data while the standard evolves underneath it. If an extension turns out to be generally useful, propose it — see CONTRIBUTING.md.
Releases are dated: YYYY-MM-DD. There are no semantic version numbers, because a schema's compatibility story is per-property rather than global, and a single version number would misrepresent it. Each release is published at a stable path — https://digitalgrid.ai/schema/<version>/ — and latest is an alias for the most recent dated release.
The current published version is draft. It carries no alias, it is not dated, and it may change under you. versions.json is the machine-readable list:
[{ "version": "draft", "aliases": [] }]Once dated releases begin, the intended rule is: a release may add optional properties, add enum values, and relax constraints. Removing a property, making an optional property required, or narrowing a constraint requires a new dated release and a documented migration note. Pin the dated version you build against, and move deliberately.
The examples in this repository are checked against the schemas on every change. To check them yourself:
npx --yes -p ajv-cli@5 -p ajv-formats@2 ajv validate \
--spec=draft2020 -c ajv-formats \
-s schema/lease.json -r schema/common.json \
-d examples/lease.example.jsonFull instructions, including how to validate your own instances, are in CONTRIBUTING.md.
Apache License 2.0. See LICENSE.