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.
$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 ConnectUnknown 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.
// 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.
$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.
$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.
$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.
offtakes 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
tryif 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
trueafter 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:openedandchat: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.