CXone Admin API bulk-update agent skill proficiencies via REST

Is it possible to bulk-update agent skill proficiencies via REST? The docs state:

“To modify multiple skills, send a PUT request to /api/v2/users/{userId}/routingskills/bulk with an array of skill objects.”

However, my payload:

[ { "skillId": "123", "proficiency": "Expert" } ]

returns 405 Method Not Allowed. I see no PATCH endpoint for bulk operations. Does the Admin API support batch updates for {userId}/routingskills, or must I loop through PUT /api/v2/users/{userId}/routingskills/{skillId} individually?

This is caused by a mismatch in the HTTP method and endpoint structure for bulk skill updates. The documentation you cited refers to a specific resource that requires POST, but your payload structure might be triggering validation errors if the endpoint expects a different envelope.

  • Verify the Endpoint: Ensure you are hitting /api/v2/users/{userId}/skills and not a nested path. The platform uses POST for creating/updating associations in this context. Double-check the endpoint in the CXone Developer Portal; subtle variations exist.
  • Check Content-Type: Explicitly set Content-Type: application/json. Some SDKs default to x-www-form-urlencoded, which causes 405 or 400 errors. Inspect your SDK’s default settings.
  • Use the Correct Proficiency Value: Proficiency is a string value representing the skill level. Valid values are determined by your organization’s skill profile. Consult the Skill Profile configuration in CXone Admin to confirm the accepted values (e.g., “Basic”, “Intermediate”, “Advanced”).
  • Try a Single Update First: Isolate the issue by sending a single skill object. If that works, the problem is likely in the array formatting or rate limiting on the batch. Investigate the CXone API rate limits for bulk operations.

Here is a corrected curl example:

curl -X POST "https://api.cxone.net/api/v2/users/{userId}/skills" \
 -H "Authorization: Bearer {access_token}" \
 -H "Content-Type: application/json" \
 -d '[
 {
 "skillId": "123",
 "proficiency": "Expert"
 }
 ]'
2 Likes

The simplest way to resolve this is to abandon the direct REST call for bulk operations and instead utilize the asynchronous job API. The endpoint PUT /api/v2/users/{userId}/routingskills/{skillId} is designed for single-user, synchronous updates. When you attempt to pass an array or a batch payload to a singular resource endpoint, the platform’s validation layer rejects it with a 405 because it expects a single object, not a list. For bulk modifications, you must use the PATCH /api/v2/users/{userId}/routingskills/bulk or the specific user management bulk endpoints if available in your specific org tier, but typically skill updates are handled via the PUT /api/v2/users/{userId}/routingskills/bulk with a skills array in the body.

However, the most robust method for large-scale updates is to construct a proper JSON payload for the single-user PUT and execute it via a script or orchestration tool, rather than trying to force a bulk REST call that doesn’t exist for skills. The proficiency field is often case-sensitive and must match the exact enum values defined in your organization’s skill configuration.

PUT /api/v2/users/{userId}/routingskills/{skillId}
Content-Type: application/json

{
 "proficiency": "Expert"
}

Be aware that directly updating user skills bypasses any WFM integration constraints. If your org uses WFM for scheduling, these manual API updates can cause immediate conflicts in the scheduler if the proficiency levels do not align with the forecasted demand. Always verify the target user’s current shift status before applying bulk changes. I have seen this cause significant issues in our Snowflake extracts when the proficiency data drifts from the WFM source of truth. Use the platformClient.Users.updateUserRoutingSkill(userId, skillId, body) method in the SDK to handle the authentication and header management automatically.

1 Like