Skip to main content
A chat widget is one URL. Everything below is a wrapper around it.
Nothing to install, no SDK, no API key, and no server of your own. The page is hosted by CallKaro, so changing the flow never needs an app release.
The same snippets are on the widget itself in the dashboard — Widgets → your chat widget → Integration — already filled in with your widget id.

Telling Us Who The Visitor Is

Two optional parameters, and both are worth adding if your app knows the answer. Your uid is stored exactly as you send it. If it happens to be a phone number it is normalised to digits, so the widget conversation lands on the same CRM contact as that person’s calls and WhatsApp — see Variables and identity.
Without a uid the visitor still gets a stable identity of their own, minted in the browser and kept — so an anonymous visitor is still the same person next week, on that device.
uid is an unauthenticated claim. Anyone who can open the widget can put any value in the URL — including a phone number that is not theirs, and be handed that contact’s CRM record. It is right for a widget embedded behind your own app’s login, which is what it is for; it must not gate anything the person should not see, and it must not be a value that is itself a secret. Signed tokens are not supported yet.

The Snippets

SFSafariViewController keeps the user inside your app and needs no extra entitlements. Use WKWebView instead if you want the chat inside your own navigation stack.

A button in your flow can open a screen in your own app instead of moving to another card — “Open Edit Profile”, “Show my orders”. Set the button’s link to your own scheme, e.g. myapp://profile/edit. In a Custom Tab or SFSafariViewController the system routes it to your app. In a WebView you handle it yourself, as in the Android snippet above. javascript:, data:, vbscript:, file: and blob: links are rejected when the flow is saved.

Attachments And The Microphone

On an AI assistant card, and during a human handoff, the composer offers a paperclip and a microphone. Two things that catch people out inside an app:
  • A WebView must grant the page’s own microphone permission request, on top of the host app’s OS-level permission. A Custom Tab or SFSafariViewController handles this for you.
  • Recording needs a secure context, which every URL above already is.
Size limits are on the introduction page.

Checking It

Open the URL in a desktop browser first. If the flow runs there, the embed will run — every snippet above loads the same page. If it does not, work down Troubleshooting — the two usual causes are an agent that was never published and an inactive Widgets subscription.

Next Steps

Card types

What you can build into the flow

Variables and identity

uid, vars, and how contacts are keyed