The definitive TypeScript SDK for ViciDial. Type-safe, zero-dependency, isomorphic.
92 API functions. 80 response schemas. 7 webhook types. 214 tests. 0 dependencies.
npm install @thornebridge/vicijsViciDial's API returns pipe-delimited plaintext over HTTP GET with credentials in query strings. Every integration today is raw fetch calls, manual string splitting, and zero type safety.
ViciJS fixes all of that:
- Full type safety for every parameter, response, and enum value
- Structured error hierarchy — catch
ViciAuthError,ViciPermissionError,ViciNotFoundError,ViciValidationError,ViciTimeoutErrorindividually - Response schemas — map pipe-delimited output to named fields instantly
- Isomorphic — works in Node.js 18+ and browsers (with CORS configured)
- ESM + CJS dual build with full
.d.tsdeclarations - Tree-shakeable — import only what you use
Control agent sessions — dial, pause, transfer, park, record, hangup.
import { ViciAgent } from '@thornebridge/vicijs';
const agent = new ViciAgent({
baseUrl: 'https://dialer.example.com',
user: 'apiuser',
pass: 'apipass',
agentUser: '1001',
});
await agent.dial({ value: '5551234567', search: 'YES', preview: 'YES' });
await agent.pause('PAUSE');
await agent.transferConference({ value: 'LOCAL_CLOSER', ingroupChoices: 'SALESLINE' });
await agent.parkCall('PARK_CUSTOMER');
await agent.recording({ value: 'START' });
await agent.hangup();
await agent.setStatus({ value: 'SALE' });
await agent.logout();Manage leads, users, campaigns, lists, DIDs, DNC, monitor agents, pull reports.
import { ViciAdmin } from '@thornebridge/vicijs';
const admin = new ViciAdmin({
baseUrl: 'https://dialer.example.com',
user: 'apiuser',
pass: 'apipass',
});
// Leads
await admin.leads.add({ phoneNumber: '5551234567', listId: 101, firstName: 'John' });
await admin.leads.update({ leadId: 12345, status: 'SALE' });
await admin.leads.batchUpdate({ leadIds: '1001,1002,1003', status: 'DNC' });
const lead = await admin.leads.allInfo({ leadId: 12345, customFields: 'Y' });
// Users
await admin.users.add({
agentUser: 'newagent', agentPass: 'pass123',
agentUserLevel: 7, agentFullName: 'New Agent', agentUserGroup: 'AGENTS',
});
// Campaigns
await admin.campaigns.update({ campaignId: 'SALES1', autoDialLevel: '3.0' });
// Real-time monitoring
const status = await admin.monitoring.agentStatus({ agentUser: '1001' });
// Reporting
const stats = await admin.reporting.agentStatsExport({
datetimeStart: '2025-01-01+00:00:00',
datetimeEnd: '2025-01-31+23:59:59',
});
// DNC
await admin.dnc.addPhone({ phoneNumber: '5551234567', campaignId: 'SYSTEM_INTERNAL' });The Admin client organizes 61 functions into 10 domain sub-clients:
| Domain | Methods | Description |
|---|---|---|
admin.leads |
11 | Add, update, search, batch update, dearchive |
admin.users |
6 | Add, update, copy, delete users |
admin.campaigns |
4 | Update campaigns, manage hopper |
admin.lists |
4 | Add, update lists, manage custom fields |
admin.phones |
4 | Add, update phones and aliases |
admin.dids |
3 | Add, copy, update DIDs |
admin.dnc |
4 | DNC and filter phone groups |
admin.monitoring |
6 | Real-time agent/group status, blind monitor |
admin.reporting |
6 | Recordings, stats, call logs |
admin.system |
12 | Version, sounds, CID groups, presets |
The Agent client exposes 31 functions for real-time session control — dialing, transfers, parking, recording, notifications, and more.
Receive and handle ViciDial callback URLs with full type safety. Build callback URLs, parse incoming webhooks, and route events.
import { buildCallbackUrl, buildEventPushUrl, CallbackVariable } from '@thornebridge/vicijs';
// Build a Dispo Call URL with template placeholders
const dispoUrl = buildCallbackUrl({
baseUrl: 'https://hooks.example.com/vici/dispo',
variables: [
CallbackVariable.LEAD_ID,
CallbackVariable.DISPO,
CallbackVariable.PHONE_NUMBER,
CallbackVariable.TALK_TIME,
CallbackVariable.RECORDING_FILENAME,
],
staticParams: { type: 'dispo_callback' },
});
// → "https://hooks.example.com/vici/dispo?type=dispo_callback&lead_id=--A--lead_id--B--&dispo=--A--dispo--B--&..."
// Build an Agent Events Push URL
const eventUrl = buildEventPushUrl('https://hooks.example.com/vici/events', {
type: 'agent_event',
});import { ViciWebhookRouter, AgentEvent } from '@thornebridge/vicijs';
const router = new ViciWebhookRouter();
// Handle by webhook type
router.on('dispo_callback', (payload) => {
console.log(`Lead ${payload.lead_id} dispositioned as ${payload.dispo}`);
console.log(`Talk time: ${payload.talk_time}s`);
});
router.on('start_call', (payload) => {
console.log(`Call started for ${payload.phone_number}`);
});
// Handle specific agent events
router.onEvent(AgentEvent.CALL_ANSWERED, (payload) => {
console.log(`Agent ${payload.user} answered a call`);
});
router.onEvent(AgentEvent.DISPO_SET, (payload) => {
console.log(`Agent ${payload.user} set disposition`);
});
// Express integration
app.get('/vici/webhook', (req, res) => {
router.handle(req.url); // auto-detects type from ?type= param
res.send('OK');
});All 7 webhook types are supported: agent_event, dispo_callback, start_call, no_agent, add_lead, dead_call, pause_max. Each has a fully typed payload with 90+ available callback variables.
Every error is typed. Every error preserves the raw ViciDial response.
import {
ViciError, // Base — catches everything
ViciAuthError, // Invalid credentials
ViciPermissionError, // Insufficient access level
ViciNotFoundError, // Resource doesn't exist
ViciValidationError, // Bad params, duplicates, disabled features
ViciHttpError, // Non-2xx HTTP status
ViciTimeoutError, // Request exceeded timeout
} from '@thornebridge/vicijs';
try {
await admin.leads.add({ phoneNumber: '5551234567', listId: 101 });
} catch (err) {
if (err instanceof ViciTimeoutError) {
console.log(`Timed out after ${err.timeoutMs}ms`);
} else if (err instanceof ViciValidationError) {
console.log('Validation failed:', err.details);
console.log('Raw response:', err.raw);
} else if (err instanceof ViciAuthError) {
console.log('Check your credentials');
}
}ViciDial returns pipe-delimited text. Use the built-in schemas to map positional fields to named properties:
import { mapFields, ADMIN_SCHEMAS, AGENT_SCHEMAS } from '@thornebridge/vicijs';
const result = await admin.leads.allInfo({ leadId: 12345 });
const lead = mapFields(result.rawData, ADMIN_SCHEMAS.lead_all_info);
lead.first_name; // 'John'
lead.phone_number; // '5551234567'
lead.status; // 'SALE'
lead.email; // 'john@example.com'
// VERSION responses auto-parse into data
const version = await admin.system.version();
version.data.version; // '2.4-34'
version.data.build; // '250720-1841'86 status codes, 49 agent events, 103 callback variables, and 30+ parameter enums — all typed.
import { AgentStatus, SystemStatus, AgentEvent } from '@thornebridge/vicijs';
AgentStatus.SALE // 'SALE'
AgentStatus.DNC // 'DNC'
SystemStatus.NEW // 'NEW'
SystemStatus.CALLBK // 'CALLBK'
AgentEvent.CALL_ANSWERED // 'call_answered'
AgentEvent.DISPO_SET // 'dispo_set'
AgentEvent.LOGGED_IN // 'logged_in'
AgentEvent.PARK_STARTED // 'park_started'interface ViciConfig {
baseUrl: string; // ViciDial server URL
user: string; // API username
pass: string; // API password
source?: string; // Call source identifier (max 20 chars, default: 'vicijs')
timeout?: number; // Request timeout ms (default: 30000)
fetch?: typeof fetch; // Custom fetch for testing/proxying
}
// Agent client extends with:
interface AgentConfig extends ViciConfig {
agentUser: string; // Agent session to control
}For browser usage, configure CORS on your ViciDial server. See the ViciDial CORS docs. Never set $CORS_allowed_origin to '*'.
Full API reference with every parameter, type, and enum value documented:
Every parameter, enum value, and function name has been cross-referenced against the official ViciDial documentation:
| Document | What We Verified | Result |
|---|---|---|
| Agent API (51KB) | 31 functions, 29 response schemas | Fully verified |
| Non-Agent API (168KB) | 61 functions, 51 response schemas | Fully verified |
| Status Codes | 86 disposition codes across 12 categories | 86/86 match |
| Agent Events | 49 push event types | 49/49 match |
| Callback URLs | 103 template variables, 7 trigger types | 103/103 match |
| Custom Fields | 8 field types | 8/8 match |
AGPL-2.0 (matching ViciDial's license)
Built by Thornebridge