Documentation
Conversational Triage API
Reference
Schemas

Schemas

Canonical reference for the wire shapes used by both transports — HTTP v2 and WebSocket. This is the only place where field-level shapes are described; the guides link here rather than repeating them.

Read models and write (input) models are listed separately. Input models always omit server-owned fields.

Enum values are in Enums and primitives; streaming event payloads in Streaming events.

Conversation

Conversation

Full read snapshot returned by both transports.

FieldTypeDescription
idUUIDConversation identifier.
status"in_progress" or "completed"Whether the conversation still accepts user messages. completed when the interview finished or the conversation was permanently terminated. Use is_terminated to distinguish those two cases.
settingsConversationSettingsEffective conversation settings.
assessmentAssessmentCurrent assessment snapshot.
messagesUserConversationMessage | AssistantConversationMessage[]Persisted message history, discriminated by role. Empty for a new conversation.
is_terminatedbooleantrue once the conversation permanently rejects further user messages for a non-recommendation reason — for example an underage patient or a confirmed demographics change. Further turn calls fail with conversation_terminated. Default false.

ConversationInput

Write model used to create a conversation.

FieldTypeRequiredDescription
settingsConversationSettingsInputyesInitial settings; missing fields use the instance default, then the platform built-in.
assessmentAssessmentInputyesPre-seeded assessment; all fields optional.

Settings

ConversationSettings

Server view of conversation settings; all fields are always present.

For create, an omitted field resolves to the default configured for your instance, then to the platform built-in listed below. An explicit request field always wins. Existing conversations keep the settings persisted at creation, so changing instance defaults does not affect conversations in flight. max_message_length is server-owned and not accepted on input.

FieldTypePlatform defaultDescription
languagestring"en"BCP-47 language tag.
channel"text" or "voice""text"Response mode optimized for text or TTS.
ui_widgets_enabledbooleanfalseEmit UI widgets in assistant content_parts and transient widget events.
opening_message_enabledbooleanfalseEmit an opening assistant message automatically.
risk_factors_enabledbooleantrueAllow the assistant to collect risk-factor evidence.
geographic_risk_factors_enabledbooleanfalseAllow the assistant to collect geographic risk-factor evidence.
handoff_policiesHandoffPolicy[][]Enabled handoff detectors; empty disables all handoff detection.
max_message_lengthinteger (> 0)1500Maximum accepted length of a user message, counted in Unicode code points, measured before PII redaction. Server-owned; per-instance.

ConversationSettingsInput

Write model used on create and on partial update. All fields are optional; omitted fields keep their current value (update) or fall back to the instance default, then the platform built-in (create). max_message_length is not accepted.

FieldTypeRequiredDescription
languagestringnoConversation language.
channel"text" or "voice"noResponse mode optimized for text or TTS.
ui_widgets_enabledbooleannoEmit UI widgets in assistant content_parts and transient widget events.
opening_message_enabledbooleannoEmit an opening assistant message automatically.
risk_factors_enabledbooleannoAllow the assistant to collect risk-factor evidence.
geographic_risk_factors_enabledbooleannoAllow the assistant to collect geographic risk-factor evidence.
handoff_policiesHandoffPolicy[]noEnabled handoff detectors. Values must be known HandoffPolicy members.

Assessment

Assessment

Conversation-level assessment snapshot.

FieldTypeDescription
ageAge or nullPatient age.
sex"male", "female", or nullPatient sex.
relationshipPatientRelationship or nullPatient relationship to the user.
evidenceEvidence[]Matched evidence items.
unmatched_evidenceUnmatchedEvidence[]Evidence not yet linked to a knowledge concept.
conditionsCondition[]Knowledge-enriched condition rows when a recommendation exists.
recommendationRecommendation or nullSet once the conversation reaches a recommendation.

Top-level conditions and recommendation.conditions carry the same Condition[] once a recommendation exists.

