LiteBot

Conversations and analytics

This chapter explains what LiteBot stores about every chat or voice session, how to read it back through the dashboard and the HTTP API, and how long it is kept. Read it when you need a transcript, want to see why a bot answered the way it did, or want cost and usage figures for a period. The cost arithmetic itself is in Cost and performance.

LiteBot writes five kinds of record to MongoDB:

Collection One document per Written by
conversations Session Conversation manager (chat) and the voice handler
request_traces Chat turn, or whole voice call Chat engine and voice handler, when tracing is on
request_analytics LLM call Analytics manager, in batches
session_analytics Session Analytics manager, every 30 s while active and at session end
leads, support_tickets Lead or ticket The bundled lead and ticket tools

All of these except leads and support_tickets carry a tenantId, taken from the bot's tenant when the row is written. Tenant users only ever see rows of their own tenant; the global admin sees all.

The conversations collection

A session starts on the first message for a new session id and gets an id of the form sess_<random> unless the caller supplies one. The document _id is the session id.

Field Meaning
sessionId Same as _id.
botId Bot currently serving the session. Changes if the intent router switches bots.
tenantId Tenant of the bot at creation.
userId Caller identity sent with the request (for a WhatsApp or phone channel this is often the phone number). null when none was sent.
messages[] The transcript. See below.
context Session variables: values passed in the chat request's context, values tools save, and flags such as call_ended on voice calls.
metadata Free-form metadata passed when the session was created.
status active or ended.
createdAt, lastActivity Start time and time of the last message.
endedAt When the session was closed.
endedBy idle-sweep when the session was closed by the idle sweep rather than by a hang-up or DELETE.
botSwitches[] { timestamp, from, to } for every bot switch.

Each entry in messages[] holds role (user, assistant, and so on), content, timestamp and an id. Assistant messages also hold toolCalls (what the model asked for) and toolResults (what each tool returned, with toolName, success and the result). toolResults is the most reliable record of what a tool did, because it is kept for as long as the conversation is.

Memory per session is capped at MAX_SESSION_MESSAGES (default 200); older messages are dropped from the stored transcript once the cap is reached. Only the last LLM_HISTORY_MAX_MESSAGES (default 40) are sent to the model.

How a session ends

  • A hang-up tool, DELETE /api/chat/session/:id, or the end of a voice call sets status: ended and endedAt.
  • Sessions idle longer than SESSION_IDLE_TIMEOUT_MS (default 30 minutes) are closed by a sweep that runs every SESSION_CLEANUP_INTERVAL_MS (default 15 minutes). The sweep also closes stale active rows in MongoDB left behind by a restart, setting endedAt to the row's own lastActivity and endedBy: idle-sweep.

See Session-end hooks for what runs when a session ends.

Reading conversations

All /api/conversations routes need a JWT or API key with the conversations read permission (Users, roles and tenants).

Method and path What it returns
GET /api/conversations Paged list. Query: page, limit (1–100, default 20), botId, userId, status, startDate, endDate, search (matches session id, user id or bot id), sortBy, sortOrder.
GET /api/conversations/stats/summary Summary counts for the same filters.
GET /api/conversations/:sessionId One conversation with messages, context and an analytics block from session_analytics.
GET /api/conversations/:sessionId/traces Execution traces for the session. See Request traces.
GET /api/conversations/export/:sessionId?format=json Download. json (default) is the full document including toolResults; csv is timestamp, role and content only.
DELETE /api/conversations/:sessionId Deletes the conversation and its session_analytics and request_analytics rows.
POST /api/conversations/bulk-delete Same for up to 100 ids: {"sessionIds": ["..."]}.
curl -s http://127.0.0.1:3345/api/conversations/sess_abc123 \
  -H "Authorization: Bearer <token>"

The single-conversation view returns each message's role, content, timestamp and toolCalls, but not toolResults. Use the JSON export when you need tool results.

Deletes do not remove request_traces rows; those expire on their own (Retention).

Request traces

A trace is the step-by-step record of how a reply was produced. Tracing is on unless ENABLE_REQUEST_TRACING=false.

  • Chat: one request_traces document per turn.
  • Voice: one document per call, written when the call ends, with steps for every turn.

Each document holds sessionId, botId, tenantId, userId, createdAt and a trace array. Step types:

step Fields
llm_call iteration, provider, model, inputTokens, outputTokens, duration (ms), toolCallsRequested. Voice turns show provider gemini-live.
tool_execution toolName, parameters, result (first 500 characters, or the error), duration, success, iteration.
llm_followup Each extra model round-trip after tools ran: iteration, duration, tokenUsage, hasMoreToolCalls.
flow_transition Node moves in a visual-flow bot (Visual flows).

A turn with several llm_followup steps took several model round-trips; that is the first place to look for slow or costly turns.

Traces exist only for sessions handled after tracing was added to your build (chat first, voice later). For older sessions, read toolResults from the conversation instead.

Session and request analytics

request_analytics

One row per LLM call. Rows are queued and written with one insert every ANALYTICS_BATCH_INTERVAL_MS (default 2000) or when ANALYTICS_BATCH_SIZE (default 50) rows are waiting, and at session end.

