Skip to main content
The widget exposes one global function, window.karta, in the Segment/Intercom style: you call karta(command, ...args). It is load-order independent - install a tiny inline queue stub, call it immediately, and the bundle replays your calls in order once it loads. If all you want is the drop-in launcher, you do not need any of this - see the Quickstart. Reach for the command API when you want to open the widget from your own UI, identify the signed-in user, or react to what happens inside it.

The inline queue stub

Add the stub once (before or after your own scripts), then load the bundle async. Calls made before the bundle arrives are buffered and replayed in order.
<script>
  // Buffers calls until the real bundle arrives, then replays in order.
  window.karta = window.karta || function () {
    (window.karta.q = window.karta.q || []).push(arguments);
  };
</script>
<script
  async
  src="https://cdn.karta.sh/widget/v1/karta.js"
  data-embed-key="pk_live_xxx"
  data-project="coffeeco/support-bot"
></script>

<script>
  // These run BEFORE the bundle finishes loading and still take effect, in
  // order: identify is applied before the session opens.
  karta("identify", { userId: "u_123", attributes: { plan: "pro" } });
  karta("on", "message:received", (e) => analytics.track("agent_reply", e));
  document.querySelector("#help").addEventListener("click", () => karta("open"));
</script>
You can also drive the whole config from JavaScript with init instead of data-*:
karta("init", {
  baseUrl: "https://agent.karta.sh",
  projectRef: "coffeeco/support-bot",
  embedKey: "pk_live_xxx",
  theme: { accent: "#d4ff4f", agentName: "Beans" },
});

Commands

CommandArgsEffect
init{ ...overrides }Per-page config overrides, merged before mount. Ignored after the widget has mounted.
identify{ userId?, attributes?, identityToken? }Identity for the next session. userId/attributes are advisory only - never an auth credential. identityToken is the verified path.
open / close / toggle-Show / hide / flip the panel. The first open/toggle/sendMessage triggers the lazy mount.
sendMessagetextProgrammatically send a user message and drive a turn.
escalate{ reason?, context? }Fire the escalate event for your page to handle (e.g. open a live-chat handoff). Event-only.
on / off / onceeventName, callbackSubscribe / unsubscribe / subscribe-once to a host-page event (below).
shutdown / reset-Tear the widget down (abort in-flight work, remove the host).
Unknown commands are logged via console.warn and ignored - a bad call never throws into your page.

Events

Subscribe with karta("on", name, callback):
EventPayloadFires when
ready-The widget has mounted and is interactive.
open / close-The panel was opened / closed.
session:started{ sessionId }A backing agent session was created (or resumed).
message:sent{ text }The user submitted a message.
message:received{ text }A turn completed; text is the final assistant message.
unread{ count }An assistant message arrived while the panel was closed (running count; resets to 0 on open).
escalate{ reason?, context? }The user or a command asked to escalate to a human. context carries the recent transcript + sessionId.
error{ message, code? }A turn failed (stream / auth / transport).
limit_reached{ message, code?, retryAfterSeconds? }The assistant hit a usage / spend / rate limit. The widget shows a friendly state and locks the composer - see Security & privacy.
karta("on", "unread", ({ count }) => setBadge(count));
karta("on", "escalate", ({ context }) => openLiveChat(context));
karta("on", "limit_reached", ({ retryAfterSeconds }) => showBackLater(retryAfterSeconds));
karta("on", "error", ({ message, code }) => console.warn("karta:", code, message));

const onReady = () => console.log("widget ready");
karta("on", "ready", onReady);
karta("off", "ready", onReady); // unsubscribe
A throwing subscriber is caught and logged - it can never break the widget or starve other subscribers.

Next

Identity

identify in depth: soft vs verified, and the HMAC scheme.

Headless & React

Skip the prebuilt UI: KartaAgentClient and <KartaWidget/>.