ChartHeroAI

DocsDeveloper Docs

Core concept

Data model

Understand encounters, activities, documents, checklists, and their generated OpenAPI contracts.

Why this matters

ChartHero's public API exposes a clinical workflow graph. Most integrations start from an encounter, then follow relationship IDs to activities, documents, patients, actors, and evaluations.

Use this page as the human-readable map. It shows the object relationships, the fields callers usually care about, and representative payloads with synthetic data. For the exact generated contract, use the rendered API Reference. The raw OpenAPI JSON is available for tooling and schema validation.

Resource graph

Text
Patient
  -> Encounter
      -> Activity
          -> Clinical document
          -> Ambient transcript
          -> Billing document
          -> Encounter checklist

Evaluation
  -> encounter_id, activity_id, document_id (the evaluated ambient transcript)
  -> evaluated_actor_id
  -> definition_id and rubric_id (from the evaluation definitions route)

Actor
  -> referenced by created_by_actor_id, updated_by_actor_id, evaluated_actor_id, and other actor fields

The default list and detail responses return primary resources with relationship IDs. Use include when you want linked sidecar resources in the same response.

Resource Role
Encounter The clinical workflow container and main sync target.
Activity A bounded clinical interaction inside an encounter, such as a visit, call, or documentation interaction.
Document A polymorphic clinical artifact linked to an encounter and optionally an activity.
Patient Patient reference and demographics, returned only when requested through include=patients.
Actor User or API-key actor referenced by API resources.
Evaluation An AI evaluation of one staff member's part in a recorded conversation. It points to the conversation's encounter, activity and transcript document.

Path IDs and relationship IDs are opaque ChartHero IDs. Do not infer storage location, organization, timestamp, or resource type from their format.

Encounter shape

An encounter is the top-level resource for a clinical workflow that ChartHero can make available to an approved partner organization. It carries the encounter status, date of service, patient relationship, activity IDs, document IDs, and approved external identifiers.

Field Type Meaning
encounter_id string Opaque ChartHero encounter ID.
organization_id string Organization that owns the encounter.
patient_id string or null Opaque patient ID after same-organization validation.
activity_ids string[] Ordered activities linked to this encounter.
document_ids string[] Ordered documents linked to this encounter.
encounter_type string or null Derived encounter type: ambient, phone_call, or clinical_documentation.
external_ids object[] Active approved source-backed identifiers for the API key's organization. Patient, encounter, actor, and provider identifiers use source, type, and value.

Example encounter detail with linked resources:

JSON
{
  "encounter": {
    "encounter_id": "enc_synthetic_001",
    "organization_id": "org_synthetic_001",
    "external_ids": [
      {
        "source": "partner_ehr",
        "type": "appointment_id",
        "value": "visit-12345"
      }
    ],
    "patient_id": "pat_synthetic_001",
    "activity_ids": ["act_synthetic_visit_001"],
    "document_ids": ["doc_synthetic_note_001"],
    "date_of_service": "2026-05-25T14:00:00Z",
    "status": "completed",
    "encounter_type": "clinical_documentation",
    "created_at": "2026-05-25T13:55:00Z",
    "updated_at": "2026-05-25T15:15:00Z",
    "created_by_actor_id": "11111111-1111-4111-8111-111111111111",
    "updated_by_actor_id": "11111111-1111-4111-8111-111111111111"
  },
  "included": {
    "patients": [
      {
        "patient_id": "pat_synthetic_001",
        "external_ids": [
          {
            "source": "partner_ehr",
            "type": "patient_id",
            "value": "patient-98765"
          }
        ],
        "first_name": "Jane",
        "last_name": "Sample",
        "date_of_birth": "1975-03-20"
      }
    ],
    "activities": [
      {
        "activity_id": "act_synthetic_visit_001",
        "encounter_id": "enc_synthetic_001",
        "external_ids": [],
        "document_ids": ["doc_synthetic_note_001"],
        "created_at": "2026-05-25T14:00:00Z",
        "updated_at": "2026-05-25T15:10:00Z",
        "created_by_actor_id": "11111111-1111-4111-8111-111111111111",
        "updated_by_actor_id": "11111111-1111-4111-8111-111111111111"
      }
    ],
    "documents": [
      {
        "document_id": "doc_synthetic_note_001",
        "encounter_id": "enc_synthetic_001",
        "patient_id": "pat_synthetic_001",
        "activity_id": "act_synthetic_visit_001",
        "external_ids": [],
        "schema_type": "document",
        "title": "Progress note",
        "content": {
          "format": "markdown",
          "text": "Synthetic assessment and plan text."
        },
        "template": {
          "template_id": "tpl_progress_note",
          "label": "Progress note",
          "type": "clinical_note"
        },
        "created_at": "2026-05-25T14:30:00Z",
        "updated_at": "2026-05-25T15:00:00Z",
        "created_by_actor_id": "11111111-1111-4111-8111-111111111111",
        "updated_by_actor_id": "11111111-1111-4111-8111-111111111111"
      }
    ],
    "actors": [
      {
        "actor_type": "user",
        "actor_id": "11111111-1111-4111-8111-111111111111",
        "external_ids": [],
        "display_name": "Dr. Jane Doe",
        "first_name": "Jane",
        "last_name": "Doe",
        "active": true
      }
    ]
  }
}

Exact generated contracts:

Operation Reference
List encounters GET /external/v1/encounters
Read encounter GET /external/v1/encounters/{encounter_id}

Activities

An activity groups documents that belong to one bounded clinical interaction inside an encounter. A single encounter can have one activity or several activities. A document can reference an activity through activity_id.

Activities are returned as sidecar resources only when requested with include=activities.

Field Type Meaning
activity_id string Opaque activity ID.
encounter_id string Parent encounter ID.
document_ids string[] Ordered supported documents assigned to this activity.
external_ids object[] Reserved for future approved activity identifiers. Currently returned as an empty array.
created_by_actor_id / updated_by_actor_id UUID or null Actor references when available.
cURL
curl "https://api.charthero.ai/external/v1/encounters/enc_synthetic_001?include=activities" \
  -H "Authorization: Bearer <api_key>"

Documents

Documents are the clinical artifacts attached to encounters. Document routes return supported variants through a schema_type discriminator.

schema_type What it represents
document Clinical markdown note content and API-safe template reference when available.
ambient_transcript Finalized transcript turns, optional source transcript for translated phone calls, recording metadata, target template reference, and phone-call metadata when applicable.
billing Selected billing codes and bounded billing context without raw payer coverage payloads.
encounter_checklist Materialized workflow/checklist state for the encounter.

Each document type below uses the same pattern: what the document represents, the fields clients usually inspect first, and a representative payload.

Use the document list to sync document resources directly:

cURL
curl "https://api.charthero.ai/external/v1/documents?limit=25&offset=0" \
  -H "Authorization: Bearer <api_key>"

Use document detail when you already have both the encounter ID and document ID:

cURL
curl "https://api.charthero.ai/external/v1/encounters/enc_synthetic_001/documents/doc_synthetic_note_001" \
  -H "Authorization: Bearer <api_key>"

Clinical documents

Clinical documents contain markdown note content, such as progress notes, handoff notes, call logs, or other generated or user-authored documentation.

Field Type Meaning
schema_type string Always document for clinical markdown documents.
content.format string Always markdown.
content.text string or null Clinical document text when available.
template object or null Public-safe template reference when available.
activity_id string or null Activity this document belongs to when the activity still exists.

Example:

JSON
{
  "document": {
    "document_id": "doc_synthetic_note_001",
    "encounter_id": "enc_synthetic_001",
    "patient_id": "pat_synthetic_001",
    "activity_id": "act_synthetic_visit_001",
    "external_ids": [],
    "schema_type": "document",
    "title": "Progress note",
    "content": {
      "format": "markdown",
      "text": "## Assessment\nSynthetic assessment text.\n\n## Plan\nSynthetic plan text."
    },
    "template": {
      "template_id": "tpl_progress_note",
      "label": "Progress note",
      "type": "clinical_note"
    },
    "created_at": "2026-05-25T14:30:00Z",
    "updated_at": "2026-05-25T15:00:00Z",
    "created_by_actor_id": "11111111-1111-4111-8111-111111111111",
    "updated_by_actor_id": "11111111-1111-4111-8111-111111111111"
  }
}

Ambient transcripts

Ambient transcript documents contain finalized transcript content and recording metadata. Phone-call variants may also include call legs, consent metadata, call outcome, selected documentation plan, and generated call-log content.

Field Type Meaning
schema_type string Always ambient_transcript for transcript documents.
workflow_variant string or null ambient or phone_call when available.
recording object or null Recording availability and duration metadata. Audio URLs are fetched separately.
transcript_language string or null Original spoken-language code for translated phone-call transcripts. Omitted for default English transcripts.
transcript object or null Final transcript turns. For translated phone calls, this is the English-normalized transcript. Null only for eligible completed no-audio phone-call documents.
source_transcript object or null Original-language transcript for translated phone calls, using the same transcript schema as transcript. Turn segmentation can differ from the English transcript.
phone_call object or null Phone-call metadata when safely available.

Example:

JSON
{
  "document": {
    "document_id": "doc_synthetic_transcript_001",
    "encounter_id": "enc_synthetic_001",
    "patient_id": "pat_synthetic_001",
    "activity_id": "act_synthetic_visit_001",
    "external_ids": [],
    "schema_type": "ambient_transcript",
    "title": "Visit recording",
    "status": "completed",
    "workflow_variant": "phone_call",
    "target_template": {
      "template_id": "tpl_call_log",
      "label": "Care coordination call log",
      "type": "call_log"
    },
    "recording": {
      "availability": "available",
      "duration_seconds": 842.4,
      "channel_count": 2,
      "channel_mode": "dual_channel"
    },
    "phone_call": {
      "active_call_leg_id": "leg_synthetic_001",
      "outcome": "connected_conversation",
      "call_legs": [
        {
          "call_leg_id": "leg_synthetic_001",
          "to_e164": "+15551234567",
          "from_e164": "+15557654321",
          "state": "ended",
          "started_at": "2026-05-25T14:00:00Z",
          "connected_at": "2026-05-25T14:00:12Z",
          "ended_at": "2026-05-25T14:14:02Z",
          "recording_consent": {
            "status": "authorized",
            "final_source": "announcement",
            "recording_started_at": "2026-05-25T14:00:20Z"
          }
        }
      ],
      "documentation_plan": {
        "action": "generate_call_log",
        "target_template": {
          "template_id": "tpl_call_log",
          "label": "Care coordination call log",
          "type": "call_log"
        }
      },
      "call_log": {
        "format": "markdown",
        "text": "Synthetic call summary and follow-up plan.",
        "generated_at": "2026-05-25T14:20:00Z",
        "generated_by": "ai"
      }
    },
    "transcript": {
      "provider": "deepgram",
      "audio_duration_seconds": 842.4,
      "turns": [
        {
          "speaker": "Clinician",
          "speaker_role": "provider",
          "channel_index": 0,
          "text": "Hi, this is the care team calling.",
          "start_seconds": 0.0,
          "end_seconds": 2.1
        },
        {
          "speaker": "Patient",
          "speaker_role": "caller",
          "channel_index": 1,
          "text": "Thanks for calling.",
          "start_seconds": 2.4,
          "end_seconds": 3.8
        }
      ]
    },
    "created_at": "2026-05-25T14:00:00Z",
    "updated_at": "2026-05-25T14:22:00Z",
    "created_by_actor_id": "11111111-1111-4111-8111-111111111111",
    "updated_by_actor_id": "11111111-1111-4111-8111-111111111111"
  }
}

Billing documents

Billing documents expose selected codes and bounded billing context. They do not include raw payer coverage payloads, raw code suggestions, or internal billing generation state.

Field Type Meaning
schema_type string Always billing for billing documents.
codes object[] Selected active billing codes.
billing_context object or null Encounter, time, patient-status, and payer context when available.
source_document_id string or null Validated public source clinical document ID when serializable.
activity_id string or null Activity this billing document belongs to when available.

Example:

JSON
{
  "document": {
    "document_id": "doc_synthetic_billing_001",
    "encounter_id": "enc_synthetic_001",
    "patient_id": "pat_synthetic_001",
    "activity_id": "act_synthetic_visit_001",
    "external_ids": [],
    "schema_type": "billing",
    "title": "Billing codes",
    "codes": [
      {
        "code_type": "cpt",
        "code": "99213",
        "label": "Office visit"
      }
    ],
    "billing_context": {
      "encounter_type": "outpatient",
      "patient_status": "established",
      "total_time_minutes": 18,
      "payer_context": {
        "source": "ehr_import",
        "payer_name": "Synthetic payer",
        "plan_name": "Synthetic plan"
      }
    },
    "source_document_id": "doc_synthetic_note_001",
    "created_at": "2026-05-25T14:40:00Z",
    "updated_at": "2026-05-25T15:10:00Z",
    "created_by_actor_id": "11111111-1111-4111-8111-111111111111",
    "updated_by_actor_id": "11111111-1111-4111-8111-111111111111"
  }
}

Encounter checklists

An encounter checklist is exposed as a document with schema_type="encounter_checklist", but it is not simple file content. It is a materialized workflow state that captures what the care team planned, discussed, addressed, deferred, dismissed, or flagged during an encounter.

Text
Encounter checklist document
  -> payload
      -> blocks
          -> tasks
              -> flags
              -> subtasks
      -> flags
  -> import_sources

The public checklist payload is designed for read-side integrations. It exposes the current materialized state, provenance, and carry-forward lineage. It does not expose internal dashboard planning state, raw event history, agent runtime state, prompts, or unsupported source payloads.

Nested internal conversation blocks are exposed as ordered top-level public blocks. The public checklist payload does not preserve conversation block hierarchy.

Checklist payloads are ordered around blocks. A workflow block represents a planned unit of work whose tasks should be treated as a strict ordered collection. ChartHero preserves workflow membership and task order, but it does not require the clinician to complete the tasks sequentially. A task_group block is a looser grouping for related tasks, checks, discussion topics, or follow-up work. Non-workflow tasks may be prioritized, regrouped, or separated as the checklist evolves. Task-specific flags are nested under each task, while payload-level flags are reserved for encounter-level checklist concerns.

Field Type Meaning
status string Checklist lifecycle: draft, active, paused, completed, or abandoned.
payload.blocks object[] Ordered checklist blocks with inline task state.
payload.flags object[] Encounter-level concerns not attached to a specific task.
payload.blocks[].tasks object[] Materialized task state, including status, priority, provenance, action flags, category, and subtasks.
payload.blocks[].tasks[].flags object[] Task-specific concerns that need attention, progress, conclusion, or dismissal.
import_sources object[] Carry-forward lineage from prior checklist content.

Checklist groupings

Concept Public meaning
workflow block Stable ordered unit of work, often from templates, carry-forward imports, or partner recommendations, with workflow-level status and provenance. Workflow tasks stay together and keep their intended order, but ChartHero does not enforce step-by-step completion.
task_group block Related loose tasks or conversation agenda items that are not a strict workflow. ChartHero may reorganize non-workflow tasks as live checklist updates run.
task.category Clinical or program-domain grouping, such as HCC, HEDIS, AWV, preventive care, chronic conditions, or administrative work.
task.subtasks Nested work items under a parent task.
Use case Use
Render live To-Do or All checklist views payload.blocks
Show Coverage completion by clinical or program domain task.category
Preserve planned workflow lineage and status workflow blocks
Export the actual checklist work payload.blocks[].tasks, plus task flags and payload flags
Show post-encounter action work Tasks where requires_action=true

