We’re building a custom agent desktop using the Embeddable Client App SDK to handle post-call workflows, and I’m hitting a wall trying to programmatically set the wrap-up code for a voice conversation once it ends. The conversation is in the wrapup state, confirmed by polling the status endpoint, but when I attempt to send a PATCH request to /api/v2/conversations/voice/{conversationId} with the updated wrap-up code ID, the server responds with a 409 Conflict. The error payload indicates that the operation is not allowed because the conversation status is invalid or locked, which is confusing since the documentation states wrap-up codes can be assigned during this phase. I’ve double-checked the OAuth token scopes, ensuring conversation:write is included, and the request headers are standard JSON content-type. The payload I’m sending is straightforward, targeting the wrapup object within the conversation resource. It seems like the API might be rejecting the update because the interaction has already transitioned to a closed state on the backend, even if the client-side status hasn’t fully reflected that yet. I’ve tried adding a small delay before the request, but that just results in a 404 Not Found, suggesting the resource is gone. Is there a specific sequence or additional header required to modify the wrap-up code via the REST API after the interaction has technically concluded? The SDK methods for setting wrap-up codes seem to be tied to the active session object, which becomes null once the call drops, leaving the REST API as the only option. I need a reliable way to update this metadata without manual intervention from the agent, as it’s critical for our reporting metrics. The current approach feels like I’m fighting against the state machine, but I can’t find any alternative endpoints or parameters that would allow this modification. Any insights into how the API handles the transition from wrapup to closed would be appreciated, especially regarding the exact window of opportunity for this update. I’ve been staring at the Swagger docs for an hour now and can’t spot the missing piece. The error message doesn’t give much to work with, just a generic conflict indication. It’s possible I’m missing a subtle requirement in the request body structure, maybe related to the interaction ID versus the conversation ID. I’ll paste the exact request and response below for reference. The timestamp on the error also seems to lag behind the actual call end time, which might be relevant. I’m running this from a Node.js backend service that communicates with the frontend app, so network latency isn’t the issue here. The API gateway logs show the request arriving correctly, but the processing fails immediately. I’ve also tried using the wrapupCodeId field directly in the root object, but that results in a 400 Bad Request, saying the field is not recognized. This suggests the structure must be nested under wrapup, which is what I’m doing. I’m out of ideas on what could be causing this specific 409 error in this context. The documentation is sparse on edge cases for wrap-up modifications. I’ve checked the developer community for similar issues, but most posts are about setting wrap-up codes manually or through Architect flows. This programmatic requirement seems to be a gap in the standard examples. I need to know if this is even possible via the REST API or if I should be looking at a different approach entirely. The SDK doesn’t expose a direct method for post-call wrap-up updates, which is why I’m resorting to raw HTTP calls. It feels like I’m missing a fundamental piece of the puzzle. The conversation ID is definitely correct, as I can fetch the details successfully before making the update attempt. The issue is strictly with the modification. I’ve also verified that the wrap-up code ID exists and is active in the organization. No permission errors, just this persistent conflict. I’m starting to think the API might not support this operation at all, despite what the docs imply. Or perhaps there’s a race condition I’m not accounting for. The state change happens so fast that by the time my request reaches the server, the conversation is already locked. I need a definitive answer on whether this is supported and, if so, how to do it correctly. I’ve tried everything I can think of, including different HTTP clients and payload formats. Nothing works. I’m stuck.
The 409 Conflict usually means the API thinks the resource is locked or in an inconsistent state, even if the status says wrapup. In NICE CXone, there’s often a race condition between the conversation state changing to wrapup and the system allowing modifications to the wrap-up code. If you’re hitting it immediately after the state change, you might be too early.
I’d suggest adding a small delay or a retry loop with exponential backoff before sending the PATCH request. Also, double-check that you’re using the correct wrapupCodeId from the POST /api/v2/conversations/voice/{conversationId} response or the GET /api/v2/wrappings endpoint. Sometimes the ID format or scope can cause issues.
Here’s a quick example using the PureCloudPlatformClientV2 SDK in JavaScript to handle this:
const platformClient = require('purecloudplatformclientv2');
async function setWrapUpCode(conversationId, wrapUpCodeId) {
const conversationsApi = new platformClient.ConversationsApi();
const body = {
wrapUpCodeId: wrapUpCodeId,
wrapUpCodeName: "Customer Satisfaction Survey" // Optional, but good for clarity
};
try {
// Wait a bit to ensure the state has fully settled
await new Promise(resolve => setTimeout(resolve, 1000));
await conversationsApi.patchConversationVoice(conversationId, body);
console.log(`Wrap-up code set successfully for conversation ${conversationId}`);
} catch (error) {
if (error.status === 409) {
console.error(`Conflict setting wrap-up code for conversation ${conversationId}. Retrying...`);
// Implement retry logic here
} else {
console.error(`Error setting wrap-up code: ${error.message}`);
}
}
}
Make sure your OAuth token has the conversations:modify scope. If the issue persists, check the x-request-id header in the response and cross-reference it with the CXone logs to see if there’s a specific validation error.