I’m trying to kick off a cobrowse session programmatically from our custom agent desktop. The goal is to start the session immediately after the agent accepts an inbound chat, so the customer sees the prompt without any manual clicks on the agent side.
I’ve got the token sorted using client credentials flow, and I can query conversation details just fine. The issue is hitting the creation endpoint. I’m sending a POST to /api/v2/conversations/cobrowse/sessions with the following JSON body:
{
"conversationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"initiatorId": "98765432-1234-5678-9abc-def012345678",
"reason": "Debugging UI issue"
}
The conversationId is confirmed active and has a chat leg. The initiatorId matches the agent’s user ID exactly. I’ve double-checked the casing.
The response I get back is a 400 Bad Request. The error payload isn’t super helpful:
{
"errors": [
{
"code": "invalid_request",
"message": "Unable to start cobrowse session for conversation."
}
]
}
I’ve tried a few things:
- Verified the service account has
cobrowse:session:write scope. It does.
- Checked the conversation state. It’s
ACTIVE.
- Tried including
targetUserId in the payload. Same result.
- Manually started a cobrowse from the native desktop for that same conversation. It works instantly.
Is there a specific requirement for the chat leg? The docs mention the session must be attached to a conversation with an active interaction, but I’m assuming that’s satisfied here. I’m also wondering if the initiatorId needs to be the customer’s ID instead of the agent’s, but that feels counter-intuitive since the agent is initiating.
Any ideas on what’s missing?
The 400 error usually comes down to the externalSessionId being missing or duplicated. You need to ensure that ID is unique for every attempt, otherwise the API rejects it outright. Also, double-check that your OAuth token has the cobrowse:write scope. Without it, the endpoint will fail silently or throw a generic bad request. Here is the minimal JSON payload structure that works reliably in my tests.
{
"externalSessionId": "unique-id-123",
"participantId": "agent-user-id-here",
"consentStatus": "CONSENTED"
}
Make sure participantId matches the actual user ID of the agent, not their email. I spent an hour debugging this last week because I was passing the conversation ID instead. It’s a subtle difference that breaks the whole request. The consentStatus field is also mandatory in the current API version. If you leave it out, you get the exact same 400 response.
Wait, hold on. You mentioned using the client credentials flow in the first post. That’s likely your root issue here. Cobrowse sessions require a specific user context to map the session to an active agent or customer identity. Client credentials tokens are service-to-service and don’t carry that user identity, which often triggers a 400 because the system can’t resolve who is initiating the session. You’ll need to switch to a user credentials flow or use a user impersonation token if you’re doing this via a backend service. Also, double-check the externalSessionId format. It needs to be a valid GUID or unique string, not null. Here’s what the corrected payload looks like with the proper scope cobrowse:write and a user-bound token.
{
"externalSessionId": "uuid-v4-here",
"initiator": {
"type": "agent",
"id": "agent-user-id"
},
"target": {
"type": "customer",
"conversationId": "active-chat-id"
}
}
Make sure the conversationId matches the active chat.