workflow_id appears only on workflow blocks and exists so import lineage can point back to a visible public object. Loose task groups do not have a workflow_id.

New conversation-derived task creation is off by default in the live checklist. The default task-generation mode can update existing tasks. Installations that enable conversation task generation may add new non-workflow tasks or task groups, but workflow blocks remain structurally protected.

Example:

JSON
{
  "document": {
    "document_id": "doc_synthetic_checklist_001",
    "encounter_id": "enc_synthetic_001",
    "patient_id": "pat_synthetic_001",
    "activity_id": "act_synthetic_visit_001",
    "external_ids": [],
    "schema_type": "encounter_checklist",
    "title": "Visit checklist",
    "status": "active",
    "payload": {
      "schema_version": "1.0",
      "blocks": [
        {
          "type": "workflow",
          "block_id": "block_synthetic_001",
          "workflow_id": "workflow_synthetic_001",
          "title": "Medication review",
          "description": {
            "format": "text",
            "text": "Medication reconciliation workflow."
          },
          "provenance": {
            "source_system": "CHARTHERO_TEMPLATE",
            "source_type": "WORKFLOW_TEMPLATE",
            "captured_at": "2026-05-25T14:45:00Z"
          },
          "tasks": [
            {
              "task_id": "task_synthetic_001",
              "title": "Review medication list",
              "note": {
                "format": "text",
                "text": "Confirm current antihypertensive dosing."
              },
              "description": {
                "format": "text",
                "text": "Reconcile patient-reported medications with chart list."
              },
              "decision": {
                "format": "text",
                "text": "Medication list reviewed and updated."
              },
              "category": "CHRONIC_CONDITIONS",
              "task_type": "MEDICATION",
              "kind": "task",
              "status": "IN_PROGRESS",
              "disposition": "BLOCKED",
              "priority": "HIGH",
              "provenance": {
                "source_system": "CHARTHERO_TEMPLATE",
                "source_type": "WORKFLOW_TEMPLATE",
                "captured_at": "2026-05-25T14:45:00Z"
              },
              "requires_action": true,
              "status_needs_confirmation": false,
              "dismissed": false,
              "flags": [
                {
                  "flag_id": "flag_synthetic_001",
                  "severity": "HIGH",
                  "title": "Medication discrepancy",
                  "reason": {
                    "format": "text",
                    "text": "Patient reported a different dose than the imported list."
                  },
                  "resolved_if": {
                    "format": "text",
                    "text": "Dose confirmed and updated in the source system."
                  },
                  "status": "IN_PROGRESS",
                  "disposition": "BLOCKED",
                  "status_needs_confirmation": false,
                  "conclusion_note": {
                    "format": "text",
                    "text": "Awaiting pharmacy confirmation."
                  },
                  "created_at": "2026-05-25T14:46:00Z",
                  "updated_at": "2026-05-25T15:10:00Z"
                }
              ],
              "subtasks": [],
              "created_at": "2026-05-25T14:45:00Z",
              "updated_at": "2026-05-25T15:15:00Z",
              "addressed_at": "2026-05-25T15:05:00Z"
            }
          ],
          "status": "IN_PROGRESS",
          "created_at": "2026-05-25T14:45:00Z",
          "updated_at": "2026-05-25T15:15:00Z"
        }
      ],
      "flags": []
    },
    "import_sources": [
      {
        "source_type": "carry_forward",
        "imported_at": "2026-05-25T14:44:00Z",
        "imported_by_actor_id": "11111111-1111-4111-8111-111111111111",
        "entries": [
          {
            "source_item_type": "workflow",
            "target_workflow_id": "workflow_synthetic_001",
            "task_mappings": [
              {
                "target_task_id": "task_synthetic_001",
                "source_status": "NOT_REACHED",
                "source_disposition": "DEFERRED"
              }
            ],
            "source_status": "NOT_REACHED",
            "source_disposition": "DEFERRED"
          }
        ]
      }
    ],
    "started_at": "2026-05-25T14:45:00Z",
    "created_at": "2026-05-25T14:45:00Z",
    "updated_at": "2026-05-25T15:15:00Z",
    "created_by_actor_id": "11111111-1111-4111-8111-111111111111",
    "updated_by_actor_id": "11111111-1111-4111-8111-111111111111"
  }
}

