Overview
Before starting we recommend reading the Introduction to Custom Integration article
Kindly remember that custom integrations:
-
Support syncing users, licenses, roles, and last used dates
-
Cannot sync expenses, even if the integrated app contains expense data
-
Work best for onboarding/offboarding/license optimization scenarios
To build your own integration and push user and license data into Torii you will need to follow the below 4 steps process.
Note, a developer is required to perform steps 3 & 4
IT - Setup/ preparation
STEP 1 - Get Torii API key
STEP 2 - Create new Custom Integration
Developer - Use the API, upload and sync users
STEP 3 - Upload the Users file to Torii
STEP 4 - Sync the uploaded file to Torii
STEP 1 - Get Torii API Key
Prerequisite - Torii admin permission is required
1. Go to Settings >> API Access
2. Click on Generate API key
3. In Generate API Key make sure you select the Full access option

4. Copy and save! the API Key - You cannot repeat this action again!
5. Click Got it

STEP 2 - Create new Custom Integration
1. Go to the Integrations page,
2. Scroll down and click the ADD CUSTOM INTEGRATION tile

3. find the App you want to integrate
4. Click Add integration

5. Copy the App account ID and paste "in a safe place"
6. Close the window

STEP 3 - Upload the users file to Torii
Prerequisites - Generate a users file named ‘users_file.json’ in the working folder and the file comply with the "File schema"
Click here for Torii's full API documentation
3 parts to the upload
-
Part 1 - Create a one-time URL upload link
-
Part 2 - Upload the file to S3
-
Part 3 - Update Torii with the upload information
Part 1 - Create a one-time URL upload link
-
Run the following command
curl -H "Authorization: Bearer API_KEY" https://api.toriihq.com/beta/files/url?name=FILE_NAME&type=customIntegrationData
-
Replace the API_KEY, and the S3_FILE_PATH with the filePath parameter, for example

You should get :
1. URL - Required for step 2
2. File path - Required for step 3

Note
- These parameters are embedded in the upload file parameters, consider it when
writing the code.
- The upload URL is valid for a short period of time, so make sure to upload the code
right after step 1
Part 2 - Upload the file to S3
-
Run the following command
curl -H "Content-Type: customIntegrationData" --data-binary @'LOCAL_FILE_PATH_AND_NAME' -X PUT S3_URL
-
Replace the LOCAL_FILE_PATH_AND_NAME with the file location and the S3_URL with the URL we got in the previous step
The result should look like the example below
Part 3 - Update Torii with the upload information
-
Run the following command
curl -d '{"path":"S3_FILE_PATH","type":"customIntegrationData"}' -H "Authorization: Bearer API_KEY" -H "Content-Type: application/json" https://api.toriihq.com/beta/files
-
Replace the API_KEY, and the S3_FILE_PATH with the filePath parameter we received in the first step, see the below example
The command result should be Torii upload ID like the below example
-
Save the id value for step 4
STEP 4 - Sync the uploaded file to Torii
-
Run the following command
curl -X PUT -d '{"idFile":"FILE_ID", "idAppAccount": "APP_ACCOUNT_ID"}' -H "Authorization: Bearer API_KEY" -H "Content-Type: application/json" https://api.toriihq.com/beta/services/sync/custom
-
Replace the API_KEY, FILE_ID from the previous step (Upload ID)
-
Replace the APP_ACCOUNT_ID you received from Torii in STEP 2 (add custom integration) like in the below example:
The command result should be a success like the below example
Error Message: Note, In case of an error, a relevant message like "Illegal file structure, Wrong file id, Wrong account", etc. will be displayed.
Last Notes:
-
The syncs are NOT incremental, meaning that on each sync you must provide all the users you currently have in the systems (and not only new ones for example)
-
It may take some time for the sync to complete.
To confirm a successful sync, Go to Integration window (1) and make sure the hourglass (2) disappeared and a green checkmark (3) is displayed.

Read our API documentation to find out more about Torii API capabilities.
Q & A
Q: Can I sync absolutely any app with Torii?
A: Yes. Torii can get data from any app.
You need to send it to the Torii API JSON file which is structured according to the Torii file schema.
Q: How often will data be pushed to Torii?
A: Up to you. to have it up to date we recommend automating it and pushing the data regularly.
When data has not been synced for more than 10 days, we show an alert in the UI.
Q: Can I perform workflow actions for a custom app?
A: Yes, through custom action configuration
Q: What happens when disconnecting custom integration?
A: App account ID is revoked and no more syncs are possible.
Users can reconnect the same account later.
The data is never deleted, similar to native integrations
Q: How do I delete and update users?
A: Each time a new file is pushed, the old data is overwritten.
If a user was removed from the file - he will be removed from the app in Torii.
If user attributes were updated in the file - they will be updated in Torii.
File schema
The file should include the following information. Note that fields must have the exact field name as shown in the following table:
Field Name |
Description |
Type |
Required |
users |
Users using the application |
User[] (see user object below) |
Yes |
licenses |
Licenses used in your org |
License[] (see license object below) |
No |
User
Field Name |
Description |
Type & Options |
Required |
|
Unique email |
String |
Yes |
firstName |
First name |
String |
No |
lastName |
Last name |
String |
No |
status |
The status of the user in Torii. Only active users are displayed as users of the application |
Enum (active/deleted) Default: active |
No |
externalStatus |
The status of the user as it appears on the application’s site |
String |
No |
roles |
Roles |
String[] |
No |
lastUsedDate |
Last date user used the application |
Date ISO 8601 (YYYY-MM-DD) |
No |
License
Field Name |
Description |
Type & Options |
Required |
name |
Unique name |
String |
Yes |
unassignedAmount |
Number of licenses that are not assigned to users |
Number |
No |
users |
Users under this license |
licenseUser[] (see licenseUser object below) |
No |
pricePerUser |
How much does it cost per user |
Number |
No |
License User
Field Name |
Description |
Type & Options |
Required |
|
User's email |
String |
Yes |
licenseStatus |
License status. If not provided, will be defined by user status |
Enum (active/inactive/deleted) |
No |
lastUsedDate |
Last date user used the license |
Date ISO 8601 (YYYY-MM-DD) |
No |
You can always contact our support team for help at support@toriihq.com.