Examples
Annotated walkthroughs of the example scripts in the examples/ directory.
Lead Import Pipeline
File: examples/lead-import.ts — Bulk lead insertion with retry, error handling, and verification via auto-pagination.
Setup
import { Convoso, ConvosoApiError } from 'convoso-js';
const client = new Convoso({
authToken: process.env.CONVOSO_AUTH_TOKEN!,
maxRetries: 3, // Retry on 429/5xx errors
onRequest: (path) => console.log(`-> POST ${path}`),
onResponse: (path, _res, data) =>
console.log(`<- ${path}`, JSON.stringify(data).slice(0, 100)),
});Hooks are configured to log every request/response — useful for debugging bulk operations.
Inserting Leads
const leads = [
{ list_id: '1001', phone_number: '5551234567', first_name: 'Jane', last_name: 'Doe' },
{ list_id: '1001', phone_number: '5559876543', first_name: 'John', last_name: 'Smith' },
{ list_id: '1001', phone_number: '5555551234', first_name: 'Alice', last_name: 'Brown' },
];
const results = { success: 0, failed: 0, errors: [] as string[] };
for (const lead of leads) {
try {
const response = await client.leads.insert({
...lead,
check_dup: 1, // Check for duplicates
check_dnc: true, // Check against DNC list
});
console.log(`Inserted lead ${response.id} (${lead.first_name} ${lead.last_name})`);
results.success++;
} catch (err) {
if (err instanceof ConvosoApiError) {
const desc = err.description ?? err.message;
console.error(`Failed: ${lead.phone_number} — ${desc} (code ${err.code})`);
results.errors.push(`${lead.phone_number}: ${desc}`);
} else {
throw err; // Re-throw non-API errors
}
results.failed++;
}
}Key patterns:
err.descriptionprovides human-readable error descriptions from the SDK's built-in code tablecheck_dupandcheck_dncare optional insert parameters that trigger server-side validation- Non-API errors are re-thrown — only business logic errors are caught and logged
Verification with Auto-Pagination
let count = 0;
for await (const lead of client.leads.searchAll({ list_id: '1001', pageSize: 50 })) {
count++;
}
console.log(`Total leads in list 1001: ${count}`);Uses searchAll() to iterate through all leads in the list without managing pagination manually.
DNC List Sync
File: examples/dnc-sync.ts — Sync a local Do-Not-Call list with the Convoso API.
Fetching Existing Entries
import { Convoso, ConvosoApiError, CONVOSO_ERROR_CODES } from 'convoso-js';
const client = new Convoso({
authToken: process.env.CONVOSO_AUTH_TOKEN!,
maxRetries: 2,
});
// Build a Set of all existing DNC phone numbers
const existing = new Set<string>();
for await (const entry of client.dnc.searchAll({
campaign_id: '500',
pageSize: 200,
})) {
existing.add(entry.phone_number);
}
console.log(`Found ${existing.size} existing DNC entries`);Using searchAll() with a Set is the most efficient way to check for existing records when you need to compare against a local list.
Inserting Missing Numbers
const numbersToBlock = ['5551112222', '5553334444', '5555556666', '5557778888'];
const toAdd = numbersToBlock.filter((num) => !existing.has(num));
for (const phone of toAdd) {
try {
const result = await client.dnc.insert({
phone_number: phone,
phone_code: '1',
campaign_id: '500',
reason: 'External DNC list sync',
});
console.log(`Added ${phone} (DNC ID: ${result.id})`);
} catch (err) {
if (err instanceof ConvosoApiError) {
console.warn(`Skipped ${phone}: ${err.description ?? err.message}`);
} else {
throw err;
}
}
}The pattern of fetch-all → diff → insert-missing ensures idempotent syncs that can be run repeatedly.
Agent Monitoring Dashboard
File: examples/agent-dashboard.ts — Real-time agent status polling with formatted output.
Polling Loop
const client = new Convoso({
authToken: process.env.CONVOSO_AUTH_TOKEN!,
maxRetries: 2,
onResponse: (_path, _res, data) => {
const d = data as Record<string, unknown>;
if (d.success === false) {
console.warn('API returned unsuccessful response');
}
},
});
const POLL_INTERVAL_MS = 10_000; // 10 seconds
while (true) {
const monitor = await client.agentMonitor.search();
console.log(`Total agents: ${monitor.total_agents}`);
console.log(`In call: ${monitor.agents_in_call}`);
console.log(`Ready: ${monitor.agents_ready}`);
console.log(`Paused: ${monitor.agents_paused}`);
for (const agent of monitor.agents) {
const name = agent.full_name.padEnd(22);
const status = (agent.status_label ?? agent.status).padEnd(15);
const campaign = (agent.campaign_name ?? '—').padEnd(15);
const duration = agent.status_time_mmss ?? '—';
console.log(`${name} ${status} ${campaign} ${duration}`);
}
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
}Key patterns:
- Response hook catches unsuccessful responses for alerting
agentPerformance.search()is called alongsideagentMonitorfor a combined dashboard- The polling interval should respect Convoso's rate limits — 10 seconds is a safe default
Running the Examples
All examples use npx tsx for direct TypeScript execution:
# Set your auth token
export CONVOSO_AUTH_TOKEN=your_token_here
# Run an example
npx tsx examples/lead-import.ts
npx tsx examples/dnc-sync.ts
npx tsx examples/agent-dashboard.ts