For the complete documentation index, see llms.txt. This page is also available as Markdown.

Data & World Model

Event-sourced world model with confidence scoring, entity graphs, enrichment, entity intelligence, and structured query endpoints.

The Platform API provides access to a unified, event-sourced world model that aggregates entities, events, and relationships from all connected systems: EHRs, voice conversations, manual imports, and AI enrichment. Every piece of data flows through a single event store, and entity state is always a computed projection of events.

Conceptual overview. For the design rationale behind the world model - why event sourcing, how confidence-based truth works, and how agents read and write during conversations - see the World Model conceptual documentation. This page covers the API surface.

Different from Classic API data access. The Classic API provides SQL access to organization-scoped relational tables. The Platform API uses an event-sourced world model that unifies data from multiple sources (EHR, voice, imports) with confidence scoring.

Design Thesis

The world model rests on a small set of invariants that shape every endpoint on this page:

  • Events are the only source of truth. Entity state is always a computed projection from events. There is no direct mutation path: the only way to change state is insert event -> recompute projection.

  • Events are append-only and immutable. New information creates a new event that supersedes the old one. The old event stays for audit, temporal debugging, and undo.

  • Entity state is a pure function of events. Same events, same state. Concurrent recomputation is safe because the projection is deterministic.

  • Confidence resolves conflicts, not timestamps. When two sources disagree, the projection takes the highest-confidence data. Within the same confidence class, most recent wins.

  • Open schema. entity_type and event_type are free-form text, not enums. New kinds of entities and observations require no schema migration.

Event Sourcing Model

