Channels

Chat widget.

One snippet. Themable. Identity-aware.

Add it once, anywhere.

Paste the snippet before your closing </body> tag. Replace YOUR_ORG_ID with the value from your dashboard. That’s the whole install.

<script>
  (function() {
    var s = document.createElement("script");
    s.src = "https://cdn.kaltalk.com/widget.js";
    s.async = true;
    s.onload = function() {
      KalTalk.init({
        organizationId: "YOUR_ORG_ID"
      });
    };
    (document.head || document.body || document.documentElement).appendChild(s);
  })();
</script>

Vite, CRA, or any other SPA? Drop the HTML snippet into your index.html. Same effect.

Pass identity if they’re signed in.

If you already know who’s on the page, pass it to the widget. Their replies attach to the same person across visits, and the AI can use the context.

KalTalk.init({
  organizationId: "YOUR_ORG_ID",
  customerExternalId: "user_123",
  customerEmail: "ada@example.com",
  customerName: "Ada Lovelace",
  customerPhone: "+1 555 0100",
  customerCompany: "Lovelace & Co",
  // Typed customer traits your team and AI agents will see on every
  // conversation. Only keys you've defined under
  // Dashboard > Data > Attributes are stored - anything else is dropped.
  // Flat, scalar-only (string / number / boolean / null), up to 10 keys.
  customerAttributes: {
    plan: "Pro",
    signup_date: "2025-01-15",
    mrr: 99,
    is_trial: false
  }
});

customerAttributes is flat and scalar-only - up to 10 keys, strings / numbers / booleans / null. Nested objects and arrays are dropped. Keys must match an active attribute defined under Dashboard › Data › Attributes - everything else is silently ignored. The identify response surfaces drop counts under droppedAttributes so you can see what didn’t land.

Values are self-reported by the visitor and shown to your team as such - don’t make trust decisions on them without a server-side check. To make identity itself trustworthy, see Identity verification.

Hide the bubble, open from your UI.

Some teams prefer to open the chat from their own button, a menu item, or a link inside the app. Pass hide: true and the default bubble never shows. Open and close the chat whenever you want with window.KalTalk.open() and window.KalTalk.close().

KalTalk.init({
  organizationId: "YOUR_ORG_ID",
  hide: true
});

// Open the chat from your own button, link, or menu item.
document.getElementById("contact-support")
  .addEventListener("click", function () {
    window.KalTalk.open();
  });

// Close it programmatically at any time.
// window.KalTalk.close();

Customize from the dashboard.

Color, position, header text, welcome message, avatar - all editable from your widget settings, no code change needed. Pick what you want, save, and your live widget updates within seconds. Need wording for the welcome message? See 25 live chat greeting examples for copy and trigger timing by page type.

A few things worth knowing.

Loads async
The snippet doesn’t block your page. It loads after everything else.
One install per app
For Next.js, React, etc., add it once at the root - not on every page.
Hide branding
The "Powered by KalTalk" footer comes off on Pro and above.

New here? Start with Quickstart.