JavaScript APIAll pages

JavaScript API

One global, one method, four verbs. $connect.push is the entire public surface — there is no second object to find, no SDK to install, and nothing to wait for before you call it.

The shape of a command#

Every command is an array of up to three elements: a verb, a key, and the arguments. The argument nesting is not decoration — several commands take a list of things, so the outer array is the argument list and the inner one is the value.

the grammar
$connect.push([verb, key, args]);

// do        run something now
// set       tell Connect about this visitor
// on / off  subscribe to a widget event
// register  expose something on this page to Connect

Unknown verbs and unknown keys are ignored. Nothing in this API throws into your page, and a mistyped command fails silently rather than breaking the widget — which is also why a typo is easy to miss.

The queue#

$connect starts as a plain array. The loader replaces it with a live object that has the same push signature, replays whatever was queued in order, and from then on runs commands immediately. You never need a readiness check.

pushing before the widget exists
// Before the loader has run, $connect is a plain array.
// Push anyway — everything is replayed in order once it boots.
window.$connect = window.$connect || [];
$connect.push(["set", "user:nickname", ["Jane Okafor"]]);
$connect.push(["do", "chat:open"]);

Commands bound for the chat window are held until the iframe is listening, so nothing pushed early is lost. If the chat window ever reloads mid-session — a browser reclaiming memory, an error recovery — the last user:* and session:data/session:segments command for each key is replayed automatically, so the visitor does not silently become anonymous again.

do — actions#

Five actions, all handled by the loader, all instant.

every action there is
$connect.push(["do", "chat:open"]);    // open the chat window
$connect.push(["do", "chat:close"]);   // close it
$connect.push(["do", "chat:toggle"]);  // whichever it is not
$connect.push(["do", "chat:hide"]);    // remove the launcher entirely
$connect.push(["do", "chat:show"]);    // put it back
["do", "chat:open"]
Opens the chat window, clears the unread badge, and fires chat:opened. On a phone this is the full-screen sheet.
["do", "chat:close"]
Closes it and fires chat:closed.
["do", "chat:toggle"]
Whichever of the two applies.
["do", "chat:hide"]
Hides the launcher and the chat window completely. The widget stays connected underneath — messages still arrive, the badge still counts — so this is a visual switch, not a teardown.
["do", "chat:show"]
Undoes chat:hide.

set — visitor data#

Six keys, each sent straight through to the visitor’s record where your agents see it. Every one of them is covered in detail, with the limits, on Identity and data.

all six set commands
$connect.push(["set", "user:email",     ["jane@acme.com", "<optional hmac>"]]);
$connect.push(["set", "user:nickname",  ["Jane Okafor"]]);
$connect.push(["set", "user:avatar",    ["https://acme.com/u/jane.jpg"]]);

$connect.push(["set", "session:data",     [[["plan", "pro"], ["mrr", 99]]]]);
$connect.push(["set", "session:segments", [["customer", "priority"]]]);
$connect.push(["set", "session:event",    [[["checkout_started", { cart: 129.9 }, "orange"]]]]);
["set", "user:email", [email, hmac?]]
The visitor’s address. The second argument is an HMAC that proves it is really them — without it the address shows as unverified. Also dismisses the widget’s offline email form.
["set", "user:nickname", [name]]≤ 120 chars
The display name your agents see instead of “Visitor”.
["set", "user:avatar", [url]]
An absolute image URL for the visitor’s avatar.
["set", "session:data", [pairs]]≤ 50 keys · values ≤ 500 chars
An array of [key, value] pairs shown as chips in the agent sidebar and searchable. Values are scalars — string, number, boolean.
["set", "session:segments", [list]]≤ 20 segments · ≤ 60 chars each
Flat labels for grouping and filtering visitors.
["set", "session:event", [events]]
An array of [name, data?, colour?] entries appended to the visitor’s timeline. Sent one request per event.

on and off — events#

Two events, both about the chat window’s open state, both fired whether the visitor clicked the launcher or your code called chat:open.

subscribing
$connect.push(["on", "chat:opened", function () {
  analytics.track("support_chat_opened");
}]);

$connect.push(["on", "chat:closed", function () {
  analytics.track("support_chat_closed");
}]);

// Removes EVERY handler registered for that event.
$connect.push(["off", "chat:opened"]);
chat:opened
The chat window became visible.
chat:closed
It became hidden.
  • Handlers can be registered before the widget loads, like any other command.
  • off takes an event name only — it removes every handler for that event. There is no way to remove one callback.
  • An exception thrown inside your handler is caught and ignored, so a bug in your analytics cannot break the widget. It will not appear in the console either; log inside your own try if you need to see it.

register — functions#

["register", "function", [manifests]] exposes functions on your page that an agent, or the AI, can run in the visitor’s browser. It has its own page: Client functions.

Globals#

window.CONNECT_WEBSITE_KEYrequired
Your public website key. Without it the loader warns once and stops.
window.CONNECT_TOKEN_IDoptional
An unguessable per-user token from your backend, tying this browser to a known visitor across devices. See Signed-in visitors.
window.CONNECT_READY_TRIGGERoptional
A function called once the queue has been replaced and drained. Define it before the snippet.
window.__CONNECT_LOADED__read only
true after the loader has run. It is also the guard that makes a second copy of the snippet a no-op.

That is the complete list. The widget patches no prototypes, adds no styles to your page, and takes no other globals.

What does not exist#

Documented because these appear in the original product specification and in Crisp-shaped code people bring with them. Calling any of them is harmless and does nothing at all.

$connect.get(…)
There are no synchronous getters. The visitor’s state lives in the cross-origin frame and cannot be read from your page.
["do", "message:send"]
A page cannot put words in a visitor’s mouth. Open the chat and let them type.
["do", "session:reset"]
No way to unbind a visitor on logout yet. On a shared device the next person inherits the session. Where that matters, use a token id so the identity at least follows the account rather than the browser.
["config", …]
Accepted by the grammar and forwarded, but nothing consumes it. Appearance is dashboard configuration.
message:received, session:loaded, …
The only events are chat:opened and chat:closed. Subscribing to any other name registers a handler that is never called.

Why the list is here#

Because a silent no-op is the worst failure mode in an API, and the alternative to writing this down is an afternoon spent wondering why your handler never fires.