Loading...
OpenAPI Directory | Velosimo Admin
Go back

Loket.nl API V2

Added: 19/02/2021
Updated at: 06/03/2023

**Is this your first time here? Please check out our [introduction to Loket (API)](./Introduction)** **The initial loading time of this developer portal may be very long due to the large number of endpoints designs being rendered when loading the page. We are looking into an alternative solution but for now please bear in mind.** # General The Loket.nl API is a RESTful API that exposes the data and features of the Loket.nl platform. The API accepts and returns JSON and can only be accessed by registered users. This documentation describes version 2 of the API. Are you looking to partner up and start building an integration based on the Loket RESTful API? Please check out the steps for partners on our [website](https://www.loket.nl/koppelingen/koppelen-met-loket/) . Have you received your client and user credentials from us? Check out the following Postman collection to help you start making your first API calls on our acceptance environment. We would recommend to install the Postman desktop app. [![Run in Postman](https://run.pstmn.io/button.svg)](https://god.gw.postman.com/run-collection/19604713-42728000-2df3-4ff0-908e-dc6ab410990c?action=collection%2Ffork&collection-url=entityId%3D19604713-42728000-2df3-4ff0-908e-dc6ab410990c%26entityType%3Dcollection%26workspaceId%3Ddde2c409-9fb2-4f40-9981-f937f73750ea#?env%5BLoket.nl%20Test%20Environment%5D=W3sia2V5IjoiQXV0aGVudGljYXRpb25TZXJ2ZXJVcmwiLCJ2YWx1ZSI6Imh0dHBzOi8vb2F1dGgubG9rZXQtYWNjLm5sLyIsImVuYWJsZWQiOnRydWUsInR5cGUiOiJ0ZXh0Iiwic2Vzc2lvblZhbHVlIjoiaHR0cHM6Ly9vYXV0aC5sb2tldC1hY2MubmwvIiwic2Vzc2lvbkluZGV4IjowfSx7ImtleSI6Ikxva2V0QXBpVXJsIiwidmFsdWUiOiJodHRwczovL2FwaS5sb2tldC1hY2MubmwvIiwiZW5hYmxlZCI6dHJ1ZSwidHlwZSI6InRleHQiLCJzZXNzaW9uVmFsdWUiOiJodHRwczovL2FwaS5sb2tldC1hY2MubmwvIiwic2Vzc2lvbkluZGV4IjoxfSx7ImtleSI6IkNsaWVudF9JZCIsInZhbHVlIjoiIiwiZW5hYmxlZCI6dHJ1ZSwidHlwZSI6InRleHQiLCJzZXNzaW9uVmFsdWUiOiIiLCJzZXNzaW9uSW5kZXgiOjJ9LHsia2V5IjoiQ2xpZW50X1NlY3JldCIsInZhbHVlIjoiIiwiZW5hYmxlZCI6dHJ1ZSwidHlwZSI6InRleHQiLCJzZXNzaW9uVmFsdWUiOiIiLCJzZXNzaW9uSW5kZXgiOjN9LHsia2V5IjoiUmVkaXJlY3RfVXJpIiwidmFsdWUiOiIiLCJlbmFibGVkIjp0cnVlLCJ0eXBlIjoidGV4dCIsInNlc3Npb25WYWx1ZSI6IiIsInNlc3Npb25JbmRleCI6NH0seyJrZXkiOiJyZWZyZXNoX3Rva2VuIiwidmFsdWUiOiIiLCJlbmFibGVkIjp0cnVlLCJ0eXBlIjoidGV4dCIsInNlc3Npb25WYWx1ZSI6IiIsInNlc3Npb25JbmRleCI6NX0seyJrZXkiOiJ0b2tlbiIsInZhbHVlIjoiIiwiZW5hYmxlZCI6dHJ1ZSwidHlwZSI6InRleHQiLCJzZXNzaW9uVmFsdWUiOiIiLCJzZXNzaW9uSW5kZXgiOjZ9XQ==) Do you want to contact us with any further questions or remarks regarding the Loket RESTful API? Please send an email to api@loket.nl, and we will get back to you. ## Environments The Loket.nl API has two different environments. The first environment is the "acceptance" environment which is used during development and returns test data. The second environment is the production environment which is to be used exclusively by approved applications. Both environments have their own URLs. * The acceptance environment can be accessed at https://api.loket-acc.nl/v2/ * The production environment can be accessed at https://api.loket.nl/v2/ ## OpenAPI documentation The endpoints are defined using the [OpenAPI 3.0 specification](https://github.com/OAI/OpenAPI-Specification), an industry-wide recognized standard for describing REST API's. __Please note:__ the endpoint documentation in this portal is not designed to be fully compatible with any automatic code generation tools. ## Change policy Over the course of time the API, and policies regarding the API can and will change. These changes are subject to the following guidelines. The following states hold true for the change policy for this API. * Loket.nl may sometimes introduce changes to the API and policies without advance notice. * Loket.nl will try to inform users of any (breaking) change in advance. * Loket.nl will not be liable to you or any third party for such modifications or any adverse effects resulting from such modifications. * Loket.nl will try to avoid breaking changes as much as possible. ## Notification periods In regard to changes Loket.nl will strive to adhere to the following notification periods per type of change. Due to our versioning strategy at resource level this API has the possibility to run multiple versions of the same resource at one time. This allows for a window in which both the old and new version are available. Allowing for a gradual move to the new version. | Type of change | Notification period | Support period old version | |------------------|---------------|---------------| | Non breaking change | 2 weeks | no new version | | Breaking change | 2 weeks | 6 months | | Critical | Due to the nature of these changes we might not be able to follow the normal procedure for change managment | depends on the severity of the issue | We define a __non breaking__ change as follows. Any change to the API that does not cause failures in the applications that consume that API. * Introducing a new optional field to an existing resource * Introducing a new endpoint * Introducing a new operation (GET/PUT/POST/PATCH/DELETE) * Introducing a new optional parameter to an endpoint * Introducing a new version for a resource We define a __breaking change__ as follows. any change to an API that could potentially cause failures in the applications that consume that API. * Changing an existing JSON element (name, datatype, pattern, min/max length etc) * Removing a JSON element, endpoint, operation or parameter * Introducing a required JSON element * Introducing a required parameter to an endpoint * Passing the `obsoleteDate` of a version for a resource ## Versioning The Loket API uses two types of versioning. API versioning and resource versioning. __API versioning__ API versioning is done via the path where after the domain URL (api.loket.nl) the path starts with the API version. The current version of the API is V2. The API version is expected to change rarely as resource versioning is available to tackle most issues that need versioning. __Resource versioning__ Every __JSON__ resource in the API is versioned via the Accept header. Allowing users of the API to influence what version is returned by setting the __mandatory__ accept header. The Accept header of request should have a value like `application/json;version=2018-01-01`. Here, the second part of the header is used to refer to a specific version of the resource (2018-01-01). When calling the API it is possible to supply other dates rather than the exact resources version(s). The businesslogic will select the version that is ON or BEFORE the given date. __For example:__ let's say there are two versions of a resource. These are 2018-01-01 and 2018-09-01. When calling the API you supply `application/json;version=2018-08-01`, in that case the API will use the version 2018-01-01 as its the nearest version in the past. A response returns what `resourceVersion` was used and the 'obsoleteDate' of that version (in most cases this is NULL). The `obsoleteDate` indicates when the resources version will no longer be available via the API. With the introduction of a new version of a resource the `obsoleteDate` for the old version will be set to 6 months after the introduction of the new resource. Allowing consumers of the resource 6 months to incorporate the change. Failure to do so will likely lead to failure in the implementation. In this developer portal you can find the service contracts for each, active, version of a resource. If, only if, there are multiple versions of a resource you can select the corresponding schema at that resource. ## Changelog The changelog for this API can be found [here](/Changelog). We strongly advise every user ofthe Loket REST API the subscribe to the email feed. Please check out the link on the changelog page. ## Legal notices Your use and access to the API is expressly conditioned on your compliance with the policies and restrictions related to the API. If Loket.nl believes that you have or attempted to violate any term, condition, or the spirit of these policies or agreements, your right to access and use the API may be temporarily or permanently revoked. # Authentication Authorization in the Loket API is based on the industry-standard OAuth 2.0 protocol. For general information on OAuth 2.0 we kindly refer to the publicly-available documentation, https://oauth.net/2/ An authorized user is required to call the Loket API. __Note:__ This is an SSL-only API. __Note:__ Only TLS 1.2 is supported. | Environment | TokenUrl | | -------------------- | -------------------------------- | | Acceptance | https://oauth.loket-acc.nl/token | | Production | https://oauth.loket.nl/token | The following OAuth 2.0 flows are supported * Authorization Code flow (standard) * Refresh Token flow (extension on the Authorization Code Flow) * SSO flow (single sign-on) * Password flow ## Authorization code flow For most clients only the authorization_code (and thus refresh_token) will be supported. Password grant type is not available for an external client. Please click the link below to see documentation on implementing the authorization code flow by external clients. __[Documentation on implementing the OAuth 2.0 authorization code flow](./OauthCode)__ ## Refresh token flow After the authorization code flow yields a refresh token the refresh_token grant can be used to obtain an access/bearer token. The expire time of the access/bearer is also returned in the response please take this into account. With the refresh token flow the two factor step will be skipped. _Refresh token request example:_ ``` POST /token grant_type=refresh_token&refresh_token={RefreshToken123}&client_Id={Client123}&client_secret={Secret123} ``` _Refresh token response example:_ ```json { "access_token": "JESJDhMBy0NPTM9SiXmYAzW45clOiQ5wSyDq3VWluguGNoKym4WPSiJoTDx67TQ", "token_type": "bearer", "expires_in": 3599, "refresh_token": "nGJtF6j6SeQbHAg", "two_factor_state": "None" } ``` ## SSO flow The SSO (single sign-on) flow is based on OAuth 2.0 and requires the authorization flow to be completed. __For more information see:__ [Documentation on OAuth 2.0 SSO flow (for allowed clients)](./OauthSSO) __Please note:__ Among other things, it is possible to set up an SSO flow with both Loket en Werknemerloket. ## Password flow The password flow is typically NOT enabled for external clients. Only by exception will the password flow be enabled for security (and practical) reasons. _Password token request examples:_ ``` POST /token grant_type=password&username={UserName123}&password={Password123}&client_Id={Client123}&client_secret={Secret123} ``` Whether client_secret is required is dependent on the configuration of the client. # Authorization In this section we explain how the API authorization service determines if a request is authorized or not. ## The authorization entities | Entity | Description | | ----|----| | Client | Loket.nl used the client as an additional authorisation entity. By linking clients to activities clients can only perform those activities they are linked to. | | User | Is linked to a client (by performing the authorization code flow) and to a set of rechten (configuration in loket.nl)| | Module (product) | Enables certain functionality for the provider/employer. Modules can be enabled and disabled on both provider and employer level.| | Role | Influences if certain "rechten" are available to the users with said role. It can also influence the scope of the data returned. For example: the API will deny an "afdelings manager" access to employee's that are not in the "afdeling" (department) that user is manager of| | Activity | Every action in the API has its own activity. Using the Open API 3.0 standard these activity names are incorporated in the documentation using the `operationId` and in most cases are named in the description of an endpoint.| | Rights (rechten) | Represent a group of activities.| ## The authorization process This flow assumes that both user and client are correctly configured and have access to the API. 1. Does the client have access to the activity? 2. Does the user have access to the activity (through "recht")? 3. Does the role have access to the activity (through "recht")? 4. Does the provider/employer have the required module enabled for the activity? 5. Does the user have access to the specified entity/ID? If the answer to all the questions above is yes then the request is authorized otherwise the request is denied with a HTTP status code 403 (Forbidden). See the simplified authorization flow in the figure below. __Side note:__ users are linked to rechten and clients are linked to activities. This leaves room for discrepancies. Where a client cannot perform the activity because the client is not authorized to call that activity even though the user does have the "recht" granting access to the activity. ![Loket authorization flow](../Authorization_flow_extern.png) ## Which users can use the API In almost all use-cases a Loket user should meet the following requirements to successfully setup an integration with that user. * The user must be a normal Loket user (so NOT a webservice user) * The user must be active (not blocked) * The user must have access to an employer * For provider users this is done by assigning the user to the appropriate Team(s) * For employer users this is done by creating a user for or linking the user to the appropriate employer(s) * The user must have all appropriate rights * For provider users this is done by assigning appropriate rights via Team (or alternatively, directly to the user) * For employer users this is done by assigning appropriate rights to the user on employer level How to setup an integration is described in the [Authentication](../#section/Authentication) section. __Side notes:__ * A user can have access to multiple employers with different rights per employer. * Please note that users set up to use the SOAP webservices (webservicegebruikers) are in no way suited to perform calls to the RESTful API, these require entirely different user set-ups. * User management on production is typically done by the provider (i.e. the accountant) and sometimes the employer. This is NOT something Loket.nl itself can do. # Data ## Data types The Loket.nl API accepts and returns JSON. Comform the [OpenAPI 3.0 specification](https://github.com/OAI/OpenAPI-Specification) the following data types are supported: * string * number (point is used to separate the integer part from the fractional part of a number) * integer (from OpenAPI) * object * array * boolean For most of these types, further specifications can be found in the `format` and `pattern` specifications in the service contract. For example a `format: date` added to a string field indicates a valid date must be supplied. ## Metadata Fields of the type 'metadata' are fields for which the possible values can be acquired via the metadata endpoint of the resource. The metedata can be obtained by appending /metadata to the current endpoint. Using the GET verb the endpoint will return a JSON output with "all" the metadata for the given resource. In some cases multiple requests are needed to obtain all the metadata required, an exmple is given below. Typically different metadata endpoints are availalbe for the POST and the PUT endpoint. If metadata endpoints are avaible for a given endpoint/resource is mentioned in the description of that endpoint. ### Example response ```json {[ { "field": "gender" options: [ { "key": 1, "value":"Man" } { "key": 2, "value":"Vrouw" } ] }, { "field": "country" options: [ { "isoCode":"NL", "key": 530, "value":"Nederland" } { "isoCode":"BE", "key": 540, "value":"Belgiƫ" } ] } ]} ``` ### Example urls __Acquiring metadata for a POST Wage__ ``` /v2/providers/employers/employees/employments/{employmentId}/wages/metadata ``` __Acquiring metadata for a PUT employee__ ``` /v2/providers/employers/employees/{employeeId}/metadata ``` __Multiple requests to get all the metadata__ In some cases there are metadata fields dependant on the selected value off another metadata field. Such is the case when adding a new concept employee. This is done in the employer context while several of the metadata fields are dependant on the payrollAdministration context. __For example:__ __Request 1__, first of a normal metadata request is performed. The response for this request will contain a list of payrolladministration for the given employer. ``` /v2/providers/employers/b869ded6-0659-4d8d-9a8a-f9e22425ec9c/jobapplicant/metadata ``` __Request 2__, when a payrolladministration is selected perform a second request to acquire the payrolladministration specific metadata. ``` /v2/providers/employers/jobapplicant/metadata/payrolladministration/54369214-14a1-41ab-892a-ea8438e34d6f ``` __Request 3__, if a `payScale` is selected perform a third request to acquire the `payGrade` for that `payScale`. ``` /v2/providers/employers/jobapplicant/metadata/salaryScaleType/54369214-14a1-41ab-892a-ea8438e34d6f ``` ### Types of metadata We diferentiate between two types of metadata. 1. Generic metadata field. The possible values for these fields are the same for every object no matter the provider, employer or employee etc. Examples are: country, gender and nationality. 2. Context specific metadata field. Examples of contexts are employer, payroll administration, provider and Loket.nl. In most cases the possible values for these field are resources in themselves and can be managed via the API. If a metadata field is context specific the context is given in the description of the field. Examples are: function, department and leaveType. __Note:__ some context specific metadata field can have multiple contexts. For example: it is possible to define an export set in the provider context. Making that export set available for all payroll administrations linked to the provider. It is also possible to add an export set in the payroll administration context. That export set is only available to that payroll administration. When requesting the metadata of export set the user will be presented with a combined list of the provider and payroll administration export sets. ## Default values Many fields in the API have a default value. In order to assist our API users to adhere to these defaults when creating a record (POST) we provide `/defaults` endpoints. * An object returned by the `defaults`endpoint resembles a fully expanded GET-object of that resource. The only case when a part of the object is NOT fully expanded is for a metaData-object that does not have a default value (for example '"gender":NULL'). * Whether an object within the resource is of the type metaData is indicated in the service contracts of that resource. * Context is determined by the GUID given in the Path. Examples are employer, payroll administration, employee and employment. * A scope is sometimes required to determine the defaults values. A scope could be a date by which Loket.nl can determine what default was active on that date. The scope can be set by supplying additional paraments in the request. If a scope is required but none is given the currently active or last know value is returned. * The fields with no default will be set to null (even if the field is normally non-nullable). * Because the GET-object is returned the readonly fields are also returned. __An example endpoint would be:__ ``` /v2/providers/employers/employees/employments/{employmentId}/payrollperioddata/defaults ``` __resulting in the following output:__ ```json { "payrollPeriod": null, "shift": { "shiftNumber": 1 }, "payslipType": { "key": 2 }, "payslipText": null, "distributionUnit": { "key": "b14acd0d-75d7-4fc8-8b22-4a3924585cab" }, "costCenter": { "key": 2 }, "costUnit": { "key": 2 }, "payrollComponents": [] } ``` __Note: Defaults endpoints are not yet generically available. If a Defaults endpoint exists this will be explicitly stated at that specific resource.__ ## Date chains For most of the resources with a startDate and endDate a chain is maintained. Chain meaning that no records can overlap in time. Loket.nl has two types of chains. 1) __Broken chain:__ It is posible for gaps te exist between the records. It is also posible to add new records in between or before existing records aslong as no overlap occures. 2) __Linked chain:__ No gaps between records are allowed. Its only posible to add new records to the end of the chain resulting in the closing of the reviouse record with the start date -1 as end date. __Note:__ Chains are sometimes maintained with an additional context. For example, For `benefits and deductions` the broken chain is maintained per `payrollComponent`. It is possible to have multiple active records for different `payrollComponent` never two active records for the same `payrollComponent`. ## Custom export For some GET (list) endpoints the API supports exporting (part of) the output JSON as a XML/CSV file. This is done by setting the `X-ReportInput` and `Accept` header. The `Accept` header supports the following 2 options: * CSV (text/csv;version=yyyy-MM-dd) * Excel (application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;version=yyyy-MM-dd) The `X-ReportInput` is a custom header that requires a JSON object with the following structure as input. The filename without extension for the report 'FileNameWithoutExtension' delimiter --> The delimiter to be used. If not set "," is used Array of objects 'fields' with 2 fields: 1. fieldName --> A Xpath reference to the field to be included in the export 2. reportColumnName --> The column name for the field 3. format --> Allows only for date formatting. e.g. dd-MM-yyyy for csv or dd-mm-yyyy for Excel (Excel only usses lowercase) 3.1 For CSV: see https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings 3.2 For Excel: https://support.microsoft.com/en-us/office/number-format-codes-5026bbd6-04bc-48cd-bf33-80f18b4eae68 __Example `X-ReportInput`:__ ```json { "fileNameWithoutExtension":"MyExport", "delimiter": ";", "fields": [ { "fieldName": "startDate", "reportColumnName": "In dienst datum", "format": "dd-MM-yyyy" }, { "fieldName": "personalDetails.firstName", "reportColumnName": "First Name" }, { "fieldName": "personalDetails.lastName", "reportColumnName": "Last Name" } ] } ``` __Example request:__ ```CURL curl --location --request GET 'https://api.loket.nl/v2/providers/employers/155c8440-8ff6-4776-98db-5d2243a073e3/employees?orderby=employeeNumber' \ --header 'Content-Type: application/json' \ --header 'Accept: text/csv;version=2020-08-18' \ --header 'X-ReportInput: {"FileNameWithoutExtension":"MyExport","Fields":[{"fieldName":"personalDetails.initials","reportColumnName":"Initials"},{"fieldName":"personalDetails.firstName","reportColumnName":"First name"},{"fieldName":"personalDetails.lastName","reportColumnName":"Last name"}]}' \--header 'Authorization: Bearer ZKoiC_g_NfYA3v0' \ ``` # Request A request to the Loket.nl API consists of several components. Each of these components are discussed in this section. ## Base URL The API can be accessed at [https://api.loket.nl](https://api.loket.nl). The version of the API is specified in the URL. The current version of the Loket.nl API is version 2. To access version 2 of the API, one simply appends `v2` to the base URL. The full base URL of the API is therefore [https://api.loket.nl/v2](https://api.loket.nl/v2). ## Endpoints The endpoints defined in the OpenAPI definition of the Loket.nl API are appended to the base URL. For example, the endpoint `/providers/employers/{employerId}/employees` can be accessed at [https://api.loket.nl/v2/providers/employers/{employerId}/employees](https://api.loket.nl/v2/providers/employers/{employerId}/employees). ## Path parameters Most endpoints require path parameter(s) in order to specify the context of the request. For example, the endpoint `/providers/employers/{employerId}/employees` contains the `employerId` path parameter. A path parameter is a unique identifier that identifies a specific resource, in this case an employer. ## Pagination The API supports two query parameters to control the pagination of the results: `pageNumber` and `pageSize`. Both of these query parameters only apply to endpoints that return lists of entities. The `pageNumber` query parameter specifies which page of the collection to return. By default `pageNumber` is set to 1 which returns the first page of the collection. Note: the pageNumber refers to the page (with a given number of entities), NOT to a specific entity within a page! The `pageSize` query parameter influences the number of entities per page. By default `pageSize` is set to 250. Note that this default may change in the future. It is not recommended to depend on this default when developing for the Loket.nl API. Examples: * ```?pageNumber=2``` to return the second page * ```?pageSize=2``` to set the page size to two ## Filtering The API supports output filtering via the querystring parameter `filter`. Filtering is possible on all fields of the following datatypes: * string * integer * boolean * date-time * decimals The following operators are available: | Operator | Description | Example | | -------------------- | --------------------- | ------------------------------- | | Comparison Operators | | | | eq | Equal | `city eq 'Redmond'` | | ne | Not equal | `city ne 'London'` | | lk | Like | `city lk 'Lond'` | | gt | Greater than | `price gt 20` | | ge | Greater than or equal | `price ge 10` | | lt | Less than | `price lt 20` | | le | Less than or equal | `price le 100` | | Logical Operators | | | | and | Logical and | `price le 200 and price gt 3.5` | | or | Logical or | `price le 3.5 or price gt 200` | Both field names and values are case insensitive. It is possible to filter on nested fields by adding the parent object before the field with a '.' to separate them. Do remember to URL encode the filter parameters. ### Examples All employments with a cancellation periode in months (the value 4 corresponds to months time unit). ``` /v2/providers/employers/{{employerId}}/employees/employments?filter=cancellationPeriodTimeUnit.key eq 4 ``` All employments with no endDate.s ``` /v2/providers/employers/{{employerId}}/employees/employments?filter=enddate eq null ``` All employments with an end date less or equal to 2017-01-01 ``` /v2/providers/employers/{{employerId}}/employees/employments?filter=enddate le '2017-01-01' ``` All employees with a employee number greater or equal 1 and less or equal 5 ``` /v2/providers/employers/{{employerId}}/employees?filter=employeeNumber ge 1 and employeeNumber le 5 ``` ## Ordering All Loket.nl API resources support ordering of the elements in the response on a specific field. All fields can be used in ordering. The list can be ordered in ascending or descending order, with ascending being the default one. Ordering on multiple fields is also by using a ',' as a separator. ### Examples Order employers by company name ascending ``` /v2/providers/employers?orderBy=companyName ``` Order employers by company name descending ``` /v2/providers/employers?orderBy=-companyName ``` Order employers by company name descending then by house number ascending ``` /v2/providers/employers?orderBy=-companyName,address.houseNumber ``` ## Headers In order to access the endpoints of the Loket.nl API, at least two request headers need to be set. __1)__ the `Authorization` header is required in order to authorize the API call. The value of this header is the word Bearer followed by a space and the access token acquired from the `/token` endpoint. For example, if the acquired access token is `AbCdEf123456`, the value of the `Authorization` headers would be: ``` Authorization: Bearer v69uloc3wcEFLePw2unot0FfAJfBocrvSwsrCo75JLUG7aE54zqSUnU ``` __2)__ The second header that is required for proper usage of the API, is the `Accept` header. This header is used for the resource versioning feature and is therefore crucial for making sure the response remains the same when new resource versions are introduced. The value of the `Accept` header differs per endpoint is defined in the OpenAPI documentation of the endpoints. ``` Accept: application/json;version=2018-01-01 ``` __3)__ In case of a PUT and sometimes a PATCH a third header is optional the if-match header. This header is used for concurrency control. Even though the header is optional we advise using this header on every PUT(PATCH) to ensure not losing data. ``` if-Match: aslkhas987da09s8udasd09a ``` # Response In addition to the responses defined in the OpenAPI documentation, the Loket.nl API also provides additional fields that give more information about the response and the entities requested. This section will explain the full response given by the Loket.nl API by examining the example response below. Example 400 response ```json { "version": { "obsoleteDate": null, "versionNumber": "2018-01-01, }, "messages": [ { "code": 83, "id": null, "type": "BrokenBusinessRule", "description": "[field] has an invalid length", "properties": [] } ], "_embedded": [] } ``` Example 200 response ```json { "totalSize": 1, "pageSize": 250, "totalPages": 1, "currentPage": 1, "version": { "obsoleteDate": null, "resourceVersion": "2018-01-01" }, "messages": [], "content": { "id": "2b4c119c-527c-4cbb-a5b2-f3a11e4b76cx", ... } } ``` ## Paging * `totalSize` has an integer value indicating the total number of entities irrespective of the page size. * `pageSize` has an integer value indicating the maximum number of entities returned per page. The page size can be influenced by setting the `pageSize` query parameter. See the section Query Parameters for more information. * `totalPages` has an integer value indicating the number of pages the requested collection holds given the specific pagesize. * `currentPage` has an integer value indicating the current page number. The current page number can be influenced by setting the `pageNumber` query parameter. See the section Query Parameters for more information. ## Version The `version` object provides information regarding the resource version of the entity requested. * `obsoleteDate` contains the date of discontinuation for the requested resource version. The value of this field can be `null` indicating that the requested resource version is not planned to be obsoleted at the time of the request. * `resourceVersion` shows the version of the requested entity. The resource version can be influenced by setting the `Accept` header. ## Messages The `messages` field contains a list of message objects related to the request made. Any warnings and errors will be communicated in this list of messages * `type` has a string value indicating the type of message. At this time the Loket.nl API supports five types of messages: `BrokenBusinessRule`, `Warning`, `Exception`, `ConcurrencyViolation` and `NotFound` . * `description` has a string value that describes the message that has occurred. * `code` is an identifying code for the message. Please note that this code may change in the future. See the documentation portal for possible message codes for an endpoint. * `id` relates the message to a specific entity in the reponse list. For example, in cases where a warning occurs for one of the entities in a list, the value of this field can be used to identify to which entity the warning applies. Currently implemented for endpoints where a multi-patch is performed (multiple actions are performed within one call) for example updating the status of one or more leaveRequests. * `properties` an array that can contain additional information regarding the message. Currently not yet fully implemented. * `_embedded` contains the list of entities as defined for each endpoint in the OpenAPI documentation. Please refer to that documentation for the contents of the `_embedded` field for each endpoint. For endpoints that return only one entity (detail endpoints) the `_embedded` field is replaced with a `content` field. The content of this field can also be found in the documentation for each endpoint. ## Headers * `etag` header is returned with every GET of a detail (single resource). This header is used for concurrency controle * `Expires` header is returned with every response to indicate how long a response can be cached * `Content-Disposition` header is used in case of downloads to provide a file name ## HTTP status codes The Loket.nl API supports the following http status codes. | Code | Is returned when | |------------------|---------------| | 200 | The request to GET, PUT, PATCH or DELETE and object was recived and processed succesfully. The response might still contain messages of the type warning. | | 201 | The request to insert (POST) a new object was recived and processed succesfully. The response might still contain messages of the type warning.| | 400 | The request was received but could not be processed. The reason(s) will be given in the response. The content type of the response may be text/plain for API-level error messages, such as when trying to call the API without SSL otherwise the content will be application/json. | | 401 | The bearer token provided in the authorization header is invalid. Do not retry the request until a new (valid) bearer token is acquired. | | 403 | The user is not authorized to access the resource. The reason will be given in the response. Do not retry the request until the, configuration, issue is resolved. | | 404 | The resource requested was not found/does not exist. | | 409 | The give if-match header in a PUT request no longer represents the current state of the object. Please acquire the current state off the object, via a GET, and resolve the differences then try again. | | 50* | A unforseen error occurred. Please check the request if everything seems te be in order on your side contact the support team. Provide as much information as possible to resolve the issue. | Note: for a limited number of endpoint a so-called multi-patch may be performed (multiple actions within one call). In that case the status code will be 200 if at least on of the actions succeeds, if other any action(s) in that call fail(s) a message will be returned including the given id of that entity. ## Caching The API uses the `Expires` header to indicate how long the item can be reused from the local cache. In most cases caching is not allowed for resources. Exceptions excist, such as pictures like the employer logo and the employee photo, in these cases the cache duration is mentioned in the description of the resource.