All Collections
Users and groups
User importers
Web API v3 for user management
Web API v3 for user management

How to connect user data from your HR tool to the platform

O
Written by Okke Formsma
Updated this week

The Web API supplies a number of HTTP endpoints that expose ways to create and modify users, groups, memberships, permissions, user activation and budgets. The target audience of this document are developers who will be implementing an API connection for user provisioning with TinQwise Growth platform.


Interactive documentation

To explore the available endpoints use the interactive documentation. It can be accessed at https://<platform name>.platform.co.nl/api/v3/public/docs/. (e.g. https://tinqwise.platform.co.nl/api/v3/public/docs/)

We recommend to test integrations on the QA environment. Any changes you've made will be reset periodically. The data on QA is refreshed on the Monday of every odd week. You can find the API for QA at https://<platform name>.qa.platform.co.nl/api/v3/public/docs/. (e.g. https://tinqwise.qa.platform.co.nl/api/v3/public/docs/)


Authentication

To connect with the reporting API in a secure way we support OAuth2 with the Client Credentials Grant flow.

A client_id, client_secret and scope are needed to request an access token that can be used for authentication. Contact the Service Desk if you need a client_id and client_secret and specify which scopes you require.

Using your client_id and client_secret request an authorization token using the Token URL. Click the Authorize button in your interactive documentation to see your token URL. This token is necessary when you send a request to our API. Please note that the scope for which the token is provided should match the scope for the API which you are trying to use. Keep in mind that tokens are only active for a limited amount of time.

There are two scopes for each endpoint, for example v3:users:read and v3:users:write. The 'read' scope is required for GET requests, the 'write' scope is requried for PUT, POST, PATCH and DELETE requests.

The available scopes are:

  • v3:users:read

  • v3:users:write

  • v3:groups:read

  • v3:groups:write

  • v3:groupmemberships:read

  • v3:groupmemberships:write

  • v3:permissions:read

  • v3:permissions:write

  • v3:activation_token:read

  • v3:activation_token:write

  • v3:budgets:read

  • v3:budgets:write


Users

The Users endpoints allow listing, creation, and modification of users.

Listing users

List users using the /api/v3/public/users/ GET endpoint. You can use a number of filters to find users with a specific email or employee_id, and filter on contract_start_date, first_login or registered_at ranges.

uuid Users are uniquely identified by their uuid, and all other endpoints in API v3 that refer to users do so through this identifier. This field is read-only.

email The email address of a user should be unique if they log in with a username+password.

first_name and last_name are used to refer to a user on the platform

contract_start_date and contract_end_date can be used in automations to automatically make content available in an onboarding programme, or automatically suspend users when their contracts end.

employee_id is a customer-specific (unique) identifier, which can be used to disambiguate users.
language: the language for a user in iso-6391 format. Only languages currently enabled on the platform are valid options. Please contact support if you need to know which languages are currently enabled on the platform.

first_login is the date-time when the user first logged in. Read-only.

registered_at is the date-time when the user used his RegistrationToken to set up his password. This field stays null when the user uses SSO to login.

is_suspended controls whether the user can log in. A suspended user does not count toward the licenses, but is not able to log in either. Also see deleting users below.

is_pending. Automations are not applied to pending users; content is not yet made available to them and it is not possible to send them notifications. A user is set to 'is_pending=false' when they log in for the first time. You can set is_pending to false so a user will receive notifications from the platform. It is not possible to set is_pending to true. Instead you may want to suspend a user.

saml_username is the username used with a saml2 SSO.

jwt_username is the username used with a JWT integration.

openid_username is the username used with an OpenID integration.

Modifying users

With a PUT or PATCH request to /api/v3/public/users/<uuid>/ you can modify existing users. The PUT requires all writable fields to be included, while the PATCH only updates provided fields.

Deleting/Suspending users

A suspended user can not log in to the platform.

It is not possible to delete a user directly. Instead, the user should be 'suspended' by setting is_suspended to true. After 6 months, the user is permanently deleted from the platform. This suspend period before deletion can be changed through a request to the servicedesk.

