Web Messaging SDK startChat() not persisting CRM ID in custom attributes

Does anyone know how to properly inject a CRM customer ID into the Genesys Cloud Web Messaging SDK session so it persists to the routing attributes? I am trying to pass a specific crm_id value via the startChat() method, but the agent console shows empty fields for this attribute upon transfer. I am using the standard embed script and initializing the conversation flow from a custom landing page. The documentation suggests using the customAttributes object, but I am unsure if the structure is correct for the SDK’s internal JSON mapping. Here is my initialization code:

const config = {
 brandId: 'abc-123',
 conversationId: null,
 customAttributes: {
 crm_id: 'CUST-998877',
 source: 'web_direct'
 }
};

genesysCloudMessaging.startChat(config);

When I inspect the network traffic, the POST request to /api/v2/conversations/messaging includes the payload, but the customAttributes object seems to be stripped or ignored during the routing phase. I also tried setting the attribute via the data parameter in the embed configuration, but that only affects the UI, not the backend routing data. I am getting a 200 OK on the chat start, but when I query the conversation details via the Conversations API using the conversationId, the customAttributes field is missing the crm_id.

Is there a specific scope or configuration flag required in the brand settings to allow external custom attributes? Or is the startChat method signature different in the latest SDK version? I am confused because the client_credentials flow for my backend APIs works fine with similar payloads, but the guest-facing SDK behaves differently. I need this ID to trigger a specific Studio flow path based on the customer’s tier. Any code examples or SDK method adjustments would be appreciated. I have been stuck on this for two days and cannot find a working example in the community docs.

As far as I remember, the customAttributes object passed directly to startChat() is often treated as transient session metadata by the Web Messaging SDK unless explicitly mapped to routing attributes in the Conversation Routing configuration. In my Angular enterprise desktop implementation, I found that simply injecting the CRM ID via the SDK client-side does not guarantee persistence to the routing_attributes payload sent to the Genesys Cloud backend.

You must ensure the attribute is defined in the Conversation Flow or Routing Configuration as a specific attribute name (e.g., crm_id). However, the SDK’s startChat method sometimes requires the data to be passed via the data property of the ChatStartOptions object, not just customAttributes.

Here is the corrected initialization pattern using the pure JavaScript SDK within an Angular service context:

import { Client, Chat } from '@genesyscloud/web-messaging-sdk';

async function initiateChatWithCRM() {
 const client = new Client({
 orgId: 'your-org-id',
 appId: 'your-app-id'
 });

 await client.login();

 const chat = new Chat(client);
 
 // Ensure the attribute key matches your Routing Configuration exactly
 const crmId = 'CRM-12345'; 
 
 await chat.startChat({
 to: 'your-flow-id',
 data: {
 crm_id: crmId // Use 'data' for routing attributes
 },
 // Do not rely solely on customAttributes for routing
 customAttributes: {
 source: 'angular-desktop'
 }
 });
}

Verify that your Conversation Flow has an Set Attribute or Routing step that explicitly reads crm_id from the incoming payload. If the attribute is not defined in the flow, it will be stripped during the routing decision. Additionally, check that your OAuth scopes include conversation:view and routing:conversation to allow the desktop app to read these attributes post-transfer.

  • Conversation Flow attribute mapping
  • Web Messaging SDK startChat payload structure
  • Routing attribute persistence rules
  • Angular service OAuth scope validation

The problem here is relying solely on client-side SDK injection without backend validation. The suggestion above is correct; transient metadata drops if the routing config doesn’t explicitly map it. You must ensure the crm_id key exists in your Conversation Flow’s routing attribute schema. If it’s missing, the API strips it during the handoff.

Verify your flow using the PureCloudPlatformClientV2 SDK to check the routing configuration:

const routingApi = platformClient.RoutingApi;
const flowId = 'your-flow-id';
const flow = await routingApi.routingFlowGet(flowId, true);
console.log(flow.routings);

Ensure the attribute is defined in the routingAttributes object within the flow JSON. If you are using a custom Digital First Omnichannel channel, you also need to map this attribute in the DFO channel settings under routingAttributes. If the key isn’t whitelisted in the routing config, the payload is sanitized before reaching the agent. Check the raw payload in the Genesys Cloud logs to confirm what actually arrived.

messaging.setParticipantAttribute('crm_id', '12345');
messaging.startChat();

You need to use setParticipantAttribute before calling startChat. The docs state that customAttributes in the start payload are transient and do not persist to routing. Using the explicit setter binds the attribute to the session object correctly, ensuring it survives the handoff to Genesys Cloud.

The problem here is assuming sdk attributes equal routing attributes. they are distinct. setparticipantattribute sets session state, not routing. you must map it in the flow. check /api/v2/conversations/flows/flowId to verify the attribute exists in the routing schema. without it, the backend ignores the sdk payload. verify via analytics api.