Documentation

The Objects API and the Objecttypes API are two components that complement each other. The Objecttypes API holds the object definitions for objects that can be stored in the Objects API. Together they provide a powerful way to create and store any kind of object.

Designed in line with the Common Ground model, they can be used by other APIs that need to store object specific data.

Both the Objects API and the Objecttypes API are and only use Open-source.

Getting started

To get you started, you might find some of these links relevant:

Objecttypes API

Standardize various types of objects in an accessible way and without the need to create a whole new API for each (simple) object.

This national level API is required for registering objects in local Objects API. Organizations can also run the API locally, to use both national and local definitions of objects.

Objects API

Easily store and expose various objects and make them available in a standardized format. It can be used by any organization to manage relevant objects. An organization can also choose to use it to expose objects to the public as Open Data.

To define the format of objects, organizations can use a national and/or local Objecttypes API.

Introduction

To store and expose various types of domain specific data, or objects, we need an appropriate API. Domain specific objects can be a “signal”, “dog”, “tree”, “parking permit”, “complaint”, “family”, or anything really.

Organizations (specifically municipalities) want to store, retrieve and connect these different kind of objects. For example: A “Zaak” (Case) should be able to refer to a “tree”, or all “trees” need to be shown on a geographic map.

These object registrations are necessary in the IT-landscape to create domain specific applications according to the Common Ground principles. Standardization of the object definitions is necessary to prevent divergent solutions and implementations.

The power of this setup is that as soon as you create or allow an objecttype, you can start storing objects of that objecttype. No deploy, setup, configuration or development needed.

Vision

It is difficult to know and to define each object in advance and create an appropriate API for it. This would cause significant slowdown of the implementation of the Common Ground principles and the IT-landscape would see a huge amount of APIs for each and every object type.

We are therefore introducing 2 complementing APIs:

Objecttypes API

At a national level, there should be a registration for all kinds of object types. The object types hold the definition of an object and these definitions can be obtained via an API, the Objecttypes API.

The definition of an object can be proposed by domain experts and approved by the VNG to become part of the national Objecttypes API. An organization can also use its own Objecttypes API to hold definitions of locally defined objects.

Objects API

An organization can set up one or more Objects APIs. Each object in the Objects API should adhere to a definition in the Objecttypes API.

Organizations can use one Objects API to store all objects, or set up multiple Objects API to separate between domains and/or open and internal data.

With the above setup, applications can now easily use objects that use the same definition in all organizations that rely on the same object type.

Background

There are many data sources available or desired. These data sources are stored on various media, ranging from an Excel file to a database. The format in which the data is stored often differs even though it concerns the same type of objects. Information models are often available, in various levels of completeness and each organization decides how to implement and expose these models to the outside world.

With the Objecttypes API an attempt is made to go beyond an information model and create a standard on a message exchange level, in the form of JSON schema.

Various data sources

There are many existing data sources that could potentially be converted to an objecttype definition.

  • The Dutch government has many open data sources including metadata (link)

  • For Dutch geographical objects, there are information models defined (link)

Definitions

Objecttype
  • A definition, represented as a JSON-schema, together with metadata about the objecttype. Each objecttype represents a collection of objects of similar form and/or function.

e.g. The objecttype tree has 2 attributes: height and type. This will hold a definition for future objects.

Object
  • A self-contained entity of data with its own identity, structured according to the JSON-schema of the objecttype.

e.g. A particular street has 3 trees. That means there are 3 objects of objecttype tree:

  1. height: 4.9m, type: oak

  2. height: 5.1m, type: oak

  3. height: 5.0m, type: pine tree

Objecttypes API
  • An API to retrieve (one or more) objecttypes.

Standardize various types of objects, on a national or just as easily on a local municipality level, and make them accessible as resources for other applications.

Objects API
  • An API to retrieve, filter, search, write, update or delete objects.

Easily store and expose various objects according to the related objecttype resource in the Objecttypes API.

Information model

The Objects and Objecttypes APIs can be represented as an information model (IM). The IM shows the relations between classes from both APIs and makes use of the Dutch standard Metamodel Informatiemodellering (MIM).

The Object and Objecttypes information model.

An organization creates and Objecttype. The Objecttype contains various meta data attributes and essentially describes the type of object and keeps track of the administrative properties. An Objecttype has one or more ObjecttypeVersions. Each ObjecttypeVersion has a version number and contains the actual attributes - stored as JSON schema - that are needed to represent an Object of this Objecttype.

Once an organization has an Objecttype with its first ObjecttypeVersion, Objects can be stored. An Object is defined by an Objecttype. The Object can change over time and these changes are reflected in Records. An Object therefore always has one or more Records of a specific ObjecttypeVersion.

History is modelled as described by the Dutch StUF standard for keeping both formal and material history and allow for formal corrections over time, without changing the material history.

Metadata

The Objecttypes API includes metadata which design is based on Gezamenlijke aanpak Metadatabeheer Data in de G4 and Datacatalogus. The mapping for all Objecttypes attributes to fields from these documents is shown in the table below.

Objecttypes attribute

Metadatabeheer

Datacatalogus

name

A - Naam

Titel

namePlural

description

Beschrijving

labels

A - Trefwoorden

Tags

maintainerOrganization

A - Eigenaar (Organisatie)

Eigenaar

maintainerDepartment

Dienst

contactPerson

A - Contactpersoon

Contactpersoon

contactEmail

E-mail contactpersoon

providerOrganization

A - Verstrekker

Verstrekker

source

B - Bronsysteem

Bron

status

B - Huidige status

Status

dataClassification

Dataclassificatie

versions/publicationDate

A - Wijzigingsdatum

Bijgewerkt

updateFrequency

A - Wijzigingsfrequentie

Updatefrequentie

documentationUrl

C - Documentatie

Visualization

The Objectypes API works together with the Objects API: Objects are of a certain objecttype. In the examples below, there is an objecttype tree that is considered the national definition. The objecttype is therefore present in the national Objecttypes API, hosted by a public national organization, such as the VNG.

The municipality of Utrecht wants to store its trees according to the national definition and indicates that the trees in its Objects API follow the objecttype tree as provided in the Objecttypes API by VNG.

As soon as the municipality of Utrecht authorizes this, trees can immediately be stored in their Objects API.

Municipality of Utrecht using its own Objects API to store trees according to the definitions from the VNG Objecttypes API.

Not only the municipality of Utrecht can do this. Many more organizations can do this and store the trees that are relevant for them according to this definition.

More organizations store their trees according to the national definition.

Every organization is free to decide which objecttypes to use but also, which Objecttypes API to use. It’s supported to run your own Objecttypes API with your own objecttypes. This is useful if you want to deviate from national standards or want to use other objecttypes that are not available in the national Objecttypes API.

In the case below, the municipality of Amsterdam decides to use their own objecttype of a tree. They run their own Objecttypes API with that specific objecttype in it.

Municipality of Amsterdam using its own Objecttypes API.

Eventually, the Objects API will contain objects of many different objecttypes that can come from many different Objecttypes API.

Mixing Objecttypes API in your Objects API

Features

Below is a list of the high level features of the APIs.

Objecttypes API
  • JSON-schema validation

    When creating a new objecttype, the JSON-schema is validated. Only valid JSON-schemas are allowed in the objecttype.

  • Versioning

    Objecttypes are versioned. This means you can create an objecttype but if the objecttype evolves, you can create a new version.

  • Admin interface

    You can create and inspect objecttypes via a user interface, meant for administrators.

Objects API
  • Objecttype validation

    When creating an object, the objecttype is inspected to see if all data is formatted according to the JSON-schema in the objecttype.

  • Formal and administrative history

    The history of each object is recorded on two axes: The formal (formele) history and the material (materiële) history.

  • Geographic search

    Objects can be searched with GeoJSON using an arbitrary geographical point or polygon.

  • Arbitrary attribute filtering

    Since the Objects API contains many different objects of different objecttypes, the attributes are different for each objecttype. The Objects API supports filtering on any attribute.

  • Authorizations

    With an API-token applications can get read or write access, per objecttype. These API-tokens can be configured in the admin interface.

Who’s behind Objects and Objecttypes API?

The Objects and Objecttypes API project was initiated by six organizations to standardize common “other” objects that are currently not exposed via an API.

In alphabetical order, they are:

  • Amsterdam

  • Delft

  • GBI (Gemeentelijke Basisprocessen Inkomen)

  • Haarlem

  • Rotterdam

  • Utrecht

The municipality of Utrecht takes the lead in this project.

Open-source

Both the Objects API and the Objecttypes API are open-source and available under the EUPL license.

In addition, this project makes use of various open-source Python libraries and npm packages under the hood.

API-specifications

The Objects API and Objecttypes API are proposed as VNG API standards and are currently in review. Their specifications can be found below.

API

Specification version(s)

Objecttypes API

1.1.0 ( Redoc, Swagger )

Objects API

2.0.0 ( Redoc, Swagger )

API Usage

In this section, we’ll show how to get started with your first object type, and create an object for this object type.

Objecttypes API

Before continuing, make sure you have an API token to access the Objecttypes API. Authentication document describes how to do it in details. In the examples below we use the API token for the Objecttypes API with the value 1234.

Let’s start with creating an object type. For example, you want to store data about trees (Bomen) in your town. First, you need to decide which attributes your data will have and to design JSON schema for trees. You can take a look at provided Examples. Here is a JSON schema which we will use in the example:

{
  "$schema": "http://json-schema.org/draft-07/schema",
  "$id": "https://api.vng.nl/objecttypes/boom/schema.json",
  "type": "object",
  "title": "Boom",
  "description": "Een houtachtig gewas (loofboom of conifeer) met een wortelgestel en een enkele, stevige, houtige stam, die zich boven de grond vertakt.",
  "properties": {
    "boomgroep": {
      "$id": "#/properties/boomgroep",
      "type": "string",
      "title": "Boomgroep",
      "description": "Aanduiding of de boom onderdeel is van een boomgroep.",
      "examples": [
        "Laanboom"
      ],
      "enum": [
        "Laanboom",
        "Boomweide",
        "Solitaire boom"
      ]
    },
    "boomhoogteactueel": {
      "$id": "#/properties/boomhoogteactueel",
      "type": "integer",
      "title": "BoomhoogteActueel",
      "description": "Hoogte van de boom in meters.\nEenheid: m"
    },
    "leeftijd": {
      "$id": "#/properties/leeftijd",
      "type": "integer",
      "title": "Leeftijd",
      "description": "Leeftijd van het beheerobject in jaren.\nEenheid: Aantal",
      "examples": []
    },
    "meerstammig": {
      "$id": "#/properties/meerstammig",
      "type": "boolean",
      "title": "Meerstammig",
      "description": "Aanduiding voor meerstammigheid bij een Boom"
    },
    "type": {
      "$id": "#/properties/type",
      "type": "string",
      "title": "Type",
      "description": "Typering van het beheerobject."
    }
  },
  "required": ["boomhoogteactueel", "leeftijd"]
}
Create an object type

Now we need to create an object type which will include this JSON schema. The object type consists of metadata of the object type and (a version of) the JSON schema. This separation exists because the Objecttypes API supports versioning of the JSON schemas. If you want to change the JSON schema in the objecttype, a new version will be created. Therefore you don’t need to worry that a new version of the Object type schema would not match the exising objects in Objects API since these objects refer to the previous version.

So let’s create the object type metadata:

POST /api/v1/objecttypes HTTP/1.1
Authorization: Token 1234

{
    "name": "boom",
    "namePlural": "bomen",
    "description": "Bomen in de publieke ruimte.",
    "dataClassification": "open",
    "maintainerOrganization": "Tree organization",
    "maintainerDepartment": "Tree API department",
    "contactPerson": "John Smith",
    "contactEmail": "john@lovestrees.nl",
    "source": "Tree navigator",
    "updateFrequency": "monthly",
    "providerOrganization": "Open data for trees",
    "documentationUrl": "http://tree-object-type.nl"
}

The response contains the url of a freshly created object type with its unique identifier and a list of versions of the JSON schema, which is initially empty.

HTTP/1.1 201 Created

{
    "url": "http://<object-type-host>/api/v1/objecttypes/<object-type-uuid>",
    "name": "boom",
    "namePlural": "bomen",
    "description": "Bomen in de publieke ruimte.",
    "dataClassification": "open",
    "maintainerOrganization": "Tree organization",
    "maintainerDepartment": "Tree API department",
    "contactPerson": "John Smith",
    "contactEmail": "john@lovestrees.nl",
    "source": "Tree navigator",
    "updateFrequency": "monthly",
    "providerOrganization": "Open data for trees",
    "documentationUrl": "http://tree-object-type.nl",
    "labels": {},
    "createdAt": "2021-03-03",
    "modifiedAt": "2021-03-03",
    "versions": []
}

Now we can add our JSON schema to the created object type as its version:

POST /api/v1/objecttypes/<object-type-uuid>/versions HTTP/1.1
Authorization: Token 1234

{
    "status": "draft",
    "jsonSchema": {
        "$schema": "http://json-schema.org/draft-07/schema",
        "$id": "https://api.vng.nl/objecttypes/boom/schema.json",
        <...>
    }
}

The response contains the url of the created version of the object type.

HTTP/1.1 201 OK

{
    "url": "http://<object-type-host>/api/v1/objecttypes/<object-type-uuid>/versions/1",
    "version": 1,
    "objectType": "http://<object-type-host>/api/v1/objecttypes/<object-type-uuid>",
    "status": "draft",
    "jsonSchema": {
        "$schema": "http://json-schema.org/draft-07/schema",
        "$id": "https://api.vng.nl/objecttypes/boom/schema.json",
        <...>
    },
    "createdAt": "2021-03-03",
    "modifiedAt": "2021-03-03",
    "publishedAt": null
}

You can see that the version has the ‘draft’ status, which means, that it can be updated without creating a new version. Once the version is set to ‘published’ you can’t change it anymore, unless you create a new version.

Publish an object type version

Let’s publish our object type version. In the Objecttypes API you can do it with a PATCH request:

PATCH /api/v1/objecttypes/<object-type-uuid>/versions/1 HTTP/1.1
Authorization: Token 1234

{
    "status": "published"
}

In the response you can see that publishedAt attribute now contains the current date:

HTTP/1.1 200 OK

{
    "url": "http://<object-type-host>/api/v1/objecttypes/<object-type-uuid>/versions/1",
    "version": 1,
    "objectType": "http://<object-type-host>/api/v1/objecttypes/<object-type-uuid>",
    "status": "published",
    "jsonSchema": {
        "$schema": "http://json-schema.org/draft-07/schema",
        "$id": "https://api.vng.nl/objecttypes/boom/schema.json",
        <...>
    },
    "createdAt": "2021-03-03",
    "modifiedAt": "2021-03-03",
    "publishedAt": "2021-03-03"
}

Now, when you try to change this version a HTTP 400 error will appear indicating you cannot change it anymore. For example:

PATCH /api/v1/objecttypes/<object-type-uuid>/versions/1 HTTP/1.1
Authorization: Token 1234

{
    "jsonSchema": {
    "$schema": "http://json-schema.org/draft-07/schema",
    "$id": "https://api.vng.nl/objecttypes/boom/schema.json",
    <...>
    "required": []
    }
}

The response should be something like this:

HTTP/1.1 400 Bad Request

{
    "non_field_errors": [
        "Only draft versions can be changed"
    ]
}
Retrieve an object type

Once the object type is created it can always be retrieved by its url:

GET /api/v1/objecttypes/<object-type-uuid> HTTP/1.1
Authorization: Token 1234

HTTP/1.1 200 OK

{
    "url": "http://<object-type-host>/api/v1/objecttypes/<object-type-uuid>",
    "name": "boom",
    "namePlural": "bomen",
    "description": "Bomen in de publieke ruimte.",
    "dataClassification": "open",
    "maintainerOrganization": "Tree organization",
    "maintainerDepartment": "Tree API department",
    "contactPerson": "John Smith",
    "contactEmail": "john@lovestrees.nl",
    "source": "Tree navigator",
    "updateFrequency": "monthly",
    "providerOrganization": "Open data for trees",
    "documentationUrl": "http://tree-object-type.nl",
    "labels": {},
    "createdAt": "2021-03-03",
    "modifiedAt": "2021-03-03",
    "versions": [
        "http://<object-type-host>/api/v1/objecttypes/<object-type-uuid>/versions/1"
    ]
}

You can see that versions attribute includes a list of urls to all the versions of this object type.

Objects API

Now we have an object type containing a JSON schema for tree objects and we are ready to create objects. Before going further please, make sure that you configured the proper authentication and authorizations in the admin:

  • The Objects API can access the Objecttypes API

  • The API token (in the Objects API) has write permissions for the object type “Boom”.

Authentication and Authorization document how to do it in details.

In the examples below we use the API token for the Objects API with the value 5678.

Create an object

First, let’s construct some tree data that matches our JSON schema in the object type “Boom”:

{
    "boomgroep": "Solitaire boom",
    "boomhoogteactueel": 3,
    "leeftijd": 100,
    "meerstammig": false
}

If you want, you can validate your JSON data against the JSON schema on JSONschema.dev

Using the URL of the created object type, we can create a tree object. If we have geographic coordinates for our object we can also include them into the request body. Don’t forget the required “Content-Crs” header to indicate the coordinate system you are using.

POST /api/v1/objects HTTP/1.1
Authorization: Token 5678
Content-Crs: EPSG:4326

{
    "type": "http://<object-type-host>/api/v1/objecttypes/<object-type-uuid>",
    "record": {
        "typeVersion": 1,
        "startAt": "2021-01-01",
        "data": {
            "boomgroep": "Solitaire boom",
            "boomhoogteactueel": 3,
            "leeftijd": 100,
            "meerstammig": false
        },
        "geometry": {
            "type": "Point",
            "coordinates": [4.908722727852763, 52.36991749536178]
        }
    }
}

The object type version is defined in typeVersion attribute. This means that we can create objects that match any version of the particular object type but in this case we only have our initial version. The response contains the URL of the object:

HTTP/1.1 201 Created

{
    "url": "http://<object-host>/api/v1/objects/<object-uuid>",
    "type": "http://<object-type-host>/api/v1/objecttypes/<object-type-uuid>",
    "record": {
        "index": 1,
        "typeVersion": 1,
        "data": {
            "leeftijd": 100,
            "boomgroep": "Solitaire boom",
            "meerstammig": false,
            "boomhoogteactueel": 3
        },
        "geometry": {
            "type": "Point",
            "coordinates": [
                4.908722727852763,
                52.36991749536178
            ]
        },
        "startAt": "2021-01-01",
        "endAt": null,
        "registrationAt": "2021-03-03",
        "correctionFor": null,
        "correctedBy": null
    }
}

When an object is created or updated, its data is always validated against the JSON schema in the related object type. If the data doesn’t match, the response will contain a HTTP 400 error.

For example, let’s try to create the following object:

POST /api/v1/objects HTTP/1.1
Authorization: Token 5678
Content-Crs: EPSG:4326

{
    "type": "http://<object-type-host>/api/v1/objecttypes/<object-type-uuid>",
    "record": {
        "typeVersion": 1,
        "startAt": "2021-03-03",
        "data": {
            "boomgroep": "Solitaire boom",
            "boomhoogteactueel": 2.5,
            "leeftijd": 100,
        }
    }
}

In the JSON schema boomhoogteactueel is of type integer but we provide a floating point number. The response will look like similar to this:

HTTP/1.1 400 Bad Request

{
    "non_field_errors": [
        "2.5 is not of type 'integer'"
    ]
}
Retrieve an object

Once the object is created, it can always be retrieved by its URL:

GET /api/v1/objects/<object-uuid> HTTP/1.1
Authorization: Token 5678

HTTP/1.1 200 OK

{
    "url": "http://<object-host>/api/v1/objects/<object-uuid>",
    "type": "http://<object-type-host>/api/v1/objecttypes/<object-type-uuid>",
    "record": {
        "index": 1,
        "typeVersion": 1,
        "data": {
            "leeftijd": 100,
            "boomgroep": "Solitaire boom",
            "meerstammig": false,
            "boomhoogteactueel": 3
        },
        "geometry": {
            "type": "Point",
            "coordinates": [
                4.908722727852763,
                52.36991749536178
            ]
        },
        "startAt": "2021-01-01",
        "endAt": null,
        "registrationAt": "2021-03-03",
        "correctionFor": null,
        "correctedBy": null
    }
}
Retrieve objects of certain object type

The Objects API supports different filter and search options. You can filter objects by:

  • object type

  • data attributes (display all trees higher than 2 meters)

  • geographic coordinates or areas (display all trees in one neighbourhood)

To filter the list by a particular object type you can use the type query parameter:

GET /api/v1/objects?type=http://<object-type-host>/api/v1/objecttypes/<object-type-uuid> HTTP/1.1
Authorization: Token 5678

HTTP/1.1 200 OK

[
    {
        "url": "http://<object-host>/api/v1/objects/<object-uuid>",
        "type": "http://<object-type-host>/api/v1/objecttypes/<object-type-uuid>",
        "record": {
            "index": 1,
            "typeVersion": 1,
            "data": {
                "leeftijd": 100,
                "boomgroep": "Solitaire boom",
                "meerstammig": false,
                "boomhoogteactueel": 3
            },
            "geometry": {
                "type": "Point",
                "coordinates": [
                    4.908722727852763,
                    52.36991749536178
                ]
            },
            "startAt": "2021-01-01",
            "endAt": null,
            "registrationAt": "2021-03-03",
            "correctionFor": null,
            "correctedBy": null
        }
    }
]
Retrieve the history of an object

The Objects API supports versioning, i.e. when an object is updated, its previous states can also be retrieved. In the API these are called records.

GET /api/v1/objects/<object-uuid>/history HTTP/1.1
Authorization: Token 5678

HTTP/1.1 200 OK

[
    {
        "index": 1,
        "typeVersion": 1,
        "data": {
            "leeftijd": 100,
            "boomgroep": "Solitaire boom",
            "meerstammig": false,
            "boomhoogteactueel": 3
        },
        "geometry": {
            "type": "Point",
            "coordinates": [
                4.908722727852763,
                52.36991749536178
            ]
        },
        "startAt": "2021-01-01",
        "endAt": null,
        "registrationAt": "2021-03-03",
        "correctionFor": null,
        "correctedBy": null
    }
]

For now we have only one record, but every time the object is changed the new record will be created.

Retrieve an object (record) for a particular date

Since there could be a difference between the real date of the object change and its registration in the system, the Objects API support both material and formal history. The material history describes the history as it should be (stored in the startAt and endAt attributes). The formal history describes the history as it was administratively processed (stored in the registeredAt attribute).

The query parameters date (material history) and registrationDate (formal history) allow for querying the records as seen from both perspectives, and can yield different results.

For example, if you want to display all the objects as they were on 2021-02-02, you can do this from 2 perspectives. First, let’s do it from the material history perspective:

GET /api/v1/objects?date=2021-02-02 HTTP/1.1
Authorization: Token 5678

HTTP/1.1 200 OK

[
    {
        "url": "http://<object-host>/api/v1/objects/<object-uuid>",
        "type": "http://<object-type-host>/api/v1/objecttypes/<object-type-uuid>",
        "record": {
            "index": 1,
            "typeVersion": 1,
            "data": {
                "leeftijd": 100,
                "boomgroep": "Solitaire boom",
                "meerstammig": false,
                "boomhoogteactueel": 3
            },
            "geometry": {
                "type": "Point",
                "coordinates": [
                    4.908722727852763,
                    52.36991749536178
                ]
            },
            "startAt": "2021-01-01",
            "endAt": null,
            "registrationAt": "2021-03-03",
            "correctionFor": null,
            "correctedBy": null
        }
    }
]

We received our tree object in the response, because in reality it came into existence on 2021-01-01 (startAt) and never ceased (endAt is empty).

Now let’s do the same but from a formal history perspective:

GET /api/v1/objects?registrationDate=2021-02-02 HTTP/1.1
Authorization: Token 5678

HTTP/1.1 200 OK

[]

Our tree object was created at 2021-03-03 (registrationAt), so it didn’t exist (administratively speaking) at 2021-02-02 yet. Hence, the Objects API response is an empty list.

Postman collections

To play around with the APIs we constructed Postman collections that work with the demo data supplied with the Quickstart.

These Postman collections are a set of pre-constructed API-calls to access the most commonly used resources and query parameters. The configuration matches the Quickstart configuration but can be changed to match your own setup.

To import the collection into Postman, follow the next steps:

  1. Open the Postman application.

  2. At the top left, click on File -> Import, or CTRL+O.

  3. Drag the file or browse using Upload Files button.

  4. Click Import.

Performance

To ensure good user experience and quality of performance, we have a dedicated performance testing repository. It runs on a system with the following specifications:

System specifications

Operating System

Debian GNU/Linux 10 (buster) [x86_64 GNU/Linux]

RAM

4GB

CPU(s)

x2 (Intel Xeon E312xx)

Hard drive

52GB

The tests run under the following conditions:

  • 500 total objects are used to ensure compatibility across older versions without pagination.

  • 4 unique objecttypes.

  • A single user simulates requests for a duration of 5 minutes.

We run the tests after every major version of the Objects API. After that, we report and document the stats. This careful analysis allows us to showcase our high-quality optimization process.

Results
Performance results per version (30 minutes)

Method

Test

v2.0.0-alpha

v1.1.1

v1.1.0

GET

Retrieve all objects (ms)

127

127

125

GET

Retrieve by data_attrs (ms)

117

111

115

GET

Retrieve by date (ms)

129

128

127

GET

Retrieve by geo coordinates (ms)

127

128

127

GET

Retrieve by registrationDate (ms)

130

131

130

GET

Retrieve by single object (ms)

106

106

109

Aggregated

123

122

122

All performance reports are available for download for all versions:

API strategy compliancy

The Objects API and Objecttypes API are designed to adhere to API principles defined in API Designrules, which is a part of Nederlandse API Strategie.

Adherence to API principles

#

Principle

Objects API

Objecttypes API

API-01

Operations are Safe and/or Idempotent

Yes, with exception of PUT

Yes

API-02

Do not maintain state information at the server

Yes

Yes

API-03

Only apply default HTTP operations

Yes

Yes

API-04

Define interfaces in Dutch unless there is an official English glossary

No, Objects API has English interface

No, Objecttypes API has English interface

API-05

Use plural nouns to indicate resources

Yes

Yes

API-06

Create relations of nested resources within the endpoint

N/a, there are no nested resources

Yes

API-09

Implement custom representation if supported

Yes

No

API-10

Implement operations that do not fit the CRUD model as sub-resources

Yes

Yes

API-16

Use OAS 3.0 for documentation

Yes

Yes

API-17

Publish documentation in Dutch unless there is existing documentation in English or there is an official English glossary available

No, Objects API has English documentation

No, Objecttypes API has English documentation

API-18

Include a deprecation schedule when publishing API changes

Yes

Yes

API-19

Allow for a maximum 1 year transition period to a new API version

Yes (6 month)

Yes (6 month)

API-20

API-20: Include the major version number only in ihe URI

Yes

Yes

API-48

Leave off trailing slashes from API endpoints

Yes

Yes

API-51

Publish OAS at the base-URI in JSON-format

Yes

Yes

The deployed APIs can be tested against API Designrules via API Test Platform. For example, the results of testing APIs deployed for Utrecht you can find here:

VNG compliancy

The Objects and Objecttypes API specifications are proposed by the municipality of Utrecht and submitted to the VNG for to become a Dutch national standard. The VNG (Vereniging van Nederlandse Gemeenten) is the Association of Dutch Municipalities.

The VNG has drafted an initial checklist for new API standards which is shown in the table below. The table below also shows the compliancy to this checklist for both APIs. This checklist is only available in Dutch.

1. Stakeholder documentatie

#

Description

Answer

Remarks

1

De voor de stakeholders relevante onderdelen van de standaard (informatiemodel, API-specificaties, functionele specificatie, architectuurmodellen, referentieimplementatie(s) en testgevallen) zijn gepubliceerd op de VNG Realisatie Github of GEMMAonline omgeving.

No 1

2

Er is een beschrijving die ontwikkelaars op weg helpt om te starten met implementatie van de API-standaard.

Yes

3

Er is uitleg en installatie-instructies van de referentieimplementaties

Yes

4

Er is uitleg over hoe mee ontwikkeld kan worden aan de referentieimplementatie(s), inclusief gebruik van relevante tooling.

Yes

5

Er zijn Postman-scripts met voorbeelden zodat consumers snel kunnen leren hoe ze de API moeten aanroepen.

Yes

6

VNG-site, API-ontwikkelagenda

Yes

No link available.

2. Informatiemodel

#

Description

Answer

Remarks

1

Indien gemeentelijke bron dan opleveren informatiemodel (semantisch informatiemodel)

Yes

2

Altijd een uitwisselingsgegevensmodel

No

3

Modellering van het semantisch informatiemodel conform laatst vastgestelde versie Metamodel Informatiemodellen (MIM)

Yes

See 2.1.

4

Informatiemodel gemodelleerd in Enterprise Architect conform de daarvoor geldende best practices

Yes

See 2.1.

5

Informatiemodel is opgeslagen in SVN

No 1

3. Architectuur

#

Description

Answer

Remarks

1

Modellen zijn gemodelleerd in Archi (Archimate 3.x) conform conventies GEMMA

No

Unclear

2

Modellen zijn opgeslagen op GitLab / Github en ingericht voor samenwerking (main/develop branches)

No

3

De stakeholders van de API-standaard zijn beschreven

Yes

4

Interactiepatronen zijn gemodelleerd

Yes

5

Positie van de API-standaard in de GEMMA informatiearchitectuur is gemodelleerd

No

Unclear

6

Verwacht gedrag van een API is gemodelleerd als applicatieproces

No

Unclear

7

De referentiecomponenten die het koppelvlak moeten realiseren zijn beschreven

Yes

8

Per referentiecomponent is beschreven welke verplicht dan wel optioneel te leveren (provider) of te gebruiken (consumer) services en operaties geïmplementeerd moeten zijn om compliant aan de standaard te zijn.

Yes

4. API-specificaties

#

Description

Answer

Remarks

1

Opgesteld in Open API Specification 3.x

Yes

2

Gepubliceerd op VNG-Realisatie Github omgeving en beschikbaar via Redoc en Swagger

No 1

3

Ontwerpbeslissing zijn vertaald naar (aanvullende) specificaties

Yes

4

Voldoet aan landelijke API strategie, in het bijzonder de core design rules

Yes

5

Informatiebeveiliging en privacy best practices (IBD) worden gevolgd

No

Unclear

6

Aanvullende specificaties die het gedrag van de API specificeren voor de provider.

No

TODO

7

