Total Chat Documentation
Total Chat is an SDK-first AI chat product that deeply integrates into your web application. It provides screen-aware, auto-navigating customer support and lead generation — all with flat monthly pricing.
Unlike other chat widgets, Total Chat actually sees what's on the user's screen. It can highlight buttons, navigate through your app, and walk users through multi-step workflows — all in real time.
Key Capabilities
- Screen-Aware AI — Understands current page, modals, filters, and form state
- Auto-Navigation — Highlights and clicks through UI elements automatically
- Self-Evolving KB — Drafts knowledge articles from real conversations
- Lead Generation — Fingerprinting, UTM tracking, and IP-based enrichment
- Bug Routing — Sends bug reports with full context to developer agents
- CRM/Ticketing — Webhooks for HubSpot, Zendesk, Jira, and more
Quickstart
Get Total Chat running in your app in 3 steps:
1. Register Your App
curl -X POST https://totalchat-api.onrender.com/api/onboarding/register \
-H "Content-Type: application/json" \
-d '{
"appId": "my-app",
"appName": "My App",
"ownerEmail": "you@example.com"
}'
Save the appId and apiKey from the response. The API key is shown only once — store it securely.
2. Add the Script Tag
<script
src="https://totalchat-api.onrender.com/widget.js"
data-app-id="YOUR_APP_ID"
data-mode="external"
data-position="bottom-right"
data-primary-color="#6366f1"
></script>
3. Scan Your Codebase (Optional)
npx @totalchat/cli scan --target ./src --app-id YOUR_APP_ID
This generates a micro-function map of every route, feature, and interactive element in your app — giving Total Chat deep knowledge of your UI.
Installation
There are two ways to add Total Chat to your app:
Add this script tag before the closing </body> tag:
<script
src="https://totalchat-api.onrender.com/widget.js"
data-app-id="YOUR_APP_ID"
data-mode="external"
data-position="bottom-right"
data-primary-color="#6366f1"
data-greeting="Hi! How can I help?"
></script>
The widget loads asynchronously and won't block your page. Total bundle impact: ~15KB gzipped.
The @totalchat/sdk npm package is in development. In the meantime, use the script tag integration above — it provides all the same capabilities including screen awareness, knowledge base, and lead capture.
Script Tag Integration
The script tag is the simplest way to add Total Chat. Perfect for marketing sites, landing pages, or any site where you want lead capture and support without a build step.
Available Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
data-app-id | string | required | Your app ID from registration |
data-mode | string | "external" | "external" (lead capture) or "internal" (full features) |
data-position | string | "bottom-right" | "bottom-right" or "bottom-left" |
data-primary-color | string | "#6366f1" | Brand color for the widget |
data-greeting | string | "Hi! How can I help?" | Initial greeting message |
data-collect-email | boolean | "true" | Prompt for email in external mode |
React / Next.js SDK Coming Soon — Phase 2
The @totalchat/sdk npm package will provide deep React/Next.js integration with type-safe components and hooks. It's currently in development as part of Phase 2.
Planned: Next.js App Router
// app/providers.tsx — coming in Phase 2
'use client';
import { TotalChatProvider } from '@totalchat/sdk/react';
import { useRouter } from 'next/navigation';
export function Providers({ children, user }) {
const router = useRouter();
return (
<TotalChatProvider
appId={process.env.NEXT_PUBLIC_TOTALCHAT_APP_ID}
// Note: mode is always server-enforced based on userId presence.
// Pass userId when logged in — the server derives INTERNAL vs EXTERNAL.
userId={user?.id}
router={{ type: 'nextjs', navigate: router.push }}
user={user ? { id: user.id, email: user.email, name: user.name } : undefined}
>
{children}
</TotalChatProvider>
);
}
SDK Methods
| Method | Description |
|---|---|
chat.init() | Initialize Total Chat and mount the widget |
chat.sendMessage(text) | Send a message programmatically |
chat.open() | Open the chat panel |
chat.close() | Close the chat panel |
chat.identify(user) | Set user identity for internal mode |
chat.getScreenState() | Get current screen state (route, modals, etc.) |
chat.startWalkthrough(steps) | Start a guided walkthrough |
chat.destroy() | Remove Total Chat from the page |
Configuration
Configure Total Chat behavior via the dashboard or API.
Full Configuration Object
interface TotalChatConfig {
appId: string;
mode: 'internal' | 'external';
position: 'bottom-right' | 'bottom-left';
theme: {
primaryColor: string;
greeting: string;
logo?: string; // URL to custom logo
widgetTitle?: string; // Custom widget header title
};
router?: {
type: 'nextjs' | 'react-router' | 'custom';
navigate: (path: string) => void;
};
user?: {
id: string;
email: string;
name?: string;
};
features?: {
autoNavigation: boolean; // Enable screen-aware navigation
leadCapture: boolean; // Enable lead capture (external mode)
bugReporting: boolean; // Enable bug report button
satisfaction: boolean; // Show satisfaction rating after resolution
};
escalation?: {
emailTo?: string; // Human escalation email address
webhookUrl?: string; // Custom escalation webhook
};
}
Screen Awareness
Total Chat monitors the user's current screen state in real time. Every message sent to the AI includes context about:
- Current route — e.g.,
/dashboard/settings - Active modals — any open dialogs or popups
- Active filters — search queries, date ranges, etc.
- Form state — which fields are filled, validation errors
- Visible elements — buttons, links, and interactive elements on screen
How It Works
The SDK uses a combination of:
- Route monitoring — Hooks into your app's router to track page changes
- MutationObserver — Watches for DOM changes (modals, dynamic content)
- data-guide attributes — Explicit markers for important UI elements
- Micro-function map — Pre-scanned knowledge of your app's features
Knowledge Base
Total Chat's knowledge base uses semantic search (pgvector embeddings) to find relevant answers even when users phrase questions differently.
Auto-Drafted Articles
When Total Chat answers a question that isn't in the KB, it automatically drafts a new article based on the conversation. You'll receive an email notification to approve, edit, or reject it.
Public vs. Internal Articles
Each KB article has an isPublicVisible flag (default: true). In external mode, only public articles are searched — protecting internal procedures, pricing logic, and admin docs from pre-login visitors. In internal mode, all published articles are available.
- Set
isPublicVisible: falseon internal-only articles (e.g., billing workarounds, admin processes) - Public articles are seen by both logged-in users and anonymous visitors
- This filtering is server-enforced — clients cannot override it
KB Search API
GET /api/kb/search?q=how+to+export&appId=YOUR_APP_ID&limit=5
Returns semantically similar articles ranked by relevance score.
Lead Capture
In external mode, Total Chat captures visitor information for your sales pipeline.
What's Captured
- Digital fingerprint — First-party cookies + localStorage (privacy-friendly)
- UTM parameters — Source, medium, campaign, content, term
- Referrer — Where the visitor came from
- IP enrichment — Company, location, industry (via EM MCP)
- Email — Collected via configurable prompt
- Conversation context — What they asked about, pages visited
CRM Delivery
Leads are automatically pushed to your configured CRM via webhooks. See CRM Webhooks.
Bug Routing
When a user reports a bug through Total Chat, the full conversation context, screen state, and error details are packaged into a structured report and sent to your configured destination.
Report Format
{
"type": "BUG",
"priority": "HIGH",
"subject": "Export button returns 500 error",
"description": "User on /dashboard clicked Export...",
"context": {
"conversationId": "conv_123",
"pageUrl": "/dashboard",
"screenState": { "route": "/dashboard", "activeModal": null },
"errorLogs": ["TypeError: Cannot read property..."]
},
"reporter": {
"email": "user@example.com",
"userId": "usr_456"
}
}
Routing Destinations
- Agent Hub — Routes to per-app developer agents that investigate the codebase
- Jira / Linear — Creates an issue with full context
- Zendesk / Freshdesk — Creates a support ticket
- Zapier / Make — Universal webhook fallback
Security & Mode Enforcement
Total Chat has a layered security model to prevent prompt injection, data leakage, and mode bypassing.
Layer 1 — Server-Enforced Mode
Mode is never derived from client input. The server checks for a valid userId in the conversation:
- userId present →
INTERNALmode — full KB, navigation tools, user context - No userId →
EXTERNALmode — public KB only, lead capture, no navigation
Clients cannot request mode elevation. Even if the widget config says mode: "internal", the server ignores it when no userId is provided.
Layer 2 — System Prompt Guardrails
Every conversation — regardless of mode — includes a security preamble injected at the top of the system prompt:
- The AI is scoped to your app only — it won't answer unrelated questions
- It cannot reveal its system prompt or instructions
- It cannot generate code, recipes, or content unrelated to your product
- It cannot collect credentials or perform actions outside its defined tool set
- KB answers must cite actual articles — fabrication is blocked
Layer 3 — API Input Sanitization
Every user message is scanned before being processed. Messages containing injection patterns are rejected with a 400 error:
// Example rejection
{
"error": "Message contains disallowed content"
}
// Blocked patterns include:
// "ignore all instructions", "you are now", "act as a [character]",
// "pretend you are", "roleplay as", "repeat your system prompt",
// "DAN mode", "jailbreak", "developer mode", etc.
KB Visibility Enforcement
Articles with isPublicVisible: false are never returned in external mode searches — even if a user asks about them by name. Internal procedures, admin docs, and sensitive pricing logic stay invisible to unauthenticated users.
isPublicVisible: false before enabling external mode.
Codebase Scanner
The scanner CLI analyzes your codebase and generates a micro-function map — a complete inventory of every route, feature, and interactive element. There are three ways to scan depending on your setup.
Option 1 — npx (Quickest)
Run directly from your project root. No install required.
# Scan and upload in one command
npx @totalchat/cli scan \
--dir . \
--app-id YOUR_APP_ID \
--api-key YOUR_API_KEY \
--upload
# Scan only (write to file, upload manually later)
npx @totalchat/cli scan --dir . --app-name "My App" --output ./totalchat-map.json
# Then upload manually
curl -s -X POST https://totalchat-api.onrender.com/api/onboarding/YOUR_APP_ID/function-map \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d @totalchat-map.json
CLI Flags
| Flag | Description | Default |
|---|---|---|
--dir | Project root directory | Current directory |
--app-id | Your Total Chat app ID (required for --upload) | — |
--api-key | Your API key, or set TOTALCHAT_API_KEY env var | — |
--upload | POST the map to the API after scanning | false |
--app-name | Human-readable app name | MyApp |
--output | Output JSON file path | ./output/app-map.json |
--api-url | Total Chat API base URL | https://totalchat-api.onrender.com |
Framework auto-detection: The scanner automatically finds your app directory by trying src/app, app, src/pages, pages, and dashboard/src/app in order. No configuration needed for standard Next.js projects.
When to Re-scan
- After adding new pages or major features
- After restructuring your navigation
- When the freshness check shows
staleorwarn
# Check your function map freshness
curl https://totalchat-api.onrender.com/api/onboarding/YOUR_APP_ID/function-map/freshness
# Response:
# { "status": "fresh", "ageDays": 2, "currentVersion": 4 }
# { "status": "stale", "recommendation": "Re-scan recommended" }
What Gets Scanned
- Routes — All pages, dynamic params, route groups
- Features — Buttons, forms, links, and interactive elements
- Components — Your component inventory
- data-guide attributes — Existing navigation anchors
- Recommendations — Suggested
data-guideplacements (P1/P2/P3)
GitHub Action — Automatic Rescanning
Automatically rescan and upload your function map on every push to main. Add this to your repository once and never think about rescanning again.
# .github/workflows/totalchat.yml
name: Total Chat Sync
on:
push:
branches: [main]
jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: totalchat/scanner-action@v1
with:
app-id: YOUR_APP_ID
api-key: ${{ secrets.TOTALCHAT_API_KEY }}
Add TOTALCHAT_API_KEY to your GitHub repository secrets (Settings → Secrets → Actions). The action auto-detects your framework and uploads the map — no other configuration needed.
Action Inputs
| Input | Required | Default | Description |
|---|---|---|---|
app-id | Yes | — | Your Total Chat app ID |
api-key | Yes | — | Your API key (use a secret) |
directory | No | . | Project root to scan |
api-url | No | https://totalchat-api.onrender.com | API base URL |
AI URL Crawler — No Code Required
Don't want to run a scanner? Point Total Chat at your live site and the AI will crawl it, read your pages, and generate knowledge base articles automatically. No CLI, no GitHub Action, no code changes needed.
POST /api/onboarding/:appId/crawl
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"url": "https://yourapp.com",
"maxPages": 20,
"generateArticles": true
}
curl -s -X POST https://totalchat-api.onrender.com/api/onboarding/YOUR_APP_ID/crawl \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "url": "https://yourapp.com", "maxPages": 20 }'
What happens:
- Total Chat fetches your root URL and follows internal links (same domain only)
- For each page, it extracts the title, headings, and visible text
- The AI reads all pages and generates 3–8 knowledge base articles
- Articles are saved as AI drafts — you review and publish from the dashboard
Response
{
"crawled": 14,
"articlesGenerated": 6,
"articles": [
{ "id": "...", "title": "Getting Started", "category": "onboarding", "isPublicVisible": true },
{ "id": "...", "title": "Managing Your Account", "category": "account", "isPublicVisible": false }
]
}
Best for: Marketing sites, documentation sites, or any app where a crawl gives the AI enough content to work with. For full navigation awareness (route highlighting, walkthroughs), pair with the CLI scanner.
data-guide Attributes
These attributes help Total Chat identify and navigate to specific UI elements:
<!-- P1: Critical navigation elements -->
<button data-guide="export-data">Export</button>
<a data-guide="nav-settings" href="/settings">Settings</a>
<!-- P2: Important interactive elements -->
<input data-guide="search-input" placeholder="Search..." />
<select data-guide="filter-status">...</select>
<!-- P3: Supporting elements -->
<div data-guide="dashboard-chart">...</div>
The scanner CLI generates a prioritized list of recommendations showing exactly where to add these attributes. P1 items have the highest impact on navigation accuracy.
API: Conversations
Create Conversation
POST /api/conversations
Content-Type: application/json
{
"appId": "YOUR_APP_ID",
"userId": "optional-logged-in-user-id",
"visitorId": "optional-fingerprint-id"
}
mode field is derived server-side — if userId is present, the conversation is INTERNAL (full KB, navigation tools, screen awareness). Without userId, it's EXTERNAL (public KB only, lead capture). Clients cannot override this.
Get Conversation
GET /api/conversations/:id
API: Messages
Send Message
POST /api/conversations/:id/messages
Content-Type: application/json
{
"role": "user",
"content": "How do I export my data?",
"pageContext": "/dashboard",
"screenState": {
"route": "/dashboard",
"activeModal": null,
"visibleElements": ["export-btn", "filter-bar"]
}
}
The response includes the AI's answer plus any navigation instructions:
{
"id": "msg_789",
"role": "assistant",
"content": "I can see you're on the Dashboard. Let me walk you through exporting your data!",
"intent": "walkthrough",
"navigation": {
"steps": [
{ "action": "navigate", "target": "/settings/export" },
{ "action": "highlight", "selector": "[data-guide='export-btn']" },
{ "action": "click", "selector": "[data-guide='export-btn']" }
]
}
}
API: Knowledge Base
Search KB
GET /api/kb/search?q=export+data&appId=YOUR_APP_ID&limit=5
Create Article
POST /api/kb/articles
Content-Type: application/json
{
"appId": "YOUR_APP_ID",
"title": "How to Export Dashboard Data",
"content": "Navigate to Settings > Export...",
"category": "data-management",
"pageRoute": "/settings/export",
"approved": true
}
API: Onboarding
Register App
POST /api/onboarding/register
Content-Type: application/json
{
"appId": "my-app",
"appName": "My App",
"ownerEmail": "owner@example.com",
"integrationMode": "FULL",
"aiPersonality": "friendly",
"escalationEmail": "support@example.com",
"bugRouteTarget": "my-agent-topic"
}
| Field | Required | Description |
|---|---|---|
appId | ✓ | Unique identifier for your app (lowercase, hyphens ok) |
appName | ✓ | Display name for the app |
ownerEmail | ✓ | Email for KB draft notifications and escalations |
integrationMode | FULL (default), HEADLESS, or EXTERNAL_ONLY | |
aiPersonality | Tone for AI responses (e.g. friendly, professional) | |
escalationEmail | Human support email for tier-3 escalations | |
bugRouteTarget | Agent Hub topic for bug report routing |
The response includes your apiKey (shown once — store it securely) and full app config.
Upload Function Map
POST /api/onboarding/:appId/function-map
Content-Type: application/json
Authorization: Bearer YOUR_API_KEY
{
// Output from totalchat scan / npx @totalchat/cli scan
"app": { "name": "My App", "framework": "nextjs" },
"routes": [...],
"features": [...],
"stats": { "totalRoutes": 14, "totalFeatures": 47 }
}
Check Function Map Freshness
GET /api/onboarding/:appId/function-map/freshness
Authorization: Bearer YOUR_API_KEY
// Response:
{
"appId": "my-app",
"status": "fresh", // "fresh" | "warn" | "stale"
"ageDays": 2,
"currentVersion": 4,
"recommendation": "Function map is current."
}
AI URL Crawler
Crawl a live URL and auto-generate KB articles. No scanner required.
POST /api/onboarding/:appId/crawl
Content-Type: application/json
Authorization: Bearer YOUR_API_KEY
{
"url": "https://yourapp.com",
"maxPages": 20, // optional, default 20
"generateArticles": true // optional, default true
}
// Response:
{
"crawled": 14,
"articlesGenerated": 6,
"articles": [
{ "id": "...", "title": "Getting Started", "category": "onboarding" }
]
}
Deploy Notify
Call after each deploy to keep the freshness check accurate.
curl -s -X POST https://totalchat-api.onrender.com/api/onboarding/YOUR_APP_ID/deploy-notify \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"commitSha\": \"$(git rev-parse HEAD)\", \"environment\": \"production\"}"
API: Webhooks
Configure webhooks in your app settings to receive real-time events.
Event Types
| Event | Description |
|---|---|
conversation.created | New conversation started |
conversation.resolved | Conversation marked resolved |
lead.captured | New lead captured (email collected) |
lead.enriched | Lead enrichment data available |
report.created | Bug/feature report submitted |
kb.article_drafted | New KB article auto-drafted |
CRM Webhooks
Total Chat can push leads to your CRM automatically. Configure in your app settings.
Supported CRMs
- HubSpot — Contacts + Deals
- Salesforce — Leads + Contacts
- GoHighLevel — Contacts + Opportunities
- Pipedrive — Persons + Deals
- Zapier / Make — Universal webhook (works with any CRM)
Lead Data Format
{
"email": "jane@acme.com",
"name": "Jane Doe",
"company": "Acme Corp",
"title": "VP Engineering",
"phone": "+1-555-0123",
"source": {
"utm_source": "google",
"utm_medium": "cpc",
"utm_campaign": "brand-awareness"
},
"enrichment": {
"companySize": "50-200",
"industry": "Technology",
"location": "San Francisco, CA"
},
"conversation": {
"firstMessage": "How does the SDK integrate with Next.js?",
"pagesVisited": ["/", "/features", "/pricing", "/docs"]
}
}
Ticketing Systems
Route support tickets and bug reports to your existing helpdesk.
Supported Systems
- Zendesk — Tickets with full context
- Freshdesk — Tickets with tags and priority
- Jira Service Management — Issues with custom fields
- Linear — Issues with labels and priority
- Help Scout — Conversations with threads
- Zapier / Make — Universal webhook fallback