> For the complete documentation index, see [llms.txt](https://docs.concurrence.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.concurrence.com/developer-guide/platform-api/data-world-model.md).

# Data & World Model

Query and manage workspace entities, enrichment, provenance, confidence-gated writes, migration metadata, data sources, and synchronization status.

The Platform API exposes workspace-scoped entity projections, event timelines, enrichment, data-source configuration, and synchronization status. Event-producing paths write source-attributed world events, and asynchronous data pipelines materialize the supported entity and timeline read models. Other platform resources, including service-owned configuration and lifecycle records, remain transactional and can emit world events separately.

{% hint style="info" %}
**Conceptual overview.** For the design rationale behind the world model - why event sourcing, how source-ranked conflict resolution works, and how agents read and write during conversations - see the [World Model conceptual documentation](https://docs.concurrence.com/data/world-model). This page covers the API surface.
{% endhint %}

{% hint style="info" %}
**Different from Classic API data access.** The Classic API provides [SQL access](/developer-guide/classic-api/data-access.md) to organization-scoped relational tables. The Platform API exposes typed operational APIs and asynchronously maintained world-model read projections.
{% endhint %}

## Storage and Projection Boundaries

The API surface combines several storage patterns. Keep these boundaries in mind:

* **Event-backed entity reads are projections.** Supported world-event families are materialized asynchronously into entity and timeline read models, so a successful emit does not imply immediate read-after-write visibility.
* **The world-event ledger is append-oriented.** A replacement can point to a prior record through `supersedes`; downstream projections derive the effective current record. This does not make every service-owned table append-only.
* **Projection behavior is type-specific.** Supported entity/event families have explicit projection logic. Arbitrary labels are not guaranteed to produce a typed entity projection or relationship edge.
* **Confidence is policy input, not a universal decision rule.** Specific projections, review flows, and connector sinks use confidence alongside source allowlists, sink support, and other policy checks.
* **Transactional resources have their own contracts.** Surfaces, connector configuration, and similar resources commit through their service APIs and may emit lifecycle events asynchronously after the transaction.

## Event Sourcing Model

World-event-producing paths emit append-oriented records with source and confidence metadata. Not every platform datum is a world event; service-owned resources expose their own CRUD and lifecycle contracts.

| Field           | Description                                                                                          |
| --------------- | ---------------------------------------------------------------------------------------------------- |
| `entity_type`   | Optional entity classification used by supported projections and queries                             |
| `event_type`    | Event identifier defined by the producing service and downstream pipeline                            |
| `data`          | Event payload (structured data, FHIR resources, agent observations, etc.)                            |
| `confidence`    | Source-class score (0.0-1.0) available to projections and delivery policies that use it              |
| `source`        | Origin system (voice\_agent, connector\_runner, ehr\_sync, transcript\_extraction, etc.)             |
| `is_current`    | Current marker on read/projection records; append-ledger supersession is represented by `supersedes` |
| `effective_at`  | Source-reported time when the observation applies                                                    |
| `review_status` | Review state (e.g. `auto_approved`, `approved`, `rejected`, `flagged`)                               |

### Confidence as Trust Architecture

World events carry a source-class confidence score, not a calibrated probability that an observation is true. The labels below are the common source classes; passing a confidence threshold alone never guarantees projection or outbound delivery.

| Level              | Confidence | Meaning                                          | Source Examples                         |
| ------------------ | ---------- | ------------------------------------------------ | --------------------------------------- |
| **Authoritative**  | 1.0        | Authoritative source or manual correction        | EHR API, manual entry, human correction |
| **Human-approved** | 0.95       | Named class retained in the confidence registry  | Not assigned by current proposal review |
| **High**           | 0.9        | Operator-verified or high-quality adapter data   | Operator verification, trusted adapter  |
| **EHR-trusted**    | 0.8        | Trusted EHR clinical data                        | EHR clinical records                    |
| **Verified**       | 0.7        | Verified or EHR-ingested data                    | Verification pass, EHR ingestion        |
| **Self-report**    | 0.5        | Patient-submitted or partially corroborated data | Patient-submitted form data             |
| **Agent-raw**      | 0.3        | Unverified agent inference                       | Raw voice-agent write                   |
| **Rejected**       | 0.0        | Discarded or explicitly rejected                 | Invalid or rejected observation         |

Current external-write proposal review authorizes a specific outbound proposal; approval does not promote the source observation into the human-approved confidence class.

Some projections, including governed enrichment winners, group confidence values into precedence tiers and use recency as a tiebreaker. Other projections can apply different type-specific logic. Selecting a winning observation does not independently verify its correctness or freshness.

Clients can filter and report on confidence. Connector write-back, which applied a confidence gate before delivering events to external systems, was retired with the [connector runner](/developer-guide/platform-api/data-world-model/connector-runner.md) on October 10, 2026.

See [Voice Agent, Confidence-Gated Writes](/developer-guide/platform-api/conversations/voice-agent.md#confidence-gated-writes) for how voice agent writes progress through the confidence pipeline.

### Supersedes Chain

Where a producer supplies or derives a supersession link, the new event references the prior event through `supersedes`. The append ledger does not mutate the prior record; downstream projections asynchronously derive which record is effectively current. Event families without a supersession key do not automatically gain this chain.

## How Agents Read and Write

Agents interact with the world model through three channels:

* **Ambient (pushed)**: selected data, such as caller identity, patient state, related entities, or location context, is included when the service, session, and runtime configuration make it available. This is bounded context, not a guarantee that every current fact is loaded or refreshed; use queried tools for authoritative details outside that payload.
* **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)**: supported voice runtimes can attach structured observations from conversation at source-appropriate confidence. Explicit write tools remain the controlled path for high-stakes mutations.

The [World Model conceptual documentation](https://docs.concurrence.com/data/world-model) covers the design rationale for this split and how it evolves as models improve.

## Entity Types

The entity APIs accept string type filters, but typed projections are implemented for a defined set of entity families. The current shared projection set is `person`, `place`, `call`, `appointment`, `outbound_task`, and `organization`. Other labels can appear in domain event timelines, but a new label does not automatically gain typed projection behavior.

| 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                                                                                                                                                                                 |
| `call`          | A voice conversation                 | Context, escalation history, safety state, human segments, audit                                                                                                                                                                        |
| `outbound_task` | A scheduled outreach task            | Lifecycle, retry state, scheduling, dispatch history                                                                                                                                                                                    |

{% hint style="info" %}
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.
{% endhint %}

### Entity Reads

Entity reads promote common attributes from projected state into typed top-level fields. Fields that do not apply to an entity type return `null`.

#### List Entities

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/{workspace\_id}/world/entities" method="get" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

Without `entity_type`, the list covers every entity type. Workspace-level records that carry no entity ID are not entities and are excluded from both the list and its total.

#### Get an Entity

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/{workspace\_id}/world/entities/{entity\_id}" method="get" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

{% hint style="warning" %}
The `state` field (object containing the full projected state) is deprecated. Use the typed fields above instead. The `state` field will continue to be returned for backward compatibility but may be removed in a future version.
{% endhint %}

## Entity Enrichment

Entities can carry governed per-key attributes beyond the typed response fields. Enrichment writes produce source-attributed, confidence-scored `entity.enriched` events, and the enrichment projection selects the current winner for each registered key.

### 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). The enrichment projection selects winners by its own `confidence_class` precedence tier, then effective time, ingestion time, and event ID. These tiers aggregate source-confidence values rather than matching every named source class one-to-one; this rule is specific to that projection contract.

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).

### Governed Enrichment Write Path

Direct enrichment writes share the registry validation path and are differentiated by source and confidence. Validation errors (unknown key, wrong value type, enum miss, sub-floor confidence) return `400` with a specific message. Connectors, surfaces, and agent runtimes have separate service paths and can emit compatible world events asynchronously.

Direct enrichment writes and registry mutations require the `admin` role or above (`Workspace:Update`). See the [Enrichment API Reference](#enrichment-api-reference) below for the full endpoint contract.

### Enrichment API Reference

#### Write an enrichment value

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/{workspace\_id}/world/entities/{entity\_id}/enrichment/{key}" method="put" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

#### Read current enrichment

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/{workspace\_id}/world/entities/{entity\_id}/enrichment" method="get" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

#### Read enrichment history

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/{workspace\_id}/world/entities/{entity\_id}/enrichment/{key}/history" method="get" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

#### Register an enrichment key

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/{workspace\_id}/world/enrichment-keys" method="post" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

#### List enrichment keys

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/{workspace\_id}/world/enrichment-keys" method="get" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

#### Update an enrichment key

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/{workspace\_id}/world/enrichment-keys/{key\_id}" method="patch" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

#### Delete an enrichment key

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/{workspace\_id}/world/enrichment-keys/{key\_id}" method="delete" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

## Entity Graph

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

```mermaid
%%{init: {"theme":"base","themeVariables":{"fontFamily":"Inter, sans-serif","fontSize":"16px","background":"#FAF8F6","primaryColor":"#F1EAE7","primaryTextColor":"#1A1817","primaryBorderColor":"#D7D2D0","secondaryColor":"#FDFCFB","tertiaryColor":"#F6F2F0","lineColor":"#575452","textColor":"#3D3937","clusterBkg":"#FDFCFB","clusterBorder":"#E8E2DF","edgeLabelBackground":"#FAF8F6","actorBkg":"#F1EAE7","actorTextColor":"#1A1817","actorBorder":"#D7D2D0","actorLineColor":"#575452","signalColor":"#575452","signalTextColor":"#3D3937","labelBoxBkgColor":"#F1EAE7","labelBoxBorderColor":"#D7D2D0","labelTextColor":"#3D3937","loopTextColor":"#3D3937","noteBkgColor":"#F6F2F0","noteBorderColor":"#D7D2D0","noteTextColor":"#3D3937","activationBkgColor":"#F1EAE7","activationBorderColor":"#D7D2D0","altSectionBkgColor":"#FAF8F6","altSectionColor":"#3D3937"},"fontFamily":"Inter, sans-serif"}}%%
flowchart TB
    P["Person<br/>(patient role)"] -->|"participant"| A["Appointment"]
    A -->|"practitioner"| PR["Person<br/>(practitioner role)"]
    A -->|"location"| L["Place"]
    P -->|"primary_care"| PR
    P -->|"coverage"| INS["Insurance"]
    C["Call"] -->|"caller"| P
    C -->|"escalation"| OP["Person<br/>(operator role)"]
    OT["Outbound Task"] -->|"patient"| P
    OT -->|"call"| C
    D["Deal"] -->|"contact"| P
    D -->|"organization"| ORG["Organization"]
```

Projected relationships can come from supported inputs such as:

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-produced events**: configured agents can emit supported relationship observations.

Relationship endpoints read projected graph edges. Availability and versioning depend on the producer and projection for that relationship type.

## Agent-Produced Knowledge

Configured agents can emit derived events such as insights or corrections with provenance fields. Whether those records become typed entity state, timeline entries, or downstream triggers depends on the event family and deployed projection.

## Data Sources

Data-source records describe an external feed: its type, connection configuration, entity types, field mappings, and `sync_strategy` (`continuous`, `scheduled`, `manual`, or `webhook`).

{% hint style="warning" %}
**Data sources no longer sync.** The [connector runner](/developer-guide/platform-api/data-world-model/connector-runner.md) that polled them was retired on October 10, 2026, and the sync-trigger operation was removed. Data-source records, status counts, and sync history remain readable, and new records can be saved, but nothing polls them. Send records through [FHIR](/developer-guide/platform-api/data-world-model/fhir.md), [Bulk Import](/developer-guide/platform-api/data-world-model/bulk-import.md), or [Customer Data Intake](/developer-guide/platform-api/data-world-model/intake.md).
{% endhint %}

Data-source status counts the events recorded for the source in the last 90 days, and sync history returns daily counts for up to 90 days (30 by default). Both report zero failures, because no sync runs.

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=fhir_store`).

### Self-Service Secret Provisioning

The generic `smart_fhir` source type is retired and cannot be created through the current API. Compatibility secret-handling code or a stored record does not establish a runnable connector. Use an active adapter's documented credential process and confirm provisioning with the implementation owner. Never include secrets in issue reports or example downloads.

## Raw Records

Supported connectors can retain records they cannot map as source-attributed raw events (commonly with a `.raw` event type). Retention and replay behavior are connector-specific; the API does not guarantee that every rejected or unmapped source payload is stored.

## Data Quality Pipeline

World events expose confidence metadata, and specific consumers apply it according to their own contracts:

* **Capture at source-appropriate confidence.** Supported producers assign a confidence class according to the source and write path. Conversational extraction is not automatically authoritative.
* **Corrections are new observations.** A supported producer can emit a new source-attributed event with its own assigned confidence and, where supported, a `supersedes` link. External-write proposal approval alone neither creates a correction nor promotes confidence.
* **No connector write-back.** Connector delivery to external systems and the external write proposal flow were retired with the connector runner. See [Review Queue](/developer-guide/platform-api/integrations/review-queue.md).

## 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

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/{workspace\_id}/entities/{entity\_id}/brief" method="post" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

### Get the Latest Brief

Cache misses fall through to the event store and repopulate the cache. When no brief has been generated, the operation returns a consistent empty shape rather than `404`.

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/{workspace\_id}/entities/{entity\_id}/brief" method="get" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

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.

### 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.

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/{workspace\_id}/world/entities/{entity\_id}/graph" method="get" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

### Provenance

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.

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/{workspace\_id}/world/entities/{entity\_id}/provenance" method="get" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

### Lineage

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).

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/{workspace\_id}/world/entities/{entity\_id}/lineage" method="get" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

### Suspected Duplicates

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/{workspace\_id}/world/entities/duplicates" method="get" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

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.

### Entity Search

Search currently uses case-insensitive display-name substring matching. It is not semantic or embedding search.

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/{workspace\_id}/world/search" method="get" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

**Permissions**: `viewer+`.

## World Sync Status

The former per-sink world sync status endpoint has been removed. Connector write-back, including delivery of approved [external write proposals](/developer-guide/platform-api/integrations/review-queue.md), stopped when the [connector runner](/developer-guide/platform-api/data-world-model/connector-runner.md) was retired on October 10, 2026. To change an external system during a conversation, use an [integration](/developer-guide/platform-api/integrations.md) and verify the result at the destination. A queryable entity is not proof that an external system holds the same record.

## Generic Data Query

A structured query endpoint provides whitelisted table access with REST-style filtering.

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/{workspace\_id}/query/{schema}/{table}" method="get" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

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

## Import Classic Conversation Metadata

`POST /v1/{workspace_id}/world/migration/conversations` imports terminal Classic conversation envelopes for migrated person entities. The operation is admin-only and accepts 1-500 conversations per request.

The operation is idempotent and correctable for a given workspace and source conversation ID. It imports conversation metadata, not transcript turns. The response reports `imported`, `created`, and `updated` counts.

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/{workspace\_id}/world/migration/conversations" method="post" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.concurrence.com/developer-guide/platform-api/data-world-model.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