Unsuspending users

If a user is suspended and you want to reactivate her (only possible within the 6 month period before a user is permanently deleted from the platform), then the user should be 'unsuspended' by setting is_suspended to false.

It is not necessary to send a new 'activation token' to the user after unsuspending her. The user can log in with her old password (or SSO).

Users will receive an automatic "welcome back" email after they are unsuspended. This behavior can be configured through the 'Unsuspend Email' feature.


Groups

Groups are the main method in TinQwise Growth platform to provide content differentiation and control permissions. The group structure is hierarchical; most groups are 'subgroups' of a 'parent group'.

Group Types

Group types are used to display groups selectors in the frontend and have some configuration options. Some group types are created by the system, such as vouchers, Remote Scorm, Admin groups and Programme group. Group Types should be used sparingly; even big platforms maybe have ten different group types, not hundreds.

It is good practice to give most groups a 'parent' group with type 'sorting', which acts as a 'top-level' group. For example:

  • Countries (type: sorting, parent: null)

    • Netherlands (type: country, parent: Countries)

      • Hilversum (type: city, parent: Netherlands)

      • Amsterdam (type: city, parent: Netherlands)

    • Belgium (type: country, parent: Countries)

      • Antwerp (type: city, parent: Belgium)

  • Vouchers (type: sorting, parent: null)

    • abcdef (type: voucher, parent: Vouchers)

Retrieving groups

Use the GET /api/v3/public/groups/ endpoint to retrieve a list of groups. You can filter on parent_uuid and group_type.

uuid is the unique identifier for this group.

group_type is the grouptype of this group.

name_i18n is the internationalized (i18n) or translated name for this group. This is a JSON object with keys corresponding to language codes (iso-6391) and values corresponding to localized names of this group. A translation should be provided for all supported languages on the platform.
Example: {"en": "Group Name", "nl": "Groepsnaam"}

parent_uuid is the uuid of the parent of this group.

external_id can be used to store a customer-specific identifier for this group, such as a uuid from a HR system.

Creating and modifying groups

POST to /api/v3/public/groups/ creates a new group.

PUT or PATCH will modify an existing group /api/v3/public/groups/{uuid}/ . The PUT requires all writable fields to be included, while the PATCH only updates provided fields.

Deleting groups

It is not possible to delete a group which is still referenced in an automation or for internal purposes (such as a Programme group).


Group Memberships

A user is member of zero or more groups. Content is unlocked for users based on the groups they are member of. Reporting rights and sub-admin permissions are also assigned on a group (see User-Group-Permissions).

Direct and indirect group memberships

The API only shows direct group membership. In TinQwise Growth platform, users are considered to be 'indirect' member of parent groups of the groups they are in. In the above example, a user will be considered to be an indirect member of the "Netherlands" group when he is in the "Amsterdam" group.

Retrieving group memberships

Use the GET /api/v3/public/group_memberships/ endpoint to retrieve a list of all group memberships.

group_uuid is the uuid of the group

user_uuid is the uuid of the user

Creating group memberships

POST a user UUID and group UUID to /api/v3/public/group_memberships/ to add a user to a group.

Deleting group memberships

Send a DELETE /api/v3/public/group_memberships/{group_uuid}/{user_uuid}/ to remove a user from a group.

Be careful when deleting group memberships. Some group memberships are used for internal purposes such as Programme access (Programme group group type) or to keep track of which voucher was used to create the user (voucher group type).

In general, it's a good rule of thumb to only delete memberships of groups that are also created through the API.

Modifying group memberships

Memberships can not be modified. They can only listed, created or deleted.


User Group Permissions

Some functionality in TinQwise Growth platform is only available to users with additional permissions. Permissions allow users to see progression reports.

To enable reporting access to a group of users for a single user, this user needs to get the 'manage members', 'view members' and 'reporting' permissions on a target group.

Retrieving user group permissions

