JavaScript API
Drive the widget from your own code β open it, start a call, read its state, listen for events.
Once the widget is installed it exposes a global, window.LimeCall, so your own code can control it.
Everything here runs in the browser and needs no API key β the widget is already authenticated by the data-key in your snippet.
Waiting until it is ready
window.LimeCall does not exist until the script has loaded, and the widget keeps initialising for a moment after that. Use the ready event:
(function poll() {
if (!window.LimeCall) return setTimeout(poll, 100);
window.LimeCall.on("ready", function (state) {
// safe to do anything here
});
})();Subscribing to ready after the widget is already ready still fires your handler, so there is no race to lose.
Methods
open()
Opens the widget panel.
close()
Closes it.
toggle()
Opens if closed, closes if open.
openTab(tab)
Opens the panel on a tab: "call", "message" or "chat".
showLauncher()
Shows the floating launcher button.
hideLauncher()
Hides it β the widget still works through the API.
call(phoneNumber)
Requests a callback to that number.
requestCallback(phone, fields)
Requests a callback and returns a promise with the result.
schedule()
Opens the scheduling view.
startWebCall()
Starts a browser call.
endWebCall()
Ends it.
hasAvailableAgents()
Promise resolving to whether anyone can actually take a call right now.
setDepartment(label)
Routes subsequent requests to a department.
getDepartments()
The departments configured on this widget.
getState()
Returns the widget's current state.
getVisitorId()
This visitor's attribution id.
on(event, handler)
Subscribes to an event.
off(event, handler)
Unsubscribes.
version
The loaded widget version.
openTab(tab)
Only "call", "message" and "chat" are accepted. Anything else returns false and does nothing.
call(phoneNumber)
Trimmed and truncated to 32 characters; an empty value returns false without submitting.
It does not tell you whether the callback was accepted. Either listen for callback:requested and callback:failed, or use requestCallback() below, which returns a promise.
requestCallback(phone, fields)
The same request, but you get the answer back:
Resolves to { ok, id, message }. It never rejects β a network failure resolves as { ok: false, id: null, message: "network error" }, so you do not need a try/catch around it.
The phone number is validated before any network call. It must be E.164 β a leading +, country code, 7β15 digits β and anything else resolves immediately with ok: false and a message saying so. Spaces, dashes and brackets are stripped for you, so +44 7700 900123 is fine; 07700900123 is not, because there is no country code.
name is capped at 80 characters and email at 120. The department set through setDepartment() and the visitor's attribution id are attached automatically β you do not pass either.
hasAvailableAgents()
Resolves to true or false: can a call actually be taken right now?
The answer depends on how the widget routes:
To a person or team
Working hours, and whether the people it routes to still resolve. Someone who has left the account makes it false, not a silent dead end.
To the AI receptionist
Your remaining AI minutes. If you are out but have an overflow person configured, it is still true β a human answers.
Use it to decide whether to offer a call at all. Offering one that nobody picks up costs more goodwill than not offering it.
It is deliberately conservative on the client and optimistic on the server. No widget key, or a network failure, resolves false β so a broken page hides the call button rather than promising a call. But if the availability check itself errors server-side it answers true, matching what the call path does: an outage should not silently switch off inbound calls. Treat it as a strong signal, not a guarantee.
setDepartment(label) and getDepartments()
If your widget has departments, you can route from code instead of making the visitor choose:
getDepartments() returns the department names as plain strings. It reads them from the widget's loaded configuration, so call it inside ready β before that it returns an empty array.
setDepartment(label) applies to every request afterwards: the form, call(), requestCallback() and browser calls. It also moves the visible department picker, if one is rendered. Pass "" or null to clear it.
A label that does not match a configured department resets the visible picker to "Any department", and routing falls back to your default. Match the names exactly as they appear in getDepartments().
getVisitorId()
Returns the attribution id the widget assigns this visitor, or null before it is ready:
It is the same id carried on callback requests, so it is how you stitch a widget conversion to a session in your own analytics.
getState()
ready
The widget has finished initialising.
open
The panel is open.
mode
Display style: inline, bubble, side or popup.
inWebCall
A browser call is in progress.
tab
The tab currently shown, or null.
visible
The widget is rendered on this page β respects your display rules.
visible is the one to check before wiring your own button to open(): a display rule may have hidden the widget on this page entirely.
Events
Subscribe with on(event, handler), unsubscribe with off(event, handler).
ready
The widget has initialised.
{ visible, mode }
open
The panel opens.
{ mode }
close
The panel closes.
{ mode }
tab
The visitor switches tab.
{ tab }
teaser
The teaser prompt is shown.
{ text }
score
The visitor's lead score changes.
{ points, total, threshold, rule }
callback:requested
A callback was accepted.
{ phone, mode, id } β mode is "now" or "schedule"; scheduledAt present when scheduled
callback:failed
A request was rejected or failed.
{ reason, phone, message } β reason is "rejected" or "network"
message:sent
The visitor sent a message.
β
webcall:started
A browser call began.
β
webcall:ended
A browser call ended.
β
Unknown event names are rejected: on() returns false rather than silently registering a handler that never fires.
Tracking a conversion
callback:requested fires only once the request was accepted, so it does not over-count:
Wire callback:failed too. A silent rejection β closed hours, a blocked number, an unsupported country β otherwise looks exactly like a visitor who changed their mind.
The score event
The widget scores visitor engagement and fires score as it changes, with the running total and the threshold it is working toward. Use it to trigger your own behaviour β reveal an offer, or open the widget β when someone is clearly engaged:
Opening from your own button
Opening from a link, with no code
Any link to #limecall opens the widget when the page loads:
#lc-open and #lc-widget do the same thing. They work across pages too, which is the useful part β put https://example.com/pricing#limecall in an email, an ad or a QR code and the widget opens on arrival, with nothing to install on the page beyond the usual snippet.
Next
Connect your own form β fire a callback from a form you already have
Widget recipes β copy-paste patterns
Was this helpful?