POST /api/v2/conversations/{conversationId}/wrap-up returns 400 Bad Request

Hey folks,

I’m trying to set a wrap-up code programmatically for a chat conversation after it ends. I’ve got a Node.js service listening to the CONVERSATION_UPDATED webhook. When the event shows state: 'ended', my code fires off a request to the Genesys Cloud API to apply the wrap-up.

The problem is I keep getting a 400 Bad Request response. The error message is pretty vague:

{
 "errors": [
 {
 "code": "bad_request",
 "message": "Invalid wrap-up code or interaction state."
 }
 ]
}

Here’s the relevant snippet from my code:

const setWrapUp = async (conversationId, wrapUpCodeId) => {
 const response = await fetch(
 `https://api.mypurecloud.com/api/v2/conversations/${conversationId}/wrap-up`,
 {
 method: 'POST',
 headers: {
 'Content-Type': 'application/json',
 'Authorization': `Bearer ${accessToken}`
 },
 body: JSON.stringify({
 wrapUpCodeId: wrapUpCodeId
 })
 }
 );
 return response.json();
};

I’ve verified the wrapUpCodeId is valid by checking it against the list from GET /api/v2/conversations/wrapupcodes. The token has conversations:write scope.

I’ve tried the following:

  • Waiting 1 second after the ended event fires before sending the request. Same error.
  • Checking if the conversation is actually in ended state via GET /api/v2/conversations/{id}. It is.
  • Trying to set the wrap-up immediately in the webhook handler. Still 400.
  • Using the Python SDK client.conversations_api.post_conversations_wrap_up. Same result.

Is there a specific state transition I’m missing? Or does the API require a different payload structure for chats vs calls? I feel like I’m hitting a timing issue, but the docs don’t mention a delay requirement.

Any ideas?

Check the state in your payload. It needs to be wrapup not ended. If the conversation is already marked ended by the system, the API rejects the update because that state is final. Try sending { "state": "wrapup", "wrapupCode": { "id": "your-code-id" } } instead.