Building a User Interface

Recommended UI patterns for rendering questions - messages, choices, symptom definitions, constraints, and the autocomplete search

The API is schema-driven: every question arrives with display messages, selectable choices, and selection constraints, and a well-built client renders from those fields generically. This page shows the recommended UI pattern for each element. For the underlying data contract — field-by-field definitions and how to construct answers — see Questions & Answers.

Messages

Messages are the text component of a question. The API can return one or more per question — render all of them, in the order they are returned, each on its own line.

They arrive as question.messages[], standard Message objects: value is the text to display, type is a placement hint (header, paragraph, bullet point…), and format tells you whether to render it as plain text or markdown.

Choices

Choices are returned in an array; there is always at least one. For each choice, text is what you display and id is what you send back in the answer.

Symptom definitions

A choice may also carry a symptom_definition — a plain-language explanation of the symptom, as a standard Message:

{
  "id": "C0041105",
  "text": "Ringing in the ears",
  "symptom_definition": {
    "value": "A perception of sound (often ringing or buzzing) without an external source.",
    "type": "PARAGRAPH",
    "format": "PLAIN_TEXT"
  }
}

Definitions are per choice: each one explains only the choice it is attached to, so render it with that choice — as supporting text under the label, or behind an info icon/expandable next to it. Respect its format like any other Message. Choices without a definition simply omit the field, so a list can mix choices with and without one.

Constraints

The constraints object has two properties, min_selections and max_selections, and together they tell you which input control to build. The combinations:

Minimum 1 — Maximum 1

Mandatory single choice: render the choices as radio buttons, and don't allow continuing without a selection.

Minimum 0 — Maximum n

Optional multi-select: render the choices as checkboxes.

Note the None of these choice in the example below. It is not part of the API response — we recommend adding it client-side as a safeguard against users clicking Continue without taking an action. It makes it explicit that the user doesn't have the symptoms (which all end up in excluded — see the answer rules).

Minimum 1 — Maximum n

Mandatory multi-select: render the choices as checkboxes, with no way to continue until at least one is selected.

Either bound may be absent — treat a missing min_selections as 0 and a missing max_selections as unlimited.

Autocomplete

The autocomplete question type is the one place a generic choice renderer isn't enough: the user searches our symptom database and adds symptoms to the consultation. The question looks like:

"question": {
    "type": "autocomplete",
    "messages": [
        {
            "value": "OK, please tell me what symptoms you would like to add.",
            "type": "PARAGRAPH",
            "format": "PLAIN_TEXT"
        },
        {
            "value": "You can add up to 3 more symptoms, 1 at a time.",
            "type": "PARAGRAPH",
            "format": "PLAIN_TEXT"
        }
    ],
    "constraints": {
        "min_selections": 1,
        "max_selections": 1
    }
}

How many symptoms may be sent in one answer is governed by constraints.min_selections/max_selections, like any other question — treat the message copy as display text only.

For this screen, our UI recommendation is a search box that calls the symptom search endpoint:

While no symptom has been added, show a button that lets the user skip this step. To signal that nothing was added, answer with the literal id skip_autocomplete:

{
    "type": "autocomplete",
    "included": ["skip_autocomplete"]
}


Once the user has selected at least one additional symptom, replace it with an Add these symptoms button and respond with the ids of the newly added symptoms (respecting the question's constraints):

{
    "type": "autocomplete",
    "included": ["assessment_C2316035"]
}


What’s Next

Did this page help you?