Pushing proactive web messages to a guest with an existing session ID

Hey folks,

Trying to send a proactive message to a customer who’s already got an open web messaging session. The docs are a bit light on this, so I’m using the POST /api/v2/conversations/messages/{integrationId}/inbound/open/message endpoint. I’m passing the externalContactId from the previous session, but I keep getting a 409 Conflict saying the contact is already engaged.

Here’s the payload:

{
 "to": [{"id": "ext_contact_id_here"}],
 "text": "Hey, need help?"
}

Am I missing a flag to force the send, or is there a different endpoint for this?

You’re hitting the 409 because you’re trying to create a new conversation resource for a contact that’s already active in an existing one. The API sees the externalContactId and says, “Hey, this person is already in a chat, don’t spawn another one.”

The docs for creating a new messaging conversation are clear: that’s not what you want. You want to inject a message into the existing session.

Since you have the sessionId (which is basically the conversationId in Genesys terms), you should be using the specific endpoint for adding parts to a conversation. In C#, it looks like this:

var client = PlatformClientFactory.BuildFromConfiguration();
var body = new WebchatMessagePart
{
 From = new ExternalId { Id = "agent-system-id" },
 To = new ExternalId { Id = guestExternalContactId },
 Type = "customer",
 Text = new List<PlainText> { new PlainText { Text = "Hello from the system!" } }
};

try
{
 await client.ConversationsMessagingApi.PostConversationsMessagingPartsAsync(
 conversationId: existingSessionId, 
 body: body
 );
}
catch (ApiException ex)
{
 // Handle errors
}

Notice I’m using PostConversationsMessagingPartsAsync. This appends the message to the ongoing thread. The From field needs to match a valid participant or system ID depending on your setup, but usually, if it’s a proactive system message, you might need to ensure the routing queue or agent is actually part of that conversation context if you want it to appear as an agent message. If it’s just a bot/system ping, make sure the Type aligns with your widget config.

Also, check if the session is actually still active. If the guest closed the widget but the server session is lingering, you might still get a conflict. Query the conversation status first. You can retrieve the messages for the session to verify its state and content. If the conversation is closed, you can’t push to it. You’d have to start fresh, but that won’t link to the old history unless you use the previousConversationId param in the new POST, which is a different beast entirely.

2 Likes