npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@l7mp/tivadar-ai-api-sdk

v0.1.7

Published

TypeScript/JavaScript SDK for Tivadar AI Backend API

Readme

@l7mp/tivadar-ai-api-sdk

TypeScript/JavaScript SDK for the Tivadar AI Backend API. Provides a fully-typed, tree-shakeable client for managing Voice Agents, Chat Agents, RAG knowledge bases, SIP telephony, subscriptions, and more.

  • Package: @l7mp/tivadar-ai-api-sdk
  • Version: 0.1.4
  • Requires: Node.js ≥ 20, or any modern browser / edge runtime with native fetch
  • Formats: CommonJS (dist/index.js) + ESM (dist/esm/index.js), with TypeScript declarations

Table of Contents

  1. Installation
  2. Quick Start
  3. Authentication
  4. Client Configuration
  5. API Reference
  6. Type Reference
  7. Error Handling
  8. Advanced Usage
  9. Low-Level API Classes

Installation

npm install @l7mp/tivadar-ai-api-sdk
# or
yarn add @l7mp/tivadar-ai-api-sdk
# or
pnpm add @l7mp/tivadar-ai-api-sdk

Quick Start

import { Api } from '@l7mp/tivadar-ai-api-sdk';

const client = new Api({
  baseUrl: 'https://api.tivadar.ai/api/v1',
  options: {
    token: 'your-jwt-token',
  },
});

const ORG_ID = 'org_abc123';

// List all voice agents
const agents = await client.voiceAgents.list(ORG_ID);
// agents: VoiceAgentWithSipTrunks[]
for (const agent of agents) {
  console.log(agent.id, agent.name);
}

// Create a voice agent
const newAgent = await client.voiceAgents.create(ORG_ID, {
  name: 'Support Agent',
  organization_id: ORG_ID,
  instructions: 'You are a helpful customer support agent.',
  greeting: 'Hello! How can I help you today?',
  language: 'en-US',
  stt_provider: 'deepgram',
  stt_model: 'nova-2',
  tts_provider: 'elevenlabs',
  tts_voice: 'Rachel',
  llm_agent: {
    llmProviderName: 'openai/gpt-4o',
    temperature: 0.7,
    maxTokens: 1024,
  },
});
console.log('Created:', newAgent.id);

Base URL

All API endpoints are versioned under /api/v1. Set the baseUrl accordingly:

| Environment | Base URL | |---|---| | Local development | http://localhost:3000/api/v1 | | Production | https://your-api-domain.com/api/v1 |


Authentication

All organization-scoped endpoints require a JWT Bearer token. Pass it at construction time or update it dynamically.

At construction time

const client = new Api({
  baseUrl: 'https://api.tivadar.ai/api/v1',
  options: { token: 'eyJhbGci...' },
});

Dynamically (e.g. after login or token refresh)

const client = new Api({ baseUrl: 'https://api.tivadar.ai/api/v1' });

// Set / update the Bearer token
client.setAccessToken('eyJhbGci...');

// Or set the full Authorization header value for non-Bearer schemes
client.setAuthorizationHeader('Basic dXNlcjpwYXNz');

// Inspect the current token
const token = client.getAccessToken(); // string | undefined

// Remove authorization entirely (e.g. on logout)
client.clearAuthorization();

The auth state is shared by reference across all internal API instances. Calling setAccessToken() once immediately affects every subsequent request — no need to recreate the client.


Client Configuration

export interface ApiClientConfig {
  /** Base URL of the Tivadar AI backend including /api/v1 path. */
  baseUrl: string;
  options?: {
    /** JWT Bearer token (without the "Bearer " prefix). */
    token?: string;
  };
}

Abort / timeout

Every method accepts an optional RequestInit object as the last parameter. Use it to pass an AbortSignal for cancellation or timeouts:

// Abort on demand
const controller = new AbortController();
const agents = await client.voiceAgents.list(ORG_ID, {
  signal: controller.signal,
});
controller.abort();