AssessmentInput

Write model used as the assessment seed on create. Read-only fields (recommendation, unmatched_evidence, conditions) are not accepted.

FieldTypeRequiredDescription
ageAgenoInitial patient age.
sex"male" or "female"noInitial patient sex.
relationshipPatientRelationshipnoPatient relationship to the user.
evidenceEvidenceInput[]noPre-seeded evidence items.

Recommendation

FieldTypeDescription
triage_levelTriageLevelTriage band for the user.
conditionsCondition[]Same enriched rows as Assessment.conditions.
has_emergency_evidencebooleanWhether emergency-level evidence was observed.
serious_evidenceSeriousEvidence[]Highlighted serious evidence.
specialistSpecialistSuggested specialist.
channelRecommendationChannelSuggested contact channel.
stop_reasonstringWhy the diagnostic flow stopped.

Evidence

Read model for one evidence item in the assessment.

FieldTypeDescription
idstringStable medical evidence identifier.
namestringEvidence label used in the conversation.
common_namestring or nullNormalized common name when available.
snomed_ctSnomedCtSNOMED CT mapping. Omitted from the response when unavailable.
stateEvidenceStateCurrent evidence state.
originEvidenceOriginHow the evidence entered the conversation.
seriousnessEvidenceSeriousnessEvidence seriousness from the knowledge base; defaults to normal when not classifiable.
parent_idstring or nullSet when an immediate parent concept is also in evidence.

EvidenceInput

Write model accepted on create; the server fills name and common_name from the knowledge base.

FieldTypeRequiredDescription
idstringyesStable medical evidence identifier.
stateEvidenceStateyesDeclared evidence state.

UnmatchedEvidence

Free-text or extracted evidence not linked to a knowledge concept.

FieldTypeDescription
namestringLabel or extracted text.
stateEvidenceStateAnswer state.

Condition

Knowledge-enriched differential condition row used in Assessment.conditions and Recommendation.conditions.

FieldTypeDescription
idstringStable condition identifier.
probabilitynumberPosterior probability for this condition.
namestringDisplay name.
common_namestringNormalized common name.
condition_detailsConditionDetailsKnowledge-base metadata for this condition.

ConditionDetails

FieldTypeDescription
icd10_codestringICD-10 code.
snomed_ctSnomedCtSNOMED CT mapping. Omitted when unavailable.
categoryConditionCategoryCondition category.
prevalenceConditionPrevalencePrevalence band.
severityConditionSeveritySeverity band.
acutenessConditionAcutenessAcuteness band.
hintstring or nullOptional advisory hint.
has_patient_educationbooleanWhether patient-education content exists.
triage_levelTriageLevelRecommended triage level for this condition.

ConditionCategory

FieldTypeDescription
idstringStable category identifier.
namestringDisplay name.

SnomedCt

FieldTypeDescription
codestringSNOMED CT code.

SeriousEvidence

FieldTypeDescription
idstringStable medical evidence identifier.
namestringEvidence label.
common_namestring or nullNormalized common name when available.

Specialist

FieldTypeDescription
idstringStable specialist identifier.
namestringDisplay name.

Messages

Which message type applies where:

TypeUsed in
UserConversationMessage / AssistantConversationMessageConversation.messages only — persisted snapshot history.
UserMessage / UserMessageInputBlocking Turn.user_message, the streaming conversation.user_message.created event, and client turn input. Includes voice fields such as is_interrupted and played_content.
AssistantMessage / AssistantMessageDeltaCompleted stream segments and blocking Turn.assistant_messages. Includes can_interrupt; no top-level role in JSON.

UserMessage

Read model for a user-authored message on turns and streaming events. Not used in Conversation.messages.

FieldTypeDescription
idUUIDStable user message identifier.
contentstringUser message text after server-side PII redaction (non-empty).
is_interruptedbooleanWhether the user cut off an in-flight assistant message. Default false.
played_contentstring or nullAssistant text actually played out before the interruption, PII-redacted when present.
traceparentstring or nullW3C Trace Context value sent by the client when starting the turn.

