Skip to content

Browser Widget

Load the script from:

https://dashboard.awajdigital.com/sdk/amarvoice-call.js

That makes AmarVoiceCall available on the page. The phone popup sits in the bottom-right corner and uses its own styles, so your page CSS will not restyle it. It still opens from open(), call(), or an incoming call if you never pass a button.

HTTPS is required. Add production hostnames under Profile → Call SDK. For http://localhost, turn on localhost test mode on that page (1 or 3 days).

const phone = new AmarVoiceCall({
tokenUrl: '/api/amarvoice-token',
callbacks: {
onRegistrationState: (state) => {},
onIncomingCall: ({ remoteParty, remoteName }) => {},
onCallAnswered: () => {},
onCallEnded: () => {},
onError: (message) => {},
onMuteChanged: (muted) => {},
},
});
phone.mount('[data-call]');

mount puts the phone popup on the page and starts connecting in the background. How a call starts is below.

Option Type Required Description
tokenUrl string Yes* Your login-protected route that proxies Mint SDK Token.
sessionUrl string No Override for POST /api/sdk/session. Taken from the token response when omitted.
token string No Already-created token. Use tokenUrl instead unless you create it yourself.
callbacks object No Optional hooks; the widget still updates itself without them.

* Pass tokenUrl, or pass both token and sessionUrl.

The SDK POSTs tokenUrl when the user connects (not on page load). After disconnect(), create a new AmarVoiceCall so it can request a token again.

Both use the same AmarVoiceCall object. mount always adds the popup. The difference is who handles the click.

Pass a selector for the elements that should open the phone.

<button type="button" data-call="01712345678">Call customer</button>
<button type="button" id="open-phone">Open phone</button>
phone.mount('[data-call], #open-phone');

Against that HTML:

  • Click Call customer — the element has data-call="01712345678", so the popup opens and a call starts to that number.
  • Click Open phone — no data-call, so the keypad opens empty and the agent types the number.

Any element you pass to mount opens the phone. data-call="01…" is the special part: that value is the destination, and the call starts. Without it, the agent uses the keypad.

You can pass a selector, a DOM element, or a list of elements. A second mount replaces the first.

phone.mount('#open-phone');
phone.mount(document.getElementById('open-phone'));
phone.mount(document.querySelectorAll('[data-call]'));

Use this when the number is already in your JavaScript — a selected row, a search result, or a handler you already have. Do not put data-call on those elements. Call mount() with no selector so the popup is on the page, then phone.call(number) from your code.

From a function

const phone = new AmarVoiceCall({
tokenUrl: '/api/amarvoice-token',
});
phone.mount();
function callCustomer(number) {
phone.call(number);
}
callCustomer('01712345678');

mount() adds the popup without wiring buttons. phone.call opens it and starts the call to that number — same result as clicking a data-call button.

From your own click handler

<tr data-phone="01712345678">
<td>Ayesha</td>
<td><button type="button" class="call-btn">Call</button></td>
</tr>
phone.mount();
document.querySelectorAll('[data-phone]').forEach((row) => {
row.querySelector('.call-btn').addEventListener('click', () => {
phone.call(row.getAttribute('data-phone'));
});
});

The number lives on the row (or in your app state), not in data-call. Your handler decides which number to dial.

Open the keypad without starting a call

phone.mount();
phone.open();

Use this for a toolbar button or shortcut that should only show the dialer. The agent types the number.

Mix both

phone.mount('[data-call]');
function callFromSearch(number) {
phone.call(number);
}

The SDK still listens to data-call buttons. Other parts of your page call phone.call with a number they already have. Incoming calls open the popup in all of these.

Method Description
mount(target?) Attach the popup to buttons (or to the page with no trigger). Returns this.
unmount() Remove the popup and unbind those buttons.
open() / close() / isOpen() Show or hide the panel.
connect() Start the session. mount() already calls this.
call(number) Place an outbound call. Also available as placeCall(number). Opens the popup. Does nothing on an empty string; errors if a call is already in progress.
answer() / reject() Answer or decline an incoming call.
hangup() End the current call (outbound or inbound).
mute() / unmute() / setMuted(boolean) Mute the local microphone on an established call. Does not put the other party on hold.
isMuted() / isOnCall() Current mute / call flags.
setAudioElement(el) Where remote audio plays. If omitted, connect() creates a hidden <audio> element.
disconnect() Sign out of the phone and return the popup to idle. Create a new AmarVoiceCall to connect again.
Callback When
onRegistrationState(state) state is registering, registered, failed, or disconnected.
onIncomingCall({ remoteParty, remoteName }) An incoming call. The popup opens itself.
onCallAnswered() Call established (outbound or inbound).
onCallEnded() Call terminated (local hangup, remote hangup, or failure after ringing).
onError(message) Connect failure, mute with no call, overlapping call(), or a call error.
onMuteChanged(muted) Mute applied or cleared, including on hangup.
  • Idle — number field, 12-key pad, Call.
  • Ringing out — destination + Hang up.
  • Ringing in — remote party, Answer, Decline.
  • Active — duration, Mute / Unmute, Hang up.
  • Ended — returns to idle after a short pause.

The widget requests the microphone when a call starts. The user must allow it.

phone.unmount();
await phone.disconnect();

Call these when your user leaves the page or logs out, and revoke the agent session from your backend with Revoke Session.