Please note: In order to use the bulk user import/edit functionality, the User Management module should be created and configured for the site.
Starting from release 9.75 and until release 9.98 inclusive, bulk user import is available only through internal API with basic authorization (login/password).
Starting from release 9.99:
User create/update is available in internal and external API via the POST: /rest/site/siteId/userBulkSave and POST: /rest/external/site/siteId/userBulkSave endpoints respectively.
Template headers and preview (convert from csv to json) is accessible via internal API only via POST: /rest/site/siteId/userBulkSave/preview and GET: /rest/site/siteId/userBulkSave/templateHeaders
Please, note the following regarding access restrictions to internal and external endpoints:
For the external endpoint POST: /rest/external/site/siteId/userBulkSave user’s access to view/edit users is respected. User does not need to have “System administrator“ or “Site Administrator“ rights as long as he has “Find user“ + “Users > Edit“ access.
Internal userBulkSave endpoints are available to system admins only.
To test endpoints use any REST client (f.e. Postman).
1) POST: /rest/site/siteId/userBulkSave/preview consumes CSV file with all info needed for creating a user and setting all related dependencies, provides validation of source file and returns array of UserImportResultWrapperDTOs which has an errors section
2) POST: /rest/site/siteId/userBulkSave (POST: /rest/external/site/siteId/userBulkSave) consumes json array of UserImport data and performs actual creation of users with setting all related dependencies
3) GET: /rest/site/siteId/userBulkSave/templateHeaders returns string of “,” separated header names, which contains up to date field names (including custom fields from user management module). It should be inserted as a first line of csv import file. All custom fields names will have signature FDname_FDid to prevent name collisions in import file header
Technical documentation for API is available on Swagger (UserBulkSaveRestController)
Note!
Starting from release 15.0.0 fields with auto content will be prefilled and field dependencies are respected in result of Bulk User Import.
For field dependencies to work: it’s important for fields to be in json in logically correct way to prevent cleanup of already filled fields by dependency in case order mixed up.
For auto prefilling: field (to be autofilled), should be removed from json. Keep in mind that validation is done before attempt to fill and save new or existed user, so if field with auto content is required and not present in JSON - validation error will be returned.
To temporary return to old behavior (ignoring dependencies and prefilling) - new yaml parameter added:
encode.webapp.external-api.legacy-set-fields
Step-by-step usage guide
Create import file:
touch import.csv
Make a request to GET: /rest/site/siteId/userBulkSave/templateHeaders
Copy response text and insert it as a first line in import.csv file
every header element (f.e. "Login", "Email") represents property of user object and values of corresponding fields from UserManagementModule (if it is configured)
Every row after header represent needed information for creation/editing a user and all related data.
When you need to create a new user "User id" should be set to 0.
Please, note: All the date values should be in ISO 8601 format. e.g. 2021-01-01
When you need to edit user, "User id" should contain an id OR "Email" should contain an email OR "Login" should contain a login of the corresponding user.
User id,Login,Email,Name,City,Phone,Mobile,Mobile Email,Address,Expired date,Access Right,Active,Portal Page,Skin,New UI Enabled,Classic UI Enabled,User groups,Division,Title,Country,Region,Sub Region,Language,IDP id,External id,User type_5708,Organisation type_5709,Client_5380,Default client_5710,Agency_5420,Count_5377 26914,users60,users60@avios.com,users60,Kyiv,0978535353,0978535353,users61.mobile@avios.com,Zhylyanska,2019-12-13,HWW - Basic,true,Dashboard,,true,true,Markets;Hogarth Hubs;Carte D'Or,Radox,Clients,United Kingdom,Unilever,Unilever,us,3,users60@avios.com,,,,Acer,, 30,users61,users61@avios.com,users61,Kyiv,0978535353,0978535353,users65.mobile@avios.com,Zhylyanska,2019-12-13,HWW - Basic,true,Dashboard,,true,true,Markets;Hogarth Hubs;Carte D'Or,Radox,Clients,United Kingdom,Unilever,Unilever,us,3,users65@avios.com,,,,Acer,, 40,users62,users62@avios.com,users62,Kyiv,0978535353,0978535353,users66.mobile@avios.com,Zhylyanska,2019-12-13,HWW - Basic,true,Dashboard,,true,true,Markets;Hogarth Hubs;Carte D'Or,Radox,Clients,United Kingdom,Unilever,Unilever,us,3,users66@avios.com,,,,Acer,,
With the above file we expect that one user with id "6914" will be edited, and two users will be created (with logins "users61" and "users62").
Email,New UI Enabled,Classic UI Enabled,City 2john57@encode.dk,false,false,Manchester
With the above file we expect that the user with email "john57@encode.dk" will be edited (no needed to set User id)
Login,New UI Enabled,Classic UI Enabled,City 2john57,true,false,London
With the above file we expect that the user with login "john57" will be edited (no needed to set User id or Email)
Import file can be validated by sending it to validation endpoint POST: /rest/site/siteId/userBulkSave/preview
Before posting a request, make sure that you have “Accept“ request header set to “application/json“
As a result of executing you will get a response in a json format where import file represented as a json objects (containing representations of represents users). F.e.:
Preview request execution: resulting JSON
{
"result": [
{
"userId": 6914,
"login": "users60",
"email": "users60@avios.com",
"name": "users60",
"city": "Kyiv",
"cellPhone": "0978535353",
"phone": "0978535353",
"cellPhoneEmail": "users61.mobile@avios.com",
"address": "Zhylyanska",
"expiredDate": "2019-12-13",
"systemAccessName": "Basic",
"active": true,
"portalPage": "Dashboard",
"siteSkin": "",
"userGroupNames": [
"Markets",
"Hubs",
"Carte"
],
"department": "Rad",
"function": "Clients",
"country": "United Kingdom",
"region": "Unilever",
"subRegion": "Unilever",
"languageCode": "us",
"idpId": 3,
"userExternalId": "users60@avios.com",
"customFields": {
"Agency": "",
"Default client": "Some",
"User type": "",
"Organisation type": "",
"Count": "",
"Client": ""
},
"newUiEnabled": true,
"classicUiEnabled": true 41
},
{
"login": "users65",
"email": "users65@avios.com",
"name": "users65",
"city": "Kyiv",
"cellPhone": "0978535353",
"phone": "0978535353",
"cellPhoneEmail": "users65.mobile@avios.com",
"address": "Zhylyanska",
"expiredDate": "2019-12-13",
"systemAccessName": "Basic",
"active": true,
"portalPage": "Dashboard",
"siteSkin": "",
"userGroupNames": [
"Markets",
"Hubs",
"Carte"
],
"department": "Rad",
"function": "Clients",
"country": "United Kingdom",
"region": "Unilever",
"subRegion": "Unilever",
"languageCode": "us",
"idpId": 3,
"userExternalId": "users65@avios.com",
"customFields": {
"Agency": "",
"Default client": "Some",
"User type": "",
"Organisation type": "",
"Count": "",
"Client": ""
},
"newUiEnabled": true,
"classicUiEnabled": true
},
{
"login": "users66",
"email": "users66@avios.com",
"name": "users66",
"city": "Kyiv",
"cellPhone": "0978535353",
"phone": "0978535353",
"cellPhoneEmail": "users66.mobile@avios.com",
"address": "Zhylyanska",
"expiredDate": "2019-12-13",
"systemAccessName": "Basic",
"active": true,
"portalPage": "Dashboard",
"siteSkin": "",
"userGroupNames": [
"Markets",
"Hubs",
"Carte"
],
"department": "Rad",
"function": "Clients",
"country": "United Kingdom",
"region": "Unilever",
"subRegion": "Unilever",
"languageCode": "us",
"idpId": 3,
"userExternalId": "users66@avios.com",
"customFields": {
"Agency": "",
"Default client": "Some",
"User type": "",
"Organisation type": "",
"Count": "",
"Client": ""
},
"newUiEnabled": true,
"classicUiEnabled": true
}
]
}
If all provided information was correct, json will not contain "error" section and is ready to be used for real bulk user import/edit
Copy mentioned json response, put it as a body parameter of request and send it to endpoint POST: /rest/site/siteId/userBulkSave (POST: /rest/external/site/siteId/userBulkSave)
As a result you will get a json with number of successfully processed entries and id's of created/edited users
Bulk user editing (random fields/parameters)
It is possible to edit only specific fields and related parameters for existing users. For this, just put to import file header only thous fields/parameters, you want to be edited.
F.e. you wan't to edit user's name, disable new UI and change value in "Default client" field in user management module field.
Your import csv file will look like this:
User id, Name,New UI Enabled,Default client_5710
26914,John,false,Abbay
36915,Ann,false,Abbay
46916,Lukas,false,Abbay
( Side note: When there's a response in the preview that continuously gives an error because the Post does not recognise the User id like in the example above, try to create the CSV File Headers starting with a comma ( , ) so in this case the headers would be ,User id, Name,New UI Enabled,Default client_5710 )
When you send it to POST: /rest/site/siteId/userBulkSave/preview endpoint you will get response
Preview request execution: resulting JSON
{
"result": [{
"userId": 6914,
"name": "John",
"customFields": {
"Default client": "Abbay"
},
"newUiEnabled": false
},
{
"userId": 6915,
"name": "Ann",
"customFields": {
"Default client": "Abbay"
},
"newUiEnabled": false
},
{
"userId": 6916,
"name": "Lukas",
"customFields": {
"Default client": "Abbay"
},
"newUiEnabled": false
}
]
}
By sending this JSON as a body to POST: /rest/site/siteId/userBulkSave (POST: /rest/external/site/siteId/userBulkSave) endpoint, you will get you user and related UserManagementModule edited
Validation
Both user preview and user save endpoints have validation mechanism. If entry you are trying to import has an error:
For POST: /rest/site/siteId/userBulkSave/preview
you will get back a JSON entry with error section where errors is explained. F.e. for import file like this:
User id,Login,Email,Name,City,Phone,Mobile,Mobile Email,Address,Expired date,Access Right,Active,Portal Page,Skin,New UI Enabled,Classic UI Enabled,User groups,Division,Title,Country,Region,Sub Region,Language,IDP id,External id,User type_5708,Organisation type_5709,Client_5380,Default client_5710,Agency_5420,Count_5377 20,users65,users65@aviost.com,users65,Kyiv,0978535353,0978535353,users65.mobile@avios.com,Zhylyanska,2019-12-13,Basic,true,Dashboard,,true,true,Markets;Hubs;Carte,Rad,Clients,United Kingdom,Unilever,Unilever,us,3,users65@avios.com,,,,Some,,
response will contain error section:
errors":{
"Default client": "Field FieldDefinition [id=5710, name=Default client] has no option \"Some\" !",
"login": "User with this login already exists in the system",
"email": "User email domain does not match the allowed one for target IDP. User cannot be created"
}
to fix it you just need to modify your import.csv file and try again
For POST: /rest/site/siteId/userBulkSave (POST: /rest/external/site/siteId/userBulkSave)
the same validation mechanism will be used. Endpoint will successfully process and save valid entries and will ignore entries with errors. In response the entries with errors will contain dedicated "error" section.
Validation rules
For user creation:
required fields for user should be present (Login, Email, Name)
unique fields should be unique for both system and system+import file (Login, Email)
For user creation/edit
Fields that configured to be unique, should be unique (including UserManagementModule fields)
Values for user related parameters f.e. Access Rights, User Groups, Country, IDP id etc should exist in the system
If IDP id is present, Email's domain should be within selected IDP's allowed domains
Expired date should be in "YYYY-MM-dd" format f.e. 2019-12-13
Email should be valid
CSV separator
coma "," (separates values of different fields f.e. Login,Email,Name)
If there is no value between two comas or after last coma it will be treated as empty value f.e.: login,,name (parser will assume that field "Email" is empty and if it is required, will show error).
If you want to ignore some value, just not include corresponding header into import file it will be set to default value (if not required) for user's creation and will be ignored on user's edit.
Multiple values separator
semicolon ";"
f.e. we want to set 3 user groups to user ("Markets", "Hubs" and "Carte"), import entry will contain:
...,User groups,... 2...,Markets;Hubs;Carte,...
Special characters in import values
If value contains special characters or national characters. It should be add to import file in quotes. F.e.
...,Name,... 2...,"J,o@h,&*Їn",...
Custom fields of UserManagementModule
Custom field of UserManagementModule in import.csv file should be represented as a header with following signature FieldDefinitionName_FieldDefinitionId (f.e. Name_5710)
GET: /rest/site/siteId/userBulkSave/templateHeaders will help to generate it correctly.
Such a solution is required to prevent name collisions for names of user's parameter and custom fields from UserManagementModule with the same name (if somebody configured it so). F.e.
...,Name,...,Name_5710 2...,Name of user,...,Value for a custom field of UMM called Name
Password management
It is impossible to set Password through bulk user import. If user created with user import functionality, password is randomly generated. To change this password every user should manually go through "Forgot password" functionality and reset it.
Password can't be edited with bulk user import/edit. Only through regular change password mechanisms.