OutEvalAI LogoOutEvalAI

TypeScript SDK

Install, authenticate, and use the @outcallerai/sdk package to call the OutCallerAI public API from Node.js and browser-based backends.

The @outcallerai/sdk package provides a typed, promise-based client for the OutCallerAI public API. It supports ESM and CommonJS, runs on Node.js 20 and 22, and works in serverless environments.

Installation

npm install @outcallerai/sdk

Requires Node.js 20+.

Package: @outcallerai/sdk on npm

Quick start

import {OutCallerAI} from "@outcallerai/sdk";

const client = new OutCallerAI({
	apiKey: process.env.OUTCALLERAI_API_KEY!,
});

const workspace = await client.workspace.getWorkspace();
console.log(workspace.name);

Configuration

OptionTypeDefaultDescription
apiKeystring(required)Workspace API key
baseUrlstringhttps://api.outcallerai.comAPI origin
timeoutMsnumber30000Request timeout in milliseconds
maxRetriesnumber2Maximum retry attempts for safe operations
maxRetryElapsedMsnumber15000Maximum total time spent retrying
maxBackoffMsnumber5000Maximum delay between retries
fetchfunctionglobalThis.fetchCustom fetch implementation
onResponsefunctionundefinedCallback for response metadata
const client = new OutCallerAI({
	apiKey: process.env.OUTCALLERAI_API_KEY!,
	baseUrl: "https://api.outcallerai.com",
	timeoutMs: 60_000,
	maxRetries: 3,
	onResponse: ({method, path, status, requestId, durationMs}) => {
		console.log(`${method} ${path} -> ${status} (${durationMs}ms)`);
	},
});

Resources

The client maps one-to-one with the REST API.

ResourceMethods
workspacegetWorkspace, updateWorkspace
usecaseslistUsecases, getUsecase, createUsecase, updateUsecase, deleteUsecase
agentslistAgents, getAgent, createAgent, updateAgent, deleteAgent
leadslistLeads, getLead, createLead, updateLead, deleteLead
callslistCalls, getCall, createCall
jobscreateCallExportJob, getJob, cancelJob

Complete usage guide

Workspace

// Get workspace
const workspace = await client.workspace.getWorkspace();
console.log(workspace.id, workspace.name);

// Update workspace name
const updated = await client.workspace.updateWorkspace({
	workspaceUpdateRequest: {name: "Acme Corp"},
});

Usecases

// List usecases
const usecases = await client.usecases.listUsecases();

// Get usecase by ID
const usecase = await client.usecases.getUsecase({useCaseId: "uc_abc123"});

// Create usecase
const created = await client.usecases.createUsecase({
	useCaseWriteRequest: {name: "Q4 Outreach", description: "Quarterly sales push"},
});

// Update usecase
const updated = await client.usecases.updateUsecase({
	useCaseId: "uc_abc123",
	useCaseWriteRequest: {name: "Updated Usecase"},
});

// Delete usecase
await client.usecases.deleteUsecase({useCaseId: "uc_abc123"});

Agents

// List agents
const agents = await client.agents.listAgents({limit: 50});

// Get agent by ID
const agent = await client.agents.getAgent({agentId: "ag_abc123"});

// Create agent
const created = await client.agents.createAgent({
	agentCreateRequest: {name: "Sales Agent", gender: "female"},
});

// Update agent
const updated = await client.agents.updateAgent({
	agentId: "ag_abc123",
	agentUpdateRequest: {name: "Updated Name", gender: "male"},
});

// Delete agent
await client.agents.deleteAgent({agentId: "ag_abc123"});

Leads

// List leads for an agent
const leads = await client.leads.listLeads({
	agentId: "ag_abc123",
	limit: 50,
});

// Get lead by ID
const lead = await client.leads.getLead({agentId: "ag_abc123", leadId: "ld_xyz789"});

// Create lead
const newLeads = await client.leads.createLead({
	agentId: "ag_abc123",
	body: {
		name: "Jane Doe",
		email: "jane@example.com",
		phone: "+911234567890",
		description: "Interested in pricing",
	},
});

