Skip to main content
Version: v0.25.0 (Latest)

The Object Model (L2)

The Data Domain (L1) defines the organisation's object types, business terms, relationships, and governance. The Object Model is the use-case layer above it. It pins the data-domain snapshots used by the use case, gives the participating object types local role names, selects the relationships that connect those roles, and narrows governance for specific business-term paths.

Governance flow from the L1 data domain through the L2 object model to the L3 data product and L4 channel. Domain governance flows through role bindings and traversal selections, with narrowing and provenance preserved at every layer.

What an Object Model Does

An Object Model is a tenant-owned, versioned use-case curation over one or more published data domains.

Data-domain snapshots are pinned. domainRefs contains at most one reference per data domain. Each reference includes dataDomainId and dataDomainVersion, so resolution always reads the intended snapshot.

Roles bind object types to use-case participants. A role has an object-model-local id and name, and its entity identifies an object type with { dataDomainId, entity }. specializes can add specialization object types to the role. In this walkthrough, the employee role binds to Person and applies the Employee specialization, while employer binds to Organization and applies Employer.

Relationships are selected from the data domain. Each relationships entry names a data-domain relationship with { dataDomainId, relationship }. The relationship type and its ends remain defined by the data domain. The object model selects which relationships participate in the use case.

Overrides are narrow-only. An overrides entry is keyed by { roleRef, path } and can tighten conformance, sdPolicy, cardinality, entryCodesSubset, or sensitive. It cannot widen the effective governance established by the referenced data domain.

The Object Model defines the effective use-case graph. The Data Product (L3) later selects the business-term paths that a particular output needs.

Create, Configure, Publish, and Resolve the Object Model

The example Object Model uses two data-domain object types and two relationships:

  • employee binds to Person and applies the Employee specialization.
  • employer binds to Organization and applies the Employer specialization.
  • residentialAddress and employment are selected from the pinned data domain.
  • email is tightened from OPTIONAL to MANDATORY for the employee role.

Create

POST /api/model/v1/objects
{
"name": "Acme Employee Onboarding",
"description": "Use-case object model for employee onboarding and badge issuance.",
"domainRefs": [
{
"dataDomainId": "9f2c1b3e-7a44-4c1e-8b0a-2d6f5e9c1a77",
"dataDomainVersion": 3
}
],
"roles": [
{
"id": "employee",
"name": "Employee",
"entity": {
"dataDomainId": "9f2c1b3e-7a44-4c1e-8b0a-2d6f5e9c1a77",
"entity": "Person"
},
"specializes": ["Employee"],
"description": "The employee participant in the use case."
},
{
"id": "employer",
"name": "Employer",
"entity": {
"dataDomainId": "9f2c1b3e-7a44-4c1e-8b0a-2d6f5e9c1a77",
"entity": "Organization"
},
"specializes": ["Employer"]
}
],
"relationships": [
{
"dataDomainId": "9f2c1b3e-7a44-4c1e-8b0a-2d6f5e9c1a77",
"relationship": "residentialAddress"
},
{
"dataDomainId": "9f2c1b3e-7a44-4c1e-8b0a-2d6f5e9c1a77",
"relationship": "employment"
}
],
"overrides": [
{
"roleRef": "employee",
"path": ["email"],
"conformance": "MANDATORY"
}
]
}

Field reference

FieldMeaning
domainRefsData-domain snapshot references. Each data domain can appear at most once.
roles[].idObject-model-local role identifier. It is used by relationships, overrides, and downstream data-product paths.
roles[].nameHuman-readable role name.
roles[].entity{ dataDomainId, entity }, identifying the bound data-domain object type.
roles[].specializesSpecialization object-type names applied to the bound object type.
relationships[]{ dataDomainId, relationship }, selecting a data-domain relationship type.
overrides[]Narrow-only governance entries keyed by a role and path. Supported fields are conformance, sdPolicy, cardinality, entryCodesSubset, and sensitive.

Configure the draft

