@takesales/sdk
v0.1.33
Published
SDK for integrating Take Sales AI agents into custom UIs
Readme
Take Sales SDK
SDK for integrating Take Sales AI agents into custom UIs. Connect to the agent via WebSocket and build your own chat interface.
Using React? See the React integration guide.
Installation
npm install @takesales/sdkQuick Start
import { TakeSalesClient } from '@takesales/sdk'
const client = new TakeSalesClient({
agentId: 'your-agent-uuid',
wsUrl: 'wss://api-agent.takesales.ai/ws',
})
client.on('connected', () => {
console.log('Agent ready')
client.sendText('Hello!')
})
client.on('agentConfig', (config) => {
console.log('Agent:', config.agentName)
})
client.on('message', (text, endOfTurn) => {
console.log('Agent says:', text)
if (endOfTurn) console.log('--- turn complete ---')
})
client.on('richContent', (content) => {
console.log('Rich content:', content.type, content.data)
})
client.on('error', (err) => {
console.error('Error:', err)
})
client.on('disconnect', (code, reason) => {
console.log('Disconnected:', code, reason)
})
client.connect()API Reference
TakeSalesClient
Framework-agnostic WebSocket client.
Constructor
new TakeSalesClient(config: TakeSalesClientConfig)| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| agentId | string | Yes | Agent UUID |
| wsUrl | string | Yes | WebSocket server URL |
| visitor | object | No | Visitor info (see below) |
| conversationId | string | No | Resume a previous session |
| isTest | boolean | No | Mark as test session |
| clientVariables | Record<string, string> | No | Pre-resolved client variables for tool enrichment |
| clientVariableConfigs | ClientVariableConfig[] | No | Auto-resolve variables from browser (localStorage, cookies, etc.) |
| reconnect | object | No | Reconnection settings |
visitor object:
| Field | Type | Description |
|-------|------|-------------|
| email | string | Visitor email |
| name | string | Visitor name |
| phone | string | Visitor phone |
| contactData | Record<string, string> | Custom contact fields |
reconnect object:
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| enabled | boolean | true | Enable auto-reconnect |
| maxAttempts | number | 5 | Max reconnect attempts |
| baseDelay | number | 1000 | Base delay in ms (exponential backoff) |
Methods
| Method | Description |
|--------|-------------|
| connect() | Open WebSocket connection |
| disconnect() | Close connection (no auto-reconnect) |
| sendText(text) | Send a text message |
| sendFormSubmit(formId, data) | Submit a lead form |
| sendScheduleConfirm(scheduleId, date, time) | Confirm a schedule |
| sendToolConfirmation(confirmationId, confirmed) | Approve/reject a tool action |
| sendUpdateVisitor(data) | Update visitor contact info |
Properties
| Property | Type | Description |
|----------|------|-------------|
| isConnected | boolean | Current connection state |
| conversationId | string \| null | Current session ID |
| agentConfig | ServerAgentConfig \| null | Agent configuration from server |
Events
client.on('connected', () => void)
client.on('message', (text: string, endOfTurn: boolean) => void)
client.on('richContent', (content: RichContent) => void)
client.on('agentConfig', (config: ServerAgentConfig) => void)
client.on('sessionCreated', (data: { conversationId: string }) => void)
client.on('toolConfirmation', (data: ToolConfirmation) => void)
client.on('usageWarning', (data: { message: string, warningType: string }) => void)
client.on('error', (error: string) => void)
client.on('disconnect', (code?: number, reason?: string) => void)Use client.off(event, listener) to remove a listener.
Client Variables
Client variables allow authenticated tools to access data from the visitor's browser (localStorage, cookies, etc.). The SDK supports three modes:
Automatic (recommended)
When no clientVariables or clientVariableConfigs are provided, the SDK automatically fetches the agent's configuration via preflight and resolves variables from the browser — the same behavior as the embedded widget.
const client = new TakeSalesClient({
agentId: 'your-agent-uuid',
wsUrl: 'wss://api-agent.takesales.ai/ws',
// Client variables are resolved automatically from preflight config
})Manual
Pass pre-resolved values directly:
const client = new TakeSalesClient({
agentId: 'your-agent-uuid',
wsUrl: 'wss://api-agent.takesales.ai/ws',
clientVariables: {
auth_token: localStorage.getItem('token') ?? '',
user_id: '12345',
},
})Config-based
Pass extraction configs (same format as the dashboard):
import { type ClientVariableConfig } from '@takesales/sdk'
const client = new TakeSalesClient({
agentId: 'your-agent-uuid',
wsUrl: 'wss://api-agent.takesales.ai/ws',
clientVariableConfigs: [
{ name: 'auth_token', source: 'localStorage', key: 'token' },
{ name: 'user_id', source: 'cookie', key: 'uid' },
],
})Supported sources: localStorage, sessionStorage, cookie, window, querySelector, meta.
If both clientVariables and clientVariableConfigs are provided, manual values take precedence.
Rich Content Types
The agent can send rich content alongside text messages. Each type has a specific data shape:
Carousel
{ type: 'carousel', data: CarouselCard[] }
interface CarouselCard {
title: string
description?: string
imageUrl?: string
url: string
price?: string
address?: string
area?: string
bedrooms?: number
images?: string[]
}Quick Replies
{ type: 'quick_replies', data: QuickReplyOption[] }
interface QuickReplyOption {
label: string
value: string
}Usage: render buttons and call sendText(option.value) on click.
Lead Form
{ type: 'lead_form', data: LeadFormCard }
interface LeadFormCard {
formId: string
fields: Array<{
key: string
type: 'text' | 'email' | 'phone' | 'textarea'
label: string
placeholder?: string
required: boolean
}>
submitLabel?: string
successMessage?: string
}Usage: render a form and call sendFormSubmit(formId, data) on submit.
Schedule Form
{ type: 'schedule_form', data: ScheduleFormCard }
interface ScheduleFormCard {
availableSlots: Array<{ date: string; times: string[] }>
propertyTitle?: string
scheduleId?: string
}Usage: render date/time picker and call sendScheduleConfirm(scheduleId, date, time).
Inline Map
{ type: 'inline_map', data: InlineMapCard }
interface InlineMapCard {
lat: number
lng: number
address: string
zoom?: number
googleMapsApiKey?: string
}Photo Gallery
{ type: 'photo_gallery', data: PhotoGalleryCard }
interface PhotoGalleryCard {
images: string[]
title?: string
}Comparator
{ type: 'comparator', data: ComparatorCard }
interface ComparatorCard {
properties: Array<{
title: string
url?: string
imageUrl?: string
price?: string
area?: string
bedrooms?: number
bathrooms?: number
differentials?: string[]
}>
}Tool Confirmation
When a tool has risk level confirm, the agent pauses execution and sends a confirmation event before proceeding. In the embedded widget, a confirmation card appears automatically in the chat. If you're using the SDK, you need to listen for the event and build your own UI.
{ type: 'tool_confirmation', data: ToolConfirmation }
interface ToolConfirmation {
confirmationId: string
toolName: string
message: string
details?: Record<string, unknown>
}Example:
// 1. Listen for the confirmation event
client.on('toolConfirmation', (data) => {
// data.toolName → tool name (e.g. "cancel_subscription")
// data.message → action description
// data.details → parameters to be sent (e.g. { userId: "123" })
// Show a confirmation dialog/card in your UI
showConfirmDialog({
title: data.toolName,
message: data.message,
params: data.details,
onConfirm: () => client.sendToolConfirmation(data.confirmationId, true),
onCancel: () => client.sendToolConfirmation(data.confirmationId, false),
});
});If the visitor confirms, the tool executes normally. If they cancel, the agent receives a notice and continues the conversation without executing the action.
Agent Config
After connecting, you receive the agent configuration from the server:
interface ServerAgentConfig {
agentId: string
workspaceId: string
agentName: string
greeting: string
avatarUrl: string | null
language: string
enableVoice: boolean
enableTextChat: boolean
collectVisitorEmail: boolean
collectVisitorName: boolean
collectVisitorPhone: boolean
quickReplies?: string[]
primaryColor?: string
secondaryColor?: string
textColor?: string
backgroundColor?: string
title?: string
subtitle?: string
// ... and more
}Use this to style your UI, show the greeting, and configure contact collection.
Connection Lifecycle
connect()
|
v
Preflight fetch (auto-discovers client variable configs)
|
v
WebSocket open
|
v
Service setup sent (agent_id + visitor info + client variables)
|
v
Server sends: agentConfig --> 'agentConfig' event
Server sends: sessionCreated --> 'sessionCreated' event
|
v
Session setup sent (text-only mode)
|
v
Server sends: setupComplete --> 'connected' event
|
v
Ready to send/receive messages
|
v
disconnect() or connection lost
|
v
Auto-reconnect (exponential backoff, up to 5 attempts)Security
Authentication uses the same model as Google Maps or Stripe.js:
agentIdis a public identifier (UUID) embedded in client code- Origin validation is enforced server-side via the agent's allowed origins list
- Configure allowed origins in the Take Sales dashboard under Agent Settings
No API keys or bearer tokens are needed for client-side usage.
Examples
Resuming a session
const savedId = localStorage.getItem('conversationId')
const client = new TakeSalesClient({
agentId: 'your-agent-uuid',
wsUrl: 'wss://api-agent.takesales.ai/ws',
conversationId: savedId ?? undefined,
})
client.on('sessionCreated', ({ conversationId }) => {
localStorage.setItem('conversationId', conversationId)
})
client.connect()With visitor identification
const client = new TakeSalesClient({
agentId: 'your-agent-uuid',
wsUrl: 'wss://api-agent.takesales.ai/ws',
visitor: {
email: '[email protected]',
name: 'John Doe',
phone: '+5511999999999',
},
})
client.connect()