UserMessageInput

Write model for a new user message.

FieldTypeRequiredDescription
idUUIDnoClient-generated identifier for stable local correlation. The server assigns one when omitted.
contentstringyesFull user-authored content (non-empty). The server may redact PII before persistence and engine processing.
is_interruptedbooleannoWhen true, the user cut off an in-flight assistant message — typical in voice channels. Default false.
played_contentstringnoAssistant text played before interruption; omit when not interrupting.
traceparentstringnoW3C Trace Context traceparent linking this turn to the caller's trace.

AssistantMessage

Canonical full representation of an assistant message — the completed form on streaming and on blocking turns.

FieldTypeDescription
idUUIDStable assistant message identifier.
turn_idUUIDTurn that produced this message.
kindMessageKindAssistant message role within the turn.
can_interruptbooleanWhether the client may interrupt this assistant segment. Derived from kind alone — see MessageKind.
content_partsContentPart[]Ordered content parts. Always present on completed assistant messages.

There is no top-level content or ui_widgets field. Concatenate text parts for plain-text rendering.

AssistantMessageDelta

In-progress chunk of an assistant message; the payload of the conversation.assistant_message.delta event.

FieldTypeDescription
idUUIDStable assistant message identifier.
turn_idUUIDTurn that is producing this message.
kindMessageKindAssistant message role within the turn.
can_interruptbooleanWhether the client may interrupt the message while streaming. Derived from kind alone — see MessageKind.
deltastringText chunk to append to the message.

Deltas carry text only. Widgets arrive on conversation.assistant_message.ui_widget and in content_parts on the completed event, never in a delta. Never treat concatenated deltas as the complete message.

UserConversationMessage

Persisted user row in Conversation.messages. Discriminator value "user".

FieldTypeDescription
role"user"Discriminator.
contentstringUser message text after server-side PII redaction.
idUUID or nullStable message identifier when assigned.
turn_idUUID or nullOwning turn when known.

AssistantConversationMessage

Persisted assistant row in Conversation.messages. Discriminator value "assistant".

FieldTypeDescription
role"assistant"Discriminator.
idUUIDStable assistant message identifier (required).
kindMessageKindAssistant message role within the turn.
content_partsContentPart[]Ordered content parts.
turn_idUUID or nullOwning turn when known.
⚠️

Client rule: branch on role. Do not read content on assistant rows or content_parts on user rows. In OpenAPI this is a oneOf with role as the discriminator.

Turn

Blocking-turn read model returned by POST /turns.

FieldTypeDescription
idUUIDStable turn identifier.
status"completed", "interrupted", or "failed"Turn outcome.
conversation_status"in_progress" or "completed"Conversation lifecycle after this turn. Same meaning as Conversation.status. Use conversation_terminated to tell a finished interview from a permanent termination.
user_messageUserMessageUser input that started the turn.
assistant_messagesAssistantMessage[]Assistant output produced by the turn.
handoffHandoff or nullSet when a handoff was requested during the turn, subject to enabled handoff_policies.
conversation_terminatedbooleantrue when the turn left the conversation permanently unable to accept further messages. The explanation for the user is in assistant_messages. Default false.

Handoff

Recorded when the assistant detects that control should pass back to the orchestrator. Emitted on conversation.handoff.requested and included on Turn for blocking turns.

FieldTypeDescription
reasonHandoffReasonWhy control should be handed off.
user_requeststringThe user request that triggered the handoff, verbatim or paraphrased.

Content parts

ContentPart

Tagged union with type as the discriminator.

