The Headless SDK provides a real-time, event-driven interface for embedding customer support chat into web applications. It manages agent sessions, streams live conversation and messaging events, and exposes actions for sending messages, updating conversation state, and controlling agent availability.
The SDK is built around a single client instance that you initialise with a session, subscribe to events via a callback, and control via action methods.
Installation
npm install @liveperson/headless-sdk
Quick Start
import { MessagingClient } from '@liveperson/headless-sdk';
// 1. Authenticate and instantiate the client
const { client, session } = await MessagingClient.create({
accountId: '12345678',
clientId: 'your-sentinel-client-id',
callbackUrl: `${window.location.origin}/auth-callback.html`,
});
// 2. Register the event callback
client.on({
callback: (event) => {
switch (event.type) {
case 'conversation/ring':
handleRing(event.value);
break;
case 'message/receive':
handleMessage(event.value);
break;
// ...other callback event handlers
}
},
});
// 3. Connect
await client.connect();
// 4. Disconnect when done
await client.disconnect();
// 5. Send an action
await client.dispatch({
action: 'message/send',
value: { conversationId: 'conv-123', content: { type: 'text', text: 'Hello!' } },
});
Core Concepts
Session Object
The MessagingClient.create() method resolves with both the client instance and a session object representing the currently authenticated agent.
interface SessionObject {
agentId: string;
accountId: string;
displayName: string;
loginName: string;
roles: string[];
privileges: readonly number[];
features: Readonly<Record<string, boolean>>;
siteSettings: Readonly<Record<string, string>>;
permissions: AgentPermissions;
permissionsReady: boolean;
}
permissions reflects the agent's real access only when permissionsReady is true — it
defaults to all false if account context failed to load during create(). privileges,
features, and siteSettings are the raw, unfiltered sources permissions derives its gated
fields from — most integrators should use permissions rather than reading these directly.
AgentPermissions itself has two sections: actions (per-dispatch-action booleans) and
configuration (derived UI/behavior flags) — see the API Reference for the full shape.
Event System
All real-time events are delivered to a single callback function registered via on(). There is no per-event-type subscription interface — every event category (rings, messages, conversation updates, typing indicators, agent state changes) flows through this one handler as a CallbackEvent with a discriminated type field.
This means your UI is responsible for routing events by type inside the callback:
client.on({
callback: (event) => {
switch (event.type) {
case 'connection/status':
handleConnectionStatus(event.value);
break;
case 'auth/error':
handleAuthError(event.value);
break;
// ... other callback event handlers
}
},
});
function handleConnectionStatus(value: ConnectionStatusValue) {
switch (value.status) {
case 'connected':
showBanner(value.reconnected ? 'Reconnected' : 'Connected');
break;
case 'reconnecting':
showBanner(`Reconnecting (attempt ${value.attempt})…`);
break;
case 'disconnected':
showBanner(`Disconnected: ${value.reason}`);
break;
case 'failed':
showBanner(`Connection failed: ${value.reason}`);
break;
}
}
function handleAuthError(value: AuthErrorValue) {
// value.code: 'TOKEN_EXPIRED' | 'TOKEN_INVALID' | 'REFRESH_FAILED'
promptReLogin(value.message);
}
Events are organized by domain:
| Domain | Events |
|---|---|
| Connection & auth |
connection/status, auth/error, auth/session-taken-over
|
| Session lifecycle |
error, session/end
|
| Conversations |
conversations/update, conversation/ring, conversation/chat-state
|
| Agent state | agent-state/change |
| Messaging |
message/receive, message/status/receive
|
The full set of supported callback events can be found in the API Reference.
Action Dispatch
While on() is the inbound channel — delivering events from the SDK to your UI — dispatch() is the outbound counterpart, used to send actions from your UI to the SDK. Together they form the low-level message bus at the heart of the SDK.
An action is an object with an action string identifying what to do, and a value carrying any associated payload. dispatch() is async — it returns a Promise that resolves with the action's result (void for message/send, a typed value for actions like profile/get or messages/query):
await client.dispatch({
action: 'message/send',
value: { conversationId: 'conv-123', content: { type: 'text', text: 'Hello!' } },
});
Actions that resolve to a value, like profile/get, work the same way — await the promise and handle rejection:
try {
const profile = await client.dispatch({
action: 'profile/get',
value: { userId: 'consumer-456' },
});
console.log(profile.firstName);
} catch (err) {
console.error('Failed to fetch profile:', err);
}
Actions are organized by domain:
| Domain | Actions |
|---|---|
agent-state/* |
get, set, custom away reasons |
conversation/* |
accept, reject, join, leave, close, transfer, resume, chat state, search, notes |
message(s)/* |
send, status, query |
profile/* |
get, set |
account/* |
skills, users, availability |
The full set of supported dispatch actions can be found in the API Reference.