Voice SDK: Click to Call From Any App
The K-LINK Voice SDK (@klink.cloud/call-sdk) lets you place and receive real phone calls from inside your own web application, using your klink.cloud telephony extension.
Overview
The K-LINK Voice SDK (@klink.cloud/call-sdk) lets you place and receive real phone calls from inside your own web application, using your klink.cloud telephony extension.
It is headless, which means it handles the calling and gives you no interface. You build the interface, so the softphone can look and behave exactly how you want. PBX credentials are never exposed in the browser: the SDK authenticates with an API token and resolves the extension credentials on the server side.
What you can build with it
A custom softphone inside your own CRM, portal or admin panel
A click to call button in a tool like Airtable, Notion, Retool or a Google Sheet
Call steps inside a custom workflow, for example call the customer, then log the outcome
An embedded dialer in an internal app so agents never switch tabs
Before you start
API token. Create one in klink.cloud under Settings > API Tokens. It looks like
kpt_.... Treat it like a password. On a public web page it should be delivered by your backend, not written into the page.A user with telephony permission. You only need the email address of a klink.cloud user who can already make calls inside app.klink.cloud. Nothing else to configure, and no extension settings to check.
Microphone permission in the browser.
HTTPS. Browsers only allow microphone access on secure pages.
How it works
Your page loads the SDK and calls
init()with the member email and API token.The SDK fetches the webphone credentials and registers with the PBX.
You call
sdk.call(number)from your own button, and audio flows through an<audio>element you provide.The call is logged automatically in klink.cloud, with recording, under Call Logs.
Minimal setup
That is the whole integration. Everything else is your own design.
Example: click to call from Airtable
This is the setup shown in the demo video. It takes a normal Airtable base of contacts and turns it into a working outbound calling tool.
Step 1. Build a small dialer page
Create a single web page that loads the Voice SDK and reads the phone number from the URL, for example https://yourcompany.com/dialer?number=+6585900251.
Host it anywhere you like. Keep the API token behind your backend.
Step 2. Add a call button in Airtable
In your contacts table, add a Button field, set the action to Open URL, and use a formula that appends the row's phone number:
Step 3. Call from the record
Click the button on any row. A new tab opens and starts dialing that contact straight away. Talk as normal, then close or end the call.
Step 4. Log the result back in Airtable
Return to the record and fill in your fields, for example:
Outcome: Connected
Notes: Requested a demo, follow up next week
Next step and date
Save the record. Your call notes now live with the contact in Airtable, while the call itself, including the recording, is stored in the klink.cloud call log.
You can go further and have the dialer page write the outcome back automatically through the Airtable API when the sessionEnded event fires.
Useful events
ready
Engine started, registering
incoming
Inbound call ringing
sessionStarted
Call established or dialing
sessionEnded
Call ended, with the reason
remoteStream
Remote audio is available
registeredChange
SIP registration state changed
error
Runtime error
Call controls
call(number), answer(callId), reject(callId), hangup(callId), hold and unhold, mute and unmute, dtmf(callId, tones), attachAudio(element), getCalls(), isRegistered, destroy()
Troubleshooting
Call connects but there is no sound
You did not call attachAudio() or handle the remoteStream event
auth_failed
The API token is wrong, expired or revoked
extension_not_found
The member email has no telephony extension assigned
extension_not_provisioned
The extension exists but is not fully set up on the PBX
Nothing happens on click
Microphone permission was denied, or the page is not served over HTTPS
network_error
The API base URL is unreachable, or the request timed out
Security
Issue one API token per integration so a leak can be revoked on its own.
Rotate or revoke tokens any time from Settings > API Tokens.
Never hard code a token in a public page. Serve it from your backend.
A token can only reach extensions inside its own tenant.
Reference
Full SDK documentation: https://developers.klink.cloud/klink-cloudcall-sdk-2202660m0 Example app: https://github.com/K-Link-Tech/call-sdk
Last updated