Changelog
New features and improvements to the Clinia Context Engine.
Production workspaces on a HIPAA-ready platform are now available on a usage-based plan that organizations can subscribe to from the Console with a credit card, a Python client is now available alongside the JavaScript one, and medications are now compared by active ingredient.
Production workspaces with a self-serve subscription
Organizations can now create production workspaces, which run on a HIPAA-ready platform and are meant for live patient data. Production workspaces come with the Flex plan, which any organization can subscribe to directly from the Console with a credit card, without going through our sales team. Flex has usage-based pricing with no commitment and includes online support. Enterprise remains available through our sales team for custom pricing and SLAs.
Every organization starts on the Free plan, with sandbox workspaces meant for testing with synthetic data and 10,000 one-time credits shared across all of its workspaces. Existing workspaces are now sandbox workspaces, and their data, credentials and integrations keep working. On Flex, any usage beyond those credits is charged monthly to the card on file.
Usage is measured in credits, based on the data your workspaces form into memory and read back. The Pricing details page in the Console lists the current rates, and Plan & billing shows the credits used in the current billing period by category, along with every invoice ready to download. Owners also manage the subscription from that page, where they can edit the billing details that appear on invoices and replace the card on file.
Python client
Version 0.8.0 of the Python client for the Context Engine API is now available on PyPI as clinia-context-engine, with both sync and async interfaces, and it handles OAuth tokens for you. See clinia/context-engine-py to get started.
Medications compared by active ingredient
The same drug often appears in a patient's record under different names and codes (e.g. brand name vs. generic). When the Context Engine compares two medications, it now recognizes when they contain the same active ingredient, even if their names and codes differ, and when they only partly overlap, as with a combination product. The result is a cleaner medication list, where each drug the patient takes shows up once with its full history from every source. Agents and clinicians reading it get a more accurate picture of what the patient is on, without having to work out on their own which entries are the same drug.
See Entity resolution.
Trace anything back to where it came from. A typed graph exposes every entity the engine holds and every decision it made, and ingestion becomes a submission you can watch, account for, and read back.
Patient Context Graph API
Every entity the engine holds for a patient — and every decision it made about them — is now readable as a typed graph.
In technical preview. See Patient context graph and Audit resolution.
New ingestion endpoints with improved reliability
Ingestion now has one endpoint per format and release — POST /v1/patients/{patientId}/ingestions/fhir/r4, .../fhir/r5 and .../cda/r2 — each answering 202 with a receipt rather than processing in the request.
The receipt's intake accounts for everything you sent, entry by entry:
structuredwhen clinical detail was read from it,text_onlywhen it was kept as prose,ignoredwith a reason when it was not used at all.
Forty resources of which nine were unusable no longer read like forty that all landed.
Read submissions back with GET .../ingestions and .../ingestions/{ingestionId}, where status is derived from the work actually running and startedAt/completedAt separate queue wait from processing time.
There is no status endpoint. You can instead use ?status=pending,processing&perPage=1 and read meta.total; zero means the patient's data has settled.
See Ingestion, How to ingest FHIR and How to ingest CDA.
Breaking change
The legacy /ingest/* surface has been removed in favor of ingestions/*. Here is a mapping to new endpoints you can use to migrate.
POST .../ingest/fhir— use.../ingestions/fhir/r4or.../fhir/r5. The release now comes from the path, so an R5 payload is read as R5 rather than parsed as R4.POST .../ingest/cda— use.../ingestions/cda/r2.POST .../ingest(batch) — send one call per format.GET .../ingest/status— use.../ingestions?status=pending,processingand readmeta.total.GET .../ingest/executionsand.../executions/{executionId}— use.../ingestionsand.../ingestions/{ingestionId}.POST .../ingest/documenthas no replacement yet; it returns as a file upload when that work lands.
Note that the POST .../sessions/ingest is unchanged for now.
Explicit route status in the API reference
Each documented route now publishes its stability as x-state in the OpenAPI spec — Generally available, Technical preview or Deprecated — and the generated client carries @experimental or @deprecated to match. Anything short of generally available repeats it at runtime, as a Warning: 299 header on every response including errors.
See API overview.
Improvements
- Studio gains an ingestions view at
/patients/{patientId}/ingestions, pairing the list of submissions with the selected receipt — timings, staged counts, failure, and theintakebreakdown. Filter and sort live in the URL, so a filtered view is a link. Creating a patient no longer holds the dialog open while files process: it closes once every submission is accepted and points you at the work still running. - A workspace refused over its organization's billing state now answers
402 PAYMENT_REQUIREDnaming the reason, rather than the opaque401every tenant failure used to share. Your credentials are fine; the organization's owner has to settle it. - Requests rejected by schema validation now return the same
{ code, type, message }envelope as every other failure, instead of a serialized validation error. Anything pattern-matching the old body has to move totypeandmessage. resolvedByonGET .../resolutionand.../reconciliationnow names the stop rule that actually settled the merge —deterministic-code-exact, say — rather than the broader layer it belongs to.- Re-sending the same content deduplicates reliably whatever
X-Request-IDit arrives under. The header no longer takes part in content identity, so a redelivery stores nothing a second time and its receipt comes back with zero staged counts. - CDA reads a condition's or allergy's clinical status from the wrapping Concern Act rather than the nested observation's documentation lifecycle, so still-active problems stop arriving marked resolved. Hospital discharge medications, and entries named only through a narrative reference, are now ingested instead of skipped.
The clinical text that used to be dropped on the way in now works for you — corroborating, completing and contradicting the structured record. And Context Engine Studio is public.
Narrative enrichment
Unstructured content is now grouped into narratives that each carry a title, a short account and one verbatim quote, and read against the facts already in the patient's record. Every reading lands as corroborates, enriches or conflicts, and every one of them is backed by the passage that justified it.
See Narratives for more details.
Narratives and sources in the Virtual File System
You and your agents can now find narratives and source documents inside the VFS.
Every condition gains a _narratives/ directory listing the narratives tied to it. Its _story.md ends with a matching Narratives section.
Separately, /sources browses the documents a record was assembled from: by title, then document, then section, content verbatim. Note that /sources is not covered by search, and facts do not yet link back to the document they came from.
See VFS paths for more details.
Context Engine Studio
The Studio is now public at clinia/context-engine-studio, Apache-2.0. It is a self-serve developer tool for exploring a workspace you already have, and the reference implementation for wiring an app to one: ingest a folder of files, browse the resolved record, and chat over it with an agent reading the same Virtual File System yours would. It is not hosted and not supported. If you have issues, you can raise them here.
Point it at a workspace with CLINIA_CONTEXT_ENGINE_API_URL and an OAuth client id and secret, and give it a Read & Write credential — it ingests and creates patients. The JavaScript client it builds on, @clinia/context-engine-js, is now published on public npm. See Explore with Studio.
Improvements
- Conditions with an
inactiveorunknownstatus are now browsable under/conditions, instead of being reachable only if you already knew the slug. - Relationship inference runs against a patient's whole record rather than the batch being ingested, so a medication ingested today links to a condition ingested last year.
- Search results no longer include facts that a later ingestion removed.
GET /reports the build actually running, as{ name, version: { number, buildSha, buildDate } }.postProcessActionsis removed fromGET /v1/patients/{patientId}/reconciliation?format=json.
Workspace credentials now carry an explicit access level that the API enforces on every call. The account Security page gets a full sign-in methods manager, and the entity resolution pipeline gets a bit leaner.
Credential access levels
When creating a workspace credential you now choose an access level: Read or Read & Write. The server enforces the corresponding OAuth scope on every request — a Read credential is rejected with HTTP 403 on any endpoint that writes data (ingest, sessions, patient delete), and receives a WWW-Authenticate: Bearer error="insufficient_scope" header in the response.
Use Read credentials for AI agents and read-only integrations; use Read & Write credentials for server-side ingest workers. The access level is fixed at creation — delete and recreate a credential to change it.
See Manage Credentials and API Overview for the full scope breakdown.
Account profile and sign-in management
A new Profile page under Account lets you edit your display name. The Security page now also manages your linked sign-in methods: you can add or change a password, and connect or disconnect Google sign-in from the same screen.
Improvements
- Entity resolution no longer runs a second LLM pass after Layer 4 adjudication. Condition pairs that Layer 4 leaves ambiguous now persist as two separate facts instead of being re-evaluated through a context-aware merge step. This reduces ingestion cost and keeps the pipeline's decisions auditable at a single decision point.
- Passwords found in known breach databases are rejected at sign-up and password change.
Memory generation becomes a workflow you can return to and extend. Treat a conversation as a living object, generate memories on demand, and enjoy sharper entity resolution along the way.
Sessions API
The Context Engine now treats a conversation as a living object instead of a single batch job. You can upsert a session and append messages as the conversation unfolds, then generate memories from it on demand through a dedicated endpoint, decoupled from any particular lifecycle event. Memory generation is no longer tied to closing a session either: come back to an existing conversation later, add new turns, and generate memories from just what's new — without reprocessing everything that came before. Generation runs through a durable background job queue for reliable extraction, and you can list a session's memories with pagination and sorting to see exactly what it has produced so far.
Improvements
- Insurance and device entities normalize more robustly during ingestion, producing complete, well-formed records across a full batch.
- Active conditions lists now reflect only confirmed diagnoses, keeping encounter reasons and other non-condition entries out of the picture.
- Condition stories link medications based on clinical relevance rather than how closely their start dates align in time, giving a more accurate picture of what's related to a condition.
- A medication's status, dose, frequency, and route now resolve to the most recently documented value, so a patient's current state reflects the latest recorded change rather than whichever value was documented most often.
The Context Engine starts to learn. Sessions now leave behind durable memories that accumulate across conversations, the resolved record grows richer, and search reaches a patient's clinical timeline.
Memories
The Context Engine now learns from your agents' work. When a patient session closes, it automatically extracts and persists memories, building a memory graph that accumulates over time instead of resetting with every session. Those accumulated memories feed relationship inference between the concepts in a patient's context graph, so agents get connected context rather than isolated facts. And because memories surface directly in the Virtual File System alongside a patient's other documents, they're reachable through the same REST API and MCP server paths you already use — no new plumbing to write.
A richer resolved record
Ingestion now captures more of what's in a patient's documents. Social-history facts — things like smoking status, occupation, and living situation — are resolved and exposed in the Virtual File System, and every lab observation in a bundle is retained per LOINC code instead of collapsing repeated results. A patient's clinical picture stays complete instead of losing detail on the way in.
Improvements
- Clinical events are now searchable through the existing search API, so you can query across a patient's timeline, not just their documents.
- VFS path conventions are now consistent between the REST API and the MCP server, so you no longer need to translate paths when switching between them.
The Context Engine locks down. Every request now authenticates with OAuth, and entity resolution gets sharper across repeated ingestion.
OAuth authentication
The Context Engine now authenticates every request with OAuth, across the entire app — the REST API and the MCP server alike. Patient data sits behind proper access control from the very first call, so you can build on top of it without standing up your own auth layer first.
Improvements
- Deleting a patient now cascades to all of their associated records, so removal is clean and doesn't leave orphaned data behind.
- Entity resolution produces fewer duplicate entities across repeated FHIR and CDA ingestion, so re-ingesting a patient's documents sharpens their resolved record instead of cluttering it.
The first release: send in a patient's clinical documents, get back a single, resolved record you can browse and query through the REST API and MCP server.
Ingest and register patients through the REST API
Send FHIR R4 or CDA documents and the Context Engine parses and normalizes them for you, then makes the structured result available for retrieval — no manual mapping, no format wrangling. Register a patient, hand over their documents, and the resolved record is ready to read back.
Patient context graph
Clinical entities are resolved across all of a patient's documents, so overlapping or repeated records collapse into a single coherent view instead of piling up as duplicates. The Context Engine also infers relationships between those resolved entities, connecting them into a graph rather than leaving them as a flat list — so an agent reasoning over a patient gets context that's linked, not just deduplicated. Both run automatically on ingestion and keep improving as more documents come in.
Virtual File System
Every patient's resolved record is exposed as a structured, navigable Virtual File System, reachable through both the REST API and the MCP server. Instead of reasoning over raw documents, you (or your agent) can browse a patient the way you'd browse a filesystem — walking straight to the conditions, medications, or encounters you care about.
Workspaces
Workspaces give you tenant-scoped isolation out of the box, so every workspace's patient data stays fully separated from every other's — multi-tenant from day one, with no setup required.