Use the GET /api/v3/public/user_group_permissions/ endpoint to retrieve a list of all user group permissions..

group_uuid is the uuid of the group

user_uuid is the uuid of the user

permission is the name of the permission (one of "manage_group", "view_members", "manage_members" and "reporting")

Creating user group permissions

POST a user UUID, a group UUID and a permission name to /api/v3/public/user_group_permissions/.

Modifying user group permissions

Permissions can not be modified, only created and deleted.

Deleting user group permissions

Send a DELETE to /api/v3/public/user_group_permissions/{group_uuid}/{user_uuid}/{permission}/ to revoke permission for a user.


User Activation Tokens

When users need to log in using an email+password, they have to set up their password first. We support this flow through a registration token. The user receives a registration link which they follow to set up their password.

Before you can create an activation token, the user must be created using the 'user' API endpoints.

You can have TinQwise Growth platform send invitation emails with tokens to users directly or you can choose to retrieve the tokens using this API and distribute them yourself.

If you're using SSO (such as SAML2 or OpenID) to log users in on TinQwise Growth platform, you should not use User Activation Tokens.

User Activation Tokens can only be created and retrieved for users who are 'pending' (who have never logged in) and who are not 'suspended' (blocked from logged in).

Retrieving user activation tokens

Use the GET /api/v3/public/user_activation_tokens/ endpoint to retrieve a list of tokens for 'pending' users.

user_uuid is the uuid of the user

created_at is the date at which the token was created.

expires_at is the date at which the token expires. An expired token can not be used. You must first delete an expired token before you can create a new one for a user.

send_email shows whether TinQwise Growth platform has sent an email to this user with the activation link.

token_url is the url that the customer should follow to activate his account.

Creating user activation tokens

POST a user UUID (user_uuid) and whether an email should be sent (send_email) to /api/v3/public/user_activation_tokens/ to create an activation token.

Modifying user activation tokens

Tokens can not be modified, only created and deleted.

Deleting user activation tokens

Send a DELETE to /api/v3/public/user_activation_tokens/{user_uuid}/ to delete a token.

Resending an activation token

If you want to send a new registration email, you have to create a new activation token:

  1. The user should be 'unsuspended' by setting the is_suspended to false.

  2. Delete any existing token(s) for this user.

  3. Create a new token for this user, and make sure to set send_email to true

It is possible to resend invites manually by using the 'control' website


Budgets

The Budget feature should be enabled on the platform in Settings to be able to use this endpoint. The Budgets endpoints allow listing, creation, and modification of user budgets.

Retrieving budgets

Use the GET /api/v3/public/user_budgets/ endpoint to retrieve a list of all user budgets.

user_uuid is the uuid of the user

Creating budgets

POST a user UUID and budget to /api/v3/public/user_budgets/ to add a budget to a user.

Modifying budgets

With a PUT or PATCH request to /api/v3/public/user_budgets/<user_uuid>/ you can modify existing users. The PUT requires all writable fields to be included, while the PATCH only updates provided fields.


Caveats and limitations

  • It is currently not possible to give users sub-admin permissions through the API. This must be done manually through Control.

  • It is currently not possible to manage group type details through the API such as whether a group type shows in profiles and can be selected in a report.


Example API usage with python and the requests library

Don't forget to replace the base url, client id and client secret with the credentials for the acceptance (QA) environment you received.

import requests

base_url = 'https://<<your platform name>>.qa.platform.co.nl'

# login
payload = {
"grant_type": "client_credentials",
"client_id": "<<your client id>>",
"client_secret": "<<your client secret>>",
"scope": "v3:users:read v3:users:write",
}
response = requests.post(f"{base_url}/o/token/", data=payload).json()
token = response["access_token"]
print("token:", token)

# list users
headers = {"Authorization": f"Bearer {token}"}
response = requests.get(f"{base_url}/api/v3/public/users/",
headers=headers).json()
print("Retrieved", response["count"], "users.")
first_user = response["results"][0]
print(first_user["first_name"], "is on the platform")

Did this answer your question?