Skip to content

Commit 5013c73

Browse files
Merge pull request #72368 from Expensify/okta-workflows
2 parents be99e70 + 9bedf2a commit 5013c73

11 files changed

+219
-0
lines changed
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
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+
![Assign and Construct cards showing credentials setup]({{site.url}}/assets/images/okta-assign-construct.png){: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+
![Read, Lookup, and Assign cards for policy mapping]({{site.url}}/assets/images/okta-lookup.png){: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+
![Construct card for inputSettings block]({{site.url}}/assets/images/okta-construct4.png){: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+
![Construct and Compose cards building employee data]({{site.url}}/assets/images/okta-construct-compose.png){: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+
![Construct card for onFinish email notification]({{site.url}}/assets/images/okta-construct3.png){: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+
![Construct card for requestJobDescription]({{site.url}}/assets/images/okta-construct2.png){:width="100%"}
148+
*Build your requestJobDescription object to define the API call details.*
149+
150+
![Compose card referencing requestJobDescription]({{site.url}}/assets/images/okta-request-compose.png){:width="100%"}
151+
*Connect your Constructed request to the Compose card to pass into the API request.*
152+
153+
6. **Set headers**
154+
155+
![Construct card for headers]({{site.url}}/assets/images/Okta-object-construct.png){: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+
![API Connector Raw Request card setup]({{site.url}}/assets/images/Okta-request1.png){: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+
![Parse and Return Error If cards for responseCode]({{site.url}}/assets/images/okta-error-handling.png){: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>
38.4 KB
Loading
78 KB
Loading
82.2 KB
Loading
167 KB
Loading
68.4 KB
Loading
35.9 KB
Loading
33.7 KB
Loading
118 KB
Loading

docs/assets/images/okta-lookup.png

182 KB
Loading

0 commit comments

Comments
 (0)