|
| 1 | +--- |
| 2 | +title: Automate User Provisioning in Expensify with Okta Workflows |
| 3 | +description: Set up Okta Workflows with Expensify’s API to automatically provision, update, and deprovision users. |
| 4 | +keywords: Okta Workflows, Expensify API, user provisioning, deprovisioning, Advanced Employee Updater, automate onboarding, SSO, identity management |
| 5 | +--- |
| 6 | + |
| 7 | +<div id="new-expensify" markdown="1"> |
| 8 | + |
| 9 | +# Automate User Provisioning in Expensify with Okta Workflows |
| 10 | + |
| 11 | +Set up Okta Workflows with Expensify’s Advanced Employee Updater API to automate user provisioning, updates, and deprovisioning — no manual entry required. |
| 12 | + |
| 13 | +--- |
| 14 | + |
| 15 | +## Who can use the Advanced Employee Updater API with Okta Workflows |
| 16 | + |
| 17 | +- **Domain Admins** in Expensify |
| 18 | +- **Okta Admins** with Workflow Builder access |
| 19 | + |
| 20 | +--- |
| 21 | + |
| 22 | +## Where to find your Expensify API credentials |
| 23 | + |
| 24 | +### Web |
| 25 | +1. While logged into your Expensify account, visit the [**Integrations Center**](https://www.expensify.com/tools/integrations/). |
| 26 | +2. Click **Generate API credentials**. |
| 27 | +3. Copy your **partnerUserID** and **partnerUserSecret**. |
| 28 | +4. Store these securely — these credentials will be used in your Okta workflow. |
| 29 | + |
| 30 | +--- |
| 31 | + |
| 32 | +## What the Okta Workflows integration with Expensify does |
| 33 | + |
| 34 | +Expensify’s native Okta integration handles authentication and SSO, but does **not** provision or update users. Use Okta Workflows with the Advanced Employee Updater API for user provisioning and updates. |
| 35 | + |
| 36 | +With this setup, you can: |
| 37 | +- Provision users into specific Workspaces (formerly policies) |
| 38 | +- Assign domain groups and managers |
| 39 | +- Deprovision terminated employees |
| 40 | +- Update names, email addresses, and more |
| 41 | + |
| 42 | +--- |
| 43 | + |
| 44 | +## How to configure Okta Workflows with Expensify |
| 45 | + |
| 46 | +### 1. Build the trigger |
| 47 | + |
| 48 | +In **Okta Workflows**, create a new flow: |
| 49 | +- Trigger: **User Created** or **User Assigned to Application** |
| 50 | + |
| 51 | +--- |
| 52 | + |
| 53 | +### 2. Retrieve workspace policy IDs from Expensify |
| 54 | + |
| 55 | +Use this API request to retrieve a list of policy IDs tied to your domain: |
| 56 | + |
| 57 | +```json |
| 58 | +{ |
| 59 | + "type": "get", |
| 60 | + "credentials": { |
| 61 | + "partnerUserID": "your_partnerUserID", |
| 62 | + "partnerUserSecret": "your_partnerUserSecret" |
| 63 | + }, |
| 64 | + "inputSettings": { |
| 65 | + "type": "policyList" |
| 66 | + } |
| 67 | +} |
| 68 | +``` |
| 69 | + |
| 70 | +We recommend using Postman or Insomnia to run this API request once, then store the results in an **Assign** card. |
| 71 | + |
| 72 | +{:width="100%"} |
| 73 | +*Use an Assign card to store your Expensify credentials and policy IDs once for reuse throughout the workflow.* |
| 74 | + |
| 75 | +--- |
| 76 | + |
| 77 | +## How to create a user in Expensify using Okta Workflows API |
| 78 | + |
| 79 | +To create or update a user, your API request must follow Expensify’s required structure. Here's what your API request payload should include in the `requestJobDescription` parameter: |
| 80 | + |
| 81 | +```json |
| 82 | +{ |
| 83 | + "type": "update", |
| 84 | + "credentials": { |
| 85 | + "partnerUserID": "your_partnerUserID", |
| 86 | + "partnerUserSecret": "your_partnerUserSecret" |
| 87 | + }, |
| 88 | + "inputSettings": { |
| 89 | + "type": "employees", |
| 90 | + "entity": "generic", |
| 91 | + "data": [ |
| 92 | + { |
| 93 | + "employeeEmail": "[email protected]", |
| 94 | + "managerEmail": "[email protected]", |
| 95 | + "policyID": "your_policy_id", |
| 96 | + "employeeID": "unique_employee_id", |
| 97 | + "firstName": "First", |
| 98 | + "lastName": "Last", |
| 99 | + "isTerminated": false |
| 100 | + } |
| 101 | + ] |
| 102 | + }, |
| 103 | + "onFinish": { |
| 104 | + "immediateResponse": true |
| 105 | + } |
| 106 | +} |
| 107 | +``` |
| 108 | + |
| 109 | +--- |
| 110 | + |
| 111 | +## End-to-end workflow example |
| 112 | + |
| 113 | +Here's how the Okta Workflows cards work together to create users in Expensify: |
| 114 | + |
| 115 | +1. **Trigger** |
| 116 | + Use **User Created** or **User Assigned to App**. |
| 117 | + |
| 118 | +2. **Retrieve user profile** |
| 119 | + Use a **Read User** or **Get Profile** card to fetch the employee’s details. |
| 120 | + |
| 121 | +3. **Lookup policy** |
| 122 | + (Optional) If your company uses multiple Workspaces, use a **Lookup** card to determine the correct `policyID`. |
| 123 | + |
| 124 | +{:width="100%"} |
| 125 | +*Use Lookup logic to assign employees to the correct Workspace based on their cost center.* |
| 126 | + |
| 127 | +4. **Build credentials and payload** |
| 128 | + Use **Assign**, **Construct**, or **Object** cards to: |
| 129 | + - Store your API credentials |
| 130 | + - Format `inputSettings` |
| 131 | + |
| 132 | +{:width="100%"} |
| 133 | +*Create a reusable inputSettings object for all your user-related API calls.* |
| 134 | + |
| 135 | + - Construct the `data` array with employee fields |
| 136 | + |
| 137 | +{:width="100%"} |
| 138 | +*Use Construct and Compose cards to format the employee data into the required API structure.* |
| 139 | + |
| 140 | + - Add an onFinish email notification (optional) |
| 141 | + |
| 142 | +{:width="100%"} |
| 143 | +*Use onFinish to trigger a follow-up action like notifying a manager after provisioning completes.* |
| 144 | + |
| 145 | +5. **Create the full request** |
| 146 | + |
| 147 | +{:width="100%"} |
| 148 | +*Build your requestJobDescription object to define the API call details.* |
| 149 | + |
| 150 | +{:width="100%"} |
| 151 | +*Connect your Constructed request to the Compose card to pass into the API request.* |
| 152 | + |
| 153 | +6. **Set headers** |
| 154 | + |
| 155 | +{:width="100%"} |
| 156 | +*Set headers for your API call, including content type and accepted format.* |
| 157 | + |
| 158 | +7. **Send the API request** |
| 159 | +Use **Raw Request** to send the `POST` to: |
| 160 | +``` |
| 161 | +https://integrations.expensify.com/Integration-Server/ExpensifyIntegrations |
| 162 | +``` |
| 163 | + |
| 164 | +{:width="100%"} |
| 165 | +*Use the Raw Request card to POST the formatted data to Expensify’s API.* |
| 166 | + |
| 167 | +8. **Handle the response** |
| 168 | +Use **Parse JSON** to extract the `responseCode`, and use **Return Error If** to catch failures. |
| 169 | + |
| 170 | +{:width="100%"} |
| 171 | +*Use Parse and Return Error If cards to handle failures returned by Expensify’s API.* |
| 172 | + |
| 173 | +--- |
| 174 | + |
| 175 | +## Common use cases for Okta Workflows with Expensify user provisioning |
| 176 | + |
| 177 | +This Okta Workflows integration guide reflects common customer workflows, such as: |
| 178 | + |
| 179 | +- Auto-provisioning employees into Workspaces at onboarding |
| 180 | +- Assigning managers and domain groups based on profile fields |
| 181 | +- Deprovisioning users when removed from an Okta group |
| 182 | +- Updating names and emails during employment changes |
| 183 | + |
| 184 | +If your setup differs or you’ve found another way to use this integration, we’d love to hear from you. Reach out to Concierge with feedback or [recommend a change to this article](https://github.com/Expensify/App/edit/main/docs/articles/Unlisted/Automate-User-Provisioning-in-Expensify-with-Okta-Workflows.md) to help expand the use cases we cover. |
| 185 | + |
| 186 | +--- |
| 187 | + |
| 188 | +# FAQ |
| 189 | + |
| 190 | +## Can I use this to update existing users? |
| 191 | + |
| 192 | +Yes. Set `"type": "update"` — the API will either update or create the user depending on whether they already exist. |
| 193 | + |
| 194 | +## Can I test the flow without creating users? |
| 195 | + |
| 196 | +Yes. Set `"dry-run": true` in the request payload to simulate the call without applying changes. |
| 197 | + |
| 198 | +## What happens if the API request contains invalid data? |
| 199 | + |
| 200 | +The API response will include a `responseCode` and `responseMessage`. Handle this using error-checking logic in your flow. |
| 201 | + |
| 202 | +## How often can I run this flow? |
| 203 | + |
| 204 | +Expensify enforces API rate limits. Avoid sending excessive requests in a short period. Batching users can help reduce the load. |
| 205 | + |
| 206 | +## Does Expensify support SCIM-based provisioning? |
| 207 | + |
| 208 | +No. Expensify does **not** support SCIM-based user provisioning. However, we do support SCIM-based deprovisioning for customers using Okta. To learn more, see [Okta SCIM API for User Deactivation](https://help.expensify.com/articles/expensify-classic/domains/Managing-Single-Sign-On-(SSO)-in-Expensify#:~:text=Advanced%20Configurations-,Okta%20SCIM%20API%20for%20User%20Deactivation,-Ensure%20your%20domain). |
| 209 | + |
| 210 | + |
| 211 | +--- |
| 212 | + |
| 213 | +## Resources |
| 214 | + |
| 215 | +- [Expensify Advanced Employee Updater API Docs](https://integrations.expensify.com/Integration-Server/doc/employeeUpdater/) |
| 216 | +- [Okta Workflows Documentation](https://help.okta.com/) |
| 217 | +- [Expensify API Explorer](https://integrations.expensify.com/Integration-Server/doc/) |
| 218 | + |
| 219 | +</div> |
0 commit comments