Getting started

What an ODS document holds, the rules every record follows, and how to check a file against the schemas.

Draft

This page can change before the first release.

One document, four pillars

An ODS file is one Document. It holds four pillars, and each pillar answers one question about the development.

Records point at each other by id across the pillars: a Trace in Methodology names the Framework in Risk that it checked. The files that records point at, such as recordings, sit in the document's files list.

The smallest document

Only odsVersion is required. A useful small document adds one feature and its source.

{
  "odsVersion": "1.0.0-rc.2"
}
{
  "odsVersion": "1.0.0-rc.2",
  "context": {
    "features": [
      {
        "id": "feature-wellsite",
        "name": "Wellsite 04-12",
        "sources": [
          {
            "id": "source-compressor",
            "name": "Compressor package"
          }
        ]
      }
    ]
  }
}

The running example

Wellsite 04-12 in Alberta: its compressor, a dwelling 450 m north-east, AER Directive 038, the night's weather, a meter survey, the calculation and the assessment. Every schema's examples come from it, and an id in it opens that record.

{
  "id": "document-0412",
  "name": "Wellsite 04-12 night-time noise assessment",
  "odsVersion": "1.0.0-rc.2",
  "generatedAt": "2026-07-24T18:00:00Z",
  "producer": {
    "name": "Example Producer",
    "version": "1.2.0"
  },
  "sharing": "approved",
  "risk": {
    "frameworks": [
      {
        "id": "framework-d038",
        "name": "Directive 038: Noise Control",
        "issuer": "stakeholder-aer",
        "jurisdiction": "jurisdiction-ab",
        "edition": "April 2024",
        "citation": {
          "title": "Directive 038: Noise Control",
          "url": "https://www.aer.ca/regulating-development/rules-and-directives/directives/directive-038"
        },
        "periods": [
          {
            "id": "period-night",
            "name": "Nighttime",
            "timeZone": "America/Edmonton",
            "windows": [
              {
                "start": "22:00",
                "end": "07:00"
              }
            ]
          }
        ],
        "variables": [
          {
            "id": "variable-bsl",
            "name": "Basic sound level",
            "value": {
              "amount": 40,
              "unit": "dB"
            }
          }
        ],
        "policies": [
          {
            "id": "policy-noise",
            "name": "Noise at dwellings",
            "type": "objective"
          }
        ]
      }
    ]
  },
  "context": {
    "stakeholders": [
      {
        "id": "stakeholder-operator",
        "name": "Example Energy Ltd.",
        "type": "organization"
      },
      {
        "id": "stakeholder-aer",
        "name": "Alberta Energy Regulator",
        "type": "organization",
        "identifiers": [
          {
            "scheme": "ca.ab.aer_ba_code",
            "value": "A0001"
          }
        ]
      },
      {
        "id": "stakeholder-consultant",
        "name": "Example Acoustics Inc.",
        "type": "organization"
      },
      {
        "id": "stakeholder-lab",
        "name": "Example Calibration Laboratory",
        "type": "organization"
      }
    ],
    "jurisdictions": [
      {
        "id": "jurisdiction-ca",
        "name": "Canada",
        "type": "country",
        "identifiers": [
          {
            "scheme": "iso_3166_1",
            "value": "CA"
          }
        ]
      },
      {
        "id": "jurisdiction-ab"
      }
    ],
    "permits": [
      {
        "id": "permit-wellsite",
        "name": "Well licence 0512345",
        "type": "licence",
        "issuer": "stakeholder-aer",
        "holder": "stakeholder-operator",
        "jurisdiction": "jurisdiction-ab",
        "status": "active",
        "effective": {
          "start": "2026-05-04T00:00:00-06:00"
        },
        "features": [
          "feature-wellsite"
        ],
        "identifiers": [
          {
            "scheme": "ca.ab.aer_licence",
            "value": "0512345"
          }
        ]
      }
    ],
    "projects": [
      {
        "id": "project-0412",
        "name": "Wellsite 04-12 compressor",
        "features": [
          "feature-wellsite",
          "feature-dwelling"
        ],
        "activities": [
          {
            "id": "activity-operation",
            "name": "Operation",
            "type": "operation"
          }
        ]
      }
    ],
    "features": [
      {
        "id": "feature-wellsite",
        "location": {
          "point": {
            "type": "Point",
            "coordinates": [
              -113.815,
              52.268,
              912.4
            ]
          },
          "crs": {
            "code": "EPSG:4617",
            "name": "NAD83(CSRS)",
            "verticalDatum": "CGVD2013",
            "verticalCode": "EPSG:6647",
            "coordinateEpoch": 2010
          },
          "absoluteHeight": 912.4,
          "positioning": {
            "method": "gnss_rtk",
            "horizontalAccuracy": 0.02,
            "verticalAccuracy": 0.03,
            "confidenceLevel": 95,
            "determinedAt": "2026-07-02T10:15:00-06:00"
          },
          "geographicIdentifiers": [
            {
              "type": "legal_land_description",
              "scheme": "ca.dls",
              "value": "04-12-038-27W4"
            }
          ],
          "linearReference": {
            "line": "feature-pipeline",
            "distance": {
              "amount": 12.4,
              "unit": "km"
            }
          }
        },
        "geometry": {
          "type": "Polygon",
          "coordinates": [
            [
              [
                -113.8157,
                52.2676
              ],
              [
                -113.8143,
                52.2676
              ],
              [
                -113.8143,
                52.2684
              ],
              [
                -113.8157,
                52.2684
              ],
              [
                -113.8157,
                52.2676
              ]
            ]
          ],
          "positioning": {
            "method": "surveyed",
            "horizontalAccuracy": 0.05,
            "confidenceLevel": 95
          },
          "original": {
            "file": "file-site-plan",
            "layer": "lease_boundary",
            "feature": "17",
            "geometryType": "CurvePolygon",
            "crs": {
              "code": "EPSG:3402"
            },
            "changes": [
              {
                "type": "curves_linearized",
                "tolerance": 0.01
              },
              {
                "type": "reprojected"
              }
            ]
          }
        },
        "sources": [
          {
            "id": "source-compressor",
            "name": "Compressor package",
            "type": "compressor",
            "location": {
              "point": {
                "type": "Point",
                "coordinates": [
                  -113.8148,
                  52.2683
                ]
              },
              "relativeHeight": 3.5
            },
            "properties": [
              {
                "type": "rated_power",
                "value": {
                  "amount": 1000,
                  "unit": "kW"
                }
              }
            ],
            "operatingStates": [
              {
                "id": "state-loaded",
                "name": "Loaded",
                "type": "full_load"
              },
              {
                "id": "state-idle",
                "name": "Idle",
                "type": "idle"
              }
            ],
            "emissions": [
              {
                "id": "emission-loaded",
                "type": "sound_power_level",
                "state": "state-loaded",
                "value": {
                  "amount": 102,
                  "unit": "dB"
                }
              }
            ]
          }
        ]
      },
      {
        "id": "feature-dwelling",
        "name": "Dwelling 450 m north-east",
        "type": "building",
        "receptorClass": "dwelling",
        "location": {
          "point": {
            "type": "Point",
            "coordinates": [
              -113.8104,
              52.2709
            ]
          },
          "relativeHeight": 1.5
        }
      },
      {
        "id": "feature-wellsite-2",
        "name": "Wellsite 04-13",
        "type": "site"
      },
      {
        "id": "feature-pipeline",
        "name": "Gathering pipeline",
        "type": "other",
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              -113.9947,
              52.25
            ],
            [
              -113.815,
              52.268
            ],
            [
              -113.78,
              52.271
            ]
          ]
        }
      }
    ],
    "instruments": [
      {
        "id": "instrument-slm"
      },
      {
        "id": "instrument-microphone",
        "name": "Microphone 1",
        "type": "microphone"
      }
    ]
  },
  "environment": {
    "weather": [
      {
        "id": "weather-2026-07-14T22",
        "name": "Night of 14 July, 22:00",
        "location": {
          "point": {
            "type": "Point",
            "coordinates": [
              -113.815,
              52.268
            ]
          }
        },
        "interval": {
          "start": "2026-07-14T22:00:00-06:00",
          "duration": "PT1H"
        },
        "properties": [
          {
            "type": "air_temperature",
            "value": {
              "amount": 16.5,
              "unit": "degC"
            }
          },
          {
            "type": "relative_humidity",
            "value": {
              "amount": 71,
              "unit": "%"
            }
          },
          {
            "type": "wind_speed",
            "value": {
              "amount": [
                1.8,
                3.1,
                4.6
              ],
              "unit": "m/s",
              "axes": [
                {
                  "quantity": "height",
                  "unit": "m",
                  "values": [
                    10,
                    50,
                    120
                  ]
                }
              ]
            }
          },
          {
            "type": "wind_direction",
            "value": {
              "amount": 225,
              "unit": "deg"
            }
          }
        ],
        "origin": {
          "tier": "reanalysis",
          "provider": "Copernicus Climate Data Store",
          "model": "ERA5"
        }
      }
    ]
  },
  "methodology": {
    "algorithms": [
      {
        "id": "algorithm-iso9613",
        "name": "ISO 9613-2 engine",
        "type": "calculation",
        "version": "4.2.0",
        "publisher": "stakeholder-operator",
        "standard": {
          "title": "ISO 9613-2:2024",
          "edition": "2024"
        },
        "mode": "Downwind conditions, with the meteorological correction of 7.3",
        "validations": [
          "evidence-conformance"
        ]
      }
    ],
    "flows": [
      {
        "id": "flow-d038",
        "name": "Directive 038 compliance",
        "version": "3",
        "frameworks": [
          "framework-d038"
        ],
        "steps": [
          {
            "id": "step-1",
            "type": "entrypoint"
          },
          {
            "id": "step-ask-hours",
            "type": "question",
            "label": "How many hours a day does the compressor run?",
            "question": {
              "answerType": "number",
              "unit": "h"
            },
            "outputs": [
              {
                "name": "hours_per_day",
                "unit": "h",
                "valueType": "number"
              }
            ]
          },
          {
            "id": "step-propagation",
            "type": "algorithm",
            "name": "Sound levels at receptors",
            "algorithm": "algorithm-iso9613",
            "sealed": true,
            "inputs": [
              {
                "name": "sources",
                "valueType": "list"
              },
              {
                "name": "receptors",
                "valueType": "list"
              }
            ],
            "outputs": [
              {
                "name": "receptor_levels",
                "quantity": "a_weighted_sound_pressure_level",
                "unit": "dB",
                "valueType": "list"
              }
            ]
          },
          {
            "id": "step-compare",
            "type": "decision",
            "name": "Compare with the permissible sound level"
          },
          {
            "id": "step-mitigation",
            "type": "outcome",
            "name": "Mitigation needed"
          }
        ],
        "edges": [
          {
            "from": "step-1",
            "to": "step-ask-hours"
          },
          {
            "from": "step-ask-hours",
            "to": "step-propagation"
          },
          {
            "from": "step-propagation",
            "to": "step-compare"
          },
          {
            "id": "edge-over-limit",
            "from": "step-compare",
            "to": "step-mitigation",
            "label": "Over the limit",
            "when": {
              "operation": "greater",
              "arguments": [
                {
                  "variable": "night_level"
                },
                {
                  "variable": "variable-night-psl"
                }
              ]
            }
          }
        ]
      }
    ],
    "assumptions": [
      {
        "id": "assumption-downwind",
        "name": "Downwind at night",
        "subject": "feature-dwelling",
        "properties": [
          {
            "type": "wind_speed",
            "value": {
              "amount": 2,
              "unit": "m/s"
            }
          }
        ],
        "basis": "The directive asks for the worst case, which is downwind with a light wind.",
        "citation": {
          "title": "Directive 038: Noise Control",
          "section": "Appendix 2"
        }
      }
    ],
    "evidence": [
      {
        "id": "evidence-night-survey",
        "name": "Night survey at the dwelling",
        "type": "measurement",
        "subject": "feature-dwelling",
        "observed": "a_weighted_sound_pressure_level",
        "result": {
          "amount": 37.8,
          "unit": "dB",
          "statistic": {
            "type": "energy_mean"
          },
          "averaging": "PT9H"
        },
        "interval": {
          "start": "2026-07-14T22:00:00-06:00",
          "end": "2026-07-15T07:00:00-06:00"
        },
        "instrument": "instrument-slm",
        "state": "state-loaded",
        "conditions": [
          "weather-2026-07-14T22"
        ],
        "links": [
          {
            "type": "reference",
            "target": "file-recording-1",
            "targetType": "File",
            "role": "recording"
          }
        ]
      },
      {
        "id": "evidence-predicted-night",
        "name": "Predicted night level at the dwelling",
        "type": "calculation",
        "subject": "feature-dwelling",
        "observed": "a_weighted_sound_pressure_level",
        "result": {
          "amount": 36.4,
          "unit": "dB"
        },
        "algorithm": "algorithm-iso9613",
        "trace": "trace-0412-night",
        "state": "state-loaded",
        "conditions": [
          "weather-2026-07-14T22"
        ]
      },
      {
        "id": "evidence-sound-power",
        "name": "Compressor sound power test",
        "type": "measurement",
        "subject": "source-compressor",
        "observed": "sound_power_level",
        "result": {
          "amount": 102,
          "unit": "dB"
        },
        "state": "state-loaded"
      },
      {
        "id": "evidence-conformance",
        "name": "ISO/TR 17534-3 test cases",
        "type": "validation",
        "algorithm": "algorithm-iso9613"
      }
    ],
    "traces": [
      {
        "id": "trace-0412-night",
        "flow": "flow-d038",
        "flowVersion": "3",
        "framework": "framework-d038",
        "status": "completed",
        "startedAt": "2026-07-20T16:02:11Z",
        "endedAt": "2026-07-20T16:02:19Z",
        "agents": [
          {
            "agent": "stakeholder-consultant",
            "role": "author"
          },
          {
            "agent": "algorithm-iso9613",
            "role": "engine"
          }
        ],
        "inputs": [
          "feature-wellsite",
          "feature-dwelling",
          "weather-2026-07-14T22"
        ],
        "outputs": [
          "evidence-predicted-night"
        ],
        "algorithms": [
          "algorithm-iso9613"
        ],
        "inputsHash": "9f2c1e4b7a0d3c5e8f6a1b2c3d4e5f60718293a4b5c6d7e8f9a0b1c2d3e4f5a6",
        "steps": [
          {
            "step": "step-propagation",
            "sealed": true,
            "outputs": [
              {
                "name": "receptor_levels",
                "value": {
                  "amount": [
                    36.4
                  ],
                  "unit": "dB"
                }
              }
            ]
          }
        ],
        "verdict": {
          "level": "pass",
          "basis": "Every dwelling meets the night-time permissible sound level."
        }
      }
    ],
    "assessments": [
      {
        "id": "assessment-0412",
        "name": "Noise impact assessment, Wellsite 04-12",
        "status": "issued",
        "authors": [
          "stakeholder-consultant"
        ],
        "issuedAt": "2026-07-24T18:00:00Z",
        "features": [
          "feature-wellsite",
          "feature-dwelling"
        ],
        "frameworks": [
          "framework-d038"
        ],
        "traces": [
          "trace-0412-night"
        ],
        "evidence": [
          "evidence-night-survey"
        ],
        "conclusions": [
          {
            "statement": "The compressor meets the night-time permissible sound level at the dwelling.",
            "verdict": "pass",
            "records": [
              "feature-dwelling"
            ]
          }
        ]
      }
    ]
  },
  "files": [
    {
      "id": "file-recording-1",
      "name": "Night survey levels",
      "path": "files/recording-1.bin",
      "mediaType": "application/octet-stream",
      "size": 1310720,
      "sha256": "ef2d127de37b942baad06145e54b0c619a1f22327b2ebbcfbec78f5564afe39d",
      "interval": {
        "start": "2026-07-14T22:00:00-06:00",
        "end": "2026-07-15T07:00:00-06:00"
      }
    },
    {
      "id": "file-certificate",
      "name": "Calibration certificate",
      "path": "files/certificate.pdf",
      "mediaType": "application/pdf",
      "sha256": "b0f8043041133f5c164e9d39897466002623fbd226c7f1d98d19dbff9a86fec7"
    },
    {
      "id": "file-noise-map",
      "name": "Night noise map",
      "path": "files/noise-map.bin",
      "mediaType": "application/octet-stream",
      "sha256": "11696c76d6f8d359a8266486c73afd8631fa834f0d9c098211d3972fab8c9997"
    },
    {
      "id": "file-site-plan",
      "name": "Site survey plan",
      "path": "files/site-plan.gpkg",
      "mediaType": "application/geopackage+sqlite3",
      "sha256": "a94c0a375882d98dae229342ca1e3d6209620124992dd880b06802f15b3693fc"
    }
  ]
}

Rules every record follows

Six rules cover most of what a producer writes. The conventions hold the rest.

Ids and references
Every entity and part has an id, unique within the document. A field that holds another record's id is named after that record or the part it plays (framework, issuer), with no Id suffix.
Codes
A code is lower snake_case, such as wind_speed, and comes from a vocabulary or from the codes a field lists.
Amounts
An amount is a Value: a number or a list, in the unit of its quantity's vocabulary term. Axes lay a list out along frequency, time or height.
Time
A point in time is an RFC 3339 date-time in a field that ends in At. A length of time is an ISO 8601 duration.
Sharing and personal information
The document's sharing says where its contents may go. A field that can hold personal information has a class that says how to treat it.
Extensions
A key that starts with x- is an extension: a producer adds it, and a reader may ignore it. Any other key that a schema does not list makes the document fail.

The conventions have every rule.

Check a document

The schemas are JSON Schema 2020-12 files, so any 2020-12 validator can check a document. With Ajv:

import Ajv2020 from "ajv/dist/2020";
import addFormats from "ajv-formats";
import keywords from "@opencycle/ods-schema/meta/keywords.json";

const ajv = new Ajv2020({ strict: true });
addFormats(ajv);
for (const { keyword } of keywords.keywords) ajv.addKeyword(keyword);
for (const schema of schemaFiles) ajv.addSchema(schema); // every file under schemas/

const validate = ajv.getSchema("https://opendevelopmentstandards.org/schema/1.0.0-rc.2/core/Document.json")!;
if (!validate(document)) console.log(validate.errors);

JSON Schema cannot check that ids resolve or that each code is in its vocabulary. The ODS validator will check these. The schema packages are not published yet; the first release publishes them.

Next