Reference · TypeScript SDK
SDK reference.
The official OnCallClerk TypeScript/JavaScript SDK. Fully typed, Promise-based, and compatible with Node.js, Deno, and edge runtimes.
Installation
Install via your preferred package manager:
Initialization
Create a client instance with your API key. All methods are available as properties on the client object.
import OnCallClerk from '@oncallclerk/sdk'
const client = new OnCallClerk({
apiKey: process.env.ONCALLCLERK_API_KEY,
// Optional configuration
baseUrl: 'https://api.oncallclerk.com', // default
timeout: 30000, // ms, default 30s
})Constructor Options
apiKeyrequiredYour OnCallClerk API key.
baseUrlOverride the API base URL. Defaults to 'https://api.oncallclerk.com'.
timeoutRequest timeout in milliseconds. Defaults to 30000.
client.agents
Create, update, list, and delete AI voice agents.
agents.list()
Retrieve all voice agents on your account.
const agents = await client.agents.list()
for (const agent of agents) {
console.log(agent.id, agent.agent_name, agent.status)
}agents.get(agentId)
Retrieve a single agent by ID.
agentIdrequiredThe unique identifier of the agent.
const agent = await client.agents.get('agt_abc123')
console.log(agent.business_name) // 'Acme Corp'
console.log(agent.phone_number) // '+14155551234'agents.create(config)
Create and deploy a new voice agent.
business_namerequiredThe business name the agent represents.
agent_namerequiredA friendly name for the agent.
voice_idrequiredThe voice to use. Get IDs from client.voices.list().
greetingrequiredThe greeting spoken when answering.
system_promptrequiredInstructions defining agent behavior.
escalation_policy'never' | 'complex' | 'requested' | 'always'. Defaults to 'never'.
forwarding_numberNumber to forward calls to on escalation.
escalation_numberDedicated escalation number.
business_hoursOperating hours. Omit for 24/7.
faqArray of {question, answer} pairs.
voice_settingsAdditional voice config (personality, name).
functions_enabledEnable built-in tool functions.
const agent = await client.agents.create({
business_name: 'Acme Corp',
agent_name: 'After-Hours Support',
voice_id: 'KR1TkIhkSykEjI4B0DtH', // Sarah
greeting: 'Thanks for calling Acme Corp after hours.',
system_prompt: `You are the after-hours support agent for Acme Corp.
Take messages and let callers know someone will follow up
during business hours.`,
escalation_policy: 'requested',
forwarding_number: '+14155559876',
business_hours: {
enabled: true,
timezone: 'America/New_York',
schedule: {
monday: { open: '17:00', close: '09:00', enabled: true },
tuesday: { open: '17:00', close: '09:00', enabled: true },
// ...
},
},
faq: [
{
question: 'When will someone call me back?',
answer: 'A team member will return your call the next business day by noon.',
},
],
})
console.log(agent.id) // 'agt_def456'
console.log(agent.status) // 'active'agents.update(agentId, config)
Update an existing agent. Only pass the fields you want to change.
const updated = await client.agents.update('agt_abc123', {
greeting: 'Hey! Thanks for calling Acme Corp.',
escalation_policy: 'always',
})
console.log(updated.greeting) // updated greetingagents.delete(agentId)
Permanently delete an agent and release its phone number.
await client.agents.delete('agt_abc123')
// Agent and all associated data removedagents.assignPhone(agentId, phoneNumber)
Assign or change the phone number for an agent.
agentIdrequiredThe agent to assign the number to.
phoneNumberrequiredE.164 formatted number (e.g. '+14155551234').
// First, find an available number
const numbers = await client.phoneNumbers.search({ country: 'US', areaCode: '415' })
// Then assign it to an agent
await client.agents.assignPhone('agt_abc123', numbers[0].phoneNumber)Function Management
agents.listFunctions(agentId)
List all available functions for an agent.
agentIdrequiredThe agent ID.
const functions = await client.agents.listFunctions(agent.id)
for (const fn of functions) {
console.log(fn.function_name, fn.enabled)
}agents.enableFunction(agentId, functionName, options)
Enable or configure a function on an agent.
agentIdrequiredThe agent ID.
functionNamerequiredFunction name (e.g. 'scheduleMeeting', 'sendEmail', 'captureLead').
options.enabledrequiredWhether to enable the function.
options.configFunction-specific configuration.
options.paramsFunction-specific parameters.
const fn = await client.agents.enableFunction(agent.id, 'scheduleMeeting', {
enabled: true,
params: {
calendly_url: 'https://calendly.com/acme/30min',
},
})
console.log(fn.function_name, fn.enabled) // 'scheduleMeeting' trueagents.disableFunction(agentId, functionName)
Disable a function on an agent.
await client.agents.disableFunction(agent.id, 'scheduleMeeting')
Integration Management
agents.listIntegrations(agentId)
List all integrations for an agent with summary stats.
const { integrations, summary } = await client.agents.listIntegrations(agent.id)
console.log(summary.connected_integrations + '/' + summary.total_integrations + ' connected')
for (const int of integrations) {
console.log(int.function_name, int.connected ? 'connected' : 'disconnected')
}agents.getIntegration(agentId, functionName)
Get detailed information about a single integration.
const detail = await client.agents.getIntegration(agent.id, 'sendGmail') console.log(detail.integration.connected) // true console.log(detail.integration.expired) // false
agents.updateIntegrationConfig(agentId, functionName, params)
Update the configuration parameters for an integration.
const updated = await client.agents.updateIntegrationConfig(agent.id, 'readGoogleSheet', {
spreadsheet_id: '1BxiM...',
tab_name: 'Leads',
header_row: 1,
})Google Sheets Helpers
agents.listSheets(agentId)
Lists Google Sheets accessible to the agent's connected Google account.
const sheets = await client.agents.listSheets(agent.id)
for (const sheet of sheets) {
console.log(sheet.name, sheet.id)
}agents.listSheetTabs(agentId, sheetId)
List all tabs in a Google Sheet.
const tabs = await client.agents.listSheetTabs(agent.id, '1BxiM...')
for (const tab of tabs) {
console.log(tab.title, tab.rowCount + ' rows')
}agents.getSheetHeaders(agentId, sheetId, tabName)
Auto-detects header rows. Returns suggestions scored by likelihood.
const headers = await client.agents.getSheetHeaders(agent.id, '1BxiM...', 'Sheet1') const best = headers.find(h => h.likely_header) console.log(best?.suggested_headers.map(h => h.header_value)) // ['Name', 'Email', 'Phone', 'Notes']
client.phoneNumbers
Search available phone numbers and manage regulatory compliance.
phoneNumbers.search(options)
Search for phone numbers available for purchase.
countryISO country code. Defaults to 'US'.
areaCodeFilter by area code.
containsSearch for numbers containing this string.
pageSizeResults per page (max 50). Defaults to 10.
pagePage number (starts at 0).
// Search for San Francisco numbers
const numbers = await client.phoneNumbers.search({
country: 'US',
areaCode: '415',
pageSize: 5,
})
for (const num of numbers) {
console.log(num.friendlyName, num.capabilities)
}
// (415) 555-1234 { voice: true, SMS: true, MMS: true }
// (415) 555-5678 { voice: true, SMS: true, MMS: false }phoneNumbers.getRegulatoryBundles(country)
Get existing regulatory bundles for a country. Required for acquiring numbers in regulated markets.
const bundles = await client.phoneNumbers.getRegulatoryBundles('GB')
const approved = bundles.filter(b => b.status === 'twilio-approved')
console.log(approved.length, 'approved bundles')phoneNumbers.createRegulatoryBundle(options)
Create a new regulatory bundle for a country with business or individual compliance data.
isoCountryCoderequiredTwo-letter ISO country code.
complianceTypeType of compliance submitter.
complianceDataBusiness or individual details (name, address, etc.).
const bundle = await client.phoneNumbers.createRegulatoryBundle({
isoCountryCode: 'GB',
complianceType: 'business',
complianceData: {
businessName: 'Acme Corp Ltd',
registrationNumber: '12345678',
businessStreet: '10 Downing Street',
businessCity: 'London',
businessPostalCode: 'SW1A 2AA',
businessCountry: 'GB',
repFirstName: 'Jane',
repLastName: 'Doe',
repEmail: 'jane@acmecorp.co.uk',
repPhoneNumber: '+447700900000',
},
})
console.log(bundle.bundleSid) // 'BU...'phoneNumbers.create(options)
Searches for an available number, purchases it, and assigns it to the specified agent in a single call. Convenience wrapper around phoneNumbers.search() + agents.assignPhone().
agent_idrequiredThe agent to assign the number to.
countryISO country code. Defaults to 'US'.
areaCodeFilter by area code.
containsSearch for numbers containing this string.
const number = await client.phoneNumbers.create({
agent_id: agent.id,
country: 'US',
areaCode: '415',
})
console.log(number.phoneNumber) // '+14155551234'
console.log(number.friendlyName) // '(415) 555-1234'client.transcripts
Access call transcripts and conversation logs.
transcripts.list(agentId, options)
Get all transcripts for a specific agent.
agentIdrequiredThe agent to get transcripts for.
limitMax number of results. Defaults to 50.
offsetNumber of results to skip.
typeFilter by call type.
outcomeFilter by call outcome.
const transcripts = await client.transcripts.list('agt_abc123', {
limit: 10,
type: 'Sales Inquiry',
})
for (const t of transcripts) {
console.log(`[${t.date}] ${t.caller} — ${t.outcome}`)
console.log(` Summary: ${t.summary}`)
console.log(` Duration: ${t.duration_minutes}m`)
}transcripts.get(agentId, transcriptId)
Retrieve a single transcript with the full conversation log.
const transcript = await client.transcripts.get('agt_abc123', 'tr_xyz789')
// Access the full conversation
for (const turn of transcript.conversation) {
console.log(`${turn.speaker}: ${turn.text}`)
}
// agent: Hello, thanks for calling Acme Corp!
// caller: Hi, I wanted to ask about your pricing.
// agent: Of course! We have three plans...client.voices
Browse available AI voices.
voices.list()
Get all available voices that can be assigned to agents.
const voices = await client.voices.list()
for (const voice of voices) {
console.log(`${voice.name} (${voice.accent}, ${voice.gender})`)
console.log(` ${voice.description}`)
}
// Kevin (American, Male)
// Professional, warm, and articulate
// Sarah (American, Female)
// Confident, friendly, and approachable
// Lucy (British, Female)
// Energetic, clear, and engagingclient.user
Manage your account profile.
user.get()
Retrieve the authenticated user's profile.
const profile = await client.user.get() console.log(profile.email) // 'jane@acmecorp.com' console.log(profile.company) // 'Acme Corp' console.log(profile.timezone) // 'America/New_York'
client.integrations
Browse the integration catalog.
integrations.catalog()
Lists all available integrations and their function schemas.
const { integrations, function_schemas } = await client.integrations.catalog()
for (const int of integrations) {
console.log(int.name + ' (' + int.auth_type + ') — ' + int.description)
console.log(' Functions:', int.functions.join(', '))
}client.oauth
Start OAuth flows for third-party integrations. Tokens are stored automatically on callback.
oauth.startGoogleCalendar(options)
oauth.startGoogleSheets(options)
oauth.startGmail(options)
Shared Parameters
agent_idrequiredThe agent to authorize.
user_idrequiredThe user initiating the auth flow.
All three methods return { success, authUrl, message }. Open authUrl in a browser to complete OAuth. Tokens are stored automatically on callback.
const { authUrl } = await client.oauth.startGoogleCalendar({
agent_id: agent.id,
user_id: 'user_123',
})
// Redirect or open authUrl in browser to complete authorization
console.log('Authorize at:', authUrl)client.subscription
Query your subscription and usage.
subscription.get()
Get your current plan, status, and usage limits.
const sub = await client.subscription.get()
console.log(sub.plan) // 'professional'
console.log(sub.status) // 'active'
console.log(sub.usage.used) // 142
console.log(sub.usage.limit) // 500
const remaining = sub.usage.limit - sub.usage.used
console.log(`${remaining} calls remaining this period`)Type Reference
Key TypeScript interfaces exported by the SDK.
interface VoiceAgent {
id: string
business_name: string
agent_name: string
phone_number: string | null
phone_number_sid: string | null
voice_id: string
greeting: string
system_prompt: string
voice_settings: {
personality?: string
name?: string
}
functions_enabled: boolean
forwarding_number: string | null
escalation_number: string | null
escalation_policy: 'never' | 'complex' | 'requested' | 'always'
business_hours: BusinessHours
faq: FAQ[]
status: 'active' | 'inactive' | 'suspended'
created_at: string
updated_at: string
}interface BusinessHours {
enabled: boolean // false = 24/7
timezone: string // IANA timezone
schedule: {
[day: string]: {
open: string // "09:00"
close: string // "17:00"
enabled: boolean
}
}
}
interface FAQ {
question: string
answer: string
}interface Transcript {
id: string
date: string
time: string
duration: number // seconds
duration_minutes: number
caller: string // E.164 phone number
type: TranscriptType
outcome: CallOutcome
rating: number
summary: string
conversation: {
speaker: 'agent' | 'caller'
text: string
}[]
agentId: string
created_at: string
}
type TranscriptType =
| 'Sales Inquiry'
| 'Support Request'
| 'General Info'
| 'Complaint'
| 'Feedback'
| 'Booking'
| 'Cancellation'
type CallOutcome =
| 'Resolved'
| 'Unresolved'
| 'Escalated'
| 'Follow-up Required'
| 'Information Provided'
| 'Lead Captured'
| 'Cancelled'
| 'No Action'
| 'Unknown'interface AvailableNumber {
phoneNumber: string
friendlyName: string
region: string
isoCountry: string
type: string
capabilities: {
voice: boolean
SMS: boolean
MMS: boolean
}
}
interface Voice {
id: string
name: string
accent: string
description: string
gender: string
}
interface UserProfile {
firstName?: string
lastName?: string
email?: string
company?: string
timezone?: string
personalPhoneNumber?: string
emailNotifications?: boolean
callNotifications?: boolean
weeklyReports?: boolean
}
interface Subscription {
plan: string
status: 'active' | 'canceled' | 'past_due'
current_period_start: string
current_period_end: string
cancel_at_period_end: boolean
usage: {
used: number
limit: number
}
}interface CreatePhoneNumberOptions {
agent_id: string
country?: string
areaCode?: string
contains?: string
}interface FunctionConfig {
id: string
agent_id: string
user_id: string
function_name: string
enabled: boolean
config: Record<string, unknown>
params: Record<string, unknown>
created_at: string
updated_at: string
}
interface EnableFunctionOptions {
enabled: boolean
config?: Record<string, unknown>
params?: Record<string, unknown>
}interface AgentIntegration {
id: string
function_name: string
integration_type: string
enabled: boolean
connected: boolean
expired: boolean
scope?: string
config: Record<string, unknown>
params: Record<string, unknown>
created_at: string
updated_at: string
metadata: {
display_name: string
description: string
oauth_required: boolean
setup_required: boolean
}
}
interface AgentIntegrationsResponse {
integrations: AgentIntegration[]
summary: {
total_integrations: number
connected_integrations: number
enabled_integrations: number
expired_integrations: number
}
}
interface AgentIntegrationDetailResponse {
integration: AgentIntegration
agent_id: string
}interface GoogleSheet {
id: string
name: string
createdTime: string
modifiedTime: string
webViewLink: string
owners: { displayName: string; emailAddress: string }[]
shared: boolean
}
interface GoogleSheetTab {
id: number
title: string
index: number
type: string
rowCount: number
columnCount: number
}
interface HeaderSuggestion {
row_index: number
row_data: string[]
score: number
likely_header: boolean
suggested_headers: {
column_index: number
column_letter: string
header_value: string
is_empty: boolean
}[]
}interface Integration {
id: string
name: string
description: string
auth_type: 'oauth' | 'api_key' | 'config' | 'none'
auth_instructions: string
functions: string[]
params: Record<string, IntegrationParam>
}
interface IntegrationCatalog {
integrations: Integration[]
function_schemas: Record<string, FunctionSchema>
}interface OAuthStartOptions {
agent_id: string
user_id: string
}
interface OAuthStartResponse {
success: boolean
authUrl: string
message: string
}Further reading
Engineering guides for teams building voice agents with this SDK.
