POST /api/v2/conversations/chat/{id}/messages returning 400 for canned response

I’m trying to inject a canned response into an active chat session using the Conversations API. The goal is to automate a standard greeting based on queue wait time. I have the conversation ID and the agent ID. Here is the payload I’m sending to POST /api/v2/conversations/chat/{conversationId}/messages:

{
 "from": {
 "id": "agent-id-here",
 "type": "agent"
 },
 "text": "Thanks for waiting. How can I help?",
 "type": "text"
}

The API returns a 400 Bad Request with the message Invalid message payload. I’ve checked the docs and the structure looks correct. The agent ID is definitely valid and part of the conversation. I’ve also tried adding the cannedResponseId field but that just breaks harder. Is there a specific header or auth scope I’m missing? We’ve got conversation:write on the token. The endpoint works fine for manual messages sent via the UI but not from our script. Running out of ideas.

The 400 error usually means the payload structure doesn’t match the strict schema for that specific endpoint. You are missing the to field, which is required for chat messages in this API version. The system needs to know exactly where the message is going, even if it’s within the same conversation.

Here is the corrected JSON payload. Notice the to object. It must reference the participant ID, not just the conversation ID.

{
 "from": {
 "id": "agent-id-here",
 "type": "agent"
 },
 "to": [
 {
 "id": "participant-id-here",
 "type": "participant"
 }
 ],
 "text": "Thanks for waiting. How can I help?",
 "type": "text"
}

You can get the participant-id by calling GET /api/v2/conversations/chat/{conversationId} and looking at the participants array. Find the entry where Data.queue.id matches your target queue, then grab that participant’s id.

Also, check your OAuth scopes. The token needs conversation:write and chat:write. If you are using a guest token or a restricted app token, it might lack the permission to inject messages as an agent.

One more thing. If you are doing this for automation, consider using the POST /api/v2/conversations/chat/{conversationId}/messages endpoint with the cannedResponseId instead of raw text. It’s cleaner and respects the canned response library settings. But for now, the missing to field is likely the blocker.

Make sure the agent is actually in a “available” or “busy” state in WFM. If the agent is offline or in a break state, the API might reject the injection because the context is invalid. I’ve seen this trip people up when scheduling shifts overlap with automated bot handoffs.

The to field was the missing piece. Added the participant ID and the 400 error vanished immediately.

It’s annoying that the docs don’t explicitly state this requirement for chat messages, but at least it’s working now. Thanks for pointing that out.