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

Connector Runner

Supported EHR, FHIR, REST, and workspace-data ingestion, plus policy-gated external delivery, observability, and outbound call dispatch.

The connector runner moves data between supported external systems and the workspace's world model. It polls configured EHR, FHIR, REST, and workspace-data sources; writes source-attributed events; delivers policy-eligible event payloads to supported destinations; and dispatches scheduled outbound calls. The legacy CRM connector and general event-review pipeline are not active connector paths.

Inbound polling is implemented for rest_api, fhir_store, smart_fhir, lakebase_schema, and the supported vendor configurations under ehr. Connector-specific webhooks can ingest changes when the external system provides a supported event or subscription flow. A source type accepted by an older stored record is not proof that a current polling handler exists.

Outbound write-back supports the connector types listed in Write-Back. Unsupported connector types are reported rather than routed through a fallback handler.

The connector runner has no public-facing API. It operates as a background service. Data sources and sync configuration are managed through the Data Sources endpoints on the Platform API, and its health is visible through the Pipeline Observability endpoints below. For the full architecture narrative - sync design, confidence gating, and review workflow - see the Connectors & EHR conceptual documentation.

Inbound Sync

Data sources feed the world model through two mechanisms:

  • Polling: supported sources are polled according to their sync strategy. Locking, checkpoints, deduplication, and retry behavior vary by adapter. A committed batch remains available after a later batch fails, but customers should use source health and history to confirm recovery.

  • Real-time webhooks: supported EHR event and subscription flows can push change notifications. Verification, deduplication, and resource retrieval follow the contract of the selected connector.

Both paths produce source-attributed world-model events. Mapping, entity resolution, and recovery behavior can differ by connector.

Polling behavior:

Feature
How It Works

Full vs light cycles

Supported EHR adapters can separate broad resource refreshes from higher-frequency resource polling.

Business hours gate

Polling can be restricted to defined operating hours to respect external API usage patterns

Reference data caching

Frequently-accessed reference data (locations, carrier lists) is reused between polls to reduce external API call volume

Configurable poll cadences

Per-resource poll intervals via poll_cadences in the data source connection config

Entity Resolution

Events can arrive with references to external entities (for example, an appointment references a patient by external ID). Supported resolver paths map stable source references to canonical IDs, create or find matching world-model entities, link events, and project graph relationships. Retry and deduplication guarantees depend on the connector's identifiers, checkpoints, and resolver path; entity resolution is not a universal request-idempotency guarantee.

External Type
Entity Type
Canonical ID Format

Patient

person

{source}:Patient:{id}

Practitioner

person

{source}:Practitioner:{id}

Location

place

{source}:Location:{id}

Appointment

appointment

{source}:Appointment:{id}

Coverage / Encounter

Linked to patient

Via participant references

Slot

Skipped

Marked to prevent re-fetching

The current resolver does not create new cross-source same_as merge edges from demographic similarity. Records from different sources remain distinct unless they share a stable canonical mapping or another supported producer links them explicitly. Historical same_as edges remain visible in entity-intelligence responses but should not be read as a current automatic-merge promise.

Derived entity views and enrichment can update asynchronously after event ingestion. A successful event write can therefore precede its appearance in every derived view.

Outbound Sync

Data captured by the voice agent during calls is gated before syncing to external systems:

  • Source allowlist: only voice_agent, encounter_finalized, and platform_api_mcp (clinical writes made through the MCP server, which must reach the EHR like the voice path) events are eligible for outbound sync. Events from api, outbound_sync_agent, ehr_sync, and connector_runner sources are excluded. This is an allowlist, not a blocklist - new sources must be explicitly added to become eligible.

  • Confidence gate: the live unattended subscriber requires verified confidence after separating review-required sinks. Approved proposal egress is a distinct human-authorized path and does not reapply that automatic confidence gate.

  • Review-gated sinks: where the private-preview proposal flow is enabled, a sink can stage an external write proposal instead of auto-pushing. An operator approves or rejects the proposal through the Review Queue. That decision authorizes the specific payload and target; it does not change the source event's confidence. Staging deduplicates the same originating write intent. This connector flow is separate from a Platform Integration's conversation-scoped approval_policy.