// Update lead
const updatedLead = await client.leads.updateLead({
	agentId: "ag_abc123",
	leadId: "ld_xyz789",
	leadUpdateRequest: {name: "Jane Smith"},
});

// Delete lead
await client.leads.deleteLead({agentId: "ag_abc123", leadId: "ld_xyz789"});

Calls

// List calls for an agent
const calls = await client.calls.listCalls({agentId: "ag_abc123", limit: 50});

// Get call by ID
const call = await client.calls.getCall({agentId: "ag_abc123", callId: "cl_xyz789"});

// Create call (initiate outbound call to a lead)
const newCalls = await client.calls.createCall({
	agentId: "ag_abc123",
	callCreateRequest: {leadId: "ld_xyz789"},
});
console.log(newCalls[0].id, newCalls[0].status);

// Bulk call creation (initiate calls to multiple leads at once)
const bulkCalls = await client.calls.createCall({
	agentId: "ag_abc123",
	callCreateRequest: {leadIds: ["ld_xyz789", "ld_abc456", "ld_def012"]},
});
console.log(`Created ${bulkCalls.length} calls`);
bulkCalls.forEach((call) => console.log(call.id, call.status));

Note: createCall accepts either leadId (single) or leadIds (bulk array). Provide one of the two — not both. Bulk creation deduplicates the leadIds array and returns an array of call objects.

Jobs

// Create call export job
const job = await client.jobs.createCallExportJob({
	callExportJobRequest: {agentId: "ag_abc123", limit: 100},
	idempotencyKey: crypto.randomUUID(),
});

// Get job status
const jobStatus = await client.jobs.getJob({jobHandle: job.handle});

// Cancel job
await client.jobs.cancelJob({jobHandle: job.handle});

Pagination

Use the paginate helper to iterate over all records.

import {paginate} from "@outcallerai/sdk";

for await (const lead of paginate(
	async (cursor) =>
		client.leads.listLeads({
			agentId: "ag_abc123",
			cursor,
			limit: 50,
		}),
	{maxPages: 1_000},
)) {
	console.log(lead.id, lead.name);
}

Idempotency

Supply an idempotencyKey to make create operations safe to retry.

const lead = await client.leads.createLead({
	agentId: "ag_abc123",
	body: {
		name: "Jane",
		email: "jane@example.com",
		phone: "+911234567890",
		description: "Interested in pricing",
	},
	idempotencyKey: crypto.randomUUID(),
});

If the same key is reused with a different payload the request returns 409.

Cancellation

Pass an AbortSignal to cancel in-flight requests.

const controller = new AbortController();
setTimeout(() => controller.abort(), 5_000);

const agents = await client.agents.listAgents({}, {signal: controller.signal});

Error handling

The SDK throws typed errors with category, status, requestId, code, and retryable fields.

import {
	AuthenticationError,
	OutCallerAIError,
	RateLimitError,
} from "@outcallerai/sdk";

try {
	const agent = await client.agents.createAgent({ ... });
} catch (error) {
	if (error instanceof AuthenticationError) {
		// The API key is invalid or has been revoked
	} else if (error instanceof RateLimitError) {
		// Back off - the SDK already retried when safe
	} else if (error instanceof OutCallerAIError) {
		console.error(error.code, error.requestId, error.category);
	}
	throw error;
}
Error typeHTTP statusRetryable
AuthenticationError401No
PermissionError403No
NotFoundError404No
RequestValidationError400/422No
ConflictError409No
RateLimitError429Yes
TimeoutError408/0Yes
ServerError5xxYes
NetworkError0Yes

Response metadata

Track request details with the onResponse callback.

const client = new OutCallerAI({
	apiKey: process.env.OUTCALLERAI_API_KEY!,
	onResponse: ({method, path, status, requestId, durationMs, rateLimit}) => {
		console.log(`${method} ${path} -> ${status} (${durationMs}ms)`);
		console.log("Rate limit:", rateLimit.remaining, "/", rateLimit.limit);
	},
});

How is this guide?