Every fact in the system (a patient's name, an appointment booking, an insurance verification, an agent-produced insight) is stored as an immutable event with a confidence score:

Field
Description

entity_type

What kind of entity (free-form text: patient, appointment, practitioner, location, call, etc.)

event_type

What happened (free-form text: patient.created, appointment.booked, coverage.verified, etc.)

data

Event payload (structured data, FHIR resources, agent observations, etc.)

confidence

Reliability score (0.0-1.0) that determines projection priority and sync eligibility

source

Origin system (voice_agent, connector_runner, ehr_sync, transcript_extraction, etc.)

is_current

Whether this is the latest version (managed by storage layer on supersede)

effective_at

When the fact was true in the real world

review_status

Review state (e.g. auto_approved, approved, rejected, flagged)

Confidence as Trust Architecture

Every event carries a confidence score that determines its reliability, downstream behavior, and sync eligibility:

Level
Confidence
Meaning
Syncs to EHR?
Source Examples

Authoritative

1.0

From source system or human-corrected

Yes (auto)

EHR API, manual entry, human correction

Human-approved

0.95

Confirmed by a human reviewer

Yes (auto)

Human review approval

High

0.9

Operator-verified or high-quality adapter data

Yes (auto)

Operator verification, trusted adapter

EHR-trusted

0.8

Trusted EHR clinical data

Yes (auto)

EHR clinical records

Verified

0.7

LLM-verified or EHR-ingested data

Yes (auto)

LLM verification pass, EHR ingestion

Self-report

0.5

Patient-submitted data, partially corroborated

No

Patient-submitted form data

Agent-raw

0.3

Raw agent inference, unverified

No

Raw voice agent write

Rejected

0.0

Discarded or explicitly rejected

Never

Junk call, hallucination

Confidence scores resolve conflicts in projections: if two events disagree about a patient's phone number, the higher-confidence one wins. Among equal confidence, the most recent one wins.

Why continuous confidence, not binary staging: binary (draft/production) forces a hard cutover. With continuous confidence, different consumers set their own thresholds: the voice agent trusts its own writes at any confidence (session-scoped), the world model API serves data above a minimum threshold, outbound sync requires verified+, and researchers can query everything. One store, many views.

See Voice Agent, Confidence-Gated Writes for how voice agent writes progress through the confidence pipeline.

Supersedes Chain

When a new event replaces an older one (e.g., updating a patient's phone number), the new event references the old one via supersedes. The storage layer sets is_current=false on the superseded event. Projections only consider current events, ensuring state is always up-to-date while maintaining the full history for audit.

How Agents Read and Write

Agents interact with the world model through three channels:

  • Ambient (pushed): data the agent should always have - caller identity, patient state, related entities, location context - is injected into the system prompt and refreshed as the conversation evolves.

  • Queried (pulled): data whose search space is too large to push - slot search, patient lookup, entity search - is retrieved through tool calls that return human-readable results.

  • Extracted (captured): structured data the agent expresses in conversation (insurance details, contact info, preferences) is captured by a parallel extraction listener and written at moderate confidence, below the verified threshold. Explicit write tools remain for high-stakes data.

The World Model conceptual documentation covers the design rationale for this split and how it evolves as models improve.

Entity Types

The world model supports an open-ended set of entity types. entity_type is free-form text, not an enum. No schema migration is needed to add new types. An agent discovering a new kind of entity creates events with the new type, and the system handles it.

Entity Type
What It Represents
Common Roles / Key State Fields

person

Any individual in the system

Patient (demographics, conditions, medications, insurance), practitioner (profile, NPI, specialty), operator (availability, performance). A single person entity can hold multiple roles; the projection detects roles from event data.

organization

A company or healthcare organization

Practice, payer, employer. Name, contacts, identifiers

place

A physical site

Clinic, hospital, office. Address, phone, hours, status

appointment

A scheduled visit

Status, participants, times, cancellation, confirmation

deal

A business opportunity or engagement

Status, pipeline stage, value, contacts

call

A voice conversation

Context, escalation history, safety state, human segments, audit

outbound_task

A scheduled outreach task

Lifecycle, retry state, scheduling, dispatch history

FHIR resource types on events (Patient, Practitioner, Location, etc.) stay unchanged. The ontological type applies at the entity level, while FHIR types describe the data format of individual events.

Typed Entity Response Fields

Entity API responses include typed top-level fields for common attributes, promoted from the projected entity state. These fields are available on all entity types. Fields that do not apply to a given entity type return null.

Field
Type
Applies To

name

string

Person, organization

phone

string (E.164)

Person, organization

email

string

Person, organization

birth_date

string (YYYY-MM-DD)

Person (patient)

gender

string

Person (patient)

mrn

string

Person (patient)

status

string

All entity types

source

string

All entity types

appointment_status

string

Appointment

appointment_start

datetime

Appointment

appointment_end

datetime

Appointment

appointment_type

string

Appointment

domain

string

Organization

industry

string

Organization

direction

string

Call

duration_seconds

float

Call

call_sid

string

Call

Entity Enrichment

Entities can carry arbitrary per-key attributes beyond the typed response fields. Enrichment values are first-class, source-attributed, confidence-scored events, not an opaque blob on the entity. Each write produces an entity.enriched event that participates in the same supersedes chain and confidence resolution as every other world model event.

Registry-Governed Keys

Every workspace maintains a registry of enrichment keys. A key is scoped to a specific (entity_type, key) pair and declares:

  • value_type: one of string, number, boolean, date, enum, json.

  • allowed_values: required when value_type=enum.

  • min_confidence: floor on write confidence; writes below this are rejected.

  • is_pii: marks the attribute for downstream PII handling.

  • source_hint, description: free-form text for admins.

Writes against an unregistered key are rejected with 400. Agent-extracted values whose key is not registered are silently dropped, so they do not pollute the event stream or compete with governed values. This gives admins full control over which attributes are tracked without blocking agent-side capture.

key and value_type are immutable after registration; create a new key and migrate if those need to change. Deleting a registered key does not delete historical entity.enriched events (the audit trail is preserved); only future writes are rejected.

Winner Selection and Audit

Reads return the current winner per (entity, key), one row with full provenance (value, value type, confidence, source, source system, effective time, ingested time, event ID). Winners are selected by confidence class (authoritative > human-approved > AI-verified > uncertain) with recency as the tiebreaker, the same resolution that governs every other world model projection.

The supersedes chain for any key is queryable for audit and temporal debugging. Each historical entry carries the full provenance plus supersedes (pointer to the event it replaced) and is_current (whether it is still the winner).

Unified Write Path

The same write path handles manual admin edits, connector backfills, form submissions, and agent-extracted captures, differentiated only by source and confidence. Validation errors (unknown key, wrong value type, enum miss, sub-floor confidence) all return 400 with a specific message.

All writes and registry mutations require the admin role or above (Workspace:Update). See the API Reference below for the full endpoint contract.

Entity Graph

Entities are connected by directed relationship edges, discovered automatically from data:

Relationships are discovered from:

  1. Reference parsing: automatically extracted during entity resolution (e.g., Appointment.participant -> Patient).

  2. Explicit events: relationship.established events created by connectors or agents.

  3. Agent discovery: autonomous agents identify relationships through data analysis.

Relationships are themselves events: discoverable, versioned, and confidence-scored.

Agent-Produced Knowledge

Agents analyze incoming data and produce derived events: insights, correlations, predictions, corrections. These derived events live in the same event store as raw data, linked to their source evidence, so other agents can read and act on them - closing the loop between observation and action.

Data Sources

External data feeds that push or pull data into the workspace:

Strategy
Behavior
Example

continuous

Polled on a frequent interval

EHR patient updates

scheduled

Polled on a cron schedule

Daily reporting

manual

Only synced via explicit API trigger

One-time imports

webhook

Receives push events (no polling)

Real-time notifications

Each data source supports status checks, sync history, and health monitoring. The connector runner manages the full lifecycle of data source polling and sync.

The data sources list endpoint accepts repeatable source_type query parameters for filtering by multiple source types in a single request (e.g., ?source_type=ehr&source_type=smart_fhir).

Self-Service Secret Provisioning

For smart_fhir data sources, the create and update endpoints support inline secret provisioning. Pass private_key_value in the connection_config and the API automatically provisions the key to secure storage, storing only a secure secret-store reference in the data source record. API responses redact all secret fields (*_value, *_pem, *_secret, *_password) and mask the stored secret reference. No manual secret provisioning is needed when connecting SMART-compliant EHR systems.

Raw Records

Source records that cannot yet be mapped into the unified entity model are still captured: the connector runner stores them as raw events carrying the original record payload (with a .raw event type). Data is never lost, just not yet unified.

Data Quality Pipeline

Data quality is a pipeline, not a gate. Every piece of data carries a confidence level, and different consumers read at different confidence thresholds:

  • Capture at source-appropriate confidence. Connector-runner writes from authoritative systems land at authoritative confidence; agent-extracted conversation data lands at moderate confidence; raw agent inference lands at agent-raw confidence.

  • Verification raises confidence. Verified data becomes sync-eligible; human approval or correction produces a new, higher-confidence event that supersedes the original.

  • Outbound sync is gated on confidence. Only events at verified confidence or above are eligible to sync to external systems. The connector runner enforces this multi-layer confidence gate before any data reaches production EHR systems.

Proposed writes to external systems can additionally be routed through human review as external write proposals before they execute - see Review Queue.

Entity Narrative Briefs

AI-generated narrative summaries of a patient entity's world model data. The platform reads the last 90 days of events, synthesizes them into a structured narrative, and persists the result as a world model event for fast retrieval.

Generate a brief on demand with POST /v1/{workspace_id}/entities/{entity_id}/brief. The response includes the narrative in both Markdown and structured JSON, evidence pointers (event IDs that informed the narrative), a confidence score (0.0-1.0), the event count, and a prompt version identifier. Returns 404 if the entity is not one of these types (patient, cohort, territory, emirate, district) or does not exist.

Retrieve the latest cached brief with GET /v1/{workspace_id}/entities/{entity_id}/brief. Cache misses fall through to the event store and repopulate the cache transparently. When no brief has been generated, the response returns a consistent empty shape (null event_id and content fields) rather than a 404.

Briefs are scoped to patient, cohort, territory, emirate, and district entities. Permissions: viewer+.

Entity Intelligence

Read endpoints for exploring individual entities: their relationship graph, data provenance, full lineage, suspected duplicates, and search.

GET /v1/{workspace_id}/world/entities/{entity_id}/graph. One-level relationship graph.

Returns center (entity metadata), edges[] (edge type, confidence), and neighbors[] (entity metadata for connected nodes). Responds with 404 if the entity is not found.

GET /v1/{workspace_id}/world/entities/{entity_id}/provenance. Data provenance and confidence history.

Returns sources[] (contributing data sources), confidence_history[] (score over time), and merge_history[] (entity resolution events). Responds with 404 if the entity is not found.

GET /v1/{workspace_id}/world/entities/{entity_id}/lineage. Full data lineage. Responds with 404 if the entity is not found.

The response contains the same sources, confidence_history, and merge_history sections as the provenance endpoint, plus outbound_sinks and review_history keys that are currently always empty arrays (kept for wire stability). For per-sink outbound sync status, use GET /world/sync/by-sink.

GET /v1/{workspace_id}/world/entities/duplicates. Suspected duplicate entities.

Parameter
Type
Default
Description

entity_type

string

-

Filter by entity type

confidence_max

float (0-1)

1.0

Max confidence threshold

Returns historical same_as merge edges sorted by ascending confidence (lowest means most uncertain). New same_as edges are no longer written; the results reflect previously recorded merges.

GET /v1/{workspace_id}/world/search. Enhanced entity search.

Parameter
Type
Default
Description

q

string

Required

Search text (case-insensitive substring match on display name)

entity_type

string

-

Filter by entity type

source

string

-

Filter by event source

confidence_min

float (0-1)

-

Min confidence threshold

limit

integer (1-100)

20

Page size

offset

integer

0

Pagination offset

Returns results[] + total count.

Permissions: viewer+.

World Sync Status

GET /v1/{workspace_id}/world/sync/by-sink. Per-sink outbound sync summary.

Shows multi-sink outbound sync progress for workspaces with multiple outbound sinks. The endpoint takes no query parameters and returns sinks[], one entry per outbound data source:

Field
Type
Description

data_source_id

string (UUID)

The outbound data source (sink)

name

string

Sink display name

source_type

string

Sink type

total

integer

Total outbound-eligible events for this sink

synced

integer

Events successfully synced

failed

integer

Events that failed to sync

pending

integer

Events awaiting sync

Generic Data Query

A structured query endpoint provides flexible table access with REST-style filter syntax:

Filter operators: eq, neq, gt, gte, lt, lte, like, ilike, in, is

Other parameters: select=col1,col2, order=col.asc, limit=100 (max, default 20), offset=0

Security: column whitelist per table, hidden sensitive columns, workspace isolation enforced server-side, maximum 100 rows per request.

API Reference

Last updated

Was this helpful?