Write-Back

A workspace can target multiple supported external systems. Each sink is configured independently with its own outbound_entity_types, and delivery outcomes are tracked per sink. A failure at one destination does not block evaluation for another.

Outbound events are routed through a handler registry that maps each sink's connector_type to the correct write-back handler. The registry is the single routing authority for all outbound paths.

Connector Type
Write-Back
Auth

fhir_store

FHIR R4 (ETag optimistic locking)

Managed credentials

smart_fhir

SMART-compliant FHIR R4

SMART Backend Services (RS384/ES384 JWT assertion)

athenahealth

athenahealth EHR adapter (Patient create/update, Appointment book/cancel)

OAuth2 client credentials

charmhealth

Charm EHR adapter

OAuth2 + API key

eclinicalworks

eClinicalWorks EHR adapter

Managed credentials

meditab

Meditab EHR adapter

Managed credentials

hazelhealth

Hazel Health EHR adapter

Managed credentials

mbp

MBP EHR adapter

Managed credentials

lakebase_schema

Workspace database schema adapter

Managed credentials

For eligible events, the connector runner maps the event payload into the target system's format:

Event Type
What Happens

patient.created

Create a patient record through the selected connector's deterministic payload mapping.

patient.updated

Merge demographics with current EHR record

appointment.booked

Create appointment (patient resolved from entity external IDs)

appointment.confirmed / cancelled

Update appointment status

coverage.created

Create insurance record (carrier fuzzy-matched from EHR carrier list)

Write-back safeguards:

  • Optimistic locking: for FHIR stores, ETag-based locking prevents lost updates. On conflict (412), the write is re-read and retried up to 3 times.

  • Confidence-aware dependencies: supported handlers can evaluate dependency confidence (for example, before creating an appointment for a patient). Confirm the selected connector's dependency behavior rather than assuming every write path performs the same check.

  • Duplicate prevention: supported patient-create paths perform connector-specific matching before record creation. Confirm the selected connector's behavior before treating this as a universal guarantee.

  • Loop prevention: the live subscriber's source policy excludes ehr_sync events from unattended write-back. Other import, proposal, and connector flows have their own loop and replay contracts.

Outbound Call Dispatch

The connector runner dispatches outbound calls when scheduled outbound_task entities become due. This implements the execution side of the voice agent's outbound system. For each due task, the runner loads the patient entity from the world model, builds a rich system prompt from the patient projection, resolves the outbound phone number, and dispatches the call - writing an outbound.dispatched or outbound.failed event with the result.

Feature
How It Works

Business hours gate

Per-task timezone-aware window (e.g., 9am-5pm ET). Outside hours, the task waits for the next window

Priority ordering

Tasks dispatched highest-priority first (1-10 scale)

Dispatch locking

Per-entity locking prevents double-dispatch

Retry with backoff

Configurable max attempts and backoff interval. Failed tasks automatically schedule the next attempt

Context

Selected patient projection data is added to the outbound task context.

Idempotency

Dispatch keyed by outbound:{entity_id}:{attempt}, safe to retry

Pipeline Observability

The Platform API exposes 10 read-only pipeline observability endpoints under /v1/{workspace_id}/pipeline/ that combine live connector runner state with stored pipeline data. In the current Console, per-source health appears under Data > Sources; legacy Sync Health links redirect there.

All operations require viewer+ access and are workspace-scoped.

Pipeline Status

Pipeline status

get

Composite pipeline dashboard: connector-runner state + Lakebase counts.

Authorizations
AuthorizationstringRequired

API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.

Path parameters
workspace_idstring · uuidRequired
Responses
200

Successful Response

application/json
statusstringRequired
connector_runner_statusstringRequired
uptime_secondsinteger · nullableOptional
active_pollsintegerOptionalDefault: 0
total_eventsinteger · nullableOptional

Read-model event count for the last 7 days. Null means the read model is empty or unavailable; zero means the read model is ready and has no events.