// Timeout after 10 seconds (Node.js 18+)
const agents = await client.voiceAgents.list(ORG_ID, {
  signal: AbortSignal.timeout(10_000),
});

API Reference

Every method returns a Promise that resolves to the parsed response body. Methods return values directly — they are not wrapped in an envelope object.


Voice Agents

Voice agents handle telephony and LiveKit-based real-time voice conversations.

voiceAgents.list(organizationId, options?)

Returns all voice agents for an organization, including any linked SIP trunk info.

const agents: VoiceAgentWithSipTrunks[] = await client.voiceAgents.list('org_abc123');

voiceAgents.listBasic(organizationId, options?)

Returns a lightweight list (id + name only) — useful for dropdowns and selectors.

const basic = await client.voiceAgents.listBasic('org_abc123');
// OrganizationsOrganizationIdVoiceAgentsBasicGet200ResponseInner[]
for (const item of basic) {
  console.log(item.id, item.name);
}

voiceAgents.get(organizationId, voiceAgentId, options?)

Fetches a single voice agent by ID, including its linked llm_agent config.

const agent: VoiceAgent = await client.voiceAgents.get('org_abc123', 'va_xyz');
console.log(agent.llm_agent?.llmProviderName); // e.g. "openai/gpt-4o"
console.log(agent.language);                   // e.g. "en-US"

voiceAgents.create(organizationId, data, options?)

Creates a new voice agent. Automatically provisions a linked LLM agent in the LangChain service.

const agent: VoiceAgent = await client.voiceAgents.create('org_abc123', {
  name: 'Sales Bot',
  organization_id: 'org_abc123',
  instructions: 'You are a sales assistant for Acme Corp.',
  greeting: 'Hi! Welcome to Acme. How can I assist you?',
  language: 'en-US',
  stt_provider: 'deepgram',
  stt_model: 'nova-2',
  tts_provider: 'elevenlabs',
  tts_model: 'eleven_turbo_v2',
  tts_voice: 'Rachel',
  enable_recording: true,
  llm_agent: {
    llmProviderName: 'openai/gpt-4o-mini',
    temperature: 0.5,
    maxTokens: 512,
    maxConversationTurns: 20,
    ragConfigName: 'my-knowledge-base', // optional RAG integration
    ragTopK: 5,
    ragScoreThreshold: 0.7,
    toolsConfig: [
      { name: 'calendar', enabled: true },
    ],
  },
});
console.log('Created agent:', agent.id);

voiceAgents.update(organizationId, voiceAgentId, data, options?)

Partially updates a voice agent. Only provide fields you want to change.

const updated: VoiceAgent = await client.voiceAgents.update(
  'org_abc123',
  'va_xyz',
  {
    name: 'Sales Bot v2',
    instructions: 'Updated instructions...',
    llm_agent: {
      llmProviderName: 'openai/gpt-4o',
      temperature: 0.3,
    },
  }
);

voiceAgents.delete(organizationId, voiceAgentId, options?)

Deletes a voice agent and its linked LLM agent.

await client.voiceAgents.delete('org_abc123', 'va_xyz');

Chat Agents

Chat agents power chat widget integrations for web applications.

chatAgents.list(organizationId, options?)

const agents: ChatAgent[] = await client.chatAgents.list('org_abc123');

chatAgents.get(organizationId, chatAgentId, options?)

const agent: ChatAgent = await client.chatAgents.get('org_abc123', 'ca_xyz');
console.log(agent.chat_api_key);     // embed this key in your frontend widget
console.log(agent.allowed_domains);  // domain allow-list

chatAgents.create(organizationId, data, options?)

