Synchronize employee data from your HRIS or identity provider to Scan2Evolve. Create, update, and manage employee records, user accounts, roles, groups, and site assignments in a single batch operation.
POST /api/v1/sync/employees
Requires OAuth 2.0 client credentials authentication. See Authentication for details.
Process up to 500 employees per request. Each employee is processed independently for reliability.
Automatically create user accounts with password reset and welcome email options.
Each employee is processed in a transaction. Partial failures don't affect other employees.
Choose between "replace" or "additive" update modes for roles, groups, and sites.
{
"syncBatchId": "batch-2024-11-18-001",
"employees": [
{
"externalEmployeeId": "EMP-100245",
"status": "ACTIVE",
"firstName": "Jane",
"lastName": "Doe",
"displayName": "Jane Doe",
"email": "jane.doe@example.com",
"phone": "+1-415-555-0123",
"jobTitle": "Maintenance Supervisor",
"department": "Facilities",
"hireDate": "2023-04-12",
"terminationDate": null,
"supervisor": {
"name": "John Smith",
"email": "john.smith@example.com"
},
"roles": [
"FIELD_TECH",
"site_manager"
],
"groups": [
{
"groupName": "Maintenance Team",
"role": "Member"
}
],
"sites": [
{
"id": "ff1223ac-dfb5-11ec-9d64-0242ac120002",
"role": "site_manager"
},
{
"id": "ff1223ac-dfb5-11ec-9d64-0242ac120001",
"role": "inspector"
}
],
"metadata": {
"badgeNumber": "A12345",
"unionMember": true,
"emergencyContact": {
"name": "John Doe",
"phone": "+1-415-555-9999"
}
},
"userAccount": {
"username": "jane.doe",
"forcePasswordReset": true,
"sendWelcomeEmail": true
},
"updateMode": "replace"
}
]
}| Field | Type | Required | Description |
|---|---|---|---|
externalEmployeeId | string | Required | Unique identifier from your system. Used as the primary key for upsert operations. Must be unique within your organization. |
status | enum | Optional | Employee status: ACTIVE, INACTIVE, or TERMINATED. Defaults to ACTIVE. Setting to INACTIVE or TERMINATED disables the user account and removes all role/group/site assignments. |
firstName | string | Optional | Employee's first name. |
lastName | string | Optional | Employee's last name. |
displayName | string | Optional | Display name for the employee. If not provided, will be generated from firstName and lastName. |
email | string | Conditional | Employee's email address. Required if userAccount is provided and status is ACTIVE. Must be unique within your organization. Must be a valid email format. |
phone | string | Optional | Employee's phone number. |
jobTitle | string | Optional | Employee's job title. |
department | string | Optional | Employee's department. |
supervisor | object | Optional | Supervisor information. Fields: name (string), email (string). |
hireDate | string | Optional | Employee hire date in ISO 8601 format (e.g., 2023-04-12 or 2023-04-12T00:00:00Z). |
terminationDate | string | null | Optional | Employee termination date in ISO 8601 format. Set to null to clear an existing termination date. |
metadata | object | Optional | Custom metadata as a JSON object. Can store any additional information about the employee (e.g., badge numbers, union membership, emergency contacts). |
updateMode | enum | Optional | Update mode for roles, groups, and sites: replace (removes existing assignments before adding new ones) or additive (only adds new assignments). Defaults to replace. |
The userAccount object controls user account creation and management:
| Field | Type | Required | Description |
|---|---|---|---|
username | string | Optional | Username for the user account. If not provided, the email address is used as the username. |
forcePasswordReset | boolean | Optional | If true, generates a temporary password and forces the user to reset it on first login. Defaults to false. |
sendWelcomeEmail | boolean | Optional | If true, sends a welcome email to the user (if forcePasswordReset is also true, includes the temporary password). Defaults to false. |
When userAccount is provided and the employee status is ACTIVE, the email field is required. The email must be unique within your organization.
The roles field is an array of role names (strings). Roles must exist in your Scan2Evolve organization. Common roles include:
site_manager - Site manager role (requires at least one site assignment)FIELD_TECH - Field technicianinspector - Inspector roleadmin - Administrator roleIf a role doesn't exist, it will be skipped with a warning in the response.
The groups field is an array of group assignment objects:
{
"groups": [
{
"groupName": "Maintenance Team",
"role": "Member"
},
{
"externalGroupId": "TEAM-001",
"role": "Lead"
}
]
}Either groupName or externalGroupId is required. Groups must exist in your organization. The rolefield is optional and can be used to specify the member's role within the group.
The sites field is an array of site assignment objects:
{
"sites": [
{
"id": "ff1223ac-dfb5-11ec-9d64-0242ac120002",
"role": "site_manager"
},
{
"id": "ff1223ac-dfb5-11ec-9d64-0242ac120001",
"role": "inspector"
}
]
}The idfield is required and must be the site's UUID from your Scan2Evolve system. Sites must exist in your organization before you can assign employees to them.
Site IDs are UUIDs that uniquely identify each site in your Scan2Evolve organization. You can find site IDs by viewing sites in the Scan2Evolve web application, or by using the Sites API (coming soon) to programmatically retrieve site information including their IDs.
The role field is optional and specifies the site-level role (see Site-Level Role Assignment below).
Site assignments can include a rolefield to specify the employee's role at that specific site. This is useful when an employee has different responsibilities at different sites.
If you assign the site_manager role at the site level, the employee must also have site_manager in their roles array. Additionally, employees with the site_manager role must have at least one site assignment.
The system validates this requirement and will return an error if violated.
| Scenario | Requirement |
|---|---|
Assigning site_manager role | Employee must have site_manager in roles array AND at least one site assignment |
Setting site-level role to site_manager | Employee must have site_manager in roles array |
Using updateMode: "replace" with site_manager role | Must provide at least one valid site in the sites array, otherwise the role assignment will fail |
The updateMode field controls how roles, groups, and sites are updated:
replace (Default)Removes all existing role/group/site assignments before adding the new ones specified in the request. Use this when you want to completely replace the employee's assignments.
additiveOnly adds new assignments without removing existing ones. Use this when you want to add additional roles, groups, or sites to an employee without affecting their current assignments.
Update mode applies to roles, groups, and sites independently. If you specify updateMode: "replace", all three types of assignments will be replaced. You cannot use different update modes for different assignment types in a single request.
{
"requestId": "sync-1700312400000-abc123",
"syncBatchId": "batch-2024-11-18-001",
"results": [
{
"externalEmployeeId": "EMP-100245",
"status": "CREATED",
"employeeId": "emp_9b3c8d7e6f5a4b3c2d1e0f",
"userId": "user_1234567890abcdef",
"warnings": []
}
],
"errors": []
}{
"requestId": "sync-1700312400000-xyz789",
"syncBatchId": "batch-2024-11-18-002",
"results": [
{
"externalEmployeeId": "EMP-100245",
"status": "UPDATED",
"employeeId": "emp_9b3c8d7e6f5a4b3c2d1e0f",
"userId": "user_1234567890abcdef",
"warnings": [
"Role 'CUSTOM_ROLE' not found, skipped"
]
},
{
"externalEmployeeId": "EMP-100246",
"status": "CREATED",
"employeeId": "emp_8a2b7c6d5e4f3a2b1c0d9e",
"userId": "user_0987654321fedcba",
"warnings": []
}
],
"errors": [
{
"externalEmployeeId": "EMP-100247",
"message": "Email is required for ACTIVE users with userAccount"
}
]
}| Field | Type | Description |
|---|---|---|
requestId | string | Unique identifier for this API request. Use this when contacting support. |
syncBatchId | string | Echo of the syncBatchId from your request, if provided. |
results | array | Array of employee processing results. Each result contains:
|
errors | array | Array of error objects for employees that failed to process. Each error contains:
|
Process employees in batches of 100-500 for optimal performance. Smaller batches (50-100) are recommended for initial syncs or when dealing with complex employee data.
The endpoint is idempotent. You can safely retry the same request multiple times. The externalEmployeeId is used as the unique key, so sending the same employee data multiple times will result in updates rather than duplicates.
Always check both the results and errors arrays in the response. Even if some employees fail, others may have succeeded. Implement retry logic for transient errors (e.g., rate limiting, temporary database issues).
Always use ISO 8601 format for dates (e.g., 2023-04-12 or 2023-04-12T00:00:00Z). See Date/Time Format documentation for details.
When assigning the site_manager role:
id)updateMode: "additive" if you want to preserve existing site assignmentsFor new employees who need user accounts:
forcePasswordReset: true to ensure secure initial passwordssendWelcomeEmail: true to notify users of their new accountsACTIVE when creating user accounts| Error Message | Cause | Solution |
|---|---|---|
externalEmployeeId is required | Missing or empty externalEmployeeId | Ensure every employee has a unique externalEmployeeId |
Email is required for ACTIVE users with userAccount | Provided userAccount but no email | Add a valid email address to the employee record |
Invalid email format | Email doesn't match valid email pattern | Ensure email follows standard format (e.g., user@example.com) |
User with email ... already exists in a different organization | Email is already used in another organization | Use a different email address or contact support |
User with email ... already exists and is linked to employee ... | Email is linked to a different employee | Email addresses must be unique. Update the existing employee or use a different email |
| Error Message | Cause | Solution |
|---|---|---|
Cannot assign site_manager role: employee must have at least one site assigned | Trying to assign site_manager role without site assignments | Include at least one site in the sites array when assigning site_manager role |
Cannot assign site_manager role at site level: employee must have 'site_manager' in their roles array | Setting site-level role to site_manager without the role in roles array | Add site_manager to the roles array before assigning it at the site level |
site_manager role requires at least one site assignment | After processing, employee with site_manager role has no site assignments (e.g., due to updateMode: "replace") | Ensure at least one valid site is provided when using updateMode: "replace" with site_manager role |
The following scenarios result in warnings (not errors) - the employee will still be processed, but the missing resources will be skipped:
Role 'ROLE_NAME' not found, skipped- Role doesn't exist in your organizationGroup 'GROUP_NAME' not found, skipped- Group doesn't exist in your organizationSite with id 'SITE_ID' not found, skipped- Site doesn't exist in your organization (the site UUID must exist in your organization)Always check the warnings array in the response to identify missing resources.
If you exceed the rate limit, you'll receive a 429 response with rate limit headers. Implement exponential backoff and retry after the specified Retry-After period.
See Error Handling for details on rate limiting.