Use the declarations included with the official IllyVoIP Webphone SDK bundle to type your dialer’s options, phone instance and current call. Keep the JavaScript facade, declarations and browser runtime from the same release.
This guide targets the official Webphone SDK 1.4.2 browser distribution. Start with the installation guide, one managed phone owner and an authenticated backend that authorizes the user’s SIP identity. Keep permanent API keys and SIP passwords out of browser code.
1. Import from the supplied package
The reviewed package declares version 1.4.2 and includes index.js and index.d.ts. Follow the official bundle download and installation guide; this package is not presented as a public npm-registry installation. The relative import below assumes your project copied the matching package into vendor/illyvoip-sdk/package.
import { createPhone } from './vendor/illyvoip-sdk/package/index.js';
import type {
ManagedPhoneOptions,
IllyVoipPhoneInstance,
IllyVoipCall
} from './vendor/illyvoip-sdk/package/index.js';
export async function createOwner(
options: ManagedPhoneOptions
): Promise<IllyVoipPhoneInstance> {
return createPhone({ ...options, autoConnect: false, autoRegister: false });
}
export function currentCall(phone: IllyVoipPhoneInstance): IllyVoipCall | null {
return phone.getCurrentCall();
}Managed options require tokenBootstrapUrl and can supply a typed tokenProvider. Your backend must issue tokens only for the signed-in user’s allowed identity. Type checking a response shape does not authorize that identity or validate a browser-supplied SIP user.
2. Keep call state nullable and actions asynchronous
export async function endSelected(call: IllyVoipCall | null): Promise<void> {
if (!call) return;
await call.hangup();
}The call can end between selection and action. Catch the rejected promise in the UI, reread the current state and avoid creating a replacement call. Use the captured call object or ID so an old button action cannot accidentally apply to a newer current call. Represent pending actions explicitly and disable competing controls.
3. Validate event payloads at the boundary
The current on and once declarations accept a string event name and an any payload. Call state is also typed as string, not a complete discriminated union. Do not invent a compiler guarantee that every event contains a valid call object.
export function observeIncoming(
phone: IllyVoipPhoneInstance,
notify: (id: string) => void
): () => void {
return phone.on('call:incoming', (raw: unknown) => {
if (!raw || typeof raw !== 'object' || !('call' in raw)) return;
const call = (raw as { call?: unknown }).call;
if (!call || typeof call !== 'object' || !('id' in call)) return;
const id = (call as { id?: unknown }).id;
if (typeof id !== 'string' || !id) return;
if (phone.getCall(id)) notify(id);
});
}This bounded example validates an ID and resolves it through the owned phone. It does not trust arbitrary payload data as a fully authenticated customer record. Render caller labels as text and keep any CRM lookup behind the application’s authorization boundary.
4. Retain subscription cleanup
- Save the disposer returned by each on or once subscription.
- On owner replacement or component teardown, stop UI actions and dispose the old subscriptions.
- Follow the application’s active-call policy, then await destroy before a replacement owner registers.
- Handle cleanup failure visibly; do not treat a resolved TypeScript compile as proof the old connection ended.
5. Type-check and test runtime behavior separately
Run your project’s strict TypeScript check with DOM and appropriate ECMAScript libraries enabled. Confirm the import resolves the matching declarations. Then test rejected token requests, null current call, malformed event data, double-click actions and stale callbacks locally. A compiler pass cannot establish microphone permission, registration, incoming routing or audible media.
When a runtime option is absent from the declarations, check the matching release source and documentation rather than casting the whole options object to any. The microphone-processing guide records one such version-specific boundary. Keep your application’s supported option surface small and explicit.
Related guides
- Add browser calling with the Webphone SDK
- Manage the IllyVoIP WebRTC Phone SDK lifecycle in React
- Add IllyVoIP browser calling to a Next.js App Router application
- Integrate the IllyVoIP WebRTC Phone SDK into Angular
Reviewed 12 October 2026 against the current IllyVoIP controls, implementation and applicable references. Available options depend on account permissions and service state.