I’m trying to clean up some stale user accounts in our Genesys Cloud org. We have a few contractors who left and I want to remove their access completely. The problem is I’m worried about breaking historical data. If I just call DELETE /api/v2/users/{userId}, does that wipe out the conversation history associated with them? Or does it just deactivate the account?
I tried doing a test run on a sandbox user first. Here’s the curl command I used:
curl -X DELETE "https://api.mypurecloud.com/api/v2/users/12345-abc-def" \
-H "Authorization: Bearer <token>"
It returned a 204 No Content. That seems fine. But when I looked at the analytics reports for that user, the name showed up as “Deleted User” and the ID was still there. That’s good. But I read somewhere that if you have active conversations assigned to a user and you delete them, the conversations get orphaned or assigned to nobody. Is that true? I want to make sure I don’t lose the audit trail for compliance.
Also, should I be removing the user from all queues and skill groups first? I tried removing them from a queue using PATCH /api/v2/queues/{queueId}/users/{userId} but I keep getting a 409 Conflict error saying the user is still in a wrap-up state or something. Maybe that’s why I can’t just delete them straight away?
Basically, what’s the safe sequence of API calls to fully remove a user without messing up the data? I’m using the Python SDK for this script. Here’s what I have so far:
client = platform_client.init(
client_id=config.client_id,
client_secret=config.client_secret,
base_url=config.base_url
)
client.login()
# Remove from queues
for queue in queues:
client.users_api.delete_user_queue(user_id, queue.id)
# Delete user
client.users_api.delete_user(user_id)
The delete_user_queue call fails if the user is logged in. I have to log them out first? Is there a way to force logout via API? Or do I just have to wait? I don’t want to write a script that hangs waiting for a user to log out.
Any advice on the best practice here? I just want to make sure the historical data stays intact for the compliance team.
DELETE /api/v2/users/{userId} doesn’t wipe history. It just marks the user as inactive. The conversation logs stay intact because they’re tied to the interaction ID, not the user object. You won’t lose that data.
The real headache is the queues. If you delete the user while they’re still assigned to a queue, the API throws a 400. You have to remove them from every queue first. Doing this manually via UI is painful.
Here’s the workflow. First, get the user’s ID. Then pull their current queue memberships. Iterate through that list and remove them from each one. Finally, delete the user.
// Node.js using NICE CXone SDK (genesys-cloud)
const { PlatformClient } = require('@nice-dcx/sdk');
async function removeUserFromQueuesAndDelete(userId, platformClient) {
// 1. Get user details to ensure they exist
const user = await platformClient.Users.getUser(userId);
if (!user) throw new Error('User not found');
// 2. Get all queues the user is in
// Note: getUserQueues might require specific scopes or pagination handling depending on volume
const queues = await platformClient.Users.getUserQueues(userId);
// 3. Remove user from each queue
if (queues && queues.entities) {
for (const queue of queues.entities) {
try {
await platformClient.Queues.removeQueueMember(queue.id, userId);
console.log(`Removed user ${userId} from queue ${queue.id}`);
} catch (err) {
// Handle case where user might already be removed or queue is inaccessible
console.warn(`Failed to remove from queue ${queue.id}:`, err.message);
}
}
}
// 4. Delete the user
try {
await platformClient.Users.deleteUser(userId);
console.log(`User ${userId} deleted successfully.`);
} catch (err) {
console.error(`Failed to delete user ${userId}:`, err.message);
}
}
If you’re doing this in Studio, just use a REST Proxy. Call GET /api/v2/users/{userId}/queues to get the list, loop through the entities, and hit DELETE /api/v2/queues/{queueId}/members/{userId} for each one. Once the list is empty, hit DELETE /api/v2/users/{userId}.
Don’t forget to check for routing skills assignments if you’re using skills-based routing. Sometimes the user object holds direct skill mappings that block deletion. Check the routing object in the user payload. If routing.skills has entries, you might need to clear those via PATCH /api/v2/users/{userId} before the delete call goes through.