PATCH /api/v2/conversations/voice/{id} transfer-to-queue returning 400 Bad Request

POST /api/v2/conversations/voice/{id}/participants/{participantId}
HTTP 400 Bad Request
{
 "errors": [
 {
 "code": "bad_request",
 "message": "Invalid participant action: transferToQueue requires a valid queueId and transferToType of 'queue'."
 }
 ]
}

We’re trying to programmatically transfer an active voice interaction to a specific queue using the JavaScript SDK. The goal is to have a custom agent desktop widget initiate a blind transfer without dropping the current leg immediately, but the API seems to reject the payload structure.

Here is the setup:

  • SDK: @genesyscloud/purecloud-platform-client-sdk-javascript v1.18.0
  • Environment: Production org (US Pacific)
  • Permissions: interaction:transfer:write and conversation:view are assigned to the integration user.
  • The participantId is verified as the agent’s own participant ID in the active conversation.

The code snippet looks like this:

const body = {
 action: 'transferToQueue',
 queueId: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890', // Valid queue ID
 transferToType: 'queue' 
};

await conversationsApi.putConversationsVoiceParticipant({
 conversationId: activeConversation.id,
 participantId: agentParticipantId,
 body: body
});

I’ve tried swapping transferToType to user just to see if the structure was wrong, but that fails with a different validation error about missing userId. I also checked the raw HTTP request being sent. The headers look fine, including the Authorization: Bearer <token> and Content-Type: application/json. The token is fresh, generated via client credentials flow.

Is there a specific sequence required before calling this? Or maybe the conversation needs to be in a ‘wrap-up’ state first? The docs are a bit light on the pre-conditions for this specific action. It feels like the API expects the agent to already be in a transfer state, but I can’t find an endpoint to set that state explicitly.