Ultravox Client SDK for Web
The `ultravox-client` library provides a web client SDK for integrating Ultravox's real-time, speech-to-speech AI capabilities into web applications. Written in TypeScript, it offers an event-driven API for managing interactive voice sessions. The current stable version is 0.5.0, indicating it is still in active development with potential for API changes in future minor releases. It enables developers to join AI-powered calls, listen for session status changes, and receive real-time speech transcripts from both users and AI agents. Key differentiators include its focus on low-latency, real-time voice interaction and its comprehensive event model for managing session state and data flow within a web browser environment, abstracting away the underlying WebSocket complexities.
Common errors
-
Error: Missing version.js file
cause The build process for the Ultravox Client SDK failed to locate or generate the `version.js` file, which is required for package metadata.fixNavigate to the SDK's root directory and run `pnpm publish --dry-run --git-checks=false`. This command should trigger the necessary pre-publish hooks that generate `version.js`. -
WebSocket connection failed: Error during WebSocket handshake: Unexpected response code: 403
cause The WebSocket server rejected the connection request, often due to an invalid or expired `joinCall` URL, or incorrect authentication/authorization.fixVerify that the `joinCall` URL passed to `session.joinCall()` is current, valid, and correctly generated by your backend using the Ultravox API. Ensure your server-side logic handles token expiry and renewal correctly. -
TypeError: Failed to construct 'WebSocket': The URL 'invalid-url' is invalid.
cause The URL provided to `session.joinCall()` is not a valid WebSocket (ws:// or wss://) URL format.fixEnsure the URL passed to `session.joinCall()` is a properly formatted WebSocket URL, starting with `ws://` or `wss://`, and that it resolves to an accessible endpoint.
Warnings
- breaking As the package is currently in an early development stage (version 0.5.0), the API is subject to breaking changes in minor versions. Developers should pin exact versions and review release notes carefully when upgrading.
- gotcha When developing or building the `ultravox-client` SDK itself, a build error 'Missing version.js file' might occur. This indicates an issue with the build tooling not generating the version file prior to compilation.
- gotcha The `UltravoxSession.joinCall()` method requires a WebSocket URL that must be generated by the Ultravox API (typically from a backend server). This URL is not static and cannot be created directly within the client-side application.
Install
-
npm install ultravox-client -
yarn add ultravox-client -
pnpm add ultravox-client
Imports
- UltravoxSession
const { UltravoxSession } = require('ultravox-client');import { UltravoxSession } from 'ultravox-client'; - UltravoxSessionStatus
import UltravoxSessionStatus from 'ultravox-client';
import { UltravoxSessionStatus } from 'ultravox-client'; - UltravoxSession (Type)
import type { UltravoxSession } from 'ultravox-client';
Quickstart
import { UltravoxSession } from 'ultravox-client';
// In a real application, replace this with a URL obtained securely from your backend
// which generates it via the Ultravox API. Do NOT hardcode or expose API keys.
const ULTRAVOX_JOIN_URL = 'wss://your-call-join-url'; // Placeholder for demonstration
const session = new UltravoxSession();
session.addEventListener('status', (event) => {
console.log('Session status changed: ', session.status);
if (session.status === 'disconnected') {
console.log('Ultravox session disconnected. Attempting to reconnect if desired.');
} else if (session.status === 'listening') {
console.log('Ultravox is now listening for your voice input. Speak freely!');
} else if (session.status === 'speaking') {
console.log('Ultravox AI is responding...');
}
});
session.addEventListener('transcripts', (event) => {
// `session.transcripts` is an array of all received transcripts.
// This event fires for both partial and final transcripts.
const currentTranscripts = session.transcripts;
console.log('Current transcripts: ', currentTranscripts);
// Example: Find and log the latest final transcript
const lastFinalTranscript = currentTranscripts.findLast(t => t.isFinal);
if (lastFinalTranscript) {
console.log(`[${lastFinalTranscript.speaker}]: ${lastFinalTranscript.text}`);
}
});
async function startUltravoxSession() {
try {
console.log('Attempting to join Ultravox call at:', ULTRAVOX_JOIN_URL);
await session.joinCall(ULTRAVOX_JOIN_URL);
console.log('Successfully joined Ultravox call. Waiting for initial status...');
} catch (error) {
console.error("Failed to join call, ensure URL is valid and network is available:", error);
}
}
startUltravoxSession();
// Example: To leave the call after some user interaction or timeout
// setTimeout(() => {
// console.log('Leaving Ultravox call after a demonstration period...');
// session.leaveCall();
// }, 60000); // Automatically leave after 60 seconds