Skip to documentation

Platform

Build reports

A report is the consulting deliverable: a client-ready snapshot of the knowledge base as of a moment in time — coverage, KPIs, top entities, gaps, and what to interview next — persisted immutably and renderable to PDF months later, byte-for-byte the same. This guide generates a snapshot with one call and fetches it back as structured JSON or a rendered PDF.

Prerequisites

  • A key with reports:write (generate) and reports:read (list/fetch).
  • A workspace with some ingested documents — a report over an empty KB is a report about an empty KB.

For what each section means and how reproducibility stamping works, see Reports & PDF deliverables.

Generate a snapshot

Generating a report computes each section against the KB at that instant and persists the result. The call returns immediately with the snapshot's id and status; the PDF renders in the background on a serialized queue. The numbers are frozen at generation — a report you hand a client in July still reads the same in December, however much the KB has grown.

POST/api/v1/reportsBearer · reports:write

Generate an as-of report snapshot over the current KB. Returns the snapshot id and status; the PDF renders asynchronously.

Request body

titlestringReport title, e.g. "Northwind — Q3 engagement report". Defaults to a workspace + date title.
sectionsstring[]Subset of [coverage, kpis, topEntities, gaps, interviewNext]. Defaults to all.
Example requestbash
curl -s -X POST https://your-host/api/v1/reports \
  -H "Authorization: Bearer $ELI_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"Northwind — Q3 engagement report"}'
Responsejson
{
  "id": "01KY13DDDDDDDDDDDDDDDDDDDD",
  "title": "Northwind — Q3 engagement report",
  "status": "generating",
  "layoutVersion": "report-v4",
  "sections": ["coverage", "kpis", "topEntities", "gaps", "interviewNext"],
  "generatedAt": "2026-07-21T12:00:00.000Z",
  "pdf": { "status": "queued", "url": null }
}

Fetch it back

Poll or fetch the snapshot by id. Once the PDF has rendered, pdf.status is ready and pdf.url points at the download. The structured datais available immediately — you don't have to wait for the PDF to consume the numbers.

GET/api/v1/reports/{id}Bearer · reports:read

Fetch a report snapshot: its stamped metadata, the computed section data, and the PDF status/URL once rendered.

Example requestbash
curl -s https://your-host/api/v1/reports/01KY13DDDDDDDDDDDDDDDDDDDD \
  -H "Authorization: Bearer $ELI_KEY"
Responsejson
{
  "id": "01KY13DDDDDDDDDDDDDDDDDDDD",
  "title": "Northwind — Q3 engagement report",
  "status": "ready",
  "layoutVersion": "report-v4",
  "generatedAt": "2026-07-21T12:00:00.000Z",
  "data": {
    "coverage": { "scorePct": 62, "topics": 41, "covered": 25 },
    "kpis": { "documents": 214, "entities": 214, "relations": 388, "deltaDocuments": 12 },
    "topEntities": [ { "id": "01KY0ZW3…", "name": "Order Platform", "type": "system", "pagerank": 0.0421 } ],
    "gaps": [ { "unit": "Logistics", "reason": "no interviews", "impact": "high" } ],
    "interviewNext": [ { "target": "VP Logistics", "why": "uncovered business unit" } ]
  },
  "pdf": { "status": "ready", "url": "https://your-host/api/v1/reports/01KY13DDDDDDDDDDDDDDDDDDDD/pdf" }
}
GET/api/v1/reportsBearer · reports:read

List report snapshots for the workspace, newest first.

Example requestbash
curl -s https://your-host/api/v1/reports \
  -H "Authorization: Bearer $ELI_KEY"
Responsejson
{
  "reports": [
    { "id": "01KY13DDDDDDDDDDDDDDDDDDDD", "title": "Northwind — Q3 engagement report", "status": "ready", "generatedAt": "2026-07-21T12:00:00.000Z" }
  ],
  "total": 1
}

The rendered PDF is at GET /api/v1/reports/{id}/pdf — the same reports:read scope, returning application/pdf. Stream it straight to disk:

GET/api/v1/reports/{id}/pdfBearer · reports:read

Download the rendered PDF. 409 if the render is still in progress or queued.

Example requestbash
curl -s https://your-host/api/v1/reports/01KY13DDDDDDDDDDDDDDDDDDDD/pdf \
  -H "Authorization: Bearer $ELI_KEY" \
  -o northwind-q3.pdf

Rendering is serialized

Headless-Chromium PDF rendering runs on a concurrency-1 queue, so a burst of report generations queues rather than exhausting the box. Expect pdf.status: "queued" briefly; GET …/pdf returns 409 until the render lands. The structured data never waits on the PDF.

The leverage

One POST turns the live state of an engagement into a frozen, reproducible artifact — the paid deliverable — and the structured data means you can also drop the same numbers into your own dashboard, email, or Slack digest without re-deriving them. Schedule the call and a Monday-morning client report is rendered before anyone opens their inbox; every re-download of an old snapshot is identical, because the layout version that produced it is stamped in. See Scheduling, drift & alerts for the cron substrate.