Field Meaning
sessionId, botId, tenantId Owner.
provider, model Provider and model that actually served the call (after any failover).
usage Token counts from the provider: promptTokens, completionTokens, totalTokens, and cachedTokens where reported.
cost, costData Cost in USD and its breakdown (Cost and performance).
responseTime Milliseconds for this call. Missing or 0 when it could not be timed (some voice turns).
toolCalls Tool calls requested in this call.
success, error Outcome. A failed turn records success: false and the error text.
timestamp, createdAt When it happened and when it was written.

session_analytics

One row per session, replaced in place while the session runs (at most every 30 seconds) and at session end.

Field Meaning
sessionId, botId, tenantId, userId Owner.
channel voice for Gemini Live calls. Absent on chat sessions; reports count a missing channel as chat.
startTime, endTime, duration Duration is in seconds.
messageCount, toolCallCount, errors, successRate Turn counts and outcome.
totalCost, totalTokens, totalInputTokens, totalOutputTokens Session totals. Cost is USD.
averageResponseTime Mean of the timed LLM calls, in ms.
averageCostPerMessage, averageTokensPerMessage Totals divided by messageCount.
provider, model Provider and model of the last call.

Analytics API

All /api/analytics routes need authentication and are scoped to your tenant. Ranges are ?days=N (default 7) or ?startDate=<ISO>&endDate=<ISO>. Where a route takes tz, it buckets days and hours in that IANA zone (default ANALYTICS_TZ, Asia/Kolkata).

Path Source What it gives
/api/analytics/report session_analytics Totals, voice and chat split, per-bot rows sorted by cost, and a daily series. Takes tz. Cached 60 s.
/api/analytics/evidence?botId= Several Evidence bundle download. See below.
/api/analytics/performance session_analytics System response times with p50, p95 and p99 of per-session averages.
/api/analytics/performance/:botId session_analytics The same for one bot.
/api/analytics/response-timeline request_analytics Average, maximum and p95 latency per hour (ranges of 2 days or less) or per day. p95 needs MongoDB 7 or later; older servers return null. Takes tz.
/api/analytics/tool-performance request_traces Per-tool call count, duration and failures. limit (default 12, max 50), botId. Says whether tracing is on.
/api/analytics/slowest-operations session_analytics The slowest bots, split into estimated components (see the note below). limit (default 10, max 100).
/api/analytics/dashboard Fan-out The datasets the dashboard Analytics page loads, in one call.

The bot routes add GET /api/bots/analytics/summary, /api/bots/analytics/:botId/detailed, /api/bots/analytics/trending, /api/bots/analytics/health and /api/bots/analytics/realtime (live in-memory sessions); GET /api/chat/stats and GET /api/chat/analytics give totals with provider and model breakdowns.

The LLM, database, tools and formatting split shown by the performance routes is an estimate (70/10/15/5 per cent of the average), not a measurement. For measured timings use traces or the metrics block of a chat reply (Cost and performance).

Evidence bundle

GET /api/analytics/evidence?botId=<id>&days=7 streams a zip named evidence-<botId>-<from>-to-<to>.zip:

File Contents
README.md What each file holds and suggested analysis questions.
bot.json The bot's current configuration: prompt, model, tools, rules.
conversations.jsonl One conversation per line, selected by createdAt.
session_analytics.jsonl One session summary per line, selected by startTime.
request_traces.jsonl One trace document per line.
summary.json Period, counts, cost, token, message and tool-call totals, and truncated.

Each file holds at most 2,000 documents, oldest first; summary.json says whether that cap was hit, so shorten the range if it was. Values under keys ending in token, password, secret, credential, authorization or api_key are replaced with [REDACTED], including inside stringified tool results.

curl -s -o evidence.zip -H "Authorization: Bearer <token>" \
  "http://127.0.0.1:3345/api/analytics/evidence?botId=<bot-id>&days=7"

Dashboard pages

  • Conversations lists sessions with the filters above. Opening one shows the transcript and a trace viewer that draws each request_traces step.
  • Analytics has the tabs Sessions, Performance, Usage, Insights, Advanced and Reports, with a range of 24 hours, 7, 30 or 90 days.
  • Reports (inside Analytics) shows the /api/analytics/report figures and has an Evidence button per bot that downloads the bundle.

See Dashboard.

Leads and support tickets

There are no /api/leads or /api/tickets routes. These collections are filled by tools:

Tool Collection What it writes
createLead leads The parameters given, plus source (default chat), score: 0, status: new, sessionId, botId, timestamps.
qualifyLead leads Updates score and status of an existing lead.
createTicket support_tickets ticketNumber (TKT-...), title, description, category, priority, status: open, customer name and email, sessionId, botId.
updateTicketStatus support_tickets New status and resolution.

leads has a unique sparse index on email, so a second lead with the same email fails. These rows carry no tenantId. Read them with your own MongoDB tooling, or write your own tool that sends them to your CRM (Tools). GET /health/ready reports not ready until both collections exist; LiteBot creates them with their indexes at start-up.

Retention

Data Kept
conversations Until you delete them. No expiry.
session_analytics, request_analytics Until you delete them, or delete the conversation through the API.
request_traces 30 days, through a TTL index on createdAt. LiteBot creates that index the first time anyone opens a trace (GET /api/conversations/:sessionId/traces); until then traces are not expired.
leads, support_tickets Until you delete them.

To enforce a retention period on the other collections, add your own TTL index in MongoDB or run a scheduled delete. Conversations contain whatever callers said, so treat them as personal data (Security).

Where to go next