Quick Start
- Create an API key in the Dashboard → Keys page.
- Create a widget in Dashboard → Widgets, or via the API:
- Embed the snippet on your site:
Customization
Appearance
Control the look of the widget via theappearance object:
primaryColor— Accent color for the widget header and buttonsposition—"bottom-right"(default) or"bottom-left"borderRadius— Corner radius in pixelsfontFamily— Custom font (loaded from Google Fonts)
Behavior
welcomeMessage— Greeting shown when the widget opensplaceholder— Input field placeholder textmaxPromptLength— Maximum characters per messageenableFileUpload— Allow users to upload images/documentsenableVoice— Enable voice input (speech-to-text)strictAbuse— Enable abuse detection heuristics (rapid-fire, content repetition, prompt-length)
Brand Soul
If the linked API key has a Brand Soul configured (via Dashboard → Keys → Brand Soul), the widget automatically inherits it. The Brand Soul defines the persona, tone, knowledge base, and behavior constraints — making the widget sound like your brand, not like a generic chatbot.Security
Domain Allowlist
ConfigureallowedOrigins on the API key to restrict which domains can embed the widget. Requests from unauthorized origins are rejected via CORS.
Bot Protection
EnablerequireTurnstile: true in the widget’s security config to add a bot-protection challenge before the first message.
Abuse Detection
WhenstrictAbuse is enabled, Theo applies server-side heuristics that flag and throttle abusive traffic patterns — including rapid-fire requests from a single IP, repetitive or duplicate content, and excessively long prompts. Exact thresholds are not published so attackers can’t calibrate around them.
Human Escalation
The widget automatically detects when users request a human agent (“talk to a real person”, “get me an agent”). You can configure custom keyword triggers and actions (redirect to URL, show message, fire webhook) in the widget’s intent config.Preview
Generate a preview token to test unpublished widgets in the Dashboard:Live Conversations & Human Takeover
Every visitor session is recorded. You can list sessions, read a full transcript, and — when a visitor needs a person — jump in:- List sessions with
GET /api/v1/iframes/{id}/conversations(filter bystatus,has_lead, date range). - Read a transcript with
GET /api/v1/iframes/{id}/conversations/{sessionId}. - Take over a live chat with
POST .../takeoverto suppress AI replies, then post operator messages withPOST .../messages. - Release the chat back to the AI with
POST .../release.
operator role so AI and human messages stay distinguishable.
Analytics
GET /api/v1/iframes/{id}/analytics?window=30d returns KPIs (sessions, leads, messages, conversion rate, average session duration), a previous-period comparison, daily time series, and top referrers/countries for building a dashboard.
Lead Capture
When a widget collects contact details, each lead is stored against its session. Retrieve them withGET /api/v1/iframes/{id}/leads (paginated, searchable) or download everything as CSV with GET /api/v1/iframes/{id}/leads/export.
