Trying to update participant attributes mid-conversation via PATCH /api/v2/conversations/{conversationId}/participants/{participantId}. The body is {"customAttributes": {"crmId": "123"}} but I get a 400 Bad Request saying customAttributes is not a valid field for this endpoint. The docs show it in the ConversationParticipant schema. Am I missing a header or is this endpoint actually read-only for attributes? Here’s the raw request body I’m sending.
{
"customAttributes": {
"crmId": "123"
},
"routing": {
"queue": {
"id": "your-queue-id"
}
}
}
The endpoint isn’t read-only, but the validation engine is stricter than the schema docs imply. You can’t just send customAttributes alone. The API expects a full ConversationParticipant object structure, and if you’re updating an active participant, omitting the routing block or other required fields often triggers that generic 400. Try including the existing routing data in your payload. It’s a UI quirk that carries over to the API layer. The docs show the field exists, but they don’t always highlight the conditional requirements for partial updates.
You’re right, nailed it. The endpoint isn’t read-only, but you definitely can’t just send a partial object. It’s strict about the structure.
If you’re using the PureCloud SDK (Node/JS), you don’t actually need to manually construct that full JSON blob. The patchConversationParticipant method handles the serialization. You just pass the ID and a ParticipantPatchRequest object.
Here’s how I usually handle it in the desktop app logic:
const api = PlatformClient.ConversationsApi;
const patchRequest = new PlatformClient.ParticipantPatchRequest({
customAttributes: {
crmId: "123"
}
});
// You still need to ensure routing is valid if the participant is active
// but the SDK often fills in defaults if you fetch first
api.patchConversationParticipant(conversationId, participantId, patchRequest);
The catch is that if the participant is currently in a queue or active state, you might need to include the routing object with the current queue ID to avoid validation errors, exactly as mentioned above. Try fetching the participant first, cloning the object, updating the attribute, and then patching. It’s a bit more verbose but saves the 400 headaches.