event_read_model_statusstring · enumOptionalDefault: emptyPossible values:
event_read_model_synced_atstring · date-time · nullableOptional
total_entitiesintegerOptionalDefault: 0
get/v1/{workspace_id}/pipeline/status
GET /v1/{workspace_id}/pipeline/status HTTP/1.1
Host: api.platform.amigo.ai
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
  "status": "text",
  "connector_runner_status": "text",
  "uptime_seconds": 1,
  "active_polls": 0,
  "total_events": 1,
  "event_read_model_status": "empty",
  "event_read_model_synced_at": "2026-01-01T00:00:00.000Z",
  "total_entities": 0,
  "sources": [
    {
      "data_source_id": "123e4567-e89b-12d3-a456-426614174000",
      "workspace_id": "123e4567-e89b-12d3-a456-426614174000",
      "source_type": "ehr",
      "connector_type": "text",
      "status": "text",
      "last_poll_at": "text",
      "last_poll_duration_ms": 0,
      "last_poll_event_count": 0,
      "last_error": "text",
      "consecutive_errors": 0,
      "connection_healthy": true
    }
  ],
  "entity_resolution": {
    "ANY_ADDITIONAL_PROPERTY": "anything"
  },
  "review_loop": {
    "ANY_ADDITIONAL_PROPERTY": "anything"
  },
  "outbound_dispatch": {
    "ANY_ADDITIONAL_PROPERTY": "anything"
  },
  "outbound_subscriber": {
    "ANY_ADDITIONAL_PROPERTY": "anything"
  },
  "reconciliation": {
    "ANY_ADDITIONAL_PROPERTY": "anything"
  },
  "gap_scanner": {
    "ANY_ADDITIONAL_PROPERTY": "anything"
  }
}

List Sources

List pipeline sources

get

Data sources with live health from Valkey cr:last_poll keys.

Authorizations
AuthorizationstringRequired

API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.

Path parameters
workspace_idstring · uuidRequired
Query parameters
searchstring · nullableOptional

Search by name, ID, type, or health status

source_typestring · nullableOptional

Filter by source type

health_statusstring · nullableOptional

Filter by health status

is_activeboolean · nullableOptional

Filter by active state

Responses
200

Successful Response

application/json
idstring · uuidRequired
namestringRequired
display_namestring · nullableOptional
source_typestring · enumRequiredPossible values:
is_activebooleanRequired
health_statusstring · enumRequiredPossible values:
event_countintegerOptionalDefault: 0
last_sync_atstring · nullableOptional
get/v1/{workspace_id}/pipeline/sources
GET /v1/{workspace_id}/pipeline/sources HTTP/1.1
Host: api.platform.amigo.ai
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
[
  {
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "name": "text",
    "display_name": "text",
    "source_type": "ehr",
    "is_active": true,
    "health_status": "unknown",
    "last_poll": {
      "at": "text",
      "duration_ms": 0,
      "event_count": 0,
      "error": "text"
    },
    "event_count": 0,
    "last_sync_at": "text"
  }
]

Source Overview

Source overview

get

Consolidated source detail: metadata, health, recent failures, last poll, outbound summary.

Authorizations
AuthorizationstringRequired

API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.

Path parameters
workspace_idstring · uuidRequired
source_idstring · uuidRequired
Responses
200

Successful Response

application/json
idstring · uuidRequired
namestringRequired
display_namestring · nullableOptional
source_typestring · enumRequiredPossible values:
is_activebooleanRequired
health_statusstring · enumRequiredPossible values:
last_sync_atstring · nullableOptional
last_sync_statusstring · enum · nullableOptionalPossible values:
last_sync_event_countintegerOptionalDefault: 0
created_atstring · nullableOptional
event_countintegerOptionalDefault: 0
entity_countintegerOptionalDefault: 0
get/v1/{workspace_id}/pipeline/sources/{source_id}/overview
GET /v1/{workspace_id}/pipeline/sources/{source_id}/overview HTTP/1.1
Host: api.platform.amigo.ai
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "name": "text",
  "display_name": "text",
  "source_type": "ehr",
  "is_active": true,
  "health_status": "unknown",
  "last_sync_at": "text",
  "last_sync_status": "success",
  "last_sync_event_count": 0,
  "created_at": "text",
  "event_count": 0,
  "entity_count": 0,
  "last_poll": {
    "at": "text",
    "duration_ms": 0,
    "event_count": 0,
    "error": "text"
  },
  "recent_failures": [
    {
      "event_id": "123e4567-e89b-12d3-a456-426614174000",
      "event_type": "text",
      "fhir_resource_type": "text",
      "sync_error": "text",
      "ingested_at": "text"
    }
  ],
  "outbound": {
    "total": 0,
    "synced": 0,
    "failed": 0,
    "pending": 0,
    "last_synced_at": "text"
  }
}

