Customer Service

CS Widget

CDN script or @starim-io/cs-widget; both need a site appKey.

pnpm add @starim-io/cs-widget
import StarIMCS, { ApiError } from '@starim-io/cs-widget'

await StarIMCS.init({ appKey: 'sk_xxx', apiBase: 'https://<your-api-host>' })

StarIMCS.on('conversation:end', (event) => console.log(event))
StarIMCS.on('conversation:new', (event) => console.log(event))

try {
  const result = await StarIMCS.endConversation()
  console.log(result.conversation.customerService.stateVersion)
  StarIMCS.startNewConversation()
} catch (error) {
  if (error instanceof ApiError) console.error(error.code)
}

Panel vs. conversation

  • close() only collapses the panel. It never ends the support conversation.
  • endConversation() ends the current business conversation and resolves with VisitorEndConversationResult. Pending sends/uploads block the operation until they finish.
  • After a successful end, call startNewConversation(). The next successfully sent message creates and binds a new conversation.

Lifecycle events

conversation:end {
  conversationId, closeReason?,
  closedBy: 'visitor' | 'agent' | 'system',
  satisfactionStatus, remote, alreadyEnded
}
conversation:new { conversationId, previousConversationId }

conversation:end fires at most once per conversation generation. remote=true means the close arrived from the service side. conversation:new fires only after the first message succeeds and the new ID is bound.

Precondition and errors

Call visitor end after the handshake returns capabilities.visitorEndConversation === true. Common codes include CS_CAPABILITY_UNAVAILABLE, CS_CONVERSATION_UNAVAILABLE, CS_CONVERSATION_ID_MISMATCH, CS_CONVERSATION_NOT_FOUND, CS_CONVERSATION_ENDED, CS_CONVERSATION_STILL_OPEN, CS_CONVERSATION_BUSY_LOCAL, CS_CONVERSATION_STATE_CHANGED, CS_CONVERSATION_BUSY, and CS_FEATURE_DISABLED.

apiBase is the brand gateway origin without /api/v1. Prefer the snippet from the CS console. Customer service is not enabled on every brand deployment.