const agent: ChatAgent = await client.chatAgents.create('org_abc123', {
  name: 'Website Assistant',
  system_prompt: 'You are a helpful assistant for our website visitors.',
  allowed_domains: ['example.com', 'www.example.com'],
  rate_limit: 60, // requests per minute per session
  widget_config: {
    title: 'Chat with us',
    placeholder: 'Type your message...',
    welcome_message: 'Welcome! How can I help?',
    theme: 'light',  // 'light' | 'dark'
    position: { side: 'right', alignment: 'bottom' },
  },
  llm_agent: {
    llmProviderName: 'openai/gpt-4o-mini',
    temperature: 0.7,
    maxTokens: 1024,
    ragConfigName: 'product-docs',
  },
});

chatAgents.update(organizationId, chatAgentId, data, options?)

await client.chatAgents.update('org_abc123', 'ca_xyz', {
  system_prompt: 'Updated system prompt.',
  rate_limit: 120,
});

chatAgents.delete(organizationId, chatAgentId, options?)

await client.chatAgents.delete('org_abc123', 'ca_xyz');

RAG (Retrieval-Augmented Generation)

Manage knowledge bases (RAG configs) that can be attached to any agent via llm_agent.ragConfigName.

rag.list(organizationId, options?)

const configs: RagConfig[] = await client.rag.list('org_abc123');
for (const cfg of configs) {
  console.log(cfg.name, cfg.vectorStoreType, cfg.embeddingProviderName);
}

rag.create(organizationId, data, options?)

const config: RagConfig = await client.rag.create('org_abc123', {
  name: 'product-docs',
  embedding_provider_name: 'openai/text-embedding-3-small',
});

rag.delete(organizationId, ragConfigName, options?)

await client.rag.delete('org_abc123', 'product-docs');

rag.documents.upload(organizationId, ragConfigName, file, sourceUrl?, metadata?, options?)

Upload a document for indexing. Accepts a File (browser) or Blob (Node.js).

// Browser
const file = document.querySelector<HTMLInputElement>('#upload')!.files![0];
const doc: RagDocument = await client.rag.documents.upload(
  'org_abc123',
  'product-docs',
  file
);

// With optional metadata
const doc = await client.rag.documents.upload(
  'org_abc123',
  'product-docs',
  file,
  undefined,                           // sourceUrl (optional external link)
  JSON.stringify({ category: 'faq' }) // metadata (optional JSON string)
);

// Node.js
import { readFileSync } from 'fs';
const buffer = readFileSync('./manual.pdf');
const blob = new Blob([buffer], { type: 'application/pdf' });
const doc = await client.rag.documents.upload(
  'org_abc123',
  'product-docs',
  blob as unknown as File
);

rag.documents.list(organizationId, ragConfigName, status?, options?)

import {
  OrganizationsOrganizationIdRagRagConfigNameDocumentsGetStatusEnum as DocStatus,
} from '@l7mp/tivadar-ai-api-sdk';

// All documents
const docs: RagDocumentList = await client.rag.documents.list(
  'org_abc123',
  'product-docs'
);

// Filter by processing status
const ready = await client.rag.documents.list(
  'org_abc123',
  'product-docs',
  DocStatus.Completed
);

rag.documents.get(organizationId, ragConfigName, documentId, options?)

const doc: RagDocument = await client.rag.documents.get(
  'org_abc123',
  'product-docs',
  'doc_abc'
);
console.log(doc.status); // 'pending' | 'processing' | 'completed' | 'failed'

rag.documents.replace(organizationId, ragConfigName, documentId, file, sourceUrl?, options?)

Replace the contents of an existing document (re-processes and re-indexes).

await client.rag.documents.replace('org_abc123', 'product-docs', 'doc_abc', newFile);

rag.documents.delete(organizationId, ragConfigName, documentId, options?)

await client.rag.documents.delete('org_abc123', 'product-docs', 'doc_abc');

Calendar

Manage calendars and events (used by voice agents for scheduling features).

calendar.listCalendars(organizationId, options?)

const response: CalendarListResponse = await client.calendar.listCalendars('org_abc123');
for (const cal of response.data ?? []) {
  console.log(cal.id, cal.name);
}

calendar.listEvents(organizationId, start, end, calendarIds?, options?)

