OnCallClerk Logo
DevelopersSDK Reference

Reference  ·  TypeScript SDK

SDK reference.

The official OnCallClerk TypeScript/JavaScript SDK. Fully typed, Promise-based, and compatible with Node.js, Deno, and edge runtimes.

.md

Installation

Install via your preferred package manager:

# npm $ npm install @oncallclerk/sdk
# yarn $ yarn add @oncallclerk/sdk
# pnpm $ pnpm add @oncallclerk/sdk

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

apiKeyrequired
string

Your OnCallClerk API key.

baseUrl
string

Override the API base URL. Defaults to 'https://api.oncallclerk.com'.

timeout
number

Request 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.

client.agents.list(): Promise<VoiceAgent[]>
Returns: Promise<VoiceAgent[]>
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.

client.agents.get(agentId: string): Promise<VoiceAgent>
Returns: Promise<VoiceAgent>
agentIdrequired
string

The 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.

client.agents.create(config: CreateAgentConfig): Promise<VoiceAgent>
Returns: Promise<VoiceAgent>
business_namerequired
string

The business name the agent represents.

agent_namerequired
string

A friendly name for the agent.

voice_idrequired
string

The voice to use. Get IDs from client.voices.list().

greetingrequired
string

The greeting spoken when answering.

system_promptrequired
string

Instructions defining agent behavior.

escalation_policy
EscalationPolicy

'never' | 'complex' | 'requested' | 'always'. Defaults to 'never'.

forwarding_number
string

Number to forward calls to on escalation.

escalation_number
string

Dedicated escalation number.

business_hours
BusinessHours

Operating hours. Omit for 24/7.

faq
FAQ[]

Array of {question, answer} pairs.

voice_settings
VoiceSettings

Additional voice config (personality, name).

functions_enabled
boolean

Enable 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.

client.agents.update(agentId: string, config: Partial<CreateAgentConfig>): Promise<VoiceAgent>
Returns: Promise<VoiceAgent>
const updated = await client.agents.update('agt_abc123', {
  greeting: 'Hey! Thanks for calling Acme Corp.',
  escalation_policy: 'always',
})

console.log(updated.greeting) // updated greeting

agents.delete(agentId)

Permanently delete an agent and release its phone number.

client.agents.delete(agentId: string): Promise<void>
Returns: Promise<void>
await client.agents.delete('agt_abc123')
// Agent and all associated data removed

agents.assignPhone(agentId, phoneNumber)

Assign or change the phone number for an agent.

client.agents.assignPhone(agentId: string, phoneNumber: string): Promise<void>
Returns: Promise<void>
agentIdrequired
string

The agent to assign the number to.

phoneNumberrequired
string

E.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.

client.agents.listFunctions(agentId: string): Promise<FunctionConfig[]>
Returns: Promise<FunctionConfig[]>
agentIdrequired
string

The 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.

client.agents.enableFunction(agentId: string, functionName: string, options: EnableFunctionOptions): Promise<FunctionConfig>
Returns: Promise<FunctionConfig>
agentIdrequired
string

The agent ID.

functionNamerequired
string

Function name (e.g. 'scheduleMeeting', 'sendEmail', 'captureLead').

options.enabledrequired
boolean

Whether to enable the function.

options.config
object

Function-specific configuration.

options.params
object

Function-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' true

agents.disableFunction(agentId, functionName)

Disable a function on an agent.

client.agents.disableFunction(agentId: string, functionName: string): Promise<void>
Returns: Promise<void>
await client.agents.disableFunction(agent.id, 'scheduleMeeting')

Integration Management

agents.listIntegrations(agentId)

List all integrations for an agent with summary stats.

client.agents.listIntegrations(agentId: string): Promise<AgentIntegrationsResponse>
Returns: Promise<AgentIntegrationsResponse>
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.

client.agents.getIntegration(agentId: string, functionName: string): Promise<AgentIntegrationDetailResponse>
Returns: Promise<AgentIntegrationDetailResponse>
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.

client.agents.updateIntegrationConfig(agentId: string, functionName: string, params: Record<string, unknown>): Promise<FunctionConfig>
Returns: Promise<FunctionConfig>
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.

client.agents.listSheets(agentId: string): Promise<GoogleSheet[]>
Returns: Promise<GoogleSheet[]>
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.

client.agents.listSheetTabs(agentId: string, sheetId: string): Promise<GoogleSheetTab[]>
Returns: Promise<GoogleSheetTab[]>
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.

client.agents.getSheetHeaders(agentId: string, sheetId: string, tabName: string): Promise<HeaderSuggestion[]>
Returns: Promise<HeaderSuggestion[]>
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.

client.phoneNumbers.search(options?: SearchOptions): Promise<AvailableNumber[]>
Returns: Promise<AvailableNumber[]>
country
string

ISO country code. Defaults to 'US'.

areaCode
string

Filter by area code.

contains
string

Search for numbers containing this string.

pageSize
number

Results per page (max 50). Defaults to 10.

page
number

Page 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.

client.phoneNumbers.getRegulatoryBundles(country: string): Promise<RegulatoryBundle[]>
Returns: Promise<RegulatoryBundle[]>
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.

client.phoneNumbers.createRegulatoryBundle(options: RegulatoryBundleOptions): Promise<{ bundleSid: string }>
Returns: Promise<{ bundleSid: string }>
isoCountryCoderequired
string

Two-letter ISO country code.

complianceType
'business' | 'individual'

Type of compliance submitter.

complianceData
ComplianceData

Business 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().

client.phoneNumbers.create(options: CreatePhoneNumberOptions): Promise<AvailableNumber>
Returns: Promise<AvailableNumber>
agent_idrequired
string

The agent to assign the number to.

country
string

ISO country code. Defaults to 'US'.

areaCode
string

Filter by area code.

contains
string

Search 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.

client.transcripts.list(agentId: string, options?: ListOptions): Promise<Transcript[]>
Returns: Promise<Transcript[]>
agentIdrequired
string

The agent to get transcripts for.

limit
number

Max number of results. Defaults to 50.

offset
number

Number of results to skip.

type
TranscriptType

Filter by call type.

outcome
CallOutcome

Filter 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.

client.transcripts.get(agentId: string, transcriptId: string): Promise<Transcript>
Returns: Promise<Transcript>
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.

client.voices.list(): Promise<Voice[]>
Returns: Promise<Voice[]>
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 engaging

client.user

Manage your account profile.

user.get()

Retrieve the authenticated user's profile.

client.user.get(): Promise<UserProfile>
Returns: Promise<UserProfile>
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.

client.integrations.catalog(): Promise<IntegrationCatalog>
Returns: Promise<IntegrationCatalog>
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)

client.oauth.startGoogleCalendar(options: OAuthStartOptions): Promise<OAuthStartResponse>
Returns: Promise<OAuthStartResponse>

oauth.startGoogleSheets(options)

client.oauth.startGoogleSheets(options: OAuthStartOptions): Promise<OAuthStartResponse>
Returns: Promise<OAuthStartResponse>

oauth.startGmail(options)

client.oauth.startGmail(options: OAuthStartOptions): Promise<OAuthStartResponse>
Returns: Promise<OAuthStartResponse>

Shared Parameters

agent_idrequired
string

The agent to authorize.

user_idrequired
string

The 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.

client.subscription.get(): Promise<Subscription>
Returns: Promise<Subscription>
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.