Varianttype valuePayload
TextContentPart"text"text: string — plain text segment.
UiWidgetContentPart"ui_widget"widget: UIWidget — structured UI payload.
JSON
{ "type": "text", "text": "How long have you had it?" }
JSON
{
  "type": "ui_widget",
  "widget": { "type": "hints", "hints": ["Yes", "No", "Not sure"] }
}

UIWidget

Tagged union nested inside ui_widget content parts and transient widget events. Discriminator is type.

Varianttype valuePayload
UIWidgetHints"hints"hints: string[] — short suggestion chips.
UIWidgetForm"form"items: UIWidgetFormItem[] — structured multi-item answer form.
UIWidgetRecommendationTriage"recommendation_triage"triage_level, specialist, channel — triage summary card.
UIWidgetRecommendationConditions"recommendation_conditions"conditions, has_emergency_findings, serious_findings — differential conditions card.
UIWidgetSummary"summary"patient, groups, unmatched — cumulative card of everything recorded so far.
UIWidgetReadBack"read_back"groups — confirmation card for findings the user just volunteered.

UIWidgetFormItem

FieldTypeDescription
namestringHuman-readable item label.
choicesstring[]Allowed answer labels in display order.

UIWidgetRecommendationCondition

Condition row embedded in recommendation_conditions widgets; same enrichment shape as Condition.

FieldTypeDescription
idstringStable condition identifier.
probabilitynumberPosterior probability.
namestringDisplay name.
common_namestring or nullNormalized common name when available.
condition_detailsConditionDetailsKnowledge-base metadata.

UIWidgetSummary

Emitted with the assistant message that asks the user to confirm what has been recorded so far. See UI widgets for when it appears and how to render it.

FieldTypeDescription
type"summary"Discriminator.
patientstring or nullDemographics heading, e.g. "Female, 30 years old" or "Female, 30 years old (someone else)". null when sex, age and patient relationship are all absent.
groupsUIWidgetSummaryGroup[]Findings grouped by state. Fixed order: present, absent, unknown. Empty groups are omitted.
unmatchedUIWidgetSummaryUnmatched or nullReported findings that matched no knowledge concept. null when there are none.

UIWidgetSummaryGroup

FieldTypeDescription
statestringStable machine key: present, absent, or unknown.
titlestringLocalized group heading, e.g. "Present", "Absent", "Not sure".
itemsUIWidgetSummaryItem[]Findings in this group, in display order.

UIWidgetSummaryItem

FieldTypeDescription
namestringLocalized common name of the matched concept.
highlightedbooleanWhether this finding was added in the turn that produced this render. Default false.
childrenUIWidgetSummaryItem[]Findings whose parent concept is this item. At most one level deep — a child's children is always [].

UIWidgetSummaryUnmatched

FieldTypeDescription
titlestringLocalized section heading, e.g. "Findings I can't use".
notestringLocalized explanation of why these findings are listed separately.
itemsUIWidgetSummaryUnmatchedItem[]The unmatched findings, deduplicated, in the order the user raised them.

UIWidgetSummaryUnmatchedItem

FieldTypeDescription
namestringThe finding as the user expressed it — not a knowledge-base name.
highlightedbooleanWhether this finding was added in the turn that produced this render. Default false.

UIWidgetReadBack

Emitted with a read_back assistant message. See Read-backs.

FieldTypeDescription
type"read_back"Discriminator.
groupsUIWidgetReadBackGroup[]Findings grouped by state. Fixed order: present, absent, unknown. Empty groups are omitted.

UIWidgetReadBackGroup

FieldTypeDescription
statestringStable machine key: present, absent, or unknown.
titlestringLocalized group heading, e.g. "Present", "Absent", "Not sure".
itemsUIWidgetReadBackItem[]Findings in this group, in display order.

UIWidgetReadBackItem

FieldTypeDescription
namestringLocalized common name of the matched concept.
highlightedbooleanAlways false on read-backs. Present for shape parity with the summary card.

Read-back items are deliberately flat: unlike UIWidgetSummaryItem they carry no children, because a single message cannot produce a parent-and-child pair to nest.