const events = await client.calendar.listEvents(
  'org_abc123',
  new Date('2025-01-01T00:00:00Z'),
  new Date('2025-01-31T23:59:59Z'),
  'cal_1,cal_2' // optional: comma-separated calendar IDs to filter
);

calendar.getEvent(organizationId, eventId, options?)

const event: CalendarEventResponse = await client.calendar.getEvent(
  'org_abc123',
  'evt_xyz'
);
console.log(event.name, event.start_time, event.end_time);

calendar.createEvent(organizationId, data, options?)

const event = await client.calendar.createEvent('org_abc123', {
  name: 'Team Standup',
  description: 'Daily standup meeting',
  start_time: new Date('2025-06-01T09:00:00Z'),
  end_time: new Date('2025-06-01T09:30:00Z'),
  calendar_id: 'cal_abc',
});

calendar.updateEvent(organizationId, eventId, data, options?)

await client.calendar.updateEvent('org_abc123', 'evt_xyz', {
  name: 'Updated Meeting Name',
  end_time: new Date('2025-06-01T10:00:00Z'),
});

calendar.deleteEvent(organizationId, eventId, options?)

await client.calendar.deleteEvent('org_abc123', 'evt_xyz');

Conversation History

Access conversation history stored by the LangChain service. History is read-only — no local DB.

history.list(organizationId, options?)

const result = await client.history.list('org_abc123');
// OrganizationsOrganizationIdConversationsGet200Response
for (const summary of result.conversations ?? []) {
  console.log(summary.id, summary.createdAt);
}

history.get(organizationId, conversationId, options?)

Returns the full conversation including all messages.

const convo: HistoryConversation = await client.history.get(
  'org_abc123',
  'session_xyz'
);

for (const msg of convo.messages ?? []) {
  console.log(`[${msg.role}] ${msg.content}`);
}

history.delete(organizationId, conversationId, options?)

await client.history.delete('org_abc123', 'session_xyz');

Recordings

Fetch presigned S3 URLs for call recordings. Requires the voice agent to have enable_recording: true.

recordings.get(organizationId, conversationId, options?)

const result: RecordingSignedUrl = await client.recordings.get(
  'org_abc123',
  'session_xyz'
);
console.log(result.url); // Presigned S3 URL — valid for a limited time

SIP / Telephony

Manage SIP trunks, dispatch rules, and phone numbers for inbound telephony routing.

sip.listTrunks(organizationId, options?)

const trunks: SipTrunkWithAgent[] = await client.sip.listTrunks('org_abc123');
for (const trunk of trunks) {
  console.log(trunk.number, trunk.dispatch_id);
}

sip.createTrunk(organizationId, data, options?)

const trunk: SipTrunk = await client.sip.createTrunk('org_abc123', {
  number: '+15551234567',
});

sip.deleteTrunk(organizationId, trunkId, options?)

await client.sip.deleteTrunk('org_abc123', 'trunk_xyz');

sip.createDispatchRule(organizationId, data, options?)

Create a SIP dispatch rule that routes inbound calls from a trunk to a voice agent.

const result = await client.sip.createDispatchRule('org_abc123', {
  trunk_id: 'trunk_xyz',
  agent_id: 'va_xyz',
});

sip.deleteDispatchRule(organizationId, dispatchId, options?)

await client.sip.deleteDispatchRule('org_abc123', 'dispatch_xyz');

sip.listPhoneNumbers(options?)

List all available phone numbers (global, not organization-scoped).

const numbers: PhoneNumber[] = await client.sip.listPhoneNumbers();

Organizations

organizations.list(options?)

List all organizations the authenticated user belongs to.

const orgs: Organization[] = await client.organizations.list();
for (const org of orgs) {
  console.log(org.id, org.name);
}

organizations.create(data, options?)

const org: Organization = await client.organizations.create({
  name: 'My Company',
});

Members

members.list(organizationId, options?)

const members: Member[] = await client.members.list('org_abc123');
for (const m of members) {
  console.log(m.user_id, m.is_admin ? '[admin]' : '');
}