De OAS3-specificatie is getest voor toepasbaarheid in de mainstream code-generatoren

Yes (1, 2)

8

API-specificaties volgen de VNG-R best practices.

No

There are no VNG-R best practices.

5. Compliancy en testen

#

Description

Answer

Remarks

1

API-standaard is geïmplementeerd in een referentieimplementatie indien voor de standaard meerdere providers van toepassing kunnen zijn

Yes (1, 2)

2

Testgevallen zijn beschreven voor elke service/operatie en aanvullende specificaties, zowel voor de happy als de unhappy flows

Yes (1, 2)

3

Elk testgeval beschrijft het logische testgeval, de teststap(pen) (wat wordt gedaan) en het verwachte resultaat

No

Unclear

4

Er zijn compliancy tests beschikbaar voor elke referentie-component (consumers en providers) en alle betreffende services en operaties, zodat leveranciers kunnen testen en aantonen dat hun applicatie voldoet aan de standaard

No

TODO

5

Voor zover nodig is ook de testdata beschreven die wordt gebruikt in de testgevallen

No

See 5.4.

6

Testgevallen zijn geïmplementeerd als Postman-scripts zodat de API geautomatiseerd getest kan worden.

No

See 5.4.

7

Postman-scripts zijn gepubliceerd op api-test.nl zodat iedereen kan testen of de API voldoet aan zijn specificatie.

No

See 5.4.

6. Referentie-implementatie

#

Description

Answer

Remarks

1

Zowel consumer als provider implementatie. Provider alleen van toepassing als meerdere providers mogelijk zijn. Minimaal zorgen voor test-implementatie

Yes (1, 2)

Same as 5.1.

2

Implementeert de OAS-specificatie inclusief de eventueel gedefinieerde aanvullende specificatie

Yes

Unsure how to provide proof.

3

Is voldoende functioneel om implementatie en gebruik van de API-standaard te demonstreren en compliancy aan te tonen

Yes

Unsure how to provide proof.

7. Overdrachtsdocument (beheer)

#

Description

Answer

Remarks

1

De genomen ontwerpbeslissingen zijn beschreven en gemotiveerd

Yes

2

Er is een lijst met bekende fouten, gewenste verbeteringen, gewenste uitbreidingen (backlog)

Yes

3

Er wordt voldaan aan de acceptatie criteria van de beheer organisatie die de standaard in beheer neemt

Yes

This checklist.

4

Beheerafspraken zijn beschreven

No

Unclear

1(1,2,3)

This is most likely an internal VNG compliancy check and is considered out of scope.

Admin interface

Both the Objects API and the Objecttypes API have an admin interface that allows you to configure the APIs and to manage objects and related object types.

Below, you can find tutorials how to use the admin interface to manage the APIs.

Authentication

Both the Objecttypes API and the Objects API support token authentication (or bearer authentication), which means that everyone who has the security token can access the API. Tokens are configured in the admin.

Objecttypes API

In this section we will create a security token for the Objecttypes API and use it in the HTTP request.

Click on the "add" button for "Token authorizations"

In the admin of the Objecttypes API click on the “add” button for “Token authorizations” resource.

Fill in the form and click on "save" button

After the form is filled in and submitted the token would be created. The token itself is a sequence of 40 letters and digits. It’s value is generated automatically when the form is submitted. In this example we will use 1234 as a token value.

Now we can use the created token to request Objecttypes API. The token should be included into “Authorization” header: Authorization: Token 1234

GET /api/v1/objecttypes HTTP/1.1
Authorization: Token 1234

HTTP/1.1 200 OK

[]

If you want to know how to use the Objecttypes API you can follow API Usage

Objects API

The creation of an authentication token for the Objects API is similar as for the Objecttypes API.

Click on the "add" button for "Token authorizations"

In the admin of the Objects API click on the “add” button for “Token authorizations” resource.

Fill in the form and click on "save" button

The “Permissions” section is used for authorizations and can be left empty for now. It’s described in the Authorization section of this document.

After the form is filled in and submitted the token would be created. The token itself is a sequence of 40 letters and digits. It’s value is generated automatically when the form is submitted. In this example we will use 5678 as a token value.

Now we can use the created token to request the Objects API. The token should be included into “Authorization” header: Authorization: Token 5678

GET /api/v1/objects HTTP/1.1
Authorization: Token 5678

HTTP/1.1 200 OK

[]

If you want to know how to use Objects API you can follow API Usage

Now you can configure Authorization for the Objects API.

Authorization

While Authentication is a process of verifying who a client is, authorization is the process of verifying what they have access to. Authorization is usually done after successful authentication.

Objecttypes API

The Objecttypes API doesn’t have a particular authorization model, i.e. every authenticated client has access to all object types.

Objects API

In the Objects API, clients have explicit access to objects based on their object types. Permissions for particular object types can be configured in the admin. In the example below we will create a permission to modify tree objects, i.e. objects of “Boom” object type.

Access to Objecttypes API

Since the access to objects is based on their object types, the Objects API should have credentials to communicate with the Objecttypes API.

Click on the "add" button for "Services"

In the admin page of the Objects API click on the “add” button for “Services” resource.

Fill in the form and click on "save" button

Fill in the form with the information about the Objecttypes API and put the Objecttypes API created in the Authentication section of this document into “Header value” field. If you use NLX you can configure it in the “NLX url” field. After the form is submitted the Objects API can access the Objecttypes API since it now has a security token for it.

Add an object type

Now we can add an object type to the Objects API, to define permissions.

Click on the "add" button for "Object type"

In the admin page of the Objects API click on the “add” button for “Object types” resource.

Fill in the form and click on "save" button

Choose the service created in the previous step and fill in the uuid of the “Boom” object type. After the form is submitted the object type name will be retrieved automatically from the Objecttypes API.

Add a permission

Finally, it’s time to create a permission to access objects with “boom” object types.

Click on the "add" button for "Permission"

In the admin page of the Objects API click on the “Add” button for “Permission” resource.

Fill in the form and click on "save" button

Select the token object created in the Authentication section, the object type created in the previous step and the permission mode.

Check allowed fields for field-based authorization

Checking the attribute “Use fields” turns on the field based authorization, i.e you can select the particular list of fields of the object this token will have access to. The field-based authorization is allowed only for “read-only” permission mode. After choosing the allowed fields you can submit the form.

Now the client who has this token can access the objects with the “Boom” object type.

If you want to know how to use Objects API you can follow API Usage

Object types

Creating and changing object types are common tasks for the Objecttypes API. API Usage describes how to do it with HTTP requests. But you can also use the Objecttypes admin to create, publish and update object types.

Create an object type

Let’s start with creating an object type. For example, you want to store data about trees in your town. First, you need to decide which attributes your data will have and to design JSON schema for trees. You can take a look at provided Examples. In this example we will use the same JSON schema as in the API Usage page.

{
  "$schema": "http://json-schema.org/draft-07/schema",
  "$id": "https://api.vng.nl/objecttypes/boom/schema.json",
  "type": "object",
  "title": "Boom",
  "description": "Een houtachtig gewas (loofboom of conifeer) met een wortelgestel en een enkele, stevige, houtige stam, die zich boven de grond vertakt.",
  "properties": {
    "boomgroep": {
      "$id": "#/properties/boomgroep",
      "type": "string",
      "title": "Boomgroep",
      "description": "Aanduiding of de boom onderdeel is van een boomgroep.",
      "examples": [
        "Laanboom"
      ],
      "enum": [
        "Laanboom",
        "Boomweide",
        "Solitaire boom"
      ]
    },
    "boomhoogteactueel": {
      "$id": "#/properties/boomhoogteactueel",
      "type": "integer",
      "title": "BoomhoogteActueel",
      "description": "Hoogte van de boom in meters.\nEenheid: m"
    },
    "leeftijd": {
      "$id": "#/properties/leeftijd",
      "type": "integer",
      "title": "Leeftijd",
      "description": "Leeftijd van het beheerobject in jaren.\nEenheid: Aantal",
      "examples": []
    },
    "meerstammig": {
      "$id": "#/properties/meerstammig",
      "type": "boolean",
      "title": "Meerstammig",
      "description": "Aanduiding voor meerstammigheid bij een Boom"
    },
    "type": {
      "$id": "#/properties/type",
      "type": "string",
      "title": "Type",
      "description": "Typering van het beheerobject."
    }
  },
  "required": ["boomhoogteactueel", "leeftijd"]
}

In the Objecttypes admin dashboard click on “Objecttypes” and click on the “Add” button.

Click on the "add" button

Fill in the form with the meta information about the object type. The uuid field is already prefilled in.

Fill in metadata

Scroll down, add the JSON schema in the “Last version” subsection and click on the “save” button.

Fill in JSON schema and save.

The object type has been created.

Publish an object type version

Let’s take a look at our freshly created object type. You can see that the object type has the ‘draft’ status, which means, that it can be updated without creating a new version. Once the object type version is published you can’t change it anymore, unless you create a new version.

Let’s publish our object type version. It can be easily done with clicking on the “publish” button.

Publish the version.

Now the status of the “last version” is changed to “published” and the value of the “JSON schema” attribute becomes read-only,

Create a new version

After the object type version is published the only way to change the JSON schema is to create a new version. You can do it by clicking on the “New version” button. The new version will have the same JSON schema as the previous one. You can use it as initial value and edit it the way you want it.

Create the new version.

In this example we remove the “required” attribute in the JSON schema and save it.

Display the version history

The versions are created to keep track on changes in the JSON schema. You can see all the previous changes if you click on the “history” button in the top right corner of the object type admin page.

Show the history of changes.

You can see all the versions, their statuses, the creation dates and the related JSON shemas.

Objects

Creating and updating objects is usually done using the Objects API. API Usage describes how to do it in detail. But it’s also possible to manage objects in the admin interface. In this tutorial we will create and update objects using the Objects admin.

Relate an object type

Each object must belong to a particular object type created in the Objecttypes API. The access to objects (the authorization) is also based on the related object types. Therefore before creating the object we need to make the object type from the Objecttypes API available in the admin interface of the Objects API. The section “Add an object type” of the Authorization describes how to do it.

Create an object

Now we can create an object. First, let’s construct some tree data that matches our JSON schema in the related object type:

{
    "boomgroep": "Solitaire boom",
    "boomhoogteactueel": 3,
    "leeftijd": 100,
    "meerstammig": false
}

If you want, you can validate your JSON data against the JSON schema on JSONschema.dev

In the Objects admin dashboard, click on “Objects” and click on the “Add” button.

Click on the "add" button

Select the object type added on the previous step in the “Object type” dropdown and fill in all the record data including JSON data, describing the tree object. “Version” is the version of the related object type. Together with the “Object type” field it identifies which JSON schema should be used to validate JSON in the “Data” field.

Fill in the object data

When you click on the “save” button the JSON data is validated against the JSON schema defined in the related object type. If the data is valid the object will be created.

Add an object record

Once the object record is created it can’t be changed. If you want to change the data the new record should be created. If the previous record contains incorrect information, it can be corrected in the “Correction” field of the next record.

Add an object record

In the Objects API you always see one record, which contains data of a certain time (by default the latest one). However in the admin interface you can see all the records created for the object.

Notifications

The Objects API can be configured to send notifications to a configured Notificaties API. These notifications are sent whenever Objects are created, updated or deleted via the Objects API. Other applications can subscribe to these notifications, for example to trigger certain processes whenever an Object is created.

For more information on the Notificaties API, please refer to the documentation.

Configuration

In order to configure notifications, navigate to the admin page and click on the “change” button next to “Notificatiescomponentconfiguratie”, under the “Configuration” tab.

Click on the "change" button next to "Notificatiescomponentconfiguratie"

On the next page, fill in the correct API root of the Notificaties API to which notifications must be sent and click on the “save” button afterwards.

Fill in the correct API root and click on the "save" button

Navigate back to the admin index page and click on the “add” button next to “Services”, under the “Configuration” tab.

Click on the "add" button next to "Services"

