If I recall correctly, the 400 error often stems from missing the id field in the nested skill objects. The API requires explicit identification for each skill update within the array.
The problem here is… well, it’s a bit of a mess. The suggestion above about the id field is technically correct for the payload structure, but if you are hitting a 400 on a “bulk” endpoint, you are likely targeting a deprecated or non-existent path. Genesys Cloud does not have a single /api/v2/users/bulk endpoint for skill updates that accepts that JSON structure. You have to iterate.
In my Laravel apps, I use Guzzle to handle this because the PHP SDK can be sluggish with large arrays. You need to fetch the user list first, then loop through them with PATCH /api/v2/users/{userId}/skills. Cache your OAuth token to avoid rate limiting yourself. Here is how I structure the request body for each user:
It depends, but typically the bulk endpoint is deprecated for this specific operation, so I switched to iterating PATCH /api/v2/users/{userId}/skills with the payload below.