DocumentsDosu Decant
Local API and Report Routes
Local API and Report Routes
Type
Topic
Status
Published
Created
Aug 4, 2026
Updated
Aug 4, 2026
Created by
Dosu Bot
Updated by
Dosu Bot

Local API and Report Routes#

Decant exposes two report endpoints — one API route (downloads a file) and one UI route (renders a preview in the React app) for each report type . All routes are served by decant serve on http://127.0.0.1:3000 by default .

Route Summary#

RouteTypePurpose
GET /api/reports/analytics.htmlAPIDownload self-contained analytics HTML report
GET /api/reports/session/{id}.htmlAPIDownload self-contained session HTML report
GET /reports/analyticsUIPrint-preview of analytics report in the app
GET /reports/session/:idUIPrint-preview of session report in the app

The UI routes (/reports/*) are mapped to the React bundle and render a light, print-ready preview with Back, Download HTML, and Save as PDF controls. The API routes (/api/reports/*.html) return the same HTML directly as a file attachment .

Query Parameters and Validation#

GET /api/reports/analytics.html accepts optional from and to query parameters :

  • Format: YYYY-MM-DD
  • Both are optional; omitting them returns an unfiltered report
  • Parsed by dateFilterFromSearch(), which discards any value that doesn't match the ISO date pattern or represents an invalid calendar date
  • The resulting DateFilter is applied via sessionDatePredicate(), which compares the first 10 characters of started_at against the bounds using >= / <=

GET /api/reports/session/{id}.html takes a numeric session ID in the URL path . The server validates it with isValidSessionId() and returns 400 invalid_session_id for non-integer or negative values . A valid but non-existent ID returns 404 .

Response Format and Headers#

Both API routes return text/html with :

  • Content-Disposition: attachment; filename="decant-analytics-report.html" (analytics) or decant-session-{id}-{slug}.html (session)
  • Content-Security-Policy: default-src 'none'; style-src 'unsafe-inline'; font-src data:; frame-ancestors 'none'
  • Zero external dependencies — no JavaScript, no remote resources; charts are inline SVG

Session report filenames slugify the session title to at most 64 ASCII characters .

Report Data Pipeline#

Each report type is assembled then rendered in two distinct steps:

Analytics report :

  1. assembleAnalyticsReport(db, { filter }) — queries totals, sessions-by-day, by-model, by-project, activity, token economics, and insights; omits insights when a date filter is active
  2. renderAnalyticsReport(data) — renders static markup via renderToStaticMarkup()

Session report :

  1. assembleSessionReport(db, id) — queries session summary, reply count, tool calls, context window timeline, token economics, tool stats, and hot files; loads at most 1 message to intentionally omit transcript content
  2. renderSessionReport(data) — renders static markup

The AnalyticsReportData and SessionReportData interfaces define the full shape passed between assembly and rendering.

Key Source Files#

FileRole
src/server.ts (lines 581–611, 1077–1078, 1787–1807)Route handlers, reportHtmlResponse(), UI route registration
src/date-filter.tsdateFilterFromSearch(), sessionDatePredicate(), ISO date validation
src/report/data.tsassembleAnalyticsReport(), assembleSessionReport(), data interfaces
src/report/render.tsxrenderAnalyticsReport(), renderSessionReport()
docs/api/openapi.yaml (lines 786–844)Authoritative parameter and response schema for both API routes

The full OpenAPI contract is also available at runtime via GET /api/openapi.json .