> ## Documentation Index
> Fetch the complete documentation index at: https://docs.callkaro.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Chat Widget

> A chat agent for your website or app — scripted where you want certainty, AI where you want conversation, and a person when neither will do

A chat widget puts a **chat agent** in front of the people already on your site
or inside your app. The visitor reads a message, taps one of your buttons or
types, and moves through a conversation you designed — and if the bot cannot
finish the job, a person on your team takes over in the same window.

<Card title="Open Widgets in the dashboard" icon="grid-2" href="https://callkaro.ai/dashboard/widgets">
  Everything on this page starts here.
</Card>

***

## The Three Modes In One Flow

A chat widget is **not** one bot style. You mix three, card by card, in the same
conversation:

<CardGroup cols={3}>
  <Card title="Scripted" icon="diagram-project">
    Buttons, questions, branches. The visitor walks exactly the paths you drew.
    Nothing is improvised, so nothing goes off-script.
  </Card>

  <Card title="AI" icon="sparkles">
    An **AI assistant** card hands the conversation to a model for as long as it
    takes — with your prompt, your functions and your data.
  </Card>

  <Card title="Human" icon="user-headset">
    A **handoff** card gives the conversation to a teammate, who replies from
    Contacts in the same window.
  </Card>
</CardGroup>

A typical flow is a scripted menu that routes most people to self-serve answers,
an AI card for "something else", and a handoff for the cases only a person can
close.

<Note>
  This is not the same thing as a WhatsApp or Instagram chat agent, which is
  prompt-driven end to end. A chat widget uses an agent in **flow** mode, and flow
  mode is only supported on the widget channel.
</Note>

***

## What We Support

|                                        | Supported                                                                                 |
| -------------------------------------- | ----------------------------------------------------------------------------------------- |
| **Channels the visitor can arrive on** | Your website (script tag or iframe), iOS, Android, React Native, Flutter, or a plain link |
| **Card types**                         | 14 — see [Card types](/widget/chat/card-types)                                            |
| **Free text**                          | On `ask` cards, on an AI card, and during a human handoff                                 |
| **Buttons**                            | Up to 30 per card, with **bold**, *italic* and links in the label                         |
| **Rich text in messages**              | `**bold**`, `*italic*`, `[text](url)` and bare URLs                                       |
| **Images / video / files out**         | `media` cards, and an AI card calling a send function                                     |
| **Files in from the visitor**          | Images, video, audio, PDF, Word, Excel — on an AI card and during a handoff               |
| **Voice notes**                        | Both directions — the visitor records in the composer, the agent records in Contacts      |
| **Your own code**                      | Python on a `function` card, and Python tools on an AI card                               |
| **Your own APIs**                      | `api` cards, and `httpx` inside your code                                                 |
| **Secrets**                            | Account secrets injected as `x_secrets`, never printed                                    |
| **CRM**                                | Every conversation becomes a contact, with variables and full transcript                  |
| **Human handoff**                      | Availability, assignment, private notes, lifecycle events                                 |
| **Tickets**                            | Your own Python, run when nobody is available                                             |
| **Business hours**                     | Per-account, in your timezone, gating handoffs only, with a configurable visitor notice   |
| **Knowledge base**                     | FAQs and articles, browsable without starting a chat                                      |
| **Identity**                           | Anonymous, browser-stable, or your own `uid`                                              |
| **Translation**                        | In the dashboard, for the agent reading and replying                                      |

***

## What The Visitor Gets

The panel opens on a home screen with your greeting, your knowledge base, and
two things to do:

<CardGroup cols={2}>
  <Card title="Chat with us" icon="message">
    Starts a new conversation, or picks up the one they left.
  </Card>

  <Card title="Conversations" icon="clock-rotate-left">
    Their own past conversations, readable in full.
  </Card>
</CardGroup>

Everything else — the messages, the buttons, the images, when a human appears —
comes from the flow you built. A **New Chat** button sits in the header
throughout, so nobody is ever stuck.

A visitor is remembered across conversations even if you never tell us who they
are. If your app *does* know who they are, pass a `uid` — see
[Variables and identity](/widget/chat/variables).

***

## How It Works