Invitations

invitations.list(organizationId, options?)

const invites: InvitationResponse[] = await client.invitations.list('org_abc123');

invitations.create(organizationId, data, options?)

const invite: InvitationResponse = await client.invitations.create('org_abc123', {
  email: '[email protected]',
  is_admin: false,
});
// Send invite.token to the user via email

invitations.accept(data, options?)

Accept an invitation token. This endpoint does not require authentication.

await client.invitations.accept({
  token: 'invitation-token-from-email',
  user_id: 'user_xyz',
});

Playground

Generate a short-lived LiveKit sandbox token to test a voice agent interactively, without a real phone call.

playground.sandboxToken(organizationId, voiceAgentId, options?)

const result: SandboxToken = await client.playground.sandboxToken(
  'org_abc123',
  'va_xyz'
);
console.log(result.token);     // LiveKit access token
console.log(result.serverUrl); // LiveKit server URL
// Use these to connect directly from the LiveKit SDK or Agents Playground

Providers

Discover which LLM, STT, TTS, and embedding providers are enabled for your organization.

llmProviders.list(organizationId, options?)

const providers = await client.llmProviders.list('org_abc123');
// OrganizationsOrganizationIdLlmProvidersGet200ResponseInner[]
// e.g. [{ name: 'openai/gpt-4o' }, { name: 'anthropic/claude-3-5-sonnet' }]
for (const p of providers) {
  console.log(p.name);
}

sttProviders.list(organizationId, options?)

const providers = await client.sttProviders.list('org_abc123');
// OrganizationsOrganizationIdSttProvidersGet200ResponseInner[]
for (const p of providers) {
  console.log(p.name); // e.g. 'deepgram'
  for (const model of p.models ?? []) {
    console.log(' -', model.id); // e.g. 'nova-2'
  }
}

ttsProviders.list(organizationId, options?)

const providers = await client.ttsProviders.list('org_abc123');
// OrganizationsOrganizationIdTtsProvidersGet200ResponseInner[]
for (const p of providers) {
  console.log(p.name); // e.g. 'elevenlabs'
  for (const model of p.models ?? []) {
    console.log(' model:', model.id);
    for (const voice of model.voices ?? []) {
      console.log('   voice:', voice.id, voice.name);
    }
  }
}

embeddingProviders.list(organizationId, options?)

const providers = await client.embeddingProviders.list('org_abc123');
// e.g. [{ name: 'openai/text-embedding-3-small' }]

Subscription

Manage billing subscriptions via Stripe integration.

subscription.getStatus(organizationId, options?)

const status: SubscriptionStatus = await client.subscription.getStatus('org_abc123');

if (status.isActive) {
  console.log('Plan:', status.plan?.name);
  console.log('Status:', status.subscription?.status);
  // 'active' | 'trialing' | 'past_due' | 'canceled' | 'paused'
}

subscription.getDetails(organizationId, options?)

Returns full subscription details including plan features and limits.

const details: SubscriptionDetails = await client.subscription.getDetails('org_abc123');

subscription.createCheckout(organizationId, data, options?)

Create a Stripe Checkout session to start or upgrade a subscription.

const session: CheckoutSessionResponse = await client.subscription.createCheckout(
  'org_abc123',
  {
    plan_slug: 'pro',
    success_url: 'https://myapp.com/billing/success',
    cancel_url: 'https://myapp.com/billing/cancel',
  }
);
window.location.href = session.url; // redirect to Stripe Checkout

subscription.cancel(organizationId, data?, options?)

// Cancel at the end of the current billing period (recommended)
await client.subscription.cancel('org_abc123', {
  cancel_at_period_end: true,
});

// Cancel immediately
await client.subscription.cancel('org_abc123', {
  cancel_at_period_end: false,
});

subscription.resume(organizationId, options?)

Undo a scheduled cancellation (must call before the period ends).

await client.subscription.resume('org_abc123');

subscription.updatePlan(organizationId, data, options?)

