In this document, the basics of the Eudonet APIs are described. Find the paragraphs below:
Search for available training groups
Project related API documentation
Authentication
For the authentication of the Eudonet API, OAuth 2.0 is being utilized.
How does oAuth work?
OAuth2.0 (Open Authorization) is a protocol that allows applications to obtain limited access to user accounts on an HTTP service. The main benefit of OAuth2.0 is that it enables the consumer's data to stay private between the consumer and the server.
OAuth2.0 works on the basis of "access tokens", which may be issued to third-party clients by an authorization server with the approval of the resource owner. The client then uses the access token to access the protected resources hosted by the resource server.
oAuth client credentials
Every app or website that will authenticate to the Eudonet API using OAuth needs to have a client ID and secret. These will be generated and provided by Eudonet. The secret will be unique for every instance to validate the OAuth tokens in a safe way. Below is defined how these are configured and how they can be used.
A single token can be obtained by the consumer which will only be valid for 1 hour. After that, a new token must be obtained. With this flow, no users will authenticate, but other Eudonet or 3rd party apps. The apps need to be able to store the client secret in a secure way. The access token is valid for 1 hour. Refresh tokens are not supported, they have no benefit in this flow. So when the access token expires, a new one should be obtained from the token endpoint. With this method, no OAuth session is kept in the database. The API will simply validate the token with the information supplied.
Code examples
1. App authenticates to the token endpoint with client id and secret. Token endpoint: https://<server name>/oauth/token
curl --location --request POST 'https://<server name>/oauth/token \
--header 'Accept: application/json' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=a_fV8gxEdAHYq.......aM-FNoIpkY99Cc' \
--data-urlencode 'client_secret=OdmQeNXdovWAYrc_H3nt........Px4hthfIa3Q' \
--data-urlencode 'grant_type=client_credentials'
2. The token endpoint validates the credentials.
3. The token endpoint returns the access token
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI...ttl13xLrt7IiU",
"token_type": "Bearer",
"expires_in": 3600
}
4. The app can use the token in the Authentication Bearer header to request data from/to the API.
curl --location --request GET 'http:///api/country/31' \
--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI...ttl13xLrt7IiU'
5. The server will validate the token (using the aud claim and expiry time) and when it succeeds, will return the response.
REST API
REST API, which stands for Representational State Transfer Application Programming Interface, is a set of rules and conventions for building and interacting with web services based on the HTTP protocol. REST API is used for creating, reading, updating, and deleting resources in a server, using simple HTTP methods like GET, POST, PUT, and DELETE.
Eudonet's API, as a REST API, allows developers to interact with Eudonet's functionalities programmatically. It serves as a medium for integrating Eudonet's services with other external systems, ranging from third-party software, mobile applications, to other web services. The API allows these systems to access and manipulate the data stored within Eudonet, offering a high degree of flexibility and customization. The documentation is designed to give a good impression on the methods used, the expected request bodies, and potential response statuses and bodies.
Use cases
In the following section a number of common use cases are described. This is just an impression. With the API module of Eudonet many more processes can be supported. Beside a large number of standard endpoints it is also possible to configure specific endpoints for custom purposes. Of course the methods and processes will be simular as the use cases below.
Login
In case there is an authenticated part of the website where a user must login, the user accounts are stored in STB CRM. To login, the endpoint 'profile/loginProfile' can be used. When the request is succesfull the profile ID and the contact ID of the user will be returned. With these ID's other user specific data can be retrieved.
Endpoint
POST https://<servername>/api/profile/loginProfile
body
{
"password": "3f78f67a-7e5e",
"username": "jdoe@eudonet.com"
}
Response
[
{
"profileID": 81,
"username": "jdoe@eudonet.com",
"status": 1,
"transaction": {
"href": "/transaction/81",
"wmut_profile_id": 81
},
"email": "",
"contactID": 3781,
"contact": {
"href": "/contact/3781",
"contactID": 3781
},
"organisationID": null,
"organisation": "",
"occupationID": null,
"occupation": ""
}
]
Add a new user
When a user doesn't exist a new user can be created. This takes two steps / endpoints:
- Create the account
- Add the personal data
For creating the account the endpoint 'profile/profile' must be used. Here the username, password and e-mail address of the user can be added. When the call succeeds a profile ID will return. This must be used to post the personal data of the user.
Endpoint
POST https://<servername>/api/profile/profile
body
{
"password": "e59b2af0-968a",
"username": "wdoe@eudonet.com"
"email": "wdoe@eudonet.com"
}
Response
[
{
"profileID": 123456
}
]
Add the personal data. There are a lot fields which can be used to add personal data, also including occupation and organisation. In the example only some basic person fields are presented. In the call the fields 'profileID' and 'type' are required. All transactions will be linked to the created profile, therefor the obtained profileID is needed. The 'type' indicates the transactiontype, what will be '10' in case of adding a person. For other transactions like subscribing for a mailinggroup, add a membership or add a pledge there are other type codes. The posted data is checked and matched in advance by a back office employee, before it is definitively added to STB CRM.
Endpoint
POST https://<servername>/api/transaction-crm/
body
{
"CrmTransaction": {
"Contact": {
"name_initials": "M",
"name_common": "Mark",
"name_suffix": "",
"name_last": "Voorboom",
"gender": 1,
"email": "",
"mobile": "",
"phone": "",
"visit_street_1": "",
"visit_nr": 0,
"visit_nr_addition": "",
"visit_zip": "",
"visit_city": "",
"visit_country_id": 31,
"BankInfo": {
},
"Occupation": {
"Organisation": {
},
},
}
},
"profileID": 123456,
"type": 10
}
Response
[
{
"transactionID": 416,
"transaction": {
"href": "/transaction/416",
"transactionID": 416
}
}
]
Search for available training groups
When using the training/event part of STB CRM the subscribing of participants is a main process. Ususally the available courses and the scheduled dates will be published on the website. From here participants can search for the appropriate training and subscribe. The scheduled trainings are called training groups in STB CRM. So to show the actual offer of trainings a request for training groups is needed. As response the main characteristics of the training group returns like the title, the start- and enddate and the location(s). Because the list of training groups can be long paging is implemented by using the parameters offset (record starting point) and limit (max number of results). The response also show the total number of groups so it's easy to calculate the number of pages. Also the lists of specific filters, related to the occurring values in the resultset are returned in the results. This can be used to refine the search on the groups.
Endpoint
GET https:///api/train-group//findByQuery?trainingTitle=HBO%20-%20Management&offset=0&limit=10
Response
[
{
"totalgroups": 1,
"groups": [
{
"endDate": "2024-02-25T22:00:00",
"endTime": "2024-02-25T22:00:00",
"groupID": 1,
"Locations": [
{
"LocationCity": "Dordrecht",
"LocationName": "BC Academie"
},
{
"LocationCity": "Amsterdam",
"LocationName": "Binnenstad Zalencentrum"
}
],
"groupCode": "000001",
"startDate": "2024-02-25T18:00:00",
"startTime": "2024-02-25T18:00:00",
"groupTitle": "HBO - Management",
"description": "De HBO Management-cursus is een veelzijdige opleiding die studenten uitrust met de kennis en vaardigheden die nodig zijn om effectief leiderschap en management uit te oefenen in een reeks zakelijke omgevingen.",
"planningInfo": null,
"Characteristics": [
{
"CharacteristicId": 11235,
"CharacteristicTitle": "Avondcursus"
}
],
"maxParticipants": 50,
"minParticipants": 1,
"numberSubscriptions": 6
},
],
"trainings": [
{
"TrainingId": 2,
"TrainingTitle": "HBO - Management"
}
],
"locationcities": [
{
"LocationCity": Dordrecht
},
{
"LocationCity": Amsterdam
}
],
"characteristicitems": [
{
"CharacteristicId": 11235,
"CharacteristicTitle": "Avondcursus"
}
]
}
]
Subscribe for a group
When a non authenticated user searches for a training to subscribe for he can navigate to the detail of a trainingroup and start subscribing. The subscription consist of 3 steps.
- Create a profile
- Add the personal data
- Subscribe for a training group
The first 2 steps were described in the first two usecases. The third step assumes that a profile has already been created. So in the posted body the profileID has to be filled in and the transaction type code should be set on '40'. The most important field what needs to be filled is 'GroupID', because this finally put the subscription on the correct training group.
Endpoint
POST https://<servername>/api/transaction-registration/
body
{
"ProfileId": 123456,
"Type": 40,
"RegistrationTransactionCreate": {
"CpOrgContactId": 0,
"ExchangeRate": 1,
"RegistrationNoteExt": "",
"RegistrationDate": "2024-08-24",
"RegistrationStatus": 1,
"CurrencyId": 1,
"GroupId": 1,
"FinPayTypeId": 1,
"YourRef": "ABCDE1234",
"InvoiceToEntity": "contact"
}
}
Response
[
{
"WmutTrainregId": 108,
"transaction": {
"href": "/transaction/jqZOG0Y8pb11W9f7$XdUQ7AfI/417",
"TransactionId": 417
}
}
]
General response codes
| Code | Description |
| 200 | The call has succeeded |
| 403 | The posted element already exists |
| 404 | No results are found with the given parameter(s) |
| 500 | The service is unavailable |
Parameters
For the parameters in the webservices there are operators available to make smart filters:
| Operator | Means | Available for type | Example |
| || | OR | All | city = 'Amsterdam||London'; |
| | | A format can be passed after the pipe | Date | startdate = '01/01/2024|MM/dd/yyyy' |
| ! | NOT | All | city= '!Amsterdam'; |
| ^ | IS NULL | All | email = '^'; |
| ^= | IS NULL / Empty / 0 |
String, Number |
number = '^='; |
| < | Smaller then | All | weight = '<100'; |
| <= | Smaller or equal to | All | city = '<=Berlin'; |
| >= | Greater or equal to | All | orderdate = '>=01/01/2001|MM/dd/yyyy'; |
| > | Greater then | All | weight = '>100'; |
| ... | Between | All |
orderdate = '01/01/2023...01/01/2024 weight = '100...200'; |
| % | Wild Card String | String |
city = 'Ams%'; city = '%ter%; city = '%dam'; |
Project related API documentation
When a project will start, app- and website third parties will gain access to a interactive page where the complete documentation of all relevant endpoints for the specific project will be available.
Webhooks
For real-time synchronization purposes, enabling webhooks is a possibility. Whenever there is a change in STB CRM, a webhook can be automatically sent to a third party. At minimum, one ID is included in the webhook, however, it is also possible to send a more substantial payload. Once the third party receives the webhook, they can manage this trigger by executing a new call or performing other business logic tasks.
Example of a webhook with only an ID
{
"type": "persons",
"id": "3989",
"event": "update",
"zone": 32768,
"administrations": [
1000
]
}
Example of a webhook with a payload
{
"type": "art_article",
"id": "3",
"event": "update",
"payload": {
"articleDescription": "USB-kabel",
"sellingPrice":"12.50",
"vatIDSell":"2"
},
"administrations": [
1000,
]
}