Introduction to Standard Elements for Things
Every Thing on GRCSchema.org carries a small set of standard elements: @context, @id, elementId, version, coreMetaData, and (on write operations) clientReferenceId. They're what make a record interpretable by machines, citable by humans, and auditable by the people who have to trust it later. This document explains each one and how to implement it.
@context
In JSON-LD (JavaScript Object Notation for Linked Data), @context defines the vocabulary for the terms used in the data structure. It provides the base URI used to expand the properties and types in the document. For GRCSchema.org vocabulary, set it to https://grcschema.org. Any application processing the JSON-LD then knows to interpret the terms according to the definitions published there.
A simple example:
{
"@context": "https://grcschema.org",
"@type": "Person",
"name": "Jane Doe",
"postalAddress": "1234 Tuff Street",
"countryCode": "USA"
}
Here @context ensures that name, postalAddress, and countryCode are understood as defined by GRCSchema.org, not guessed at by the consumer.
@context appears once, at the root of the response body. Nested objects don't repeat it (see the Overview on Objects).
@id
The @id property is the unique identifier for the item described. It's a URL, and it does two jobs at once: it points to where more information about the item lives, and it acts as a node identifier that other parts of the document (or other documents entirely) can reference.
@id is what keeps two entities with similar properties from collapsing into one. Two people might share a name and a job title. They will never share an @id.
elementId
elementId is the record identifier for a particular record within its system's data set. It exists so external sources can reference the record without parsing the full @id URL to extract it. The @id can also address child collections, e.g. https://grcschema.org/authority-document/1/citation for the citations within a document.
How @id and elementId work together:
{
"@context": "https://grcschema.org",
"@type": "AuthorityDocument",
"@id": "https://grcschema.org/authority-document/1",
"elementId": 1
}
The @id uniquely identifies this AuthorityDocument across every system that ever references it. The elementId identifies it within its home system. One is the global address, the other is the local key.
version
Versioning of Things is tracked within GRCSchema.org. Versioning of properties is not. This lets participating organizations document which version of the schema a record is intended to comply with, while GRCSchema.org itself stays backward compatible, minimizing version dependencies.
Tying a schema Thing to a particular vendor's API version is the ISV's job, done in their API context. See Schema versioning vs. API versioning.
coreMetaData
coreMetaData is the provenance record that travels with every Thing: who created it, who changed it, whether it's alive, and whether you can trust it. A mapping or record that can't show its history isn't auditable, and compliance data gets audited.
The property is coreMetaData (lowerCamelCase, like every property). Its value is the Type CoreMetaData, published as its own Thing in the Shared vocabulary at grcschema.org/vocabularies/shared/coreMetaData. That registry entry, not this page, is the authoritative definition. Its structure:
{
"coreMetaData": {
"@type": "CoreMetaData",
"checksum": "String | A change fingerprint: the SHA-256 hash of the record's '@type', 'elementId', most recent 'modified.timeStamp', and 'live' value. Not tamper-evidence. See the checksum page.",
"created": {
"@type": "Created",
"organization": {
"@type": "Organization",
"@id": "URL | The full unique link to the organization so it is traversable by this property.",
"elementId": "String | A unique and persistent identifier for the organization within the system's data set.",
"name": "String | The name of the organization."
},
"person": {
"@type": "Person",
"@id": "URL | The full unique link to the person so it is traversable by this property.",
"elementId": "String | A unique and persistent identifier for the person within the system's data set.",
"name": "String | The name of the person."
},
"timeStamp": "Datetime | When the record was created."
},
"deprecatedBy": "URL | The record that deprecated this one, if any.",
"live": "Boolean | \"live\" (1) or \"deprecated\" (0).",
"modified": {
"@type": "Modified",
"organization": {
"@type": "Organization",
"@id": "URL | The full unique link to the organization so it is traversable by this property.",
"elementId": "String | A unique and persistent identifier for the organization within the system's data set.",
"name": "String | The name of the organization."
},
"person": {
"@type": "Person",
"@id": "URL | The full unique link to the person so it is traversable by this property.",
"elementId": "String | A unique and persistent identifier for the person within the system's data set.",
"name": "String | The name of the person."
},
"timeStamp": "Datetime | When the record was last modified."
},
"notes": "String | Additional text information.",
"status": "String | The item's release status as one of these values: Released, Redacted, In Edit, Re-Queued, Recommended, Not Applicable, On Hold, Restricted, In Review, Queued.",
"supersededBy": "URL | The Thing ID that supersedes this Thing.",
"validated": "Integer | Whether this record is validated by an authority: 1 = Created, 2 = Reviewed, 3 = Review Approved."
}
}
Notes on the fields auditors lean on:
- The checksum is a change fingerprint, not tamper-evidence. What it is and isn't for is specified on the checksum page.
- The status list is closed. Ten values, no others valid.
- Between supersededBy and deprecatedBy, records don't disappear. They get replaced, visibly.
What coreMetaData buys you
- Integrity: the checksum and validation flags surface tampering and unreviewed changes.
- Audit trail: creation and modification tracking (who, when) gives auditors the history they will ask for.
- Lifecycle:
live,status,supersededBy, anddeprecatedBycarry a record from creation through deprecation without ever losing the thread. - Traceability: identifiers plus timestamps mean every record's lineage can be followed, by people and by machines.
clientReferenceId
When creating records (POST) or updating them (PATCH), an optional key-value pair adds idempotency protection and non-repudiation. There's enough to say about it that it has its own page.