Upgrade or downgrade the subscription plan.

const result: UpdatePlanResponse = await client.subscription.updatePlan(
  'org_abc123',
  { plan_slug: 'enterprise' }
);

subscription.pause(organizationId, data?, options?)

await client.subscription.pause('org_abc123', {
  resumes_at: '2025-09-01', // optional ISO date to auto-resume
});

subscription.unpause(organizationId, options?)

await client.subscription.unpause('org_abc123');

subscription.billingPortal(organizationId, data, options?)

Generate a Stripe Customer Portal session URL for self-service billing management.

const portal: BillingPortalResponse = await client.subscription.billingPortal(
  'org_abc123',
  { return_url: 'https://myapp.com/settings' }
);
window.location.href = portal.url;

subscription.getCredits(organizationId, options?)

const balance: CreditBalance = await client.subscription.getCredits('org_abc123');
console.log(balance.balance, balance.currency);

subscription.getTransactions(organizationId, creditType?, limit?, offset?, options?)

const txns: CreditTransactionsResponse = await client.subscription.getTransactions(
  'org_abc123',
  'voice_minutes', // optional: filter by credit type
  20,              // limit (default: 20)
  0                // offset for pagination
);
for (const tx of txns.data ?? []) {
  console.log(tx.amount, tx.description, tx.createdAt);
}

Type Reference

All types are exported from the package root.

import type {
  // Agents
  VoiceAgent,
  VoiceAgentCreate,
  VoiceAgentUpdate,
  VoiceAgentMetadata,
  VoiceAgentWithSipTrunks,
  ChatAgent,
  ChatAgentCreate,
  ChatAgentUpdate,

  // LLM
  LlmAgent,
  LlmAgentInput,
  LlmAgentUpdateInput,
  ToolConfig,

  // RAG
  RagConfig,
  RagConfigCreate,
  RagDocument,
  RagDocumentChunk,
  RagDocumentList,
  RagDocumentChunkList,

  // Calendar
  Calendar,
  CalendarEvent,
  CalendarEventCreate,
  CalendarEventUpdate,
  CalendarEventResponse,
  CalendarListResponse,
  CalendarWithAgent,

  // History
  HistoryConversation,
  HistoryMessage,
  HistorySummary,

  // Recordings
  RecordingSignedUrl,

  // Organizations & Members
  Organization,
  OrganizationCreate,
  OrganizationUpdate,
  Member,

  // Invitations
  InvitationCreate,
  InvitationAccept,
  InvitationResponse,

  // SIP / Telephony
  SipTrunk,
  SipTrunkCreate,
  SipTrunkWithAgent,
  DispatchRuleCreate,
  PhoneNumber,

  // Playground
  SandboxToken,

  // Widget (Chat)
  WidgetConfig,
  WidgetPosition,

  // Subscription
  SubscriptionStatus,
  SubscriptionDetails,
  CreateCheckoutSessionRequest,
  CheckoutSessionResponse,
  CancelSubscriptionRequest,
  UpdatePlanRequest,
  UpdatePlanResponse,
  PauseSubscriptionRequest,
  PauseSubscriptionResponse,
  BillingPortalRequest,
  BillingPortalResponse,
  CreditBalance,
  CreditTransaction,
  CreditTransactionsResponse,
} from '@l7mp/tivadar-ai-api-sdk';

Key type shapes

VoiceAgentCreate

interface VoiceAgentCreate {
  name: string;           // required
  organization_id: string; // required
  instructions?: string;  // system prompt / persona instructions
  greeting?: string;      // first spoken utterance when a call connects
  stt_provider?: string;  // e.g. 'deepgram'
  stt_model?: string;     // e.g. 'nova-2'
  tts_provider?: string;  // e.g. 'elevenlabs'
  tts_model?: string;     // e.g. 'eleven_turbo_v2'
  tts_voice?: string;     // e.g. 'Rachel'
  language?: string;      // BCP-47 code for STT + TTS, e.g. 'en-US', 'hu-HU'
  enable_recording?: boolean;
  metadata?: VoiceAgentMetadata;
  llm_agent?: LlmAgentInput;
}

