Setting wrap-up code via API after conversation ends returns 400 Bad Request

I’m trying to automate the assignment of wrap-up codes for voice interactions using the Genesys Cloud Conversations API. The goal is to trigger this from a webhook when the interaction ends, so agents don’t have to manually select the code in the client.

I’m using the PUT /api/v2/conversations/voice/{conversationId}/wrapup endpoint. I have the conversation ID from the webhook payload. I’m sending a JSON body with the wrapupCodeId and a short description.

Here is the cURL request I am testing with:

curl -X PUT "https://api.mypurecloud.com/api/v2/conversations/voice/abc-123-def/wrapup" \
 -H "Authorization: Bearer <token>" \
 -H "Content-Type: application/json" \
 -d '{
 "wrapupCodeId": "my-wc-id-123",
 "wrapupCodeName": "Voicemail"
 }'

The response is consistently a 400 Bad Request. The error message says:

{
 "errors": [
 {
 "code": "invalid_argument",
 "message": "Wrap-up code ID is invalid or not found in the associated queue."
 }
 ]
}

I’ve verified the wrapupCodeId is correct by querying GET /api/v2/wf/wrapupcodes. The code exists and is associated with the queue the agent is logged into.

Is this endpoint only available for the agent’s session? Or am I missing a required field in the JSON payload? The docs aren’t super clear on what happens if the interaction is already in a completed state when this call is made.

Wrap-up codes usually need to be assigned via the wrap-up endpoint, not the conversation details endpoint. Try using the dedicated /api/v2/conversations/voice/{conversationId}/wrapup endpoint instead.

const wrapup = await platformClient.ConversationsApi.postConversationVoiceWrapup(conversationId, {
 wrapupCodeId: 'your-code-id',
 wrapupText: 'Auto-assigned'
});