Create a new JSON-LD context definition
Description
Use case 1.2 to create a new JSON-LD context definition is specified as follows.
Use Case UC1.2: Create a new JSON-LD context definition |
Goal: Create a new standalone JSON-LD context definition that uses terms from Core Vocabularies. |
Primary Actors: Semantic Engineer, Software Engineer |
Description: The goal is to design and create a new JSON-LD context definition that is not part of a more comprehensive semantic data specification, relying on terms from existing CVs as much as possible. As an information exchange data model, a JSON-LD context definition can be integrated in describing data, building APIs, and other operations involved in information exchange. |
Example: Core Person Vocabulary [cpv-json-ld], Core Business Vocabulary [cbv-json-ld] |
Note: A detailed methodology to be applied for use cases will be provided in the Create a new JSON-LD context definition section. |
Guideline to create a new JSON-LD context definition
This section provides guidelines for addressing use case UC1.2.
JSON-LD is a W3C Recommendation for serialising Linked Data, combining the simplicity, power, and Web ubiquity of JSON with the concepts of Linked Data. Creating JSON-LD context definitions facilitates this synergy. This ensures that when data is shared or integrated across systems, it maintains its meaning and can be understood in the same way across different contexts. This guide describes how to create new JSON-LD contexts for existing Core Vocabularies.
The three key phases are:
-
Import or define elements
-
Shape structure
-
Review and validate
Import or define elements
When a Core Vocabulary has defined an associated JSON-LD context already, it is not only easy, but also advisable to directly import this context using the @import
keyword. This enables seamless reuse and guarantees that any complex types or elements defined within the vocabulary are integrated correctly and transparently within new schemas.
In cases where the Core Vocabulary does not provide an JSON-LD context, it is necessary to create the corresponding field element definitions for the reused URIs. To start, gather all the terms from the selected Core Vocabulary that need to be included in the JSON-LD context.
Then, decide the desired structure of the JSON-LD file, by defining the corresponding keys, such as Person.givenName
. These new fields must adhere to the naming defined by the selected Core Vocabulary to maintain consistency.
Finally, assign URIs to keys. Each term in the JSON-LD context must be associated with a URI from an ontology that defines its meaning in a globally unambiguous way. Associate the URIs established in Core Vocabularies to JSON keys using the same CV terms.
The ones that are imported by the Core Vocabularies, shall be used as originally defined.
Shape structure
Main shaping of the structure
Start with defining the structure of the context by relating class terms with property terms and then, if necessary, property terms with other classes.
Commence by creating a JSON structure that starts with a @context
field. This field will contain mappings from one’s own vocabulary terms to other’s respective URIs. Continue by defining fields for Classes and subfields for their properties.
If the JSON-LD context is developed with the aim of being used directly in exchange specific to an application scenario, then aim to establish a complete tree structure that starts with a single root class. To do so, specify precise @type
references linking to the specific Class.
If the aim of the developed JSON-LD context is rather ensuring semantic correspondences, without any structural constraints, which is the case for core or domain semantic data specification, then definitions of structures specific to each entity type and its properties suffice, using only loose references to other objects.
Improvements to the structure
To meet wishes from API consumers, one may use aliasing of keywords, where a JSON-LD context element is given a more easily recognisable string.
One can also extend the context by reusing terms from Core Vocabularies, which also uses the @import
keyword if included as a whole. Alternatively, single elements can be added, such as additional properties and mapping those to other vocabulary elements of other vocabularies.
Review and validate
First, one should review the created context against any prior requirements that may have been described: is all prospected content indeed included in the context?
Second, the syntax should be verified with a JSON-LD validator, such as JSON-LD Playground to ensure that the context is free of errors and all URLs used are operational.
UC 1.2 tutorial on creating JSON-LD context
Introduction
Public administrations often need to share information about their services with other organisations and the public. To do this effectively, the data must be easy to understand and work seamlessly across different systems. However, public services are becoming more complex, which means we need to capture more details, concepts, and relationships to handle various use cases.
The Core Public Service Vocabulary Application Profile (CPSV-AP) provides a generic framework to describe public services in a machine-readable way. It helps public administrations share and organise information about services. However, sometimes CPSV-AP needs to be extended with new concepts or restrictions to address more general or specific use cases.
For example, the terms Service and RequiredEvidence were introduced in CPSV-AP-NO to extend the CPSV-AP model such that it can fulfil the specific needs identified in Norway, where:
-
Service allows for describing not only public services but also general ones, enabling the representation of services provided through partnerships or private organisations.
-
RequiredEvidence provides a way to explicitly define the documentation or credentials needed to access a service, such as proof of address for health insurance registration. To make CPSV-AP more flexible and useful, creating a JSON-LD context is essential. JSON-LD helps structure the data so it can be easily shared and understood by different systems. This tutorial addresses the use case UC1.2, and will show how to create a JSON-LD context for an Application Profile that extends CPSV-AP with new concepts like Service and RequiredEvidence, which are defined by reusing concepts from the Core Business Vocabulary (CBV), following ideas from CPSV-AP-NO.
By extending CPSV-AP and using JSON-LD, public administrations can better organise their data, making it easier to share and integrate across systems while supporting a wider range of use cases.
Steps to create a JSON-LD context
Import or define elements:
Since CPSV-AP provides an existing JSON-LD context, we can import it in our own JSON-LD context using the @import statement. For example, in case of CPSV-AP version 3.2.0, the context can be directly reused like this:
{
"@context": {
"@import": "https://raw.githubusercontent.com/SEMICeu/CPSV-AP/master/releases/3.2.0/context/cpsv-ap.jsonld"
}
}
If a context that we can reuse does not exist, define the elements explicitly. For example, CPSV-AP uses specific terms such as PublicService and ContactPoint. These terms must be mapped to URIs.
{
"@context": {
"PublicService": "http://purl.org/vocab/cpsv#PublicService",
"ContactPoint": "http://data.europa.eu/m8g/ContactPoint"
}
}
If a context needs to be extended, define the new elements explicitly. For example, if we need new terms (classes), such as Service and RequiredEvidence, which are not in CPSV-AP these terms must be mapped to URIs (the examples are inspired from CPSV-AP-NO) :
{
"@context": {
"Service": "http://example.com/cpsvap#Service",
"RequiredEvidence": "http://example.com/cpsvap#RequiredEvidence"
}
}
Shape the structure
Once you’ve imported or defined the relevant terms, you need to structure your JSON-LD context to reflect the relationships between the classes and their properties. This allows you to describe public services and their details in a standardised and machine-readable format.
Let’s look at an example where we define a Service and some of its key properties, such as contactPoint, description, name and hasRequiredEvidence.
{
"@context": {
"@import": "https://raw.githubusercontent.com/SEMICeu/CPSV-AP/master/releases/3.2.0/context/cpsv-ap.jsonld",
"Service": "http://example.com/cpsvap#Service",
"Service.hasRequiredEvidence": {
"@id": "http://example.com/cpsvap#RequiredEvidence",
"@container": "@set"
},
"Service.description": {
"@id": "http://purl.org/dc/terms/description",
"@type": "http://www.w3.org/1999/02/22-rdf-syntax-ns#langString",
"@container": "@set"
},
"Service.name": {
"@id": "http://purl.org/dc/terms/title",
"@type": "http://www.w3.org/1999/02/22-rdf-syntax-ns#langString",
"@container": "@set"
},
"Service.contactPoint": {
"@id": "http://data.europa.eu/m8g/contactPoint",
"@type": "@id",
"@container": "@set"
}
}
}
Explanation of JSON-LD keywords used
-
@context: Defines the mapping between terms (e.g., PublicService) and their corresponding IRIs.
-
@container: Specifies how values are structured. For instance,
-
@set: Explicitly defines a property as an array of values. It ensures that even if the data includes just one value, it will still be treated as an array by JSON-LD processors. This makes post-processing of JSON-LD documents easier as the data is always in array form, even if the array only contains a single value
-
-
@id: Provides the unique identifier (IRI) for a term or property.
-
@type: Specifies the type of a value. Commonly used for linking to classes or data types.
-
@import: Imports another JSON-LD context, allowing reuse of its terms.
Example of a simple service instance
After defining the context and structure, you can now describe an actual Service instance by referencing the terms you defined earlier.
Example scenario
Let’s assume a public administration offers a service called "Health Insurance Registration". This service allows citizens to register for health insurance, which requires certain documents (evidence) to complete the process. Citizens might need to contact the administration for guidance, and the service details should be structured in a way that makes it easy to share and integrate across systems.
To illustrate this, we’ve created a JSON-LD context representation of this service, highlighting
-
The required evidence for registration (e.g., Proof of Address).
-
The service’s name and description for clarity.
-
Contact information for users who may need assistance.
Try this in JSON-LD Playground here
{
"@context": [
"https://raw.githubusercontent.com/SEMICeu/CPSV-AP/master/releases/3.2.0/context/cpsv-ap.jsonld"
],
"@id": "http://example.org/service/healthInsuranceRegistration",
"@type": "PublicService",
"PublicService.name": {
"@value": "Health Insurance Registration",
"@language": "en"
},
"PublicService.description": {
"@value": "A service for registering for health insurance.",
"@language": "en"
}
}
Aliasing keywords for API compatibility (REST API example)
When working with REST APIs, it is often beneficial to alias certain JSON-LD keywords for simpler or more consistent representations in client applications. For example, you might alias JSON-LD’s @id
to url
and @type
to type
to make the data more intuitive for API consumers, especially when working with legacy systems or client-side frameworks that use specific naming conventions.
Example of aliasing keywords
{
"@context": {
"url": "@id",
"type": "@type",
"Service": "http://purl.org/vocab/cpsv#PublicService",
"Service.name": "http://purl.org/dc/terms/title",
"Service": "http://purl.org/vocab/cpsv#PublicService",
"Service.description": "http://purl.org/dc/terms/description"
},
"url": "http://example.com/service/healthInsuranceRegistration",
"type": "Service",
"Service.name": "Health Insurance Registration",
"Service.description": "A service for registering for health insurance."
}
In this example:
-
url
is an alias for@id
-
type
is an alias for@type
By aliasing these terms, the API responses are simplified and more familiar to the developers interacting with the service, especially if they are accustomed to a different JSON structure.
Extend the context by reusing terms from Core Vocabularies
To highlight the reuse of terms from existing CVs, we can import the Core Business Vocabulary (CBV) context alongside the CPSV-AP context to gain access to business-related terms. This step ensures that you can use the additional terms from CBV, such as LegalEntity, Organisation, and ContactPoint, to enrich your Service descriptions.
{
"@context": [
{
"@import": "https://raw.githubusercontent.com/SEMICeu/CPSV-AP/master/releases/3.2.0/context/cpsv-ap.jsonld"
},
{
"@import": "https://raw.githubusercontent.com/SEMICeu/Core-Business-Vocabulary/master/releases/2.2.0/context/core-business-ap.jsonld"
}
]
}
Define additional properties from the Core Business Vocabulary
Add CBV terms to enhance the description of the Service entity.
{
"@context": {
"Service.providedBy": {
"@id": "http://example.com/legal#providedBy",
"@type": "http://example.com/legal#LegalEntity"
},
"LegalEntity": "http://www.w3.org/ns/legal#LegalEntity"
}
}
Map extended properties in a service instance:
Use the extended properties to describe more aspects of Service instances. For example:
{
"@context": [
"https://raw.githubusercontent.com/SEMICeu/CPSV-AP/master/releases/3.2.0/context/cpsv-ap.jsonld",
"https://raw.githubusercontent.com/SEMICeu/Core-Business-Vocabulary/master/releases/2.2.0/context/core-business-ap.jsonld",
{
"ex": "http://example.org/"
}
],
"@id": "http://example.org/service/healthInsuranceRegistration",
"@type": "PublicService",
"PublicService.name": {
"@value": "Health Insurance Registration",
"@language": "en"
},
"PublicService.description": {
"@value": "A service for registering for health insurance.",
"@language": "en"
},
"ex:providedBy": {
"@id": "http://example.org/legalEntity/healthDepartment",
"@type": "LegalEntity"
}
}
Final review and validation
Use an online tool such as the JSON-LD Playground to validate JSON-LD context and make sure there are no errors.

Error example:
If the @import
URLs for external contexts are incorrect or unavailable, the validation tool may display an error such as:
-
"Error loading remote context" or
-
"Context could not be retrieved."
{
"@context": [
{ "@import": "https://invalid-url/cpsv-ap.jsonld" }
]
}
These errors typically occur when the referenced context URL is malformed or unreachable, as shown in the following figure:
