This document intends to summarise the bare minimum of steps needed, via the least amount of API calls to create a new system user within "MyWorkPal".
Pre-requisites:
API Client access
See How to create API Clients to see how to obtain API Client IDs and secrets
Permissions
The API Client requires all the base permissions to read tenants, users, the associated employee/personal details of a user, and have write access for the creation. It is recommend the Admin User linked to the API Client is a system admin. (See Admin User Roles for more details). Only tenants that the API client has access to will be returned.
Environment "variables"
Within all examples:
{{url}} would be a full HTTPS URI such as https://webapi.myworkpal.co.uk
The process can be defined using the following logic:
I wish to perform the creation using the following details:
- the unique email to identify the user john@doe.com {{user_email}}
- for the "MyWorkpal" tenant company known to me as "Company Doe" {{company_name}}
During I will learn:
- tenant Subdomain for Company Doe, as {{sub_domain_name}}
- tenant Id for Company Doe, as {{tenant_id}}
- the unique SystemID for the user with email john@doe.com, as {{system_id}}
Within this process, I expect to ensure existence of the tenant, and confirm no existing user under this email.
Stage 1 - locate and identify target tenant by name
GET
Querystring parameters ("oData")
$inlinecount | string | "allpages" |
$filter | string | "tolower(Name) eq '{{company_name}}'" (EQ operation for exact find) |
$orderby | string | "Name asc" |
$top | int | 1 |
$skip | int | 0 |
Only the filter value needs adjustment. Using the example, the full URL querystring becomes:
{{url}}/api/admin/tenant/list/get?$inlinecount=allpages&$filter=tolower(Name) eq 'company doe'&$orderby=Name asc&$top=1&$skip=0
- please pay attention to the need to supply in lowercase - allowing a relaxed case-insensitive search.
Should the subdomain already be known, the filter can be adjusted to provide the same lookup, note the change in property reference.
{{url}}/api/admin/tenant/list/get?$inlinecount=allpages&$filter=tolower(SubDomainName) eq 'subdomainname'&$orderby=Name asc&$top=1&$skip=0
Response
Return | |
Status code | Description |
403 | Incorrect access for the request |
400 | Invalid request or unexpected error (detail will be in the response) |
200 | Successful response |
500 | Other exception unhandled |
Success response structure:
{ "count": 1, "results": [ { "adminUserDetails": null, "userCount": 0, "isSelected": false, "inOfflineMode": false, "offlineModeUrl": null, "locale": null, "dncLocale": null, "dateCreated": "0001-01-01T00:00:00", "lastUpdated": null, "id": 123, "name": "Company Doe", "subDomainName": "{{sub_domain_name}}", "inDemoMode": false, "theme": "mwp", "privateHomepage": null, "publicHomepage": null, "domainId": null, "domain": null } ] }
For a successful response but unsuccessful search, the response will simply appear as above but have a "count" of zero, along with a result array with no items. For a successful find, the "Id" "Name" and "SubDomainName" attributes are the values to be noted.
Stage 2 - existence of a user within a tenant [pre or post creation]
GET
Querystring parameters ("oData")
$inlinecount | string | "allpages" |
$filter | string | "tolower('{{user_email}}') eq tolower(EmailAddress)) " (EQ operation for exact find) |
$top | int | 1 |
$skip | int | 0 |
Only the filter value needs adjustment. Using the example detail and learned subdomain value, the full URL querystring becomes:
{{url}}/api/admin/users/list/get/all/{{subdomainname}}?$inlinecount=allpages&$filter=tolower('{{user_email}}') eq tolower(EmailAddress))&$top=1&$skip=0
- please pay attention to the need to supply in lowercase - allowing a relaxed case-insensitive search.
Response
Return | |
Status code | Description |
403 | Incorrect access for the request |
400 | Invalid request or unexpected error (detail will be in the response) |
200 | Successful response |
500 | Other exception unhandled |
Success response structure:
{ "count": 1, "results": [ { "id": {{system_id}}, "torusAccountId": 0, "userAccountId": {{system_id}}, "totalRewardStatementsId": null, "tenantId": {{tenant_id}}, "tenant": "{{sub_domain_name}}", "username": "username", "avatarImageFile": null, "displayName": "display name", "emailAddress": "{{user_email}}", "secretKey": "304743", "verificationKey": null, "passwordChanged": null, "isAccountVerified": false, "isLoginAllowed": true, "isAccountClosed": false, "isLockedOut": false, "accountClosed": null, "lastLogin": null, "lastFailedLogin": null, "failedLoginCount": 0, "hashedPassword": null, "alternateEmailAddress": null, "ccToAlternateEmailAddress": false, "preferredName": null, "personLastUpdated": null, "personDateCreated": null, "salutationId": null, "salutationTitle": null, "forenames": "jon", "middlenames": null, "surname": "processclosetest", "secondSurname": null, "dateOfBirth": null, "genderId": null, "genderName": null, "niNumber": null, "nationality": null, "personDetailsLastUpdated": null, "personDetailsDateCreated": null, "owner": null, "payrollNumber": null, "costCentreName": null, "startDate": null, "leaveDate": null, "employeeId": 1028, "lineManagerId": null, "lineManagerTeamCount": null, "holidayApproverId": null, "holidayApproverTeamCount": null, "hasLeft": null, "contactTelephoneNumber": null, "workTelephoneNumber": null, "payDate": null, "salary": null, "futureSalary": null, "futureSalaryDate": null, "benefitAllowance": null, "futureBenefitAllowance": null, "qualifyingEarnings": null, "holidayTrading": null, "matchingFactor": null, "department": null, "division": null, "location": null, "jobTitle": null, "personId": 0, "dateCreated": "2022-05-16T15:20:09.677", "lastUpdated": "2022-05-16T15:20:09.773" } ] }
For a successful response but unsuccessful search, again the response will simply appear as above but have a "count" of zero, along with a result array with no items. There can not therefore be a user within this tenant with the specified email, and that's in any "state" eg processed, open or closed. A successful find contains many values - of which only "id" or "userAccountId" is required - this is the "SystemId" of the user and is supplied twice here, can be either value noted.
Stage 3 - creation of a user
POST
Request
The following raw content needs to be sent in the request:
Body
Data requirements (mandatory data all items).
"requestDTO" requirements (Json camelcase)
UserAccount | Obj | Main section containing user details |
- EmailAddress | string | Desired Email address for the user account |
- Tenant | string | Tenant Sub Domain value |
PersonDetails | Obj | Non mandatory, would contain optional details |
ContactNumbers | Obj | Non mandatory, would contain optional details |
AddressDetails | Obj | Non mandatory, would contain optional details |
EmployeeDetails | Obj | Non mandatory, would contain optional details |
MetaDataPersonal | Obj | Mandatory, containing tenant specific MetaData |
- Groups | Array | Mandatory, at present required at minimum as empty |
MetaDataEmployee | Obj | Mandatory, containing tenant specific MetaData |
- Groups | Array | Mandatory, at present required at minimum as empty |
This represents the least amount of information needed for account creation. Our API is set to create an account with the possibility of assigning a wealth of information during a wizard stage, both in generic terms and tenant specific (meta data).
Turned into RAW Json, the working example becomes:
{"userAccount":{"emailAddress":"{{user_email}}","tenant":"{{sub_domain_name}}"},"personDetails":{},"contactNumbers":[],"addressDetails":{},"employeeDetails":{},"metaDataPersonal":{groups: []},"metaDataEmployee":{groups: []}}
this contains the subdomain name (as learned) and the target email, and nothing more.
Response
Return | |
Status code | Description |
403 | Incorrect access for the request |
400 | Invalid request or unexpected error (detail will be in the response) |
200 | Successful response |
500 | Other exception unhandled |
Success response structure:
{ "successful": true, "status": "UserAccountService.CreateNewUserViaWizard completed successfully as admin.", "exceptionMessage": null, "exceptionMessages": null, "userAccountId": {{system_id}}, "username": "{{user_email}}", "nonce": null, "redirectPath": null }
Should the response be successful but the request detail fail, the Success and Status attributes will flag as False with a message/explanation. When successfully made, the username will return as the provided email, alongside the all important "UserAccountId" which is the "SystemId".
One may now return to Stage 2 to verify the match in SystemId's.
Stage 3 - updating existing user values (modify, add, remove)
With possession of a fresh/new, or existing user SystemID, along with the tenant detail to which they belong, it is now possible to move deeper into data management for the MyWorkPal account.
For managing the core Employee record for the user, please refer to:
https://support.myworkpal.co.uk/a/solutions/articles/101000558909
For managing the core Personal Details record for the user, please refer to:
https://support.myworkpal.co.uk/a/solutions/articles/101000558964
For managing Address record(s) for the user, please refer to:
https://support.myworkpal.co.uk/a/solutions/articles/101000558976
For managing Salary records for the user, please refer to:
https://support.myworkpal.co.uk/a/solutions/articles/101000558994
For managing Employee Details Meta Data for the user, please refer to:
https://support.myworkpal.co.uk/a/solutions/articles/101000559034