On the “add service” page, fill in the following information:

  1. Label: the name of the Service, i.e. Notificaties API

  2. Type: NRC (Notifications

  3. Api root url: the same URL as in the “Notificatiescomponentconfiguratie”

  4. Client ID: a valid client ID to identify the Objects API (registered in Autorisaties API)

  5. Secret: a secret corresponding to the client ID (registered in Autorisaties API)

  6. Authorization type: ZGW client_id + secret

  7. Header key / Header value: leave empty

  8. OAS: a URL pointing to the OpenAPI specification of the Notificaties API, the API root from step 2, followed by schema/openapi.yaml

  9. Nlx url: leave empty

  10. User ID: a user ID to show in the audittrail

  11. User representation: a human readable representation of this application to show in the audittrail

Finally, click on the “save” button.

Click on the "add" button next to "Services"

In order for this configuration to work, API authorizations must be configured in an Autorisaties API. Open Zaak is an example of an application that implements this API. For more information on how to configure API authorizations in Open Zaak, please refer to the Open Zaak authorization documentation.

Installation

In addition to making its source code available publicly, the reference implementation for the Objects API and Objecttypes API are also maintained and work out-of-the-box for most use cases.

For the sake of simplicity, we have chosen to use Docker and Docker Compose for this.

Quickstart

A simple docker-compose-quickstart.yml file is available to get the APIs up and running in minutes. This file has some convenience settings to get started quickly and these should never be used for anything besides testing:

  • A default secret is set in the SECRET_KEY environment variable.

  • A predefined database and database account is used.

  • API authorizations are disabled.

With the above remarks in mind, let’s go:

Objecttypes API
  1. Create a project folder:

    $ mkdir objecttypes-api
    $ cd objecttypes-api
    
  2. Download the docker-compose file:

    $  wget https://raw.githubusercontent.com/maykinmedia/objecttypes-api/master/docker-compose-quickstart.yml -O docker-compose-qs.yml
    
  3. Start the Docker containers:

    $ docker-compose -f docker-compose-qs.yml up -d
    
  4. Import a demo set of objecttypes:

    $ docker-compose exec web src/manage.py loaddata demodata
    
  5. Create a superuser

    $ docker-compose exec web src/manage.py createsuperuser
    
Objects API
  1. Create a project folder:

    $ mkdir objects-api
    $ cd objects-api
    
  2. Download the docker-compose file:

    $ wget https://raw.githubusercontent.com/maykinmedia/objects-api/master/docker-compose-quickstart.yml -O docker-compose-qs.yml
    
  3. Start the Docker containers:

    $ docker-compose -f docker-compose-qs.yml up -d
    
  4. Import a demo set of objects (linking to the demo objecttypes):

    $ docker-compose exec web src/manage.py loaddata demodata
    
  5. Create a superuser

    $ docker-compose exec web src/manage.py createsuperuser
    
  6. Retrieve an object via the Objects API in your webbrowser:

    http://localhost:8000/api/v1/objects/
    

After you have the Objects API and the Objecttypes API running you can configure Authentication, Authorization and use the API’s.

Environment configuration reference

The Objects and Objecttypes APIs can be run both as a Docker container or a VPS / dedicated server. It relies on other services, such as database and cache backends, which can be configured through environment variables.

Available environment variables
Required settings
  • DJANGO_SETTINGS_MODULE: which environment settings to use. Available options:

    • objects.conf.docker or objecttypes.conf.docker

    • objects.conf.dev or objecttypes.conf.dev

    • objects.conf.ci or objecttypes.conf.ci

  • SECRET_KEY: secret key that’s used for certain cryptographic utilities. You should generate one via miniwebtool

  • ALLOWED_HOSTS: A comma separated (without spaces!) list of domains that serve the installation. Used to protect against Host header attacks. Defaults to * for the docker environment and defaults to 127.0.0.1,localhost for the dev environment.

Database settings
  • DB_HOST: Hostname of the PostgreSQL database. Defaults to db for the docker environment, otherwise defaults to localhost.

  • DB_USER: Username of the database user. Defaults to objects or objecttypes,

  • DB_PASSWORD: Password of the database user. Defaults to objects or objecttypes,

  • DB_NAME: Name of the PostgreSQL database. Defaults to objects or objecttypes,

  • DB_PORT: Port number of the database. Defaults to 5432.

Other settings
  • ADMINS: Comma seperated list (without spaces!) of e-mail addresses to sent an email in the case of any errors. Defaults to an empty list.

  • SITE_ID: The database ID of the site object. Defaults to 1.

  • DEBUG: Used for more traceback information on development environment. Various other security settings are derived from this setting! Defaults to True for the dev environment, otherwise defaults to False.

  • IS_HTTPS: Used to construct absolute URLs and controls a variety of security settings. Defaults to the inverse of DEBUG.

  • SUBPATH: If hosted on a subpath, provide the value here. If you provide /gateway, the component assumes its running at the base URL: https://somedomain/gateway/. Defaults to an empty string.

  • SENTRY_DSN: URL of the sentry project to send error reports to. Defaults to an empty string (ie. no monitoring).

  • NOTIFICATIONS_DISABLED: indicates whether or not notifications should be sent to the Notificaties API for operations on the Object endpoint. Defaults to True for the dev environment, otherwise defaults to False.

Specifying the environment variables

There are two strategies to specify the environment variables:

  • provide them in a .env file

  • start the component processes (with uwsgi/gunicorn/celery) in a process manager that defines the environment variables

Providing a .env file

This is the most simple setup and easiest to debug. The .env file must be at the root of the project - i.e. on the same level as the src directory ( NOT in the src directory).

The syntax is key-value:

SOME_VAR=some_value
OTHER_VAR="quoted_value"
Provide the envvars via the process manager

If you use a process manager (such as supervisor/systemd), use their techniques to define the envvars. The component will pick them up out of the box.

Deployment

Both (Objects and Objecttypes) APIs are containerized applications and can be deployed to a single server or Kubernetes cluster. We use Ansible playbooks for the single server deployment and Helm chart for Kubernetes cluster.

The documentation includes installation process and the reference configuration.

Objects API deployment
Single server

Deployment is done via Ansible. Currently, only single server deployments are described but you can just as easily deploy the application in a Kubernetes environment.

Warning

The deployment configuration (called a “playbook”) is very simplistic and also contains sensitive values. This makes the playbook more readable but is not following good practices!

Server preparation

You can configure the Ansible playbook to install relevant services, do it manually, or have these pre-installed. You will need:

  • Nginx

  • Docker

  • Python3

  • Python3 PIP

Apart from Docker, you can install all these with something like:

$ sudo apt-get install nginx python3 python3-pip

For Docker, follow the instructions here: https://docs.docker.com/engine/install/

Database

Objects API uses PostgreSQL DB with PostGIS extension. You can enable geerlingguy.postgresql role in the Ansible playbook to install it or do it manually following the instructions here: https://postgis.net/install/

You will also need access to, or create, a database. You can create a database with something like:

$ sudo su postgres --command="createuser <db-username> -P"
Enter password for new role:
Enter it again:
$ sudo su postgres --command="createdb <db-name> --owner=<db-username>"
Installation
  1. Download the project from Github or just the deployment files.

    $ git clone git@github.com:maykinmedia/objects-api.git
    
  2. Setup virtual environment:

    $ python3 -m venv env/
    $ source env/bin/activate
    $ pip install ansible
    

    Note

    Sometimes, additional or updates packages are needed if they are not installed by the Ansible setup installation. You can do so like this:

    $ python -m pip install -U pip
    $ pip install ordered_set packaging appdirs six
    
  3. Install Ansible collections:

    $ ansible-galaxy collection install community.docker
    $ ansible-galaxy collection install git+https://github.com/maykinmedia/commonground-ansible.git
    

    Note

    The last collection might require explicit access.

  4. Edit the playbook app.yml to match your setup. Take special note of all TODO settings and read through all the comments and variables.

  5. Run the playbook:

    $ ansible-playbook app.yml --become --ask-become-pass
    
Kubernetes

Here you can find a reference implementation of the Objects API deployment for a Kubernetes cluster using Helm.

This Helm chart installs the Objects API and is dependent on a PostgreSQL database, installed using a subchart.

Warning

The default settings are unsafe and should only be used for development purposes. Configure proper secrets, enable persistence, add certificates before using in production.

Installation

Install the Helm chart with following commands:

cd deployment/kubernetes/objects
helm dependency build .
helm install objects .

Use Kubernetes CLI to monitor the status of deployment:

kubectl get pods

If the Ingress is not configured you can use port-forward to check the status of the application:

export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=objects,app.kubernetes.io/instance=objects" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace default $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT
Objecttypes API deployment
Single server

Deployment is done via Ansible. Currently, only single server deployments are described but you can just as easily deploy the application in a Kubernetes environment.

Warning

The deployment configuration (called a “playbook”) is very simplistic and also contains sensitive values. This makes the playbook more readable but is not following good practices!

Server preparation

You can configure the Ansible playbook to install relevant services, do it manually, or have these pre-installed. You will need:

  • PostgreSQL

  • Nginx

  • Docker

  • Python3

  • Python3 PIP

Apart from Docker, you can install all these with something like:

$ sudo apt-get install postgresql nginx python3 python3-pip

For Docker, follow the instructions here: https://docs.docker.com/engine/install/

You will also need access to, or create, a database. You can create a database with something like:

$ sudo su postgres --command="createuser <db-username> -P"
Enter password for new role:
Enter it again:
$ sudo su postgres --command="createdb <db-name> --owner=<db-username>"
Installation
  1. Download the project from Github or just the deployment files.

    $ git clone git@github.com:maykinmedia/objecttypes-api.git
    
  2. Setup virtual environment:

    $ python3 -m venv env/
    $ source env/bin/activate
    $ pip install ansible
    

    Note

    Sometimes, additional or updates packages are needed if they are not installed by the Ansible setup installation. You can do so like this:

    $ python -m pip install -U pip
    $ pip install ordered_set packaging appdirs six
    
  3. Install Ansible collections:

    $ ansible-galaxy collection install community.docker
    $ ansible-galaxy collection install git+https://github.com/maykinmedia/commonground-ansible.git
    

    Note

    The last collection might require explicit access.

  4. Edit the playbook app.yml to match your setup. Take special note of all TODO settings and read through all the comments and variables.

  5. Run the playbook:

    $ ansible-playbook app.yml --become --ask-become-pass
    
Kubernetes

Here you can find a reference implementation of the Objecttypes API deployment for a Kubernetes cluster using Helm.

This Helm chart installs the Objecttypes API and is dependent on a PostgreSQL database, installed using a subchart.

Warning

The default settings are unsafe and should only be used for development purposes. Configure proper secrets, enable persistence, add certificates before using in production.

Installation

Install the Helm chart with following commands:

cd deployment/kubernetes/objecttypes
helm dependency build .
helm install objecttypes .

Use Kubernetes CLI to monitor the status of deployment:

kubectl get pods

If the Ingress is not configured you can use port-forward to check the status of the application:

export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=objecttypes,app.kubernetes.io/instance=objecttypes" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace default $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT

Examples

Within the initial project, 3 example objecttypes have been created.

Boom (Tree)

The “Boom” objecttype is based on the open source Gemeentelijk Gegevensmodel (GGM) which in turn is based on the Informatiemodel Beheer Openbare Ruimte (IMBOR) which is a collection of the Basisregistratie Grootschalige Topografie (BGT) and the Informatiemodel geografie (IMGeo).

A small script was used to convert the GGM EAP model to JSON schema.

Metadata

Attribute

Value

name

boom

namePlural

bomen

description

labels

maintainerOrganization

Gemeente Delft

maintainerDepartment

contactPerson

Ashkan Ashkpour

contactEmail

aashkpour@delft.nl

providerOrganization

source

status

draft

dataClassification

open

createdAt

August 27, 2020

modifiedAt

publishedAt

updateFrequency

documentationUrl

Schema

You can download the JSON schema boom.json or view it below:

{
  "$schema": "http://json-schema.org/draft-07/schema",
  "$id": "https://api.vng.nl/objecttypes/boom/schema.json",
  "type": "object",
  "title": "Boom",
  "description": "Een houtachtig gewas (loofboom of conifeer) met een wortelgestel en een enkele, stevige, houtige stam, die zich boven de grond vertakt.",
  "default": {},
  "examples": [],
  "properties": {
    "beleidsstatus": {
      "$id": "#/properties/beleidsstatus",
      "type": "string",
      "title": "Beleidsstatus",
      "description": "Beleidsstatus is een functiecategorie bomen conform de richtlijnen NVTB, t.b.v. de bepaling van de monetaire waarde.",
      "examples": [
        "Structuurbepalend/hoofd(groen/bomen)structuur"
      ],
      "enum": [
        "Structuurbepalend/hoofd(groen/bomen)structuur",
        "Geen specifieke status-verkorte omloop (tot ca. 20 jaar) en bomen 3e grootte",
        "Beschermwaardig/monumentaal",
        "Geen specifieke status-functionele laan- en parkbomen"
      ]
    },
    "beoogdeomlooptijd": {
      "$id": "#/properties/beoogdeomlooptijd",
      "type": "string",
      "title": "BeoogdeOmlooptijd",
      "description": "De potentieel haalbare omlooptijd, in relatie tot de standplaats (schatting).",
      "examples": [
        "75-100 jaar"
      ],
      "enum": [
        "75-100 jaar",
        "30-50 jaar",
        ">200 jaar",
        "50-75 jaar",
        "20-30 jaar",
        "100-150 jaar",
        "< 10 jaar",
        "Onbekend",
        "10-20 jaar",
        "150-200 jaar"
      ]
    },
    "boombeeld": {
      "$id": "#/properties/boombeeld",
      "type": "string",
      "title": "Boombeeld",
      "description": "Onderhoudssituatie van de boom.",
      "examples": [
        "Niet van toepassing"
      ],
      "enum": [
        "Niet van toepassing",
        "Verwaarloosd boombeeld",
        "Aanvaard boombeeld",
        "Achterstallig boombeeld",
        "Boombeeld regulier (HB)",
        "Niet te beoordelen"
      ]
    },
    "boombeschermer": {
      "$id": "#/properties/boombeschermer",
      "type": "string",
      "title": "Boombeschermer",
      "description": "Wanneer een boombeschermer aanwezig is, wordt het GUID van het beheerobject Boombeschermer gekoppeld aan het object Boom.\nToelichting: Constructie, meestal van metaal, rondom het onderste  gedeelte van de stam, bedoeld ter bescherming van de stam.",
      "examples": []
    },
    "boomboomvoorziening": {
      "$id": "#/properties/boomboomvoorziening",
      "type": "string",
      "title": "BoomBoomvoorziening",
      "description": "Mogelijkheid om 1 of meerdere boomvoorzieningen bij een boom te registreren.",
      "examples": [
        "TODO"
      ],
      "enum": [
        "TODO"
      ]
    },
    "boomgroep": {
      "$id": "#/properties/boomgroep",
      "type": "string",
      "title": "Boomgroep",
      "description": "Aanduiding of de boom onderdeel is van een boomgroep.",
      "examples": [
        "Laanboom"
      ],
      "enum": [
        "Laanboom",
        "Boomweide",
        "Solitaire boom"
      ]
    },
    "boomhoogteactueel": {
      "$id": "#/properties/boomhoogteactueel",
      "type": "integer",
      "title": "BoomhoogteActueel",
      "description": "Hoogte van de boom in meters.\nEenheid: m",
      "examples": []
    },
    "boomhoogteklasseactueel": {
      "$id": "#/properties/boomhoogteklasseactueel",
      "type": "string",
      "title": "BoomhoogteklasseActueel",
      "description": "Aanduiding van de boomhoogte in meters ingedeeld in vaste klassen.\nToelichting: Boomhoogte in meters, ingedeeld in vaste klassen,  gemeten vanaf het maaiveld tot de top van de boom, bij vormbomen gemeten tot de hoogste knot of de gewenste hoogte (Bron: RAW)",
      "examples": [
        "TODO"
      ],
      "enum": [
        "TODO"
      ]
    },
    "boomhoogteklasseeindbeeld": {
      "$id": "#/properties/boomhoogteklasseeindbeeld",
      "type": "string",
      "title": "BoomhoogteklasseEindbeeld",
      "description": "Aanduiding van de boomhoogte van het eindbeeld, in meters ingedeeld in vaste klassen.\nToelichting: Boomhoogte in meters, ingedeeld in vaste klassen,  gemeten vanaf het maaiveld tot de top van de boom, bij vormbomen gemeten tot de hoogste knot of de gewenste hoogte (Bron: RAW)",
      "examples": [
        "TODO"
      ],
      "enum": [
        "TODO"
      ]
    },
    "boomspiegel": {
      "$id": "#/properties/boomspiegel",
      "type": "string",
      "title": "Boomspiegel",
      "description": "Wanneer een boomspiegel aanwezig is, wordt het GUID van het beheerobject Boomspiegel gekoppeld aan het object Boom.\nToelichting: Boomspiegel: afgebakend oppervlak rondom de stam van een boom, dat niet is ingeplant.",
      "examples": []
    },
    "boomtypebeschermingsstatusplus": {
      "$id": "#/properties/boomtypebeschermingsstatusplus",
      "type": "string",
      "title": "BoomTypeBeschermingsstatusPlus",
      "description": "Nadere aanduiding voor de speciale status van de boom.",
      "examples": [
        "TODO"
      ],
      "enum": [
        "TODO"
      ]
    },
    "boomveiligheidsklasse": {
      "$id": "#/properties/boomveiligheidsklasse",
      "type": "string",
      "title": "Boomveiligheidsklasse",
      "description": "Aanduiding van de veiligheid van de boom, ingedeeld in vaste klassen.\nToelichting: Voor bosplantsoen met boomvormers is de mate van veiligheid van het beheerobject voor de omgeving relevant. Hiervoor is nog geen landelijk vastgestelde classificatie. Boomveiligheid: Aanduiding voor de veiligheid van personen, dieren, objecten en goederen in de nabijheid van een boom.",
      "examples": [
        "Niet te beoordelen"
      ],
      "enum": [
        "Niet te beoordelen",
        "Boom zonder gebreken",
        "Onbekend",
        "Attentieboom",
        "Risicoboom"
      ]
    },
    "controlefrequentie": {
      "$id": "#/properties/controlefrequentie",
      "type": "string",
      "title": "Controlefrequentie",
      "description": "Aanduiding van de frequentie van de controle van het beheerobject.\nToelichting: \"De frequentie van de boomveiligheidscontrole. Dit is de periodieke visuele controle van een boom in het kader van de zorgplicht (voortkomend uit artikel 6:162 van het BW) ten behoeve van het vaststellen van een (potentieel toekomstig) risico dat de boom vormt voor zijn omgeving. \nDe term boomveiligheidscontrole heeft betrekking op het gehele proces om in het veld de benodigde gegevens te verkrijgen voor het logboek, zoals beschreven in de CROW Richtlijn Boomveiligheidsregistratie.\n\"",
      "examples": [
        "TODO"
      ],
      "enum": [
        "TODO"
      ]
    },
    "feestverlichting": {
      "$id": "#/properties/feestverlichting",
      "type": "string",
      "title": "Feestverlichting",
      "description": "Wanneer Feestverlichting aanwezig is, wordt het GUID van het beheerobject Feestverlichting gekoppeld aan het gekoppelde beheerobject.",
      "examples": []
    },
    "groeifase": {
      "$id": "#/properties/groeifase",
      "type": "string",
      "title": "Groeifase",
      "description": "Aanduiding van de groeifase van een boom.\nToelichting: Er is geen volledige eenduidigheid over de indeling, maar over het algemeen worden bij een boom zon 4 groeifasen onderscheiden. Het onderscheid is gebaseerd op de verschillen in beheermaatregelen.",
      "examples": [
        "Jeugdfase"
      ],
      "enum": [
        "Jeugdfase",
        "Volwassen fase",
        "Eindfase",
        "Aanlegfase",
        "Onbekend",
        "Niet te beoordelen"
      ]
    },
    "groeiplaatsinrichting": {
      "$id": "#/properties/groeiplaatsinrichting",
      "type": "string",
      "title": "Groeiplaatsinrichting",
      "description": "Wanneer een groeiplaatsinrichting aanwezig is, wordt het GUID van het beheerobject Groeiplaatsinrichting gekoppeld aan het object Boom",
      "examples": []
    },
    "herplantplicht": {
      "$id": "#/properties/herplantplicht",
      "type": "boolean",
      "title": "Herplantplicht",
      "description": "Aanduiding of er in het kader van de Wet Natuurbescherming sprake is van een herplantplicht.",
      "examples": []
    },
    "kiemjaar": {
      "$id": "#/properties/kiemjaar",
      "type": "integer",
      "title": "Kiemjaar",
      "description": "Kiemjaar van de boom.\nEenheid: Jaartal",
      "examples": []
    },
    "kroondiameterklasseactueel": {
      "$id": "#/properties/kroondiameterklasseactueel",
      "type": "string",
      "title": "KroondiameterklasseActueel",
      "description": "Diameter van de kroon van de boom in meters ingedeeld in vaste klassen.",
      "examples": [
        "TODO"
      ],
      "enum": [
        "TODO"
      ]
    },
    "kroondiameterklasseeindbeeld": {
      "$id": "#/properties/kroondiameterklasseeindbeeld",
      "type": "string",
      "title": "KroondiameterklasseEindbeeld",
      "description": "Diameter van de kroon van het eindbeeld van de boom in meters ingedeeld in vaste klassen.",
      "examples": [
        "TODO"
      ],
      "enum": [
        "TODO"
      ]
    },
    "kroonvolume": {
      "$id": "#/properties/kroonvolume",
      "type": "integer",
      "title": "Kroonvolume",
      "description": "Volume van de boomkroon in kubieke meters\nEenheid: m3",
      "examples": []
    },
    "leeftijd": {
      "$id": "#/properties/leeftijd",
      "type": "integer",
      "title": "Leeftijd",
      "description": "Leeftijd van het beheerobject in jaren.\nEenheid: Aantal",
      "examples": []
    },
    "meerstammig": {
      "$id": "#/properties/meerstammig",
      "type": "boolean",
      "title": "Meerstammig",
      "description": "Aanduiding voor meerstammigheid bij een Boom",
      "examples": []
    },
    "monetaireboomwaarde": {
      "$id": "#/properties/monetaireboomwaarde",
      "type": "number",
      "title": "MonetaireBoomwaarde",
      "description": "Monetaire waarde volgens richtlijnen NVTB.\nEenheid: ",
      "examples": []
    },
    "snoeifase": {
      "$id": "#/properties/snoeifase",
      "type": "string",
      "title": "Snoeifase",
      "description": "Aanduiding van de snoeifase van de boom.",
      "examples": [
        "Begeleidingssnoeifase"
      ],
      "enum": [
        "Begeleidingssnoeifase",
        "Onbekend",
        "Niet van toepassing",
        "Onderhoudssnoeifase"
      ]
    },
    "stamdiameter": {
      "$id": "#/properties/stamdiameter",
      "type": "integer",
      "title": "Stamdiameter",
      "description": "Aanduiding voor de diameter van de stam.\nEenheid: cm",
      "examples": []
    },
    "stamdiameterklasse": {
      "$id": "#/properties/stamdiameterklasse",
      "type": "string",
      "title": "Stamdiameterklasse",
      "description": "Aanduiding van de diameter van de stam in diameterklassen.",
      "examples": [
        "TODO"
      ],
      "enum": [
        "TODO"
      ]
    },
    "takvrijeruimtetotgebouw": {
      "$id": "#/properties/takvrijeruimtetotgebouw",
      "type": "integer",
      "title": "TakvrijeRuimteTotGebouw",
      "description": "De benodigde takvrije ruimte tussen het gebouw en de zijkant van de boom.\nEenheid: m",
      "examples": []
    },
    "takvrijestam": {
      "$id": "#/properties/takvrijestam",
      "type": "string",
      "title": "TakvrijeStam",
      "description": "De benodigde takvrije stam in het eindbeeld, gemeten vanaf maaiveld tot aan de onderste gesteltak.\nEenheid: m\nToelichting: Takvrije stam: gedeelte van de stam, gemeten vanaf maaiveld tot aan eerste gesteltak. Eindbeeld: vorm van een boom in volgroeide staat, omschreven door middel van takvrije zone en/of takvrije stam. Als synoniem wordt vaak gebruikt de opkroonhoogte: de verticaal gemeten vrije hoogte tussen maaiveld en kroon van de boom.",
      "examples": [
        "0 m."
      ],
      "enum": [
        "0 m.",
        "Anders, namelijk",
        "4 m.",
        "2 m.",
        "8 m.",
        "6 m.",
        "Onbekend",
        "Niet te beoordelen"
      ]
    },
    "takvrijezoneprimair": {
      "$id": "#/properties/takvrijezoneprimair",
      "type": "integer",
      "title": "TakvrijeZonePrimair",
      "description": "De benodigde takvrije ruimte tussen de weg of het fietspad en de onderkant van de boomkroon (eindbeeld van de boom). Als aan beide zijden van de boom een weg en een fietspad ligt, wordt de takvrije ruimte boven de weg aangeduid met primair, en de takvrijke ruimte boven het fietspad met secundair.\nEenheid: m\nToelichting: Takvrije zone: vrije ruimte ten behoeve van verkeer of andere omgevingsfactoren.",
      "examples": []
    },
    "takvrijezonesecundair": {
      "$id": "#/properties/takvrijezonesecundair",
      "type": "integer",
      "title": "TakvrijeZoneSecundair",
      "description": "De benodigde takvrije ruimte tussen het fietspad en de onderkant van de boomkroon (eindbeeld van de boom). Als aan beide zijden van de boom een weg en een fietspad ligt, wordt de takvrije ruimte boven de weg aangeduid met primair, en de takvrijke ruimte boven het fietspad met secundair.\nEenheid: m\nToelichting: Takvrije zone: vrije ruimte ten behoeve van verkeer of andere omgevingsfactoren.",
      "examples": []
    },
    "transponder": {
      "$id": "#/properties/transponder",
      "type": "string",
      "title": "Transponder",
      "description": "Nummer of identificatie van een transponder op een beheerobject.",
      "examples": []
    },
    "type": {
      "$id": "#/properties/type",
      "type": "string",
      "title": "Type",
      "description": "Typering van het beheerobject.",
      "examples": [
        "Haag"
      ],
      "enum": [
        "Haag",
        "Fruitteelt",
        "Buitenfitness",
        "Betonverharding",
        "Dilatatievoegovergang",
        "Beheervak - brug",
        "Dienstgang",
        "Vacumpompstation",
        "Putschacht",
        "Beregeningspomp",
        "Behendigheidstoestel",
        "Laadperron",
        "Schroefpomp",
        "Erfafscheidingsput",
        "Waaierdeur",
        "Kast",
        "Trottoirband",
        "Hoogspanningskabel",
        "Dubbelkerende afsluiter",
        "Spijlenhek",
        "Met instroomvoorziening",
        "Palen met draad",
        "Doelwand",
        "Faunatunnel groot",
        "Hondenpoepbak",
        "Waterloop",
        "Aansluitleiding",
        "Werk in uitvoering-bord",
        "Palen met planken",
        "Schutsluis",
        "Muur met hek",
        "Natuurlijke elementen",
        "Informatief verkeersbord",
        "Speciale bank",
        "Sinusvormige verkeersdrempel",
        "Verzamelput",
        "Gegraven tunnel",
        "Stobbe",
        "Boomteelt",
        "Verkeersplateau",
        "Terreindeel",
        "Heesters",
        "Afsluiter rioolleiding",
        "Sportcombinatietoestel",
        "Overgangsconstructie voor integraal kunstwerk",
        "Klimtoestel",
        "Volleybalset",
        "Geleidebarrier",
        "Boomrooster",
        "Familiegraf",
        "Sandwichconstructie",
        "Spoor",
        "Enkele bak",
        "Schommel",
        "Eenvoudige picknicktafel",
        "Overdekte bank",
        "Laagspanningskabel",
        "Trottoirkolk",
        "Hefdeur",
        "Gecombineerde straat-trottoirkolk",
        "Spiraal gegolfd stalen duikerbuizen",
        "Toldeur",
        "Beheervak - tunnel",
        "Planken beschoeiing",
        "Lozingspunt",
        "Faunatunnel klein",
        "Atletiekbaan",
        "Basketbalbord",
        "Boom niet vrij uitgroeiend",
        "Drinkwatermeter",
        "Struikrozen",
        "Boomkratten",
        "Tunnelobject",
        "Middenspanningskabel",
        "Infiltratiekolk",
        "Veerooster",
        "Nestkast voor zoogdieren",
        "Bebakeningselement",
        "Blauwe spiegel",
        "Fruitboom",
        "Heide",
        "Stedenbandbord",
        "Drukrioleringspomp",
        "Solitair gras",
        "Thematische picknicktafel",
        "Rijrichtingbord",
        "Drijvende mat",
        "Veldafscheiding",
        "Verlichtingsobject",
        "Picknicktafel zeshoekig",
        "Sensor",
        "Septictank",
        "Zuigerpomp",
        "Planten",
        "Bedekt",
        "Eigen bouw",
        "Grote sproeier",
        "Ontstoppingsput",
        "Parcours",
        "Basket",
        "Technische gang",
        "Houten beschoeiing",
        "Afsluiter beregeningsleiding",
        "Centrifugaalpomp",
        "Damtafel",
        "Fietsbeugel",
        "Onderbord",
        "Sluiswachterskantoor",
        "Toegangspoort",
        "Standaard reflector",
        "Fitnesstoestel",
        "Winterverblijf amfibien",
        "Avontuurlijke speelplek",
        "Hoog raster",
        "Reinigende put",
        "Opruimplicht hondenpoep",
        "Beheervak - gemaal",
        "Signaleringsband",
        "Onverhard",
        "Balspelterrein",
        "Kwelder",
        "Wervelput",
        "Hoekblok",
        "Lamellenvoegovergang",
        "Stootband",
        "Gemaal in natte opstelling",
        "Waterinrichtingsobject",
        "Lijnmarkering",
        "Zinloos geweld tegel",
        "Keermuur met bank",
        "Meubilair",
        "Bouwspeelplaats",
        "JongerenOntmoetingsPlek",
        "Greppel",
        "Waterspeeltoestel",
        "Lozingsput",
        "Vrijverval rioolleiding",
        "Overbruggingsobject",
        "Beheervak - verkeersregelinstallatie",
        "Duikelrek fitness",
        "Vingervoegovergang",
        "Grasland agrarisch",
        "Scheiding",
        "Rijstrook",
        "Puntmarkering",
        "Voorrangsbord",
        "Puntdeur",
        "Steilwand",
        "Dubbele bak",
        "Skateboardbaan",
        "Externe overstortconstructie",
        "Schampkant",
        "Vluchtgang",
        "Matten",
        "Jeu de Boules",
        "Dwarsgang",
        "Natte pompkelder",
        "Basketbalpaal",
        "Meervoudige voegovergang",
        "Onderwaterbeschoeiing",
        "Schaaktafel",
        "Tafeltennistafel",
        "Persluchtpomp",
        "Graft",
        "Boombank",
        "Mechanische transportleiding",
        "Oorlogsgraf",
        "Boom vrij uitgroeiend",
        "Oeverzwaluwenwand",
        "Leidingelement",
        "V-polder",
        "Wildspiegel op voet",
        "Drijvende bak",
        "Overnamepunt",
        "Straatkolk",
        "Kabelbaan",
        "Zandvlakte",
        "Zandspeeltoestel",
        "Kunststofverharding",
        "Leiboom",
        "Duikelrek",
        "Hondenrooster",
        "Midgetgolfbaan",
        "Bebouwde kombord",
        "Doorspuitput",
        "Knotboom",
        "Halfverharding",
        "Zinkerput",
        "Schuine trottoirband",
        "Turntoestel",
        "Educatietoestel",
        "Verbodsbord",
        "Verholen goot",
        "Buishek",
        "Huisvuilcontainerplaats",
        "Geleidehek",
        "Schotbalk",
        "Pompput",
        "Roldeur",
        "Klimplant",
        "Skatevoorziening",
        "Uitneembare brug",
        "Put",
        "Kruisingsput",
        "Dynamische snelheidsindicator",
        "Glijbaan",
        "Fietscrossbaan",
        "Vlakmarkering",
        "Waterspeelplaats",
        "Hek Verre Veld",
        "Keersluis",
        "Piramideblok",
        "Vegetatieobject",
        "Fietsabri",
        "Trapeziumvormige verkeersdrempel",
        "Bijzondere putconstructie",
        "Gras- en kruidachtigen",
        "GVC beschoeiing",
        "GRIP",
        "Rioolput met geleiding",
        "Buispaal",
        "Mattenvoegovergang",
        "Bomengranulaat",
        "Fietsenrek",
        "Beweegbare brug",
        "Bord",
        "Installatie",
        "Flexibele voegovergang",
        "IJsvogelwand",
        "Kleine sproeier",
        "Wanden dak methode tunnel",
        "Groenobject",
        "IBA",
        "Mast",
        "Onbedekt",
        "Voorwaarschuwingsbord",
        "Rimob",
        "Backstop",
        "Leiplant",
        "Wand",
        "Standaard",
        "Beluchtingsrooster",
        "Buffer",
        "Elementenverharding",
        "Toegangshekinstallatie",
        "Rietland",
        "Struiken",
        "Interne overstortconstructie",
        "Uitlaatpunt",
        "Beheervak - sluis",
        "Begroeid",
        "Overstortput",
        "Verkeerstegel",
        "Afsluiter gasleiding",
        "Stuwput",
        "Schampblok",
        "Grondwatermeter",
        "Doorspoelput",
        "Staafmathek",
        "Poef",
        "Bouwwerk",
        "Combinatietoestel",
        "Visoverwinteringsplek",
        "Skateterrein",
        "Voetbalveld",
        "Roostergoot",
        "Duiventil",
        "Atletiekvoorziening",
        "Perceelaansluitpunt",
        "Zandspeelplaats",
        "Boomkorf",
        "Gaashek",
        "Bouwland",
        "Boom",
        "Tennisbaan",
        "Flespaal",
        "Infiltratiebassin",
        "Bomenzand",
        "Reddingsboei",
        "Asbaktegel",
        "Kunstwerk",
        "Eenzijdig kerende afsluiter",
        "Gemengd bos",
        "Winterverblijf algemene amfibien en kamsalamder",
        "Net",
        "Vrijverval transportleiding",
        "Weginrichtingsobject",
        "FunctioneelGebied",
        "Watervogels",
        "Basaltblokken",
        "Nooduitlaat",
        "Opsluitband",
        "Straatbank",
        "Gemaal in droge opstelling",
        "DRIP",
        "Duin",
        "Rijbaan",
        "Ijsbaan",
        "Reddingshaak",
        "Biofilter",
        "Doel",
        "Klimklauterparcours",
        "Brugwachterskantoor",
        "Grondwatermeetpunt",
        "Wiptoestel",
        "Bodembedekkers",
        "Laag raster",
        "Geleiderail",
        "Boombumper",
        "Solitaire heester",
        "Gierzwaluwtil",
        "Bomengrond",
        "Moeras",
        "Bushalteband",
        "Water over weg",
        "Slik",
        "Adoptiebak",
        "Verdekte put",
        "Afsluiter waterleiding",
        "Fietsklem",
        "Vijzelgemaal",
        "Afgezonken tunnel",
        "Boomjuk",
        "Tennisbaanafrastering",
        "Berging",
        "Leiding",
        "Gekandelaberde boom",
        "Boostergemaal",
        "Gazonband",
        "Fietssleuf",
        "Trimbaan",
        "Nestkast voor vogels",
        "Busvriendelijke verkeersdrempel",
        "Draaitoestel",
        "Paal",
        "Velddrain",
        "Verbindingsstuk",
        "Binnenterrein",
        "Microtunneling,",
        "Perkoen",
        "Fietssteun",
        "Rij-ijzer",
        "Motorfietsdrempel",
        "Zeecontainer",
        "Knikkertegel",
        "Wildrooster",
        "Schijnvoeg",
        "Schroefcentrifugaalpomp",
        "Paaltje (Amsterdammertje)",
        "Winterverblijf rugstreeppad",
        "Bromfietsdrempel",
        "Korfbalpaal",
        "Opbouwputtunnel",
        "Water over water",
        "Zinkvoeg",
        "Weg",
        "Waterobject",
        "Fietsenkluis",
        "Rood wit paaltje (toegangsbeperking)",
        "Vaste brug",
        "Houtwal",
        "Geleideband",
        "Monsternamepunt",
        "Wegobject",
        "Schoolspeelplaats",
        "Groot wild",
        "Overkapping",
        "Loofbos",
        "Thematische bank",
        "Handbediende slagboom",
        "Vijzelpomp",
        "Riooleindgemaal",
        "Zitmuur",
        "Keermuur met plantenbak",
        "Verwijsbord",
        "Mechanische rioolleiding",
        "Waarschuwingsbord",
        "Vormboom",
        "Geboorde tunnel",
        "Speeltuin",
        "Sociaal spel",
        "Speelkuil",
        "Watervlakte",
        "Draaiende reflector",
        "Naaldbos",
        "Bak",
        "Omleidingsbord",
        "Spuisluis",
        "Vluchtdeur",
        "Boombunker",
        "Speelplek",
        "Verborgen voegovergang",
        "Grasland overig",
        "Asfaltverharding",
        "Voegovergang met of zonder balken en randprofielen met afdichtingrubbers",
        "Elektrische slagboom",
        "Bosplantsoen",
        "Verzameldrain",
        "Haltetegel",
        "Inspectieput",
        "Boomkrans",
        "Parkeerbord",
        "Winterverblijf slangen",
        "Sierhek",
        "Snelheidsbord",
        "Geallieerdengraf",
        "Fietstrommel"
      ]
    },
    "typebeschermingsstatus": {
      "$id": "#/properties/typebeschermingsstatus",
      "type": "string",
      "title": "TypeBeschermingsstatus",
      "description": "Aanduiding voor de speciale status van de boom.",
      "examples": [
        "Monumentale boom"
      ],
      "enum": [
        "Monumentale boom",
        "Geen beschermingsstatus",
        "Rust - en of verblijfplaats fauna"
      ]
    },
    "typeomgevingsrisicoklasse": {
      "$id": "#/properties/typeomgevingsrisicoklasse",
      "type": "string",
      "title": "TypeOmgevingsrisicoklasse",
      "description": "Aanduiding van het omgevingsrisico van het beheerobject.\nToelichting: Classificering voor de intensiteit van het gebruik van de omgeving van een boom en daarmee de mate waarin de omgeving van de boom risicoverhogend is voor eventuele schade bij stambreuk, takbreuk of instabiliteit. Aanvullende informatie: vast te stellen door de boomeigenaar.",
      "examples": [
        "Hoog"
      ],
      "enum": [
        "Hoog",
        "Gemiddeld",
        "Laag",
        "Onbekend",
        "Geen"
      ]
    },
    "typeplus": {
      "$id": "#/properties/typeplus",
      "type": "string",
      "title": "TypePlus",
      "description": "Nadere typering van het type beheerobject.",
      "examples": [
        "Grind Rail"
      ],
      "enum": [
        "Grind Rail",
        "Overhead Ladder",
        "Draaiende stoeltjes (type A)",
        "Klimladder",
        "Steeple-chase waterbak",
        "Dubbele draaibrug",
        "Neststeen voor gierzwaluw",
        "Drievoudig duikelrek",
        "Spoelleiding",
        "Waterrad",
        "Natuursteen",
        "Hoogspringbak",
        "Twist en Wobble",
        "Squat en Shoulder Press en Lat Pull Down",
        "Vacumpompstation",
        "Minidoel",
        "Roll-In Ramp",
        "Ramp",
        "Zandbak",
        "Mini Box",
        "Step block",
        "Combinatie - Peuter",
        "Type 4 - Meer assen - 1 richting",
        "Bootcamp Box en Gear",
        "Evenwichtsplateau op veren",
        "Pull up bars",
        "Sierbestrating",
        "Driekhoeksmarkering",
        "Infiltratiegreppel",
        "Balance beam",
        "Speelhuis",
        "Nestkast bosuil",
        "Nestkast koolmees",
        "Type 2 - Rotatie op meerdere assen",
        "Triple Bars",
        "Betonelement",
        "Rietvegetatie",
        "Zandtransporttoestel",
        "Suspension trainer",
        "Cross Trainer",
        "Fijne sierheester",
        "Botanische rozen",
        "Street Workout, Parkour",
        "Parkeervak",
        "Ruw gras",
        "Hellingklimmer",
        "Log hop",
        "Nestkast boomklever",
        "Kliedertafel",
        "Chest Press en Horizontal Row",
        "Kunstgras",
        "Verspringbak",
        "Heesters",
        "Split Quarter Pipe",
        "Ophaalbrug",
        "Hurdles",
        "Loopbrug",
        "Opdrukken",
        "Tafeltennistafel rond",
        "Lo-Box",
        "Hobbelbrug",
        "Klaphek",
        "Pontje",
        "Klimpaal",
        "Speelschip",
        "Speeltrein",
        "Bodembedekkende heesters",
        "Overgangsstuk",
        "Perceelaansluitleiding",
        "Rek- en strekbrug",
        "Onderbroken brede streep",
        "Weide",
        "Body Flexer",
        "Ven",
        "Gebogen evenwichtsbalk",
        "Ballentrechter",
        "Behendigheidsparcours",
        "Midi Ramp",
        "Vertikale ladder",
        "Leunhek",
        "Wateremmer",
        "Nestkast grote bonte specht",
        "Bandenloop",
        "Gewone normale vaste brug",
        "Kogelstotenbak",
        "Cultuurrozen",
        "Start Box",
        "Multi net",
        "Zandspeelhuis",
        "Loopton",
        "Upperbody Trainer - Free Runner - Body Flexer",
        "Grasveld",
        "Angle Box",
        "Struikvormers",
        "Type 3B - Meerpunts - Meerdere richtingen",
        "Toroveld",
        "Verbeterde overstortput",
        "Bergingsleiding",
        "Wobble en Step",
        "Y-stuk",
        "Core twist",
        "Vast",
        "Dubbele taludkabelbaan",
        "Wijngaarden",
        "Vollegrondsteelt",
        "Zonemarkering",
        "Hangelduo",
        "Instructiebord",
        "Big Wedge",
        "Drijvende brug",
        "Getalmarkering",
        "Duo ab - bench en ladder",
        "Free Runner - Cross Trainer - Power bike",
        "Doorgetrokken en dubbele smalle strepen",
        "Nestkast pimpelmees",
        "Liggerbrug",
        "Step",
        "Enterladder",
        "Tafeltennistafel vierkant",
        "Nestkast boomkruiper",
        "Zesvoudig duikelrek",
        "Klauterparcours",
        "Doorgetrokken brede streep",
        "Square Pull Up Station",
        "Planten",
        "Enkel duikelrek",
        "Stapstenen",
        "Nestkast zwarte roodstaart",
        "Tafelvoetbaltafel",
        "Taludglijbaan - type 2",
        "Buik- en rugsteun",
        "Zand",
        "Schuifhek",
        "Jump pod",
        "Mobile bar",
        "Fitnesstoestel",
        "Hefbrug",
        "Persleiding",
        "Parkeerplaats",
        "Infiltratieriool",
        "Beek",
        "Box Ramp",
        "Over Under",
        "Upright Row en Press Down",
        "Natte heide",
        "Afgekruist vlak",
        "Nestkast roodborst",
        "Zandkraan",
        "Hexagon Pull Up Station",
        "Verkeersdruppel",
        "Bootcamp & Circuit Training",
        "Zandspeeltafel",
        "Klimrek",
        "Type 2B - Enkelpunts - Meerdere richtingen",
        "Ruimtenet",
        "Frame",
        "Brug",
        "Monkey bar",
        "Trapschot",
        "Stappalen",
        "Type 5 - Zweefwip",
        "Verplaatsbaar",
        "Vleermuiskast rosse vleermuis",
        "Watertappunt",
        "Wobble en Swing en Step en Twist",
        "Zigzag-markering",
        "Kunststof vloer",
        "Rolverbinding",
        "Dubbelstaafmathek",
        "Griend en hakhout",
        "Verloopstuk",
        "Zwarte grond",
        "Tractorband",
        "Klapbrug",
        "Mini Ramp",
        "Jurytrap",
        "Handrail Box",
        "Kooi",
        "Push up bars",
        "Pijlmarkering",
        "Kanaal",
        "Bloemrijk gras",
        "Coping",
        "Kruipbuis",
        "Gecombineerde glijbaan - type 1",
        "Ster klim-duikelrek combinatie",
        "Double Chest Press",
        "Speelauto",
        "Grondwaterpomp",
        "Fietsparkeervak",
        "Spine",
        "Type 3 - Rotatie om 1 punt",
        "Pannaveld",
        "Twist en Swing",
        "Nestkast Marter",
        "Corner Ramp",
        "Netbrug oversteek",
        "Pants Driveway",
        "Verstopschotten",
        "Zandverstuiving",
        "Curved Grind Rail",
        "Dip Bench",
        "Hangtouwen",
        "Vakwerkbrug",
        "Vijver",
        "Beachvolleybalveld",
        "Nestkast gierzwaluw",
        "Decline Bench",
        "Duo pull up bar en ladder",
        "Dakboom",
        "Enterrek",
        "Betonstraatstenen",
        "Molens op spoor met voet of hand aangedreven (type D)",
        "Gaybrapad",
        "Nestkast steenuil",
        "Triple Ramp Grinder",
        "Vleermuiskast gewone dwergvleermuis",
        "Wall with Net",
        "Klimgordijn",
        "Sit up bench - Power Bike",
        "Grove sierheester",
        "Open duinvegetatie",
        "Externe overstortput",
        "Laagstam boomgaarden",
        "Crank",
        "Droge heide",
        "Hoogstam",
        "Wiebelbrug",
        "Evenwichtsbalk",
        "Dichte deklagen",
        "Plasberm",
        "Stammentrap",
        "Voetbaldoelnet",
        "Thematische basketbalpaal",
        "Klimmuur/ladder combi",
        "Trekvaste koppeling",
        "Klassieke draaimolen met meedraaiende vloer (type B)",
        "Hinkelbaan",
        "Quad Box",
        "Dubbele basculebrug",
        "Verkeersbord",
        "Hemelwaterriool",
        "Side Panel",
        "Turnbrug",
        "Lijnvormige haag",
        "Fietssymbool",
        "Fun box",
        "Upperbody Trainer",
        "Bochtstuk",
        "Enkelvoudige kabelbaan",
        "Fly box",
        "Bench",
        "Platform",
        "Pirouette",
        "Suspension Trainer, Parallel Bars & Magnetic Bells Link",
        "Vogelvide",
        "Los",
        "Jump Box",
        "Speelpaneel",
        "Speelplatform",
        "Basketbalterrein",
        "Valdempend gras",
        "Rolbrug",
        "Volleybalveld",
        "Discuskooi",
        "Flensverbinding",
        "Double Turbo Challenge",
        "Gras- en kruidachtigen",
        "Wobble en Swing",
        "Ollie Jump",
        "Parallel bar",
        "Type 2A - Enkelpunts - 1 richting",
        "Combi Step",
        "Rondobollen",
        "Cross Training, Street Workout 130m_",
        "Balanceernet",
        "Heesterrozen",
        "Poel",
        "Metaal",
        "Praatpaal",
        "Bomen en struikvormers",
        "Rodeo stier",
        "Vrijstaande glijbaan - type 2",
        "Fitness Bike",
        "Verdrijfstrepen",
        "Ballenpaal",
        "Basket en doel",
        "Meerdelig duikelrek",
        "Hoogstam boomgaarden",
        "Small Wedge",
        "Natuurlijke oeverzwaluwwand",
        "Rivier",
        "Chill schijf",
        "Telefoonpaal",
        "Thematisch evenwichtsplateau op veren",
        "Bodembedekkende rozen",
        "Crosstrainer",
        "Waterwip",
        "Bokspringpaal",
        "Flex Wheel - Body Flexer",
        "Magnetic bells, suspension trainer en multi net link",
        "Blokboom",
        "Workout combination",
        "Boomstam",
        "Nestkast spreeuw",
        "Hand Bike",
        "Stretch Bar",
        "Circuit Training",
        "Steunbrug",
        "Magnetic bells",
        "Nestkast Eekhoorn",
        "Tuibrug",
        "Sit up bench",
        "Trapoefenwand",
        "Plas",
        "Loopvlonder",
        "Open grond",
        "Lasverbinding",
        "Drievoudig duikelrek gebogen",
        "Enkelvoudige taludkabelbaan",
        "Boogbrug",
        "Cross Training, Circuit Training, Bootcamp, Street Workout 256m_",
        "Gesloten duinvegetatie",
        "Type 1 - Wip - 1 richting",
        "Vaste planten",
        "Bedrijfsaansluitleiding",
        "Ruigte",
        "Twist en Step",
        "Grind Bench",
        "Type 6 - Schommelwip met enkelvoudige hoge as",
        "Geknipte boom",
        "Klimnet met duikelrekken",
        "Enkelstaafmathek",
        "Nestkast bonte vliegenvanger",
        "Kolkaansluitleiding",
        "Gazon",
        "Pompunit",
        "Flat Bank",
        "Drukleiding",
        "Overige markering",
        "Klimwand",
        "T-stuk",
        "Vouwhek",
        "Double Overhead Ladder",
        "Ongewapend verdeuveld beton",
        "Bolboom",
        "Zandgraver",
        "Pleinplakker",
        "Grind Box",
        "Draaihek",
        "Transportrioolleiding",
        "Hout",
        "Trainingsdoeltje",
        "Pull up bars, parallel bars & multi net link",
        "Voethek",
        "Kunstmatige oeverzwaluwwand",
        "Taludglijbaan - type 1",
        "Roll-off Ramp",
        "Glas",
        "Draaiende evenwichtsbalk",
        "Schudzeef",
        "Strip",
        "Boomvormers",
        "Flat Bank with Platform",
        "Braakliggend",
        "Bron",
        "Voetbaldoel",
        "Ongewapend nietverdeuveld beton",
        "Haven",
        "Tuinbouwgrond",
        "Supernova",
        "Puzzelbord",
        "Zoab en open deklagen",
        "Ruig gras",
        "Zandstransportband",
        "Archimedesspiraal",
        "Container",
        "Zinker",
        "Net",
        "Type 4 - Contactschommel",
        "Glijverbinding",
        "Combinatie van een smalle doorgetrokken en een smalle onderbroken streep",
        "High rotator",
        "Horden",
        "Doel P-model",
        "Schraalgrasland",
        "Ingemetselde nestkast",
        "Turnparcours",
        "JOP",
        "Plaatbrug",
        "Flex Wheel",
        "Bollenteelt",
        "Chin up",
        "Ringenrek met balanceertouw",
        "Pendelwaag",
        "Hang- en zweefmolens (type C)",
        "Street Spine",
        "Balansvorm",
        "Straatbaksteen",
        "Hellende enterladder",
        "Cladding",
        "Enkelvoudige platformkabelbaan",
        "Evenwichtsparcours",
        "Tegels",
        "Vacumleiding",
        "Bodembedekkende vaste planten",
        "Ollie Hurdle",
        "Volcano",
        "Bodembedekkers",
        "Touwbalans",
        "Speeltafel",
        "Touwbrug",
        "Talud verkeersdrempel",
        "Touwduikelrek",
        "Gracht",
        "Combi",
        "Gecombineerde glijbaan - type 2",
        "Quarterpipe",
        "Lijmverbinding",
        "Zee",
        "Sloot",
        "Tuinachtige grond",
        "Vuilwaterriool",
        "Kogelslingerkooi",
        "Half Pipe",
        "Draaibrug",
        "Woordmarkering",
        "Dubbele platformkabelbaan",
        "Nestkast winterkoning",
        "Wiebelplaat",
        "Akkerbouw",
        "Frame klimtoestel",
        "Body Flexer - Upperbody Trainer",
        "Looptouw",
        "Helmgras",
        "Hink-stapspringbak",
        "Speelboot",
        "Springkussen",
        "Geschoren boom",
        "Stuwrioolleiding",
        "Nestkast torenvalk",
        "Dip - bar",
        "Trampoline",
        "Strand en strandwal",
        "Duikerbrug",
        "Interne overstortput",
        "Ladder",
        "Frame & net",
        "Voorwaarschuwingsdriehoek",
        "Drievoudig duikelrek zigzag",
        "Free Runner - Cross Trainer",
        "Gewapend beton",
        "Bootcamp Base",
        "Samenhangend",
        "Zwevende evenwichtsbalk",
        "Oppervlakbehandelingen",
        "Bergbezinkleiding",
        "Rioolstreng",
        "Flat Ramp",
        "Take Off Ramp",
        "Goot",
        "Onderbroken smalle streep",
        "Basculebrug",
        "Optrekken",
        "Panel",
        "Steps",
        "Pull up Station",
        "Combinatie - Kleuter",
        "Monkey bar extended",
        "Dubbele ophaalbrug",
        "Shaped Grind Rail",
        "Parallel bars",
        "Push up bars met paal",
        "Kindertafel",
        "Laagstam",
        "Verspring- en hinkstapspringbak",
        "Draaischijf (type E)",
        "Piramidevorm",
        "Touw tornado",
        "ZinloosGeweldMarkering",
        "Step en Swing",
        "Vrijstaande glijbaan - type 1",
        "Jongerenbank",
        "Slinger-klim-entercombi",
        "Vormhaag",
        "Hangbrug",
        "Speelspoor",
        "Speelstoel en tafel",
        "Nestkast huismus",
        "Springplank",
        "Moerasvegetatie",
        "Type 1 - Rotatie om 1 as",
        "Polsstokhoogspringbak",
        "Draaimolen",
        "Overstortleiding",
        "Incline Press",
        "Boter-kaas-eieren",
        "Palenwoud",
        "Waterpomp",
        "Klimschans",
        "Vlot",
        "Dubbele kabelbaan",
        "Rear Panel",
        "Gemengd riool",
        "Hockeydoel",
        "Free Runner",
        "Planter for Steps",
        "Waterglijbaan",
        "Jump Ramp",
        "Pyramid",
        "Combinatie - Kind",
        "Doorgetrokken smalle streep",
        "Wisselperken",
        "Natuurlijke grasvegetatie",
        "Wall Ride",
        "Blokhaag",
        "Meer",
        "Draadcircus",
        "Puntstukken en witte vlakken",
        "Klein fruit",
        "Power Bike",
        "Type 3A - Meerpunts - 1 richting",
        "Stammenstapel",
        "Steunsprong",
        "Wiebelloop",
        "Zitpaal",
        "Cross & Circuit Training"
      ]
    },
    "typevermeerderingsvorm": {
      "$id": "#/properties/typevermeerderingsvorm",
      "type": "string",
      "title": "TypeVermeerderingsvorm",
      "description": "Wijze waarop de plant of boom is vermeerderd.",
      "examples": [
        "Veredeld"
      ],
      "enum": [
        "Veredeld",
        "Eigen wortel",
        "Onbekend",
        "Gent",
        "Gezaaid"
      ]
    },
    "verplant": {
      "$id": "#/properties/verplant",
      "type": "boolean",
      "title": "Verplant",
      "description": "Aanduidig of het groen- of vegetatieobject verplant is.",
      "examples": []
    },
    "verplantbaar": {
      "$id": "#/properties/verplantbaar",
      "type": "boolean",
      "title": "Verplantbaar",
      "description": "Aanduiding of de boom verplant kan worden.",
      "examples": []
    },
    "vrijedoorrijhoogte": {
      "$id": "#/properties/vrijedoorrijhoogte",
      "type": "string",
      "title": "VrijeDoorrijhoogte",
      "description": "De benodigde vrije ruimte tussen de weg of het fietspad, en de onderkant van de boomkroon of van een bouwwerk boven de weg, zoals een viaduct of tunnel.\nEenheid: m\nToelichting: Takvrije zone boven het wegdek en onder de kroon waar bestuurders van voertuigen vrije doorgang genieten tot een hoogte zoals is bepaald door de wegbeheerder.",
      "examples": [
        "4,5 m. en groter"
      ],
      "enum": [
        "4,5 m. en groter",
        "6,5 m. en groter",
        "0 m.",
        "2,5 m. en groter",
        "Onbekend"
      ]
    },
    "vrijedoorrijhoogteprimair": {
      "$id": "#/properties/vrijedoorrijhoogteprimair",
      "type": "string",
      "title": "VrijeDoorrijhoogtePrimair",
      "description": "De benodigde vrije ruimte tussen de weg of het fietspad, en de onderkant van de boomkroon of van een bouwwerk boven de weg, zoals een viaduct. Als aan beide zijden van de boom een weg en een fietspad ligt, wordt de vrije doorrijhoogte boven de weg aangeduid met primair, en de takvrije ruimte boven het fietspad met secundair.\nEenheid: m",
      "examples": [
        "4,5 m. en groter"
      ],
      "enum": [
        "4,5 m. en groter",
        "6,5 m. en groter",
        "0 m.",
        "2,5 m. en groter",
        "Onbekend"
      ]
    },
    "vrijedoorrijhoogtesecundair": {
      "$id": "#/properties/vrijedoorrijhoogtesecundair",
      "type": "string",
      "title": "VrijeDoorrijhoogteSecundair",
      "description": "De benodigde vrije ruimte tussen de weg of het fietspad, en de onderkant van de boomkroon of van een bouwwerk boven de weg, zoals een viaduct. Als aan beide zijden van de boom een weg en een fietspad ligt, wordt de vrije doorrijhoogte boven de weg aangeduid met primair, en de takvrije ruimte boven het fietspad met secundair.\nEenheid: m",
      "examples": [
        "4,5 m. en groter"
      ],
      "enum": [
        "4,5 m. en groter",
        "6,5 m. en groter",
        "0 m.",
        "2,5 m. en groter",
        "Onbekend"
      ]
    },
    "vrijetakval": {
      "$id": "#/properties/vrijetakval",
      "type": "string",
      "title": "VrijeTakval",
      "description": "Aanduiding of vrije takval is toegestaan.",
      "examples": [
        "Onbekend"
      ],
      "enum": [
        "Onbekend",
        "Geen vrije takval mogelijk",
        "Vrije takval mogelijk"
      ]
    }
  },
  "required": [],
  "additionalProperties": false
}

Melding (Notification)

The “Melding” objecttype was created from scratch based loosely on data models from existing applications used by the Dimpact muncipalities.

Metadata

Attribute

Value

name

melding

namePlural

meldingen

description

labels

maintainerOrganization

Dimpact

maintainerDepartment

contactPerson

Hugo ter Doest

contactEmail

hugo.terdoest@dimpact.nl

providerOrganization

source

status

draft

dataClassification

open

createdAt

August 27, 2020

modifiedAt

publishedAt

updateFrequency

documentationUrl

Schema

You can download the JSON schema melding.json or view it below:

{
    "default": {},
    "description": "The root schema comprises the entire JSON document.",
    "examples": [
        {
            "hoofdcategorie": "groen",
            "subcategorie": "snoeien",
            "fotos": [
                "www.example.com/path/to/foto1",
                "www.example.com/path/to/foto2"
            ],
            "toelichting": "struiken belemmereren de doorgang",
            "locatie": "lat-long, 52°16'10.1\"N 6°46'10.6\"E",
            "adres": "Bonairestraat 24 Hengelo",
            "servicegebied": "Weidehoek (afgeleid van locatie)",
            "BAG-object": "www.example.com/path/to/BAG-object",
            "toelichtingLocatie": "toelichting op de locatie, niet verplicht",
            "klant": "www.example.com/path/to/klant"
        }
    ],
    "required": [
        "hoofdcategorie",
        "toelichting",
        "locatie"
    ],
    "title": "Het objecttype Melding Openbare Ruimte",
    "properties": {
        "hoofdcategorie": {
            "default": "",
            "description": "Categorie van de melding",
            "enum": [
                "groen",
                "grijs",
                "water",
                "overig",
                null
            ],
            "examples": [
                "groen"
            ],
            "title": "The hoofdcategorie schema"
        },
        "subcategorie": {
            "default": "",
            "description": "Per hoofdcategorie zijn er bepaalde subcategorieen toegestaan",
            "examples": [
                "snoeien"
            ],
            "title": "The subcategorie schema",
            "enum": [
                "snoeien",
                "kappen",
                null
            ]
        },
        "fotos": {
            "default": [],
            "description": "An explanation about the purpose of this instance.",
            "examples": [
                [
                    "www.example.com/path/to/foto1",
                    "www.example.com/path/to/foto2"
                ]
            ],
            "title": "Een lijst van nul of meer URI's naar foto's",
            "additionalItems": true,
            "items": {
                "type": "string",
                "anyOf": [
                    {
                        "$id": "#/properties/fotos/items/anyOf/0",
                        "type": "string",
                        "title": "The first anyOf schema",
                        "description": "An explanation about the purpose of this instance.",
                        "default": "",
                        "examples": [
                            "URI1",
                            "URI2"
                        ]
                    }
                ]
            }
        },
        "toelichting": {
            "$id": "#/properties/toelichting",
            "type": "string",
            "title": "The toelichting schema",
            "description": "An explanation about the purpose of this instance.",
            "default": "",
            "examples": [
                "struiken belemmereren de doorgang"
            ]
        },
        "locatie": {
            "$id": "#/properties/locatie",
            "type": "string",
            "title": "The locatie schema",
            "description": "An explanation about the purpose of this instance.",
            "default": "",
            "examples": [
                "lat-long, 52°16'10.1\"N 6°46'10.6\"E"
            ]
        },
        "adres": {
            "$id": "#/properties/adres",
            "type": "string",
            "title": "The adres schema",
            "description": "An explanation about the purpose of this instance.",
            "default": "",
            "examples": [
                "Bonairestraat 24 Hengelo"
            ]
        },
        "servicegebied": {
            "$id": "#/properties/servicegebied",
            "type": "string",
            "title": "The servicegebied schema",
            "description": "An explanation about the purpose of this instance.",
            "default": "",
            "examples": [
                "Weidehoek (afgeleid van locatie)"
            ]
        },
        "BAG-object": {
            "$id": "#/properties/BAG-object",
            "type": "string",
            "title": "The BAG-object schema",
            "description": "An explanation about the purpose of this instance.",
            "default": "",
            "examples": [
                "www.example.com/path/to/BAG-object"
            ]
        },
        "toelichtingLocatie": {
            "$id": "#/properties/toelichtingLocatie",
            "type": "string",
            "title": "The toelichtingLocatie schema",
            "description": "An explanation about the purpose of this instance.",
            "default": "",
            "examples": [
                "toelichting op de locatie, niet verplicht"
            ]
        },
        "contactgegevens": {
            "default": {},
            "description": "A URI to a Klant resource",
            "examples": [
                "/path/to/klant"
            ],
            "required": [],
            "title": "URI naar een Klant zoals in ZGW API's gespecificeerd",
            "additionalProperties": true
        }
    },
    "additionalProperties": true
}

Vordering (Debt claim)

The “Vordering” objecttype is converted from an existing information model from the Gemeentelijke Basisprocessen Inkomen (GBI). The GBI gemeenten work together to create common proceses and models for the work-and-income domain.

As a test, they created a JSON schema for debt claims from their (huge) ontology.

Metadata

Attribute

Value

name

vordering

namePlural

vorderingen

description

labels

maintainerOrganization

GBI

maintainerDepartment

contactPerson

Geurt-jan van Renswoude

contactEmail

Geurt-jan.van.Renswoude@ordina.nl

providerOrganization

source

status

draft

dataClassification

open

createdAt

August 27, 2020

modifiedAt

publishedAt

updateFrequency

documentationUrl

Schema

You can download the JSON schema vordering.json or view it below:

{
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
                "Vordering": {
                        "properties": {
                                "Id": {
                                        "type": "string",
                                        "pattern": "^(\\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\\}{0,1})$",
                                        "description": "n.t.b."
                                },
                                "Status": {
                                        "type": "string",
                                        "description": "n.t.b."
                                },
                                "Subcategorie": {
                                        "type": "string",
                                        "description": "n.t.b."
                                },
                                "Categorie": {
                                        "type": "string",
                                        "enum": [
                                                "Onbekend",
                                                "Ongehuwd en geen geregistreerd partner en nooit gehuwd of geregistreerd partner geweest",
                                                "Gehuwd",
                                                "Gescheiden",
                                                "Weduwe/weduwnaar",
                                                "Geregistreerd partner",
                                                "Gescheiden geregistreerd partner",
                                                "Achtergebleven geregistreerd partner",
                                                "Ongehuwd en geen geregistreerd partner, eventueel wel gehuwd of geregistreerd partner geweest"
                                        ],
                                        "description": "n.t.b."
                                },
                                "VaststeldatumTerugvordering": {
                                        "type": "string",
                                        "description": "n.t.b."
                                },
                                "Priotype": {
                                        "type": "string",
                                        "description": "n.t.b."
                                },
                                "Vorderingtype": {
                                        "type": "string",
                                        "enum": [
                                                "Algemeen",
                                                "Verrekening"
                                        ],
                                        "description": "n.t.b."
                                },
                                "Regeling": {
                                        "type": "string",
                                        "enum": [
                                                "Participatiewet"
                                        ],
                                        "description": "n.t.b."
                                },
                                "Fiscaal": {
                                        "type": "string",
                                        "enum": [
                                                "Ja",
                                                "Nee"
                                        ],
                                        "description": "n.t.b."
                                },
                                "PeriodeStartdatum": {
                                        "type": "string",
                                        "description": "n.t.b."
                                },
                                "PeriodeEinddatum": {
                                        "type": "string",
                                        "description": "n.t.b."
                                },
                                "Debiteuren": {
                                        "type": "array",
                                        "items": {
                                                "$ref": "#/definitions/Debiteur"
                                        },
                                        "minItems": 1,
                                        "maxItems": 2,
                                        "UniqueItems": true
                                },
                                "Deelvorderingen": {
                                        "type": "array",
                                        "items": {
                                                "$ref": "#/definitions/Vordering"
                                        },
                                        "minItems": 0,
                                        "UniqueItems": true
                                },
                                "Aflossingen": {
                                        "type": "array",
                                        "items": {
                                                "$ref": "#/definitions/Aflossing"
                                        },
                                        "minItems": 0,
                                        "UniqueItems": true
                                },
                                "Correcties": {
                                        "type": "array",
                                        "items": {
                                                "$ref": "#/definitions/Correctie"
                                        },
                                        "minItems": 0,
                                        "UniqueItems": true
                                },
                                "Rechtmaanden": {
                                        "type": "array",
                                        "items": {
                                                "$ref": "#/definitions/Rechtmaand"
                                        },
                                        "minItems": 0,
                                        "UniqueItems": true
                                },
                                "Restituties": {
                                        "type": "array",
                                        "items": {
                                                "$ref": "#/definitions/Restitutie"
                                        },
                                        "minItems": 0,
                                        "UniqueItems": true
                                },
                                "Verminderingen_terugvordering": {
                                        "type": "array",
                                        "items": {
                                                "$ref": "#/definitions/VerminderingTerugvordering"
                                        },
                                        "minItems": 0,
                                        "UniqueItems": true
                                },
                                "Indienende_organisatie": {
                                        "type": "array",
                                        "items": {
                                                "$ref": "#/definitions/OrganisatorischeEenheid"
                                        },
                                        "minItems": 1,
                                        "maxItems": 1,
                                        "UniqueItems": true
                                },
                                "Behandelende_organisatie": {
                                        "type": "array",
                                        "items": {
                                                "$ref": "#/definitions/OrganisatorischeEenheid"
                                        },
                                        "minItems": 1,
                                        "maxItems": 1,
                                        "UniqueItems": true
                                },
                                "Gerelateerd_vorderingsverzoek": {
                                        "type": "array",
                                        "items": {
                                                "$ref": "#/definitions/Vorderingsverzoek"
                                        },
                                        "minItems": 1,
                                        "maxItems": 1,
                                        "UniqueItems": true
                                },
                                "Gerelateerde_aflossingsafspraken": {
                                        "type": "array",
                                        "items": {
                                                "$ref": "#/definitions/Aflossingsafspraak"
                                        },
                                        "minItems": 0,
                                        "UniqueItems": true
                                }
                        },
                        "additionalProperties": false,
                        "required": [
                                "Id",
                                "Status",
                                "Subcategorie",
                                "Categorie",
                                "VaststeldatumTerugvordering",
                                "Priotype",
                                "Vorderingtype",
                                "Regeling",
                                "Fiscaal",
                                "PeriodeStartdatum",
                                "PeriodeEinddatum"
                        ]
                },
                "Debiteur": {
                        "properties": {
                                "Id": {
                                        "type": "string",
                                        "pattern": "^(\\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\\}{0,1})$",
                                        "description": "n.t.b."
                                },
                                "Persoon": {
                                        "type": "array",
                                        "items": {
                                                "$ref": "#/definitions/Persoon"
                                        },
                                        "minItems": 1,
                                        "maxItems": 1,
                                        "UniqueItems": true
                                }
                        },
                        "additionalProperties": false,
                        "required": [
                                "Id"
                        ]
                },
                "Persoon": {
                        "properties": {
                                "PersoonsId": {
                                        "type": "string",
                                        "pattern": "^(\\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\\}{0,1})$",
                                        "description": "n.t.b."
                                },
                                "VoorlettersAanschrijving": {
                                        "type": "string",
                                        "description": "n.t.b."
                                },
                                "Voorvoegsel": {
                                        "type": "string",
                                        "description": "n.t.b."
                                },
                                "Geslachtsnaamstam": {
                                        "type": "string",
                                        "description": "n.t.b."
                                },
                                "AanhefAanschrijving": {
                                        "type": "string",
                                        "description": "n.t.b."
                                },
                                "BurgerlijkeStaat": {
                                        "type": "string",
                                        "enum": [
                                                "Onbekend",
                                                "Ongehuwd en geen geregistreerd partner en nooit gehuwd of geregistreerd partner geweest",
                                                "Gehuwd",
                                                "Gescheiden",
                                                "Weduwe/weduwnaar",
                                                "Geregistreerd partner",
                                                "Gescheiden geregistreerd partner",
                                                "Achtergebleven geregistreerd partner",
                                                "Ongehuwd en geen geregistreerd partner, eventueel wel gehuwd of geregistreerd partner geweest"
                                        ],
                                        "description": "n.t.b."
                                },
                                "Burgerservicenummer": {
                                        "type": "string",
                                        "pattern": "^[0-9]{9}$",
                                        "description": "n.t.b."
                                },
                                "Geboortedatum": {
                                        "type": "string",
                                        "description": "n.t.b."
                                },
                                "Geslachtsaanduiding": {
                                        "type": "string",
                                        "description": "n.t.b."
                                },
                                "CodeBrpGegevensGeheim": {
                                        "type": "string",
                                        "description": "n.t.b."
                                },
                                "Naamgebruik": {
                                        "type": "string",
                                        "description": "n.t.b."
                                },
                                "DatumOverlijden": {
                                        "type": "string",
                                        "description": "n.t.b."
                                },
                                "Voornamen": {
                                        "type": "string",
                                        "description": "n.t.b."
                                },
                                "Scheidingsteken": {
                                        "type": "string",
                                        "description": "n.t.b."
                                },
                                "Predicaat": {
                                        "type": "string",
                                        "description": "n.t.b."
                                },
                                "AdellijkeTitel": {
                                        "type": "string",
                                        "enum": [
                                                "A",
                                                "B"
                                        ],
                                        "description": "n.t.b."
                                },
                                "Namenreeks": {
                                        "type": "boolean",
                                        "description": "n.t.b."
                                },
                                "ANummer": {
                                        "type": "integer",
                                        "pattern": "^-?[0-9]{1,}$",
                                        "description": "n.t.b."
                                }
                        },
                        "additionalProperties": false,
                        "required": [
                                "PersoonsId",
                                "VoorlettersAanschrijving",
                                "Voorvoegsel",
                                "Geslachtsnaamstam",
                                "AanhefAanschrijving",
                                "BurgerlijkeStaat",
                                "Burgerservicenummer",
                                "Geboortedatum",
                                "Geslachtsaanduiding",
                                "CodeBrpGegevensGeheim",
                                "Naamgebruik",
                                "DatumOverlijden",
                                "Voornamen",
                                "Scheidingsteken",
                                "Predicaat",
                                "AdellijkeTitel",
                                "Namenreeks",
                                "ANummer"
                        ]
                },
                "Vorderingscomponent": {
                        "properties": {
                                "Id": {
                                        "type": "string",
                                        "pattern": "^(\\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\\}{0,1})$",
                                        "description": "n.t.b."
                                },
                                "Boekingsdatum": {
                                        "type": "string",
                                        "description": "n.t.b."
                                },
                                "Bedrag": {
                                        "type": "number",
                                        "pattern": "^-?[0-9]((;|,|\\.)[0-9]{2}|)$",
                                        "description": "n.t.b."
                                },
                                "Vorderingscomponenttype": {
                                        "type": "string",
                                        "enum": [
                                                "Aflossing",
                                                "Rechtmaand",
                                                "Restitutie",
                                                "Vermindering terugvordering",
                                                "Correctie"
                                        ],
                                        "description": "n.t.b."
                                }
                        },
                        "additionalProperties": false,
                        "required": [
                                "Id",
                                "Boekingsdatum",
                                "Bedrag",
                                "Vorderingscomponenttype"
                        ]
                },
                "Aflossing": {
                        "allOf": [
                                {
                                        "$ref": "#/definitions/Vorderingscomponent"
                                },
                                {
                                        "properties": {
                                                "Id": {
                                                        "type": "string",
                                                        "pattern": "^(\\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\\}{0,1})$",
                                                        "description": "n.t.b."
                                                },
                                                "Ontvangstdatum": {
                                                        "type": "string",
                                                        "description": "n.t.b."
                                                },
                                                "Aflossingskenmerk": {
                                                        "type": "string",
                                                        "description": "n.t.b."
                                                }
                                        },
                                        "additionalProperties": false,
                                        "required": [
                                                "Id",
                                                "Ontvangstdatum",
                                                "Aflossingskenmerk"
                                        ]
                                }
                        ]
                },
                "Correctie": {
                        "allOf": [
                                {
                                        "$ref": "#/definitions/Vorderingscomponent"
                                },
                                {
                                        "properties": {},
                                        "additionalProperties": false,
                                        "required": []
                                }
                        ]
                },
                "Rechtmaand": {
                        "allOf": [
                                {
                                        "$ref": "#/definitions/Vorderingscomponent"
                                },
                                {
                                        "properties": {
                                                "Id": {
                                                        "type": "string",
                                                        "pattern": "^(\\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\\}{0,1})$",
                                                        "description": "n.t.b."
                                                },
                                                "Jaar": {
                                                        "type": "integer",
                                                        "pattern": "^[1-2]{1}[0-9]{3}$",
                                                        "description": "n.t.b."
                                                },
                                                "Maand": {
                                                        "type": "integer",
                                                        "pattern": "^([1-9]{1}|1[0-2]{1})$",
                                                        "description": "n.t.b."
                                                },
                                                "Boekjaar": {
                                                        "type": "integer",
                                                        "pattern": "^[1-2]{1}[0-9]{3}$",
                                                        "description": "n.t.b."
                                                }
                                        },
                                        "additionalProperties": false,
                                        "required": [
                                                "Id",
                                                "Jaar",
                                                "Maand",
                                                "Boekjaar"
                                        ]
                                }
                        ]
                },
                "Restitutie": {
                        "allOf": [
                                {
                                        "$ref": "#/definitions/Vorderingscomponent"
                                },
                                {
                                        "properties": {
                                                "Id": {
                                                        "type": "string",
                                                        "pattern": "^(\\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\\}{0,1})$",
                                                        "description": "n.t.b."
                                                },
                                                "Betaaldatum": {
                                                        "type": "string",
                                                        "description": "n.t.b."
                                                }
                                        },
                                        "additionalProperties": false,
                                        "required": [
                                                "Id",
                                                "Betaaldatum"
                                        ]
                                }
                        ]
                },
                "VerminderingTerugvordering": {
                        "allOf": [
                                {
                                        "$ref": "#/definitions/Vorderingscomponent"
                                },
                                {
                                        "properties": {
                                                "Id": {
                                                        "type": "string",
                                                        "pattern": "^(\\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\\}{0,1})$",
                                                        "description": "n.t.b."
                                                },
                                                "Vaststeldatum": {
                                                        "type": "string",
                                                        "description": "n.t.b."
                                                },
                                                "Verminderingtype": {
                                                        "type": "string",
                                                        "description": "n.t.b."
                                                },
                                                "MotivatieVermindering": {
                                                        "type": "string",
                                                        "description": "n.t.b."
                                                }
                                        },
                                        "additionalProperties": false,
                                        "required": [
                                                "Id",
                                                "Vaststeldatum",
                                                "Verminderingtype",
                                                "MotivatieVermindering"
                                        ]
                                }
                        ]
                },
                "OrganisatorischeEenheid": {
                        "properties": {
                                "OrganisatieEenheidId": {
                                        "type": "string",
                                        "pattern": "^(\\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\\}{0,1})$",
                                        "description": "n.t.b."
                                },
                                "OrganisatieIdentificatie": {
                                        "type": "string",
                                        "description": "n.t.b."
                                },
                                "DatumOpheffing": {
                                        "type": "string",
                                        "description": "n.t.b."
                                },
                                "EMailadres": {
                                        "type": "string",
                                        "pattern": "^[A-Za-z0-9_-]+([.][A-Za-z0-9_-]+)*@[A-Za-z0-9_-]+([.][A-Za-z0-9_-]+)*[.][A-Za-z0-9]+$",
                                        "description": "n.t.b."
                                },
                                "Naam": {
                                        "type": "string",
                                        "description": "n.t.b."
                                },
                                "NaamVerkort": {
                                        "type": "string",
                                        "description": "n.t.b."
                                },
                                "Omschrijving": {
                                        "type": "string",
                                        "description": "n.t.b."
                                },
                                "Telefoonnummer": {
                                        "type": "string",
                                        "pattern": "^0[1-9][0-9]{8}$",
                                        "description": "n.t.b."
                                }
                        },
                        "additionalProperties": false,
                        "required": [
                                "OrganisatieEenheidId",
                                "OrganisatieIdentificatie",
                                "DatumOpheffing",
                                "EMailadres",
                                "Naam",
                                "NaamVerkort",
                                "Omschrijving",
                                "Telefoonnummer"
                        ]
                },
                "Vorderingsverzoek": {
                        "properties": {
                                "Id": {
                                        "type": "string",
                                        "pattern": "^(\\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\\}{0,1})$",
                                        "description": "n.t.b."
                                },
                                "Status": {
                                        "type": "string",
                                        "description": "n.t.b."
                                },
                                "Regeling": {
                                        "type": "string",
                                        "description": "n.t.b."
                                }
                        },
                        "additionalProperties": false,
                        "required": [
                                "Id",
                                "Status",
                                "Regeling"
                        ]
                },
                "Aflossingsafspraak": {
                        "properties": {
                                "Id": {
                                        "type": "string",
                                        "pattern": "^(\\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\\}{0,1})$",
                                        "description": "n.t.b."
                                },
                                "Startdatum": {
                                        "type": "string",
                                        "description": "n.t.b."
                                },
                                "Einddatum": {
                                        "type": "string",
                                        "description": "n.t.b."
                                },
                                "Bedrag": {
                                        "type": "number",
                                        "pattern": "^-?[0-9]((;|,|\\.)[0-9]{2}|)$",
                                        "description": "n.t.b."
                                }
                        },
                        "additionalProperties": false,
                        "required": [
                                "Id",
                                "Startdatum",
                                "Einddatum",
                                "Bedrag"
                        ]
                }
        },
        "type": "object",
        "properties": {
                "Vordering": {
                        "$ref": "#/definitions/Vordering"
                }
        }
}