VoiceAgentMetadata

interface VoiceAgentMetadata {
  allowedFunctions?: string[]; // names of callable functions / tools
  rag_index?: string;          // legacy: RAG index name
}

LlmAgentInput

interface LlmAgentInput {
  llmProviderName: string;       // required — e.g. 'openai/gpt-4o'
  temperature?: number;          // 0.0–2.0, controls randomness
  maxTokens?: number;            // maximum tokens per response
  maxConversationTurns?: number; // max back-and-forth turns before ending
  ragConfigName?: string;        // name of a RagConfig to attach
  ragTopK?: number;              // top-K documents to retrieve from the RAG
  ragScoreThreshold?: number;    // minimum similarity score (0.0–1.0)
  toolsConfig?: ToolConfig[];    // tool/function configurations
  rateLimit?: number;            // max requests per minute
  allowedOrigins?: string[];     // CORS origins for the chat endpoint
}

ToolConfig

interface ToolConfig {
  name: string;                  // tool identifier, e.g. 'calendar', 'weather'
  enabled: boolean;
  config?: Record<string, any>;  // tool-specific configuration object
}

ChatAgentCreate

interface ChatAgentCreate {
  name: string;                  // required
  system_prompt?: string;        // persona / instructions for the chat agent
  allowed_domains?: string[];    // domains permitted to use the widget
  rate_limit?: number;           // requests per minute per session
  widget_config?: WidgetConfig;
  llm_agent?: LlmAgentInput;
}

WidgetConfig

interface WidgetConfig {
  position?: WidgetPosition;     // { side: 'right'|'left', alignment: 'bottom'|'top' }
  title?: string;                // widget header title
  placeholder?: string;          // input field placeholder
  theme?: 'light' | 'dark';
  welcome_message?: string;      // greeting shown before the first message
}

RagConfig

interface RagConfig {
  name: string;                  // unique name used as ragConfigName in agents
  organization: string;
  vectorStoreType: string;       // 'memory' | 'qdrant' | 'weaviate'
  vectorStoreUrl?: string;       // required for qdrant/weaviate
  embeddingProviderName: string; // e.g. 'openai/text-embedding-3-small'
  chunkSize: number;             // tokens per document chunk
  chunkOverlap: number;          // token overlap between chunks
  maxFileSizeMb: number;
  processingTimeoutS: number;
  createdAt: Date;
  updatedAt: Date;
}

SubscriptionStatus

interface SubscriptionStatus {
  isActive: boolean;             // true when status is 'active' or 'trialing'
  service?: SubscriptionStatusService;
  subscription?: SubscriptionStatusSubscription | null;
  plan?: SubscriptionStatusPlan | null;
}

Error Handling

The SDK throws typed errors for HTTP and network failures.

import { ResponseError, FetchError } from '@l7mp/tivadar-ai-api-sdk';

async function safeGet(orgId: string, agentId: string) {
  try {
    return await client.voiceAgents.get(orgId, agentId);
  } catch (err) {
    if (err instanceof ResponseError) {
      // HTTP error (4xx / 5xx)
      console.error('HTTP', err.response.status);

      const body = await err.response.json().catch(() => ({}));
      console.error('Message:', body.error || body.message);

      switch (err.response.status) {
        case 401:
          // Token expired — refresh and retry
          client.setAccessToken(await refreshToken());
          return client.voiceAgents.get(orgId, agentId);
        case 403:
          throw new Error('Not authorized for this organization');
        case 404:
          return null; // resource not found
        default:
          throw err;
      }
    }

    if (err instanceof FetchError) {
      // Network-level error (DNS, timeout, CORS, offline)
      console.error('Network error:', err.cause.message);
      throw err;
    }

    throw err; // unexpected
  }
}

Advanced Usage

Middleware

