Forms
Forms describe the structured data model that Tiep completes during every consultation. Tiep uses a restricted version of the standardized JSON Form Schema to define the structure of the medical reports.
Form lifecycle
Tiep supports two ways to pair consultations with forms:
Option 1: Facility-managed catalog
- Publish your catalog. Create the forms ahead of time via
POST /forms. Each form is bound to a specialty (x-specialty) so only the relevant doctors see it. - AI-predicted selection. During the consultation, the AI looks at the doctor’s specialty and consultation context to predict the best form. The doctor can accept the suggestion or switch to another allowed form through the UI.
- Extraction. Once the consultation is recorded, the AI model fills the selected form. When the doctor saves, Tiep sends your webhook the completed payload—either as the HL7 bundle or the
formDatadump.
Option 2: Session-bound form selection (HIS driven)
If your workflow already knows which form applies, call POST /generate-token with the desired form in the request. The token bounds the session to that exact form, so there is no need for the doctor to choose. The rest of the flow is identical: Tiep captures the consultation, populates the referenced form, and delivers the payload to your webhook in the configured format (HL7 or formData).
Top-level metadata
| Field | Required | Description |
|---|---|---|
x-specialty | ✅ | Medical specialty (see the MedicalSpecialty enum) that scopes which providers can use the form. |
type | ✅ | Must be "object" for the root node. All nested nodes can be object, array, string, number, or boolean. |
x-internal-id | Optional | Stable identifier you control so you can version or reference the form outside Tiep. |
x-icon-id | Optional | UI hint (1–30) for picking one of the built-in icons in the Tiep UI. |
The form depth is capped at five levels (root object plus three nested objects and a leaf). If you exceed this, the API rejects the submission to keep prompts and rendering predictable.
Property schema (FormProperty)
Every entry inside properties is a Form Property, including the root object property that defines the form. Key attributes:
title(required): Human-readable label shown to physicians. Usex-title-translationsandx-description-translationsadditionally when you need localized strings.description: Required for non-object type properties, acts as a prompt and tells the AI model how to answer the field.type: One ofstring,number,boolean,array, orobject.properties: Only valid and required whentypeisobject. Each key inside this map becomes the property name informData.required: Only for objects. Array of child property names (keys) that must be answered.enum: Use for simple lists of string literals (e.g.,"LEFT","RIGHT").anyOf/oneOf: Provide coded options. Each element must follow what we call aForm Concept, withconst(coded value) andtitle(human-readable label).oneOfenforces single selection,anyOfallows multiple selections.x-resource-type: For HL7 payloads. Maps the property to a FHIR resource (OBSERVATION,CONDITION,MEDICATION_REQUEST,SERVICE_REQUEST,ALLERGY_INTOLERANCE,CARE_PLAN). Defaults toOBSERVATION.
A property cannot define both properties and anyOf/oneOf, and non-object properties cannot include properties.
Coded choices with FormConcept
As mentioned, when a field needs structured coding, include an array of FormConcept objects:
Form snippet:
"severity": {
"title": "Pain severity",
"type": "string",
"oneOf": [
{ "const": "0", "title": "Mild" },
{ "const": "1", "title": "Moderate" },
{ "const": "2", "title": "Severe" }
],
}
formData snippet:
"severity": "0"
Example form definition
{
"x-specialty": "ORTHOPEDICS",
"x-internal-id": "shoulder-follow-up-v1",
"type": "object",
"title": "Shoulder follow-up",
"description": "Track short-term progress after the initial visit.",
"properties": {
"encounter": {
"type": "object",
"title": "Encounter details",
"required": ["reason"],
"properties": {
"reason": {
"title": "Reason for visit",
"type": "string",
"enum": ["pain", "stiffness", "post-op"]
},
"priority": {
"title": "Priority",
"type": "string",
"oneOf": [
{ "const": "ROUTINE", "title": "Routine" },
{ "const": "URGENT", "title": "Urgent" }
],
"x-resource-type": "SERVICE_REQUEST"
}
}
},
"assessment": {
"type": "object",
"title": "Assessment",
"properties": {
"diagnoses": {
"title": "Diagnoses",
"type": "array",
"anyOf": [
{ "const": "M75.1", "title": "Rotator cuff tear" },
{ "const": "M75.2", "title": "Bicipital tendinitis" }
]
},
"plan": {
"title": "Plan",
"type": "string",
"description": "Free-text instructions for the patient."
}
}
}
},
"required": ["encounter"]
}
Example formData payload
{
"encounter": {
"reason": "pain",
"priority": "URGENT"
},
"assessment": {
"diagnoses": ["M75.1"],
"plan": "Start PT twice a week"
}
}
Conditional logic (dependencies, branching, dynamic lists) is under active development. For now, keep forms to simple property trees with static requirements. We will let you know before those advanced capabilities roll out so you can plan schema updates.