Case Synthesis
List synthesized case narrative threads, poll the build status, and trigger an asynchronous recompute. Synthesis discovers document stories and missing-document findings.
Case synthesis discovers stories (threads) across your resolved documents: chains of documents that explicitly reference one another, plus the deterministic missing-document findings those references imply. For example, an invoice citing a purchase order number that no document in your workspace satisfies surfaces as a missing-document finding on that thread.
Synthesis is a higher-level view than individual cases. Where the linking graph connects documents through shared field values, synthesis narrates each connected group into a readable story with a title, a one-line blurb, and a paragraph summary. It also generalizes recurring threads into process types so you can see the shapes of work flowing through your corpus.
Because synthesis runs an LLM step and can take minutes on a large corpus, it never runs on read. The GET /v1/cases/threads endpoint serves a cached artifact only. To rebuild, call POST /v1/cases/synthesis/recompute, which enqueues the work on a worker and returns immediately, then poll GET /v1/cases/synthesis/status until the build clears.
GET /v1/cases/threads returns whatever was last built. When new documents resolve, the cached artifact is flagged dirty: true, signalling that a recompute would refresh the stories. Recompute is the only operation that spends LLM credits./v1/cases/threadsThreads Response
Response fields
Response
{
"threads": [
{
"id": "thr_1a2b3c4d",
"doc_ids": ["doc_uuid_1", "doc_uuid_2", "doc_uuid_3"],
"start": "2024-09-01",
"end": "2024-10-15",
"title": "Acme Corp PO-2024-001 Procurement",
"blurb": "Purchase order, invoice, and delivery note for Acme Corp order PO-2024-001.",
"summary": "Three documents share purchase order PO-2024-001: the original PO, a matching invoice for $4,250, and a delivery note. The chain is complete with no missing references.",
"findings": []
}
],
"doc_meta": {
"doc_uuid_1": { "filename": "po_2024_001.pdf", "doc_type": "Purchase Order", "date": "2024-09-01" }
},
"cases": {
"process": [],
"subject": [],
"stats": { "n_process": 0, "n_subject": 0 }
},
"stats": { "n_threads": 1 },
"dirty": false
}Synthesis Status
Poll this endpoint after triggering a recompute. The building flag is true while a worker is running the pipeline and clears when the build finishes. On success built_at advances and build_error is null; on failure building clears and build_error carries the reason, so a poll loop terminates on a visible error rather than spinning forever.
/v1/cases/synthesis/statusResponse fields
Response
{
"building": true,
"dirty": true,
"built_at": "2024-11-01T12:00:00.000Z",
"build_error": null,
"n_threads": 14,
"never_built": false
}Trigger Recompute
Enqueue an asynchronous synthesis build for the workspace and return immediately. The work runs off the request path on a worker, so the response does not contain the artifact. The operation is idempotent: if a fresh build is already in flight it is not re-enqueued, and the response status reflects whether the build was newly queued or already building.
/v1/cases/synthesis/recomputeResponse fields
Response
{
"ok": true,
"status": "queued",
"build_started_at": "2024-11-08T10:00:00.000Z"
}A typical flow is to call recompute, then poll GET /v1/cases/synthesis/status every few seconds until building is false. When the build clears successfully, fetch the refreshed stories from GET /v1/cases/threads.
Errors
Error responses