Get started

JavaScript and TypeScript SDK

Use a typed server-side SDK wrapper for Node.js, Next.js route handlers, and worker jobs.

Back to documentation
Get started9 min
1

Install the server wrapper

Place this client in server-only code, then inject QUICKCALLAI_API_KEY from your runtime secrets.

JavaScript / TypeScript SDK
type QuickCallConfig = {
  apiKey: string
  baseUrl?: string
}

type InitiateCallInput = {
  phoneNumber: string
  customerName: string
  prompt: string
  language?: string
  voiceModel?: string
  provider?: "twilio" | "vobiz" | "frejun" | "livekit"
  agentId?: string
  transferPhoneNumber?: string
}

type QuickCallApiResponse = {
  success?: boolean
  message?: string
  error?: string
  [key: string]: unknown
}

type CreateCallResponse = QuickCallApiResponse & {
  call_id?: string | number
  call_sid?: string
  status?: string
}

type CallStatusResponse = QuickCallApiResponse & {
  call_id?: string | number
  call_sid?: string
  provider_call_id?: string
  status?: string
  lifecycle_state?: string
  transcript?: unknown
  summary?: string
}

export class QuickCallAI {
  private readonly apiKey: string
  private readonly baseUrl: string

  constructor(config: QuickCallConfig) {
    this.apiKey = config.apiKey
    this.baseUrl = (config.baseUrl || "https://ai.quickcall.tech/api").replace(/\/+$/, "")
  }

  private async request<T extends QuickCallApiResponse = QuickCallApiResponse>(
    path: string,
    init: RequestInit = {},
  ): Promise<T> {
    const response = await fetch(`${this.baseUrl}${path}`, {
      ...init,
      headers: {
        Authorization: `Bearer ${this.apiKey}`,
        "Content-Type": "application/json",
        ...(init.headers || {}),
      },
    })
    const data = await response.json().catch(() => ({})) as QuickCallApiResponse
    if (!response.ok || data.success === false) {
      throw new Error(data.message || data.error || `QuickCallAI API error: ${response.status}`)
    }
    return data as T
  }

  initiateCall(input: InitiateCallInput): Promise<CreateCallResponse> {
    return this.request<CreateCallResponse>("/calls/demo/initiate", {
      method: "POST",
      body: JSON.stringify({
        phone_number: input.phoneNumber,
        customer_name: input.customerName,
        prompt: input.prompt,
        language: input.language || "en-US",
        voice_model: input.voiceModel || "aura-asteria-en",
        provider: input.provider || "twilio",
        agent_id: input.agentId || null,
        transfer_phone_number: input.transferPhoneNumber || null,
      }),
    })
  }

  getCallStatus(callId: string): Promise<CallStatusResponse> {
    return this.request<CallStatusResponse>(`/calls/demo/${encodeURIComponent(callId)}/status`)
  }

  endCall(callId: string): Promise<QuickCallApiResponse> {
    return this.request(`/calls/demo/${encodeURIComponent(callId)}/end`, { method: "POST" })
  }
}
2

Run a call and poll status

Create the call, persist the returned call_id, and poll status only from trusted backend code.

Usage
const quickcall = new QuickCallAI({ apiKey: process.env.QUICKCALLAI_API_KEY! })

const created = await quickcall.initiateCall({
  phoneNumber: "+15551234567",
  customerName: "Asha Patel",
  prompt: "Qualify the lead and book a demo if there is interest.",
  language: "en-IN",
  voiceModel: "google:en-IN-Chirp3-HD-Charon",
  provider: "twilio",
})

const status = await quickcall.getCallStatus(String(created.call_id))