Update Users to UUID (v21 to v22+)
Kiteworks API v22 changed all user IDs from sequential integers to Universally Unique Identifier (UUID) strings. If your integration targets v21 or earlier, update every place your code stores, constructs, or compares user IDs.
Who Is Affected
X-Accellion-Version: 22 or higher (including v28), all user IDs are UUID strings.
Not sure which version your integration targets? See Check Your API Version before continuing.
What Changed
In API v22, all ID fields for admin users, standard users, and admin roles changed from sequential integers to UUID strings. Several related resources also changed in API v22, including Contacts, Devices, and Data Leak Investigator (DLI) exports.
// Old (v21 and earlier)
{ "id": 42, "basedirId": 100, "mydirId": 101, "syncdirId": 102 }
// New (v22 and later, including v28)
{ "id": "c3d4e5f6-e5f6-7890-abcd-ef1234567890", "basedirId": "d4e5f6a7-f6a7-8901-bcde-f01234567891", "mydirId": "e5f6a7b8-a7b8-9012-cdef-012345678902", "syncdirId": "f6a7b8c9-b8c9-0123-defa-123456789013" }
Step 1 — Audit Your Code
Run these searches in your source tree to find all places where integer user IDs appear in URL construction or variable assignments:
# Find integer user ID usage in URL construction
grep -rn "rest/admin/users/[0-9]" ./src
grep -rn "rest/users/[0-9]" ./src
grep -rn "user_id\s*=\s*[0-9]" ./src
grep -rn "int(.*user_id\b" ./src
Step 2 — Update Path Parameters
Replace integer values with UUID strings in the {id} path parameter across all admin and standard user endpoints:
| Example Endpoint | Notes |
|---|---|
GET /rest/admin/users/{id}, PUT /rest/admin/users/{id}, DELETE /rest/admin/users/{id} | Admin user management |
GET /rest/users/{id} | Standard user lookup |
GET /rest/users/me | Returns the authenticated user — no path change needed, but the id field in the response is now a UUID string |
For example, to get a user by ID:
# Old — integer user ID
user_id = 42
resp = requests.get(
f"{base_url}/rest/admin/users/{user_id}",
headers={"Authorization": f"Bearer {token}", "X-Accellion-Version": "21"},
)
# New v28 — UUID string
user_id = "c3d4e5f6-e5f6-7890-abcd-ef1234567890"
resp = requests.get(
f"{base_url}/rest/admin/users/{user_id}",
headers={"Authorization": f"Bearer {token}", "X-Accellion-Version": "28"},
)
Step 3 — Update Query Parameters
Replace integer values with UUID strings in the following query parameters:
| Parameter | Notes |
|---|---|
id:in | Comma-separated list of user UUIDs |
userId | Single user UUID |
userId:in | Comma-separated list of user UUIDs |
For example, to filter users by ID:
# Before — v21, integer filter
resp = requests.get(
f"{base_url}/rest/admin/users",
params={"userId": 42},
headers={"Authorization": f"Bearer {token}", "X-Accellion-Version": "21"},
)
# After — v28, UUID filter
resp = requests.get(
f"{base_url}/rest/admin/users",
params={"userId": "c3d4e5f6-e5f6-7890-abcd-ef1234567890"},
headers={"Authorization": f"Bearer {token}", "X-Accellion-Version": "28"},
)
Step 4 — Update Request Body Fields
In the PUT /rest/adminRoles/{id}/users request body, replace each objects[].id integer with a UUID string. For example, to assign users to an admin role:
// Old
{ "objects": [{ "id": 42 }, { "id": 99 }] }
// New v28
{ "objects": [{ "id": "c3d4e5f6-e5f6-7890-abcd-ef1234567890" }, { "id": "d4e5f6a7-f6a7-8901-bcde-f01234567891" }] }
Step 5 — Update Response Parsing
The following user object fields now return UUID strings:
| Field | Appears In |
|---|---|
id | All user objects (GET /rest/admin/users, /rest/users/me, etc.) |
basedirId | User object — ID of the user's base directory folder |
mydirId | User object — ID of the user's personal folder |
syncdirId | User object — ID of the user's sync folder |
For example, to access the updated fields after a response:
# Old — v21, user directory IDs were integers
user = resp.json()
home_folder_id = user["basedirId"] # was: 100 (integer)
# New v28 — UUID strings
user = resp.json()
home_folder_id = user["basedirId"] # now: "d4e5f6a7-f6a7-8901-bcde-f01234567891" (UUID string)
See All Affected Endpoints
End-to-End Example
The following example shows how UUIDs flow from one response into the next request: list users to obtain their UUIDs, then assign one to an admin role.
import requests
# Step 1: List users — the response now returns UUID strings for all ID fields
resp = requests.get(
f"{base_url}/rest/admin/users",
headers={"Authorization": f"Bearer {token}", "X-Accellion-Version": "28"},
)
users = resp.json()["data"]
user_uuid = users[0]["id"] # e.g. "c3d4e5f6-e5f6-7890-abcd-ef1234567890"
# Step 2: Assign that user to an admin role — pass the UUID into the request body
role_id = "a1b2c3d4-e5f6-7890-abcd-ef1234567890" # Replace with your admin role's UUID
requests.put(
f"{base_url}/rest/adminRoles/{role_id}/users",
headers={
"Authorization": f"Bearer {token}",
"X-Accellion-Version": "28",
"Content-Type": "application/json",
},
json={"objects": [{"id": user_uuid}]},
)
Next Steps
After completing all five steps, test your integration against a v22+ (or v28) instance and verify that user operations return UUID strings in all ID fields.
- Update Mail & Email to UUID (v20 to v21+) → Upgrade mail and email IDs if you built your integration against v20 or earlier.
- Update Files & Folders to UUID (v18 to v19+) → Upgrade file and folder IDs if you built against v18 or earlier.
- Upgrade to API v28 → Apply all remaining breaking changes to reach the current API version.