Headless JavaScript phone-call SDK for the K-Link Customer Support Platform.It lets your application place and receive calls through your K-Link telephony
extension without exposing PBX credentials to the browser user. The SDK
authenticates against the K-Link public API with an API token, resolves the
extension's webphone credentials server-side, and then drives the WebRTC call
engine locally. No UI is included — you bring your own.Install#
Zero runtime dependencies — the telephony engine is bundled inside the
package and loaded lazily on init().Prerequisites#
1.
A K-Link API token — create one under Settings → API Tokens
(kpt_...). Treat it like a password; on the web it should be delivered
to the page by your backend, not hard-coded.
2.
The member you connect as must have a telephony extension assigned in
K-Link (Settings → Phone Extension).
3.
Microphone permission in the browser.
Quick start#
API#
KlinkCallSdk.init(config)#
| Option | Type | Default | Description |
|---|
userEmail | string | — (required) | K-Link member email whose extension to use |
accessToken | string | — (required) | K-Link API token (kpt_...) |
apiBaseUrl | string | https://apigw.klinkcx.com | Public API origin |
requestTimeoutMs | number | 15000 | Credential-fetch timeout |
Returns Promise<KlinkCallSdk>. Throws KlinkCallSdkError with code:
invalid_config · auth_failed · extension_not_found ·
extension_not_provisioned · network_error · init_failed.Events#
| Event | Payload | When |
|---|
ready | — | Engine started, registration in progress |
incoming | { call } | Inbound call ringing |
sessionStarted | { call } | Call established / dialing |
sessionEnded | { callId, cause } | Call ended |
remoteStream | { callId, stream } | Remote call audio available |
connected / disconnected | — | PBX socket transport state |
registeredChange | { registered } | SIP registration state |
registrationFailed | { code, message } | Registration rejected |
error | { scope, detail } | Runtime errors |
destroyed | — | After destroy() |
on(event, fn) returns an unsubscribe function. once and off are also
available.Call controls#
call(number) · answer(callId) · reject(callId) · hangup(callId) ·
hold/unhold(callId) · mute/unmute(callId) · dtmf(callId, tones) ·
attachAudio(element) · getCalls() · isRegistered · destroy()Audio (required)#
The SDK renders no UI, but it can manage call audio for you — pass it an
<audio> element once and remote streams are piped in and released
automatically:sdk.attachAudio(document.querySelector('audio')!)
Prefer to control playback yourself? Listen for the remoteStream event:sdk.on('remoteStream', ({ callId, stream }) => {
myAudioElement.srcObject = stream
})
Without one of these, calls connect but stay silent. See
examples/basic for a complete working app.Example app#
A minimal framework-free test UI lives in examples/basic
(it installs the published @klink.cloud/call-sdk from npm):Security notes#
Rotate or revoke API tokens from Settings → API Tokens at any time;
in-flight SDK instances keep working until the PBX signature expires, but
new init calls with a revoked token fail with auth_failed.
Issue one API token per integration so a leak is independently revocable.
The SDK only ever reads extensions belonging to the token's own tenant.
Modified at 2026-06-12 08:40:44