Source History

Source sync history

get

Event counts bucketed by time window for a specific source.

Authorizations
AuthorizationstringRequired

API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.

Path parameters
workspace_idstring · uuidRequired
source_idstring · uuidRequired
Query parameters
date_fromstring · date-time · nullableOptional
date_tostring · date-time · nullableOptional
intervalstring · enumOptionalDefault: 1hPossible values:
hoursinteger · min: 1 · max: 720 · nullableOptional
Responses
200

Successful Response

application/json
bucketstringRequired
source_systemstring · nullableOptional
event_countintegerRequired
get/v1/{workspace_id}/pipeline/sources/{source_id}/history
GET /v1/{workspace_id}/pipeline/sources/{source_id}/history HTTP/1.1
Host: api.platform.amigo.ai
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
[
  {
    "bucket": "text",
    "source_system": "text",
    "event_count": 1
  }
]

Source Events

Source events

get

Paginated events for a specific data source.

Authorizations
AuthorizationstringRequired

API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.

Path parameters
workspace_idstring · uuidRequired
source_idstring · uuidRequired
Query parameters
sort_bystring[]OptionalDefault: []
limitinteger · max: 200OptionalDefault: 50
continuation_tokenanyOptional
event_typestring · nullableOptional

Filter by event type

entity_typestring · nullableOptional

Filter by entity type

date_fromstring · date-time · nullableOptional

Filter events ingested on or after this time

date_tostring · date-time · nullableOptional

Filter events ingested on or before this time

Responses
200

Successful Response

application/json
has_morebooleanRequired
continuation_tokenanyOptional
get/v1/{workspace_id}/pipeline/sources/{source_id}/events
GET /v1/{workspace_id}/pipeline/sources/{source_id}/events HTTP/1.1
Host: api.platform.amigo.ai
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
  "items": [
    {
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "event_type": "text",
      "entity_type": "text",
      "entity_id": "123e4567-e89b-12d3-a456-426614174000",
      "source": "text",
      "source_system": "text",
      "confidence": 1,
      "ingested_at": "2026-01-01T00:00:00.000Z"
    }
  ],
  "has_more": true,
  "continuation_token": null
}

Outbound Summary

Outbound sync summary

get

Per-sink outbound sync aggregation: synced/failed/pending counts.

Authorizations
AuthorizationstringRequired

API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.

Path parameters
workspace_idstring · uuidRequired
Responses
200

Successful Response

application/json
data_source_idstring · uuidRequired
data_source_namestringRequired
totalintegerRequired
syncedintegerRequired
failedintegerRequired
pendingintegerRequired
last_synced_atstring · nullableOptional
get/v1/{workspace_id}/pipeline/outbound
GET /v1/{workspace_id}/pipeline/outbound HTTP/1.1
Host: api.platform.amigo.ai
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
[
  {
    "data_source_id": "123e4567-e89b-12d3-a456-426614174000",
    "data_source_name": "text",
    "total": 1,
    "synced": 1,
    "failed": 1,
    "pending": 1,
    "last_synced_at": "text"
  }
]

Outbound Log

Outbound sync log

get

Paginated outbound sync log for a specific sink.

Authorizations
AuthorizationstringRequired

API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.

Path parameters
workspace_idstring · uuidRequired
data_source_idstring · uuidRequired
Query parameters
limitinteger · max: 200OptionalDefault: 50
continuation_tokenanyOptional
statusstring · enum · nullableOptionalPossible values:
Responses
200

Successful Response