QuestionFinding

Serious-finding row inside UIWidgetRecommendationConditions.serious_findings.

FieldTypeDescription
idstringStable medical evidence identifier.
namestringEvidence label.
common_namestring or nullNormalized common name when available.
parent_idsstring[]Parent concept identifiers.

Reasoning

Reasoning

Read model for the reasoning behind one completed turn.

FieldTypeDescription
turn_idUUIDTurn this reasoning describes.
conditionsReasoningCondition[]Knowledge-enriched conditions considered at the turn boundary.
evidenceReasoningEvidence[]Evidence, matched or unmatched, visible at the turn boundary.
summarystring or nullFree-text rationale summary when available.

ReasoningCondition

FieldTypeDescription
idstringStable condition identifier.
probabilitynumberProbability at the turn boundary.
namestringDisplay name.
common_namestringNormalized common name.

ReasoningEvidence

FieldTypeDescription
namestringEvidence label.
stateEvidenceStateState at the turn boundary.

Condition drill-down

ConditionExplanation

FieldTypeDescription
condition_idstringThe condition this explanation refers to.
supporting_evidenceExplainEvidence[]Evidence supporting the condition.
conflicting_evidenceExplainEvidence[]Evidence conflicting with the condition.
unconfirmed_evidenceExplainEvidence[]Relevant evidence that was not confirmed.

When an explanation is unavailable — no recommendation, the condition is not in the recommendation set, or demographics are incomplete — all three lists are empty and the response is still 200 OK.

ExplainEvidence

FieldTypeDescription
idstringStable medical evidence identifier.
namestringEvidence label.
common_namestring or nullNormalized common name when available.

ConditionPatientEducation

FieldTypeDescription
condition_idstringThe condition this content refers to.
titleRichTextNodeArticle title.
sectionsPatientEducationSection[]Ordered patient-education sections.

PatientEducationSection

FieldTypeDescription
namePatientEducationSectionTypeSection identifier.
titleRichTextNodeSection heading rendered as rich text.
contentRichTextNode[]Section body rendered as a list of rich-text nodes.

RichTextNode

Recursive rich-text node.

FieldTypeDescription
node_typeRichTextNodeTypeKind of node.
contentRichTextNode[]Child nodes; empty for leaf text nodes.
valuestring or nullText payload for text nodes.
targetstring or nullLink target for link nodes.

Errors

Error

FieldTypeDescription
codestringMachine-readable identifier; see Error codes.
messagestringHuman-readable explanation.
detailsValidationErrorDetail[]Optional. Present whenever the failure was field validation — on HTTP 422 (invalid_request) and on the WebSocket invalid_payload error. The two transports use different codes for the same class of failure.

ValidationErrorDetail

One entry per request field that failed validation.

FieldTypeDescription
locationstringPath to the offending field, e.g. body.settings.language or body.assessment.evidence[0].id.
messagestringWhy the value was rejected, e.g. Input should be a valid string.
typestringStable validation-failure identifier for programmatic branching, e.g. string_type, missing.

location is formatted differently on each transport — do not parse it with one rule. On HTTP its first segment names the part of the request that failed (body, query, path, header, or cookie) and array positions are bracketed: body.assessment.evidence[0].id. On WebSocket it is a dot-joined path prefixed with the frame's event type, and array positions are plain segments: conversation.create.conversation.assessment, conversation.create.conversation.assessment.evidence.0.id. For an HTTP body that is not valid JSON, location is body and message names the syntax problem.

Error.message summarizes at most the first five entries and appends ; and N more beyond that; details always lists every failure. Submitted values are never echoed back in either field.

InfoDTO

Returned by GET /info.

FieldTypeDescription
snomed_ct_versionstring or nullSNOMED CT version URI used by the instance's medical model mappings, per the SNOMED URI Standard.

Was this page helpful?