<Steps>
  <Step title="Build a chat agent in flow mode">
    Create a chat agent on the **widget** channel with mode **Flow**, then draw
    the conversation on the canvas.
    [Chat agents →](https://callkaro.ai/dashboard/agents)
  </Step>

  <Step title="Publish it">
    A flow only goes live when you publish the version. The builder blocks
    publishing while anything is unwired, so a half-built flow cannot reach a
    visitor.
  </Step>

  <Step title="Create a chat widget">
    In **Widgets**, create a widget of type **Chat** pointing at that agent. You
    get a widget id.
    [Widgets →](https://callkaro.ai/dashboard/widgets)
  </Step>

  <Step title="Put it in your site or app">
    One URL, one script tag, or a few lines of Swift, Kotlin or JS.
    [Install →](/widget/chat/install)
  </Step>

  <Step title="Watch it in Contacts">
    Every conversation becomes a contact with a full transcript, and a teammate
    can reply from there.
    [Contacts →](https://callkaro.ai/dashboard/contacts)
  </Step>
</Steps>

***

## Where Conversations Appear

Everything a chat widget produces lands in
[**Contacts**](https://callkaro.ai/dashboard/contacts), not Call History.

* A contact row is created for **every** conversation, even an anonymous one.
  Filter the channel to **Widget** to see only these.
* Opening a contact shows the full transcript, the variables the flow collected,
  any functions the AI card ran, and — if a human is involved — who it is
  assigned to.
* A teammate can reply straight into that transcript and the visitor sees it
  immediately, without refreshing.
* The timeline also carries **private notes** and **lifecycle events**
  (transferred, ticket raised, chat ended) that the visitor never sees.

<Info>
  The flow's variables are shown alongside the transcript. If your flow asked for
  an order id, you can read it there without scrolling the conversation.
</Info>

***

## Limits Worth Designing Around

| Limit                               | Value                       |
| ----------------------------------- | --------------------------- |
| Cards in one flow                   | 5,000                       |
| Buttons or branches on one card     | 30                          |
| Message length                      | 4,000 characters            |
| Button label length                 | 80 characters               |
| Turns in one conversation           | 200                         |
| How long a conversation resumes for | 12 hours idle               |
| Concurrent chats per teammate       | 10                          |
| API card timeout                    | 8 seconds                   |
| Run-code card timeout               | 8 seconds                   |
| AI card function timeout            | 5–120 seconds, per function |
| Functions on one AI card            | 10                          |
| Visitor upload — image              | 5 MB                        |
| Visitor upload — video / audio      | 16 MB                       |
| Visitor upload — document           | 20 MB                       |
| Uploads per session                 | 10 per minute               |

There is no idle timer: nothing is ever sent to a visitor unprompted, so there
is no "still there?" nudge and no auto-close.

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Create a chat widget" icon="plus" href="/widget/chat/create-a-chat-widget">
    Agent, flow, publish, widget
  </Card>

  <Card title="Card types" icon="diagram-project" href="/widget/chat/card-types">
    All fourteen cards and every field
  </Card>

  <Card title="The AI card" icon="sparkles" href="/widget/chat/ai-card">
    Prompt, model, functions, attachments, billing
  </Card>

  <Card title="Variables and identity" icon="brackets-curly" href="/widget/chat/variables">
    Templating, `uid`, `vars`, contact keys
  </Card>

  <Card title="Appearance and hours" icon="palette" href="/widget/chat/appearance">
    Branding, business-hours notice, rich text
  </Card>

  <Card title="Human handoff" icon="user-headset" href="/widget/chat/human-handoff">
    Availability, replying, notes, voice notes
  </Card>

  <Card title="Chat routing" icon="sliders" href="/widget/chat/chat-routing">
    Hours, away, no-reply, end-of-chat
  </Card>

  <Card title="Raise a ticket" icon="ticket" href="/widget/chat/ticket-fallback">
    Your own Python, run when nobody is free
  </Card>

  <Card title="Install in your app" icon="code" href="/widget/chat/install">
    Web, iOS, Android, React Native, Flutter
  </Card>

  <Card title="Build a flow with Claude" icon="wand-magic-sparkles" href="/widget/chat/build-with-claude">
    Describe the bot, import the JSON
  </Card>

  <Card title="Troubleshooting" icon="wrench" href="/widget/chat/troubleshooting">
    When it will not load, or will not reply
  </Card>
</CardGroup>