The underlying BaseAPI supports pre/post/onError middleware for logging, retry logic, and header injection.

import {
  Configuration,
  VoiceAgentsApi,
  type Middleware,
} from '@l7mp/tivadar-ai-api-sdk';

const loggingMiddleware: Middleware = {
  pre: async (ctx) => {
    console.log(`→ ${ctx.init.method} ${ctx.url}`);
    return ctx; // must return { url, init }
  },
  post: async (ctx) => {
    console.log(`← ${ctx.response.status} ${ctx.url}`);
    return ctx.response;
  },
  onError: async (ctx) => {
    console.error(`✗ ${ctx.url}`, ctx.error);
    // return a fallback Response to recover, or undefined to propagate the error
  },
};

const configuration = new Configuration({
  basePath: 'https://api.tivadar.ai/api/v1',
  accessToken: () => getTokenFromStore(), // called on every request
  middleware: [loggingMiddleware],
});

const voiceAgentsApi = new VoiceAgentsApi(configuration);
const agents = await voiceAgentsApi.organizationsOrganizationIdVoiceAgentsGet({
  organizationId: 'org_abc123',
});

Retry middleware example

const retryMiddleware: Middleware = {
  post: async (ctx) => {
    if (ctx.response.status === 429) {
      const retryAfter = parseInt(ctx.response.headers.get('Retry-After') ?? '1', 10);
      await new Promise(r => setTimeout(r, retryAfter * 1000));
      return fetch(ctx.url, ctx.init);
    }
  },
};

Token refresh middleware example

const authMiddleware: Middleware = {
  post: async (ctx) => {
    if (ctx.response.status === 401) {
      const newToken = await refreshAccessToken();
      client.setAccessToken(newToken);
      const retryInit = {
        ...ctx.init,
        headers: {
          ...ctx.init.headers as Record<string, string>,
          Authorization: `Bearer ${newToken}`,
        },
      };
      return fetch(ctx.url, retryInit);
    }
  },
};

Custom fetch (testing / polyfills)

import { Configuration, VoiceAgentsApi } from '@l7mp/tivadar-ai-api-sdk';

const config = new Configuration({
  basePath: 'https://api.tivadar.ai/api/v1',
  fetchApi: myCustomFetch, // any fetch-compatible implementation
});

Low-Level API Classes

The Api convenience client wraps these generated classes. Use them directly if you need full control over request construction or want to add per-instance middleware.

| Class | Api namespace | |---|---| | VoiceAgentsApi | client.voiceAgents | | ChatAgentsApi | client.chatAgents | | CalendarApi | client.calendar | | HistoryApi | client.history | | RecordingsApi | client.recordings | | RAGApi | client.rag | | SIPApi | client.sip | | OrganizationsApi | client.organizations | | MembersApi | client.members | | InvitationsApi | client.invitations | | PlaygroundApi | client.playground | | LLMProvidersApi | client.llmProviders | | STTProvidersApi | client.sttProviders | | TTSProvidersApi | client.ttsProviders | | EmbeddingProvidersApi | client.embeddingProviders | | SubscriptionApi | client.subscription |

All classes extend BaseAPI from ./runtime and accept a Configuration instance.

import { Configuration, VoiceAgentsApi } from '@l7mp/tivadar-ai-api-sdk';

const config = new Configuration({
  basePath: 'https://api.tivadar.ai/api/v1',
  accessToken: 'your-jwt-token',
});

const api = new VoiceAgentsApi(config);

// Low-level: returns ApiResponse<T> — call .value() to get the parsed body
const raw = await api.organizationsOrganizationIdVoiceAgentsGetRaw({
  organizationId: 'org_abc123',
});
console.log(raw.raw.status); // HTTP status
const agents = await raw.value(); // VoiceAgentWithSipTrunks[]

// Convenience: resolves directly to the parsed body
const agents = await api.organizationsOrganizationIdVoiceAgentsGet({
  organizationId: 'org_abc123',
});

License

See LICENSE in this package.