The advanced employee updater is designed to allow dynamic and customizable employee provisioning and de-provisioning in Expensify. It will allow you to:
Provision employees into Expensify policies based on customizable fields, such as employee department, country, job code, etc.
De-provision employees from Expensify, based on customizable fields, such as termination date
Assign employees to Expensify domain groups based on customizable fields, such as employee department, country, job code, etc.
Automatically invite managers to policies they have subordinates on
Automatically detect employee email address changes, and merge both addresses into the same account
Import additional information from the employee feed into Expensify, to reuse for custom data export
API Principles
Employee feed examples with various amounts of information provided:
The API call should be made to the regular endpoint https://integrations.expensify.com/Integration-Server/ExpensifyIntegrations. There are three ways to pass the employee data:
Directly as a parameter of the request
As a URL, that Expensify will load the data from (using Basic Authentication)
Hosted on a SFTP server, that Expensify will load the data from
requestJobDescription format
Name
Format
Valid values
Description
type
String
update
credentials
JSON object
Contains your Expensify API credentials, and information to access the feed by URL if needed.
dataSource
String
download, request, or sftp
Dictates how Expensify should retrieve your employee feed.
inputSettings
JSON object
See inputSettings below.
Optional elements
dry-run
Boolean
true, false
If set to true, employees will not actually be provisioned or updated. Use this for development.
onFinish
JSON array
See onFinish
You can configure the recipients list of email addresses that should receive a summary email of the changes made by the API.
setEmployeePrimaryPolicy
String
none (default), new_employees, all_employees
none: we will never update an employee's primary policy. new_employees: we will set an employee's primary policy to the policyID parameter if they were not a member of that policy yet. all_employees: we will update the primary policy for every employee.
inputSettings
Name
Format
Valid values
Description
type
String
employees
entity
String
Should always be set to generic.
Response format
{"responseCode":200,"dry-run":false,"updatedEmployeesCount":3,"diff":{"diffToAdd":{"0123456789ABCDEF":["employee1@domain.com","employee2@domain.com"],"ABCDEF0123456789":["employee3@domain.com"]},"diffToRemove":{"B1C7903C636F4A51":["terminatedEmployee@domain.com"]}},"securityGroupEmployeesMap":{"407184":["employee1@domain.com","employee2@domain.com"],"830936":["employee3@domain.com"]},"skippedEmployees":[{"email":"employee6@domain.com","reason":"No policy found for 'Marketing'"},{"email":"employee7@domain.com","reason":"Invalid manager email address 'manager@domain '"}]}
Response codes
Response code
Meaning
200
Success
410
Invalid input data, e.g. employee data is missing
500
Other
Response data
Key
Meaning
dry-run
Whether the job was run in dry-run mode, meaning employee data was not actually updated in Expensify
updatedEmployeesCount
Number of employees that were or would have been updated, depending on if the job was run in dry-run mode
diff, diffToAdd, diffToRemove
Email addresses of employees that were or would have been invited or removed from policies, grouped by policy IDs
securityGroupEmployeesMap
Email addresses of employees that were or would have been assigned to Domain Groups, grouped by domain group IDs
skippedEmployees
List of employees that could not be updated, with a reason why