Resource shapes (Deprecated)
We observed that many users found the term shape confusing, so we simplified it to document type for clarity.
Where a shape was previously used, it is now replaced by a document type with a similar name. A few examples include:
- The shape
imxjson_shapeis now the document typeimx_completed_json. - The shape
other_document_shapeis now the document typeother_document.
What is a shape
Within Linckr every resource is conforming to a certain shape. The term shape is borrowed from the Solid Specification and is nothing more than a schema or contract definition or type of a data object.
In Linckr all the personal data of a consumer is stored in a Solid data pod. This is the reason why we use the term shape, because it is well-known in the Solid world.
Examples of common data schema's are GraphQL Schema, XSD Schema, JSON Schema, ...
What schema type do we support today
Solid pods build further on the principles of linked data. In the Linked data world data is stored in RDF format and schema's can be defined in the Shex or the Shacl language. At Linckr we have chosen to not store data as linked data (yet).
Today all structured data is stored in Json and conforms to a given Json-schema. Unstructured data like photo's, pdf's etc. are stored as binaries.
IMX JSON data shape & example
Every completed infomediation contains at least one resource where the shape is imx_json. This shape has the following json-schema
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"metadata": {
"type": "object",
"properties": {
"connectionId": {
"type": "string"
},
"organisationName": {
"type": "string"
},
"organisationWebId": {
"type": "string"
},
"consumerFirstname": {
"type": "string"
},
"consumerLastname": {
"type": "string"
},
"consumerWebId": {
"type": "string"
},
"journeyReference": {
"type": "string"
},
"journeyType": {
"type": "string"
},
"consumerRole": {
"type": "string"
},
"validTillDate": {
"type": "array",
"items": [
{
"type": "integer"
},
{
"type": "integer"
},
{
"type": "integer"
},
{
"type": "integer"
},
{
"type": "integer"
},
{
"type": "integer"
},
{
"type": "integer"
}
]
},
"consentDate": {
"type": "array",
"items": [
{
"type": "integer"
},
{
"type": "integer"
},
{
"type": "integer"
},
{
"type": "integer"
},
{
"type": "integer"
},
{
"type": "integer"
},
{
"type": "integer"
}
]
},
"providerMessage": {
"type": "string"
},
"templateTypeMetaData": {
"type": "object",
"properties": {
"documentTypeNames": {
"type": "object",
"properties": {
"nl_NL": {
"type": "string"
},
"en_EN": {
"type": "string"
}
},
"required": [
"nl_NL",
"en_EN"
]
},
"providerMessage": {
"type": "string"
}
},
"required": [
"documentTypeNames",
"providerMessage"
]
}
},
"required": [
"connectionId",
"organisationName",
"organisationWebId",
"consumerFirstname",
"consumerLastname",
"consumerWebId",
"journeyReference",
"journeyType",
"consumerRole",
"validTillDate",
"consentDate",
"providerMessage",
"templateTypeMetaData"
]
},
"data": {
"type": "object"
}
},
"required": [
"metadata",
"data"
]
}
Within the latter shape the data object is a container object that can in its turn consist of none, one or multiple shapes.
The infomediation template id determines which shapes are part of the data object. Let's illustrate this with an example.
Example
Let's assume the infoMediations query returns the following response:
{
"data": {
"infoMediations": [
{
"id": "6f0cb271-b163-4f00-9416-4e6abb5f7469",
"template": {
"__typename": "InformationRequestInfoMediationTemplate",
"id": "PERSONAL_INFORMATION",
"type": "INFORMATION_REQUEST_TEMPLATE",
"name": "Persoonsgegevens"
},
"status": "COMPLETED",
"resources": [
{
"id": "941fd20a-3467-46d3-a5ef-f4145beab908",
"nameToDisplay": "20230418_0639_Michael_Cornelis_PERSONAL_INFORMATION_8373ab_7_b",
"shape": "imx_pdf_shape",
"mediaType": "application/pdf"
},
{
"id": "327db463-f068-4741-87aa-4abb1e2a6fef",
"nameToDisplay": "20230418_0639_Michael_Cornelis_imxjson_shape",
"shape": "imx_json_shape",
"mediaType": "application/json"
}
]
}
]
}
}
We can read that the templateId is PERSONAL_INFORMATION and based on that id we can agree the shapes that are part of the data container in the imx_json_shape. Let's agree in this example that the shape is called personal_info_shape and complies with the following json schema:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"sub": {
"type": "string"
},
"given_name": {
"type": "string"
},
"family_name": {
"type": "string"
},
"preferred_username": {
"type": "string"
},
"email": {
"type": "string"
},
"email_verified": {
"type": "boolean"
},
"gender": {
"type": "string"
},
"birthdate": {
"type": "string"
},
"phone_number": {
"type": "string"
},
"phone_number_verified": {
"type": "boolean"
},
"address": {
"type": "object",
"properties": {
"street_address": {
"type": "string"
},
"postal_code": {
"type": "string"
},
"country": {
"type": "string"
}
},
"required": [
"street_address",
"postal_code",
"country"
]
}
},
"required": [
"sub",
"given_name",
"family_name",
"preferred_username",
"email",
"email_verified",
"gender",
"birthdate",
"phone_number",
"phone_number_verified",
"address"
]
}
Let's assume that the resource with id 941fd20a-3467-46d3-a5ef-f4145beab908 and shape imx_json_shape that conforms to the json schema defined above contains the following values:
{
"metadata": {
"connectionId": "8ee0c676-cd71-46d3-9b81-647c0fe2499d",
"organisationName": "Immo Hengelen",
"organisationWebId": "https://sandbox.use.id/hengelen",
"consumerFirstname": "Michael",
"consumerLastname": "Cornelis",
"consumerWebId": "https://sandbox.use.id/michaelcornelis",
"journeyReference": "8373ab_7_b",
"journeyType": "RESIDENCE_JOURNEY",
"consumerRole": "BUYER",
"validTillDate": [
2023,
7,
17,
6,
39,
36,
922227154
],
"consentDate": [
2023,
4,
18,
6,
39,
36,
922263709
],
"providerMessage": "Hey Michael\n\nZou ik je persoonlijke informatie mogen?\n\nMet vriendelijke groeten\n\nMichael",
"templateTypeMetaData": {
"providerMessage": "Hey Michael<br><br>Zou ik je persoonlijke informatie mogen?<br><br>Met vriendelijke groeten<br><br>Michael"
}
},
"data": {
"personal_info_shape": {
"sub": "c72823f2-1554-47a7-b53b-14b5ea11980b",
"given_name": "Michael",
"family_name": "Cornelis",
"preferred_username": "michael+postman@lemon.be",
"email": "michael+postman@lemon.be",
"email_verified": true,
"gender": "m",
"birthdate": "1994-01-02",
"phone_number": "+32478499683",
"phone_number_verified": true,
"address": {
"street_address": "Heistraat 6-",
"postal_code": "7383HG",
"country": "NL"
}
}
}
}
The data container contains one object called personal_info_shape which complies with the agreed-upon json schema. This data can be parsed by an ERP system to reuse the data and automate tasks.
Overview of shapes & json schema's we support today
The following shapes are likely to change in the nearby future. We are also working on a feature that we can always remain backward compatible with the agreed-upon shapes.
Digidentity user info shape
shape digidentity_user_info_shape
{
"schema": {
"properties": {
"given_name": {
"type": "string"
},
"family_name": {
"type": "string"
},
"birthdate": {
"type": "string"
},
"gender": {
"type": "string"
},
"email": {
"type": "string"
},
"identity_document": {
"oneOf": [
{
"type": "object",
"properties": {
"type": {
"type": "string"
},
"number": {
"type": "string"
},
"expiration_date": {
"type": "string"
},
"state": {
"type": "string"
}
}
},
{
"type": "null"
}
]
}
},
"required": []
}
}
Retrieve data shape
shape retrieve_data_shape
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"first_name": {
"type": "string",
"pattern": "^[A-Za-z ,.'-]+$"
},
"last_name": {
"type": "string",
"pattern": "^[A-Za-z ,.'-]+$"
},
"birthdate": {
"type": "string"
},
"birthplace": {
"type": "string"
},
"address": {
"type": "string",
"pattern": "^[0-9A-Za-z ,.'-]+$"
},
"postal_code": {
"type": "string"
},
"residence": {
"type": "string",
"pattern": "^[0-9A-Za-z ,.'-]+$"
},
"country": {
"type": "string",
"pattern": "^[0-9A-Za-z ,.'-]+$"
}
},
"required": [
"first_name",
"last_name",
"birthdate",
"birthplace",
"address",
"postal_code",
"residence",
"country"
]
}
Retrieve pep shape
shape pep_shape
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"first_name": {
"type": "string",
"pattern": "^[A-Za-z ,.'-]+$"
},
"last_name": {
"type": "string",
"pattern": "^[A-Za-z ,.'-]+$"
},
"birthdate": {
"type": "string"
},
"birthplace": {
"type": "string"
},
"address": {
"type": "string",
"pattern": "^[0-9A-Za-z ,.'-]+$"
},
"postal_code": {
"type": "string"
},
"residence": {
"type": "string",
"pattern": "^[0-9A-Za-z ,.'-]+$"
},
"country": {
"type": "string",
"pattern": "^[0-9A-Za-z ,.'-]+$"
}
},
"required": [
"first_name",
"last_name",
"birthdate",
"birthplace",
"address",
"postal_code",
"residence",
"country"
]
}
Financial questions buyer shape
shape financial_questions_buyer_shape
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"buyer": {
"type": "object",
"properties": {
"reason": {
"type": "string"
},
"known_price": {
"type": "boolean"
},
"approximation_price": {
"type": "number"
}
},
"required": [
"reason",
"known_price"
],
"if": {
"properties": {
"known_price": {
"const": true
}
}
},
"then": {
"required": [
"approximation_price"
]
}
},
"financing": {
"type": "object",
"properties": {
"needs_financing": {
"type": "boolean"
},
"source": {
"type": "string",
"oneOf": [
{
"const": "PRIVATE",
"title": "private funds"
},
{
"const": "EXTERNAL",
"title": "external financing"
},
{
"const": "BOTH",
"title": "combination of private funds and external financing"
}
]
}
},
"if": {
"properties": {
"needs_financing": {
"const": true
}
}
},
"then": {
"required": [
"source"
]
}
},
"private_funds": {
"type": "object",
"properties": {
"sources": {
"type": "array",
"uniqueItems": true,
"items": {
"oneOf": [
{
"const": "interest_income",
"title": "interest income"
},
{
"const": "financial_products",
"title": "investments in financial products"
},
{
"const": "dividends",
"title": "dividends"
},
{
"const": "real_estate",
"title": "income from real estate interests"
},
{
"const": "labour",
"title": "income from labour, benefits or pension"
},
{
"const": "inheritance",
"title": "inheritance"
},
{
"const": "donation",
"title": "donation"
},
{
"const": "sale_of_activa",
"title": "sale of activa such as shares or real estate"
},
{
"const": "crypto",
"title": "cryptocurrency trading"
},
{
"const": "other",
"title": "Other"
}
]
}
},
"inheritance_source": {
"type": "string",
"pattern": "^[A-Za-z ,.'-]+$"
},
"donation_source": {
"type": "string",
"pattern": "^[A-Za-z ,.'-]+$"
},
"other": {
"type": "string",
"pattern": "^[A-Za-z ,.'-]+$"
}
},
"allOf": [
{
"if": {
"properties": {
"sources": {
"contains": {
"const": "inheritance"
}
}
}
},
"then": {
"required": [
"inheritance_source"
]
}
},
{
"if": {
"properties": {
"sources": {
"contains": {
"const": "donation"
}
}
}
},
"then": {
"required": [
"donation_source"
]
}
},
{
"if": {
"properties": {
"sources": {
"contains": {
"const": "other"
}
}
}
},
"then": {
"required": [
"other"
]
}
}
]
},
"external_financing": {
"type": "object",
"properties": {
"regulated": {
"type": "string",
"oneOf": [
{
"const": "regulated",
"title": "Regulated"
},
{
"const": "non_regulated",
"title": "Not regulated"
},
{
"const": "loan",
"title": "Private person"
}
]
},
"regulated_institution_name": {
"type": "string",
"pattern": "^[0-9A-Za-z ,.'-]+$"
},
"non_regulated_funding_provider_name": {
"type": "string",
"pattern": "^[0-9A-Za-z ,.'-]+$"
},
"non_regulated_funding_provider_address": {
"type": "string",
"pattern": "^[0-9A-Za-z ,.'-]+$"
},
"loan_financing": {
"type": "string",
"pattern": "^[0-9A-Za-z ,.'-]+$"
}
}
}
},
"allOf": [
{
"if": {
"properties": {
"financing": {
"properties": {
"source": {
"oneOf": [
{
"const": "PRIVATE"
},
{
"const": "BOTH"
}
]
},
"needs_financing": {
"const": true
}
}
}
}
},
"then": {
"properties": {
"private_funds": {
"properties": {
"sources": {
"minItems": 1
}
}
}
}
}
},
{
"if": {
"properties": {
"financing": {
"properties": {
"source": {
"oneOf": [
{
"const": "EXTERNAL"
},
{
"const": "BOTH"
}
]
},
"needs_financing": {
"const": true
}
}
}
}
},
"then": {
"properties": {
"external_financing": {
"required": [
"regulated"
],
"if": {
"properties": {
"regulated": {
"const": "regulated"
}
}
},
"else": {
"if": {
"properties": {
"regulated": {
"const": "non_regulated"
}
}
},
"else": {
"required": [
"loan_financing"
]
},
"then": {
"required": [
"non_regulated_funding_provider_name",
"non_regulated_funding_provider_address"
]
}
},
"then": {
"required": [
"regulated_institution_name"
]
}
}
},
"required": [
"external_financing"
]
}
}
],
"required": [
"buyer"
]
}
Ubo shape shape
shape determine_ubo_shape
{
"schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"shares_organisation_more_than_25": {
"type": "boolean"
},
"shares_economic_interest_more_than_25": {
"type": "boolean"
},
"control_organisation_more_than_25": {
"type": "boolean"
},
"actual_control_organisation": {
"type": "boolean"
}
},
"required": [
"shares_organisation_more_than_25",
"shares_economic_interest_more_than_25",
"control_organisation_more_than_25",
"actual_control_organisation"
],
"allOf": [
{
"if": {
"properties": {
"shares_organisation_more_than_25": {
"const": true
}
}
},
"then": {
"properties": {
"shares_organisation_percentage": {
"type": "number"
}
},
"required": [
"shares_organisation_percentage"
]
}
},
{
"if": {
"properties": {
"shares_economic_interest_more_than_25": {
"const": true
}
}
},
"then": {
"properties": {
"shares_economic_interest_percentage": {
"type": "number"
}
},
"required": [
"shares_economic_interest_percentage"
]
}
},
{
"if": {
"properties": {
"control_organisation_more_than_25": {
"const": true
}
}
},
"then": {
"properties": {
"control_organisation_percentage": {
"type": "number"
}
},
"required": [
"control_organisation_percentage"
]
}
}
]
}