The create request accepts all four structural collections. A draft can also be updated through dedicated replacement endpoints:

PUT /api/model/v1/objects/{objectModelId}/domain-refs
{
"domainRefs": [
{
"dataDomainId": "9f2c1b3e-7a44-4c1e-8b0a-2d6f5e9c1a77",
"dataDomainVersion": 3
}
]
}
PUT /api/model/v1/objects/{objectModelId}/roles
PUT /api/model/v1/objects/{objectModelId}/relationships
PUT /api/model/v1/objects/{objectModelId}/overrides

Each endpoint replaces its corresponding collection. The request bodies are respectively { "roles": [...] }, { "relationships": [...] }, and { "overrides": [...] }. The object model must be in DRAFT for authoring changes.

Use PATCH /api/model/v1/objects/{objectModelId} for the mutable name and description fields. Use POST /api/model/v1/objects/{objectModelId}/version with no request body to increment the snapshot version.

Publish

The lifecycle has two values: DRAFT and PUBLISHED. Set the status with:

PUT /api/model/v1/objects/{objectModelId}/status
{ "status": "PUBLISHED" }

Resolve

Resolve the model against its pinned data-domain snapshots:

GET /api/model/v1/objects/{objectModelId}/resolved

200 OK returns a ResolvedObjectModel. Resolution applies role specializations, projects the selected relationships, and folds the object-model overrides into each effective business-term overlay.

{
"objectModelId": "c4d5e6f7-8a9b-4c0d-8e1f-2a3b4c5d6e7f",
"objectModelVersion": 1,
"domainRefs": [
{
"dataDomainId": "9f2c1b3e-7a44-4c1e-8b0a-2d6f5e9c1a77",
"dataDomainVersion": 3
}
],
"roles": [
{
"id": "employee",
"entity": "Person",
"specializes": ["Employee"],
"partyType": "natural_person",
"attributes": [
{
"path": ["given_name"],
"valueType": "Text",
"sourceEntity": "Person",
"overlays": { "conformance": "OPTIONAL" }
}
]
}
],
"relationships": [
{
"name": "residentialAddress",
"relationType": "has-address",
"sourceRole": "employee",
"targetEntity": "Address",
"targetAttributes": []
}
],
"schemaRelationships": []
}

The resolved role attributes include terms inherited through specializes. A relationship traversal can resolve a term such as ["residentialAddress", "country"] from the employee role into the related Address object type.

Generate a JSON Schema

The object model can produce a JSON Schema from its resolved shape. The current generation operation supports JSON_SCHEMA as its targetType.

POST /api/model/v1/objects/{objectModelId}/schemas
{
"targetType": "JSON_SCHEMA",
"register": false
}

The response is a GeneratedObjectModelSchemaResult containing objectModelId, objectModelVersion, targetType, the serialized schema, and a nullable schemaId. When register is true, schemaId identifies the registered schema.

Narrowing and Version Pinning

The effective model is resolved in this order:

  1. Data Domain (L1) establishes the canonical object types, business terms, relationships, and governance overlays.
  2. Object Model (L2) binds roles and relationships and applies its narrow-only overrides.
  3. Data Product (L3) selects paths and can narrow the selected terms further.
  4. Channel (L4) maps selected paths to an output and does not change model governance.

domainRefs makes the first step deterministic. A downstream data product pins the Object Model with objectModelRef: { objectModelId, objectModelVersion }, so it continues to resolve against the intended snapshot.

License

The semantic-model authoring API is gated by the semantic-modeling.v1 enterprise feature. Every request in this walkthrough uses an operator bearer token, and the tenant context is resolved from that token.

Authorization: Bearer <operator access token>
Content-Type: application/json

Next Steps

  • Data Product (L3): pin this published Object Model and select role-rooted traversal paths.
  • Modeling Your World: review the four-layer model, governance, and version pinning.
  • Data Domain (L1): author the object types, business terms, relationships, and governance that this Object Model composes.