Use checklist fields as state, not as UI instructions. For example, status, priority, requires_action, dismissed, and status_needs_confirmation describe the task state at response time. For display order, use payload.blocks. For domain coverage, use task.category. Use workflow IDs on workflow blocks to preserve workflow lineage, not as the only grouping mechanism.

Exact generated document contracts:

Operation Reference
List documents GET /external/v1/documents
Read document GET /external/v1/encounters/{encounter_id}/documents/{document_id}
Fetch audio URL GET /external/v1/encounters/{encounter_id}/documents/{document_id}/audio

Evaluations

An evaluation belongs to the conversation it evaluates. It carries the encounter_id, activity_id and document_id of that conversation, the evaluated person's evaluated_actor_id, and the definition_id and rubric_id that describe what was measured and expected. Evaluation routes are separate from encounter and document routes and require encounters:read, patients:read and evaluations:read; encounter and document responses don't include evaluations.

Field Points to
encounter_id The encounter, returned with include=encounters.
activity_id The activity the conversation belongs to.
document_id The ambient_transcript document that was evaluated.
evaluated_actor_id The evaluated user actor, returned with include=actors.
definition_id, rubric_id The definition and rubric releases, returned with include=evaluation_definitions or from the definitions route.

Inside an evaluation, result.dimensions has one entry per dimension of the definition, unique by key, and result.findings has any number of findings, unique by finding_id within the evaluation. Each dimension's finding_ids lists the findings that support its score. A finding can support several dimensions, or none, and finding categories don't map to dimensions.

See How evaluations work for the resource and Fetch evaluations for the routes.

Operation Reference
List evaluations GET /external/v1/evaluations
Read evaluation GET /external/v1/evaluations/{evaluation_id}
List evaluation definitions GET /external/v1/evaluation-definitions

Fetching linked resources

Use include when you want linked resources in one response. No sidecars are returned by default.

cURL
curl "https://api.charthero.ai/external/v1/encounters?include=patients,activities,documents,actors" \
  -H "Authorization: Bearer <api_key>"
cURL
curl "https://api.charthero.ai/external/v1/documents?include=encounters,patients,activities,actors" \
  -H "Authorization: Bearer <api_key>"

The allowed include values are route-specific. Use the generated operation contracts for exact query parameter behavior:

Route family Guide Generated reference
Encounters Fetch encounters GET /external/v1/encounters
Documents Fetch documents GET /external/v1/documents
Evaluations Fetch evaluations GET /external/v1/evaluations
Pagination and filters Pagination and filters API Reference

Keeping clients current

Treat this page as the conceptual map. Treat the generated reference as the exact contract for today's responses. ChartHero adds optional response fields only after updating the reference and the Changelog, so build clients that ignore response fields they don't recognize, and validate responses strictly against the OpenAPI in your tests, not at runtime.

Before implementing or updating a client, check:

  1. the API Reference for operation behavior and generated examples;
  2. the raw OpenAPI JSON for tooling and schema validation;
  3. the Changelog for public contract updates.

Next steps

ChartHeroAI

Developer documentation for ChartHero APIs, adapters, and integrations.

HIPAA-aligned safeguards

BAA available

ChartHero AI LLC