application/json
has_morebooleanRequired
continuation_tokenanyOptional
get/v1/{workspace_id}/pipeline/outbound/{data_source_id}/log
GET /v1/{workspace_id}/pipeline/outbound/{data_source_id}/log HTTP/1.1
Host: api.platform.amigo.ai
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
  "items": [
    {
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "event_id": "123e4567-e89b-12d3-a456-426614174000",
      "synced_at": "2026-01-01T00:00:00.000Z",
      "sync_error": "text",
      "attempt_count": 1,
      "created_at": "2026-01-01T00:00:00.000Z"
    }
  ],
  "has_more": true,
  "continuation_token": null
}

Entity Resolution Metrics

Entity resolution metrics

get

Historical same_as merge-edge counts (written by the pre-SDP resolver; merge detection now lives in the Databricks pipeline — new edges are not produced) and entity resolution loop status.

Authorizations
AuthorizationstringRequired

API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.

Path parameters
workspace_idstring · uuidRequired
Responses
200

Successful Response

application/json
total_same_as_edgesintegerRequired
recent_merges_24hintegerRequired
loop_statusstringRequired
last_tick_atstring · nullableOptional
get/v1/{workspace_id}/pipeline/entity-resolution
GET /v1/{workspace_id}/pipeline/entity-resolution HTTP/1.1
Host: api.platform.amigo.ai
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
  "total_same_as_edges": 1,
  "recent_merges_24h": 1,
  "loop_status": "text",
  "last_tick_at": "text"
}

Legacy Review Counters

The retired event-review pipeline has no producer. Its compatibility counters remain zero and do not represent external write proposals.

Review pipeline metrics

get

Review queue depth, approval rate, and average review time.

Authorizations
AuthorizationstringRequired

API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.

Path parameters
workspace_idstring · uuidRequired
Responses
200

Successful Response

application/json
queue_depthintegerRequired
approved_7dintegerRequired
rejected_7dintegerRequired
avg_review_time_hoursnumber · nullableOptional
total_itemsintegerOptionalDefault: 0
get/v1/{workspace_id}/pipeline/review
GET /v1/{workspace_id}/pipeline/review HTTP/1.1
Host: api.platform.amigo.ai
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
  "queue_depth": 1,
  "pending_by_priority": {
    "ANY_ADDITIONAL_PROPERTY": 1
  },
  "approved_7d": 1,
  "rejected_7d": 1,
  "avg_review_time_hours": 1,
  "total_items": 0
}

Throughput

Event throughput

get

Event throughput time series across all sources.

Authorizations
AuthorizationstringRequired

API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.

Path parameters
workspace_idstring · uuidRequired
Query parameters
date_fromstring · date-time · nullableOptional
date_tostring · date-time · nullableOptional
intervalstring · enumOptionalDefault: 1dPossible values:
hoursinteger · min: 1 · max: 720 · nullableOptional
bucket_minutesinteger · min: 1 · max: 1440 · nullableOptional
Responses
200

Successful Response

application/json
bucketstringRequired
source_systemstring · nullableOptional
event_countintegerRequired
get/v1/{workspace_id}/pipeline/throughput
GET /v1/{workspace_id}/pipeline/throughput HTTP/1.1
Host: api.platform.amigo.ai
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
[
  {
    "bucket": "text",
    "source_system": "text",
    "event_count": 1
  }
]

Source Health

Connection health is tracked per source using consecutive error counts. A source is marked degraded after 3+ consecutive poll failures and recovers automatically on the next successful poll.

Live health metrics reflect recent poll activity and reset when the connector runner restarts; stored event counts and sync history are unaffected.

Graceful Degradation

If the connector runner is temporarily unavailable, the pipeline endpoints still return stored event counts, sync history, and entity resolution metrics. Only live component states and active poll counts are omitted. The dashboard stays functional during connector runner restarts or deployments.

Connector Settings

Connector definitions are managed through workspace settings with typed configuration models. Each connector definition includes:

Field
Description

connector_type

The external system type (maps to the handler registry)

sync_strategy

Sync cadence: continuous, scheduled, manual, or webhook

connection_config

System-specific connection parameters (endpoints, credentials, resource scoping)

poll_cadences

Per-resource type polling intervals

The connector settings endpoint validates sync strategy values with strict type checking, preventing misconfiguration bugs. The data source response includes an is_stale field computed from the connector's last successful sync and its configured cadence. Configuration changes are picked up automatically on the next sync cycle - no restart is needed.

Last updated

Was this helpful?