For AI agents: the documentation index is at /docs/aidbox/llms.txt. A Markdown version of this page is available at /docs/aidbox/notebooks.md or by requesting it with the Accept: text/markdown header.
Aidbox Docs
All notebooks

How to build and test a Questionnaire in Aidbox Forms Builder

Two ways: create from scratch or convert PDF

16 cells · updated Feb 4, 2025

This is a read-only view. Responses shown were saved when the notebook was published — open it in your own Aidbox to run the cells against live data.

Introduction

Aidbox Forms allows you to create forms based on the FHIR SDC spec, store them as FHIR Questionnaire resources, and extract data into FHIR QuestionnaireResponse and other FHIR resources in Aidbox for further use.

We’ll demonstrate this using the NCD/CVD Risk Assessment Form as an example.

Create two test patients

Before building the form, create test patients in Aidbox to test and debug the Questionnaire.

REST Send Cells run only inside Aidbox. Use Run in Aidbox above to open this notebook in your own instance.
POST /
content-type: application/yaml

resourceType: Bundle
type: transaction
entry:
  - resource:
      resourceType: Patient
      gender: male
      name:
        - given: 
            - John
          family: Doe
      birthDate: '1996-05-12'
      id: john
    request:
      method: PUT
      url: /Patient/john
  - resource:
      resourceType: Patient
      gender: female
      name:
        - given: 
            - Jane
          family: Doe
      id: jane
      birthDate: '1993-09-11'
    request:
      method: PUT
      url: /Patient/jane
Response: Body
Status: 200
type: transaction-response
resourceType: Bundle
entry:
- resource:
    id: john
    name:
    - given: [John]
      family: Doe
    gender: male
    birthDate: '1996-05-12'
    resourceType: Patient
    meta: {lastUpdated: '2025-02-03T01:13:55.776235Z', createdAt: '2025-02-03T01:13:55.776235Z', versionId: '6'}
  response: {etag: '6', location: /Patient/john/_history/6, status: '200', lastModified: '2025-02-03T01:13:55.776235Z'}
- resource:
    id: jane
    name:
    - given: [Jane]
      family: Doe
    gender: female
    birthDate: '1993-09-11'
    resourceType: Patient
    meta: {lastUpdated: '2025-02-03T01:13:57.244057Z', createdAt: '2025-02-03T01:13:57.244057Z', versionId: '7'}
  response: {etag: '7', location: /Patient/jane/_history/7, status: '200', lastModified: '2025-02-03T01:13:57.244057Z'}
id: '21'

There are two ways to create a FHIR Questionnaire in Aidbox Forms:

  • Create from scratch - Use the UI Form Builder to design a new form. (option A)
  • Convert a PDF (paper form) to a Questionnaire – Upload a PDF form and automatically generate a digital version. (option B)

Option A: Create form from scratch with calculated expression, enable when condition and data extraction to Observations

Let's create part of the NCD/CVD Risk Assessment Form

1.. Open Aidbox Forms

2.. Click "Create Template"

3.. Choose "Create in UI Builder"

4.. Click on form title to open Questionnaire settings

5.. Change title to "NCD/CVD Risk Assesment Form"

6.. Create sections:

Create Patient Section

  1. Add "Group"
  2. Add "Name" a. Add Text item b. Change text to "Name"
  3. Add "Gender" a. Add Choice item b. Add two options: male, female

Create BMI section

  1. Add Group and change name to "Obesity"
  2. Add "Height"
    • Add new Quantity item
    • Change text to "Height"
    • Change link id to "height"
    • Change unit to "cm"
  3. Add "Weight"
    • Add new Quantity item
    • Change text to "Weight"
    • Change link id to "Weight"
    • Change unit to "kg"
  4. Add BMI
    • Add new Decimal item
    • Change text to "BMI"
    • Set item code to:
    system: http://snomed.info/sct
    code: 60621009
    display: Body Mass Index 
    
    • Change calculated expression to:
    (%resource.repeat(item).where(linkId='weight').answer.value.value / 
    

%resource.repeat(item).where(linkId='height').answer.value.value.power(2)) * 10000 ```

  • Enable data extraction
    • Click on "Extraction" checkbox
    • Choose "Extract to Observation"

Create Smoking status section

  1. Add new Choice item
  2. Change text to "Smoking Status"
  3. Change item code to:
    system: http://snomed.info/sct
    code: 365981007
    display: Tobacco smoking behavior - finding 
    
  4. Import choice options
    • Click "Use ValueSet" under the "Options"
    • Click "Use external terminology server"
    • Set your terminology server to https://tx.fhirlab.net/fhir
    • Search needed valueset "Smoking status"
  5. Enable data extraction
    • Click on "Extraction" checkbox
    • Choose "Extract to Observation"

Create Alcohol Intake section

  1. Add new Choice item
  2. Change text to "Alcohol intake"
  3. Add two options:
    • Never consumed | never-consumed
    • Yes | yes

Create Excessive Alcohol Intake section

  1. Create new group with name "Excessive Alcohol Intake"
  2. Add enable when rule. In "Rules" section:
    1. Click "Enable when" checkbox
    2. Choose "Conditions"
    3. Add new rule to show this group when: answer to "Alcohol Intake" question is "Yes"

Create Excessive Alcohol questions:

For males:

  1. Add new Choice question
  2. Change text to "In the past 6 months had 5 drinks in a row"
  3. Change item code to:
    system: http://snomed.info/sct
    code: 719848005
    display: Disorder caused by alcohol
    
  4. Import Answers from https://tx.fhirlab.net/fhir (search value set Yes_No)
  5. Add enable when rule:
    • answer to "Patient gender" is "Male"
  6. Turn on extraction to Observation

For females:

  1. Duplicate last question
  2. Change text to "In the past 6 months had 4 drinks in a row"
  3. Change enable when rule:
    • answer to "Patient Gender" is "Female"

Option B: Convert PDF to Questionnaire

Follow these steps to convert a PDF form into a FHIR Questionnaire in Aidbox Forms:

1.. Download the PDF file NCD/CVD Risk Assessment Form

2.. Copy your ChatGPT API key (required for conversion):

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

3.. Open Aidbox Forms

4.. Click "Create Template".

5.. Select "Import Questionnaire".

6.. Upload your PDF file and paste your ChatGPT API key.

7.. Click "Import"—your form will be converted and appear in the Aidbox Forms Builder.

8.. Edit the CVD/NCD Form as needed (see the steps of option A).

You can use any PDF form to go through this process. (e.g., NCD/CVD Risk Assessment Form, Maternal Client Record, or Child Immunization Record).

Test the form and Verify Data Storage

Let's test the form to ensure that rules work correctly and data is saved in Aidbox storage.

1. Get the Questionnaire ID

Run the following SQL query in Aidbox to retrieve the ID of the Questionnaire you just created:

SQL Send Cells run only inside Aidbox. Use Run in Aidbox above to open this notebook in your own instance.
select id, resource#>>'{title}' from Questionnaire 
order by cts desc limit 10

2. Generate the Form Link

Use the $populatelink operation to generate a link to open the form:

REST Send Cells run only inside Aidbox. Use Run in Aidbox above to open this notebook in your own instance.
POST /fhir/Questionnaire/30048d73-a63b-434c-aadd-6265209d366d/$populatelink
content-type: application/yaml

resourceType: Parameters
parameter:
  - name: subject
    valueReference: 
      reference: Patient/john
  - name: local
    valueBoolean: true
Response: Body
Status: 200
resourceType: Parameters
parameter:
- {name: link, valueUri: 'http://localhost:8080/ui/sdc#/questionnaire-response/111ff2cb-bd1f-4f6c-b8f4-5784929500c9?token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJTRENSU0FTaGFyZWRMaW5rSXNzdWVyIiwiZXhwIjoxNzM5MTQ1NjAwLCJvcGVyYXRpb25zIjpbImZoaXItcHJvY2Vzcy1yZXNwb25zZSIsInByb2Nlc3MtcmVzcG9uc2UiXSwicSI6eyJpZCI6IjMwMDQ4ZDczLWE2M2ItNDM0Yy1hYWRkLTYyNjUyMDlkMzY2ZCIsInVybCI6Imh0dHA6Ly9mb3Jtcy5haWRib3guaW8vcXVlc3Rpb25uYWlyZS9jdmQtbmNkLXJpc2stYXNzZXNzbWVudC1mb3JtIiwiY2Fub25pY2FsIjoiaHR0cDovL2Zvcm1zLmFpZGJveC5pby9xdWVzdGlvbm5haXJlL2N2ZC1uY2Qtcmlzay1hc3Nlc3NtZW50LWZvcm0ifSwicXIiOnsiaWQiOiIxMTFmZjJjYi1iZDFmLTRmNmMtYjhmNC01Nzg0OTI5NTAwYzkifX0.dYRtNpvfwBrD89AroKWri9_lwXNM3CJkQRCgogE5zTKtbx-7hgSqvSaZn-gaF_ffAdSZN-3mkc1dmXG0iPK2xlXBuH6LX0wEdE0IPZY9TXWnxR3QgDJIk-QuVkkPyeQV5IUhTWsdtvxnXmtqHOgH4pEO5vRP6e_LIK2sGDrR3UvCA3OxNcUP0X3MSdNi8YjXU_UseXz6AgpB1iCooesAgRETUXr1eKbC3MvxqbBfLa5VqtPinMj3F8kvEuKhkz2nnbC0BzxBieqIHrlrBNJDRfN468hz8ETAUjXXdST3kd7sA1Gkuus7G5vLQxD2yhiDMLpn9e2Czq9c8zBUQ5XQIQ'}

3. Fill out the Form and get the QuestionnaireResponse

1.. Open the Form using the generated link.

2.. Fill out the answers and click "Submit".

3.. Verify that responses were recorded by retrieving the QuestionnaireResponse from Aidbox:

SQL Send Cells run only inside Aidbox. Use Run in Aidbox above to open this notebook in your own instance.
select * from QuestionnaireResponse order by ts desc limit 1
Result
idtsctstxidstatusresourceresource_type
111ff2cb-bd1f-4f6c-b8f4-5784929500c92025-02-03T01:48:20Z2025-02-03T01:47:53Z32updated{"questionnaire":"http://forms.aidbox.io/questionnaire/cvd-ncd-risk-assessment-form","meta":{"createdAt":"2025-02-03T01:47:53.995170Z","versionId":"31","lastUpdated":"2025-02-03T01:48:16.043477Z"},"item":[{"item":[{"text":"Alcohol Intake","answer":[{"value":{"Coding":{"code":"yes","display":"Yes"}}}],"linkId":"3.2"},{"text":"In the past month had 5 drinks in a row","answer":[{"value":{"Coding":{"code":"373066001","system":"http://snomed.info/sct","display":"Yes"}}}],"linkId":"3.3"}],"text":"Smoking and Alcohol Intake","linkId":"3"},{"item":[{"text":"Height","answer":[{"value":{"Quantity":{"unit":"cm","value":180}}}],"linkId":"height"},{"text":"Weight","answer":[{"value":{"Quantity":{"unit":"kg","value":89}}}],"linkId":"weight"},{"text":"BMI","answer":[{"value":{"decimal":{"ib":-1,"rep":"27.469135802469136","tag":"f"}}}],"linkId":"G3CAnFK1"}],"text":"Obesity Assessment","linkId":"4"}],"resourceType":"QuestionnaireResponse","author":{"identifier":{"type":{"coding":[{"code":"UID","system":"urn:system:aidbox","display":"User ID"}]},"value":"38439b9c-54c8-43ea-b4a9-b690abf6801b","system":"http://localhost:8080"}},"status":"completed","id":"111ff2cb-bd1f-4f6c-b8f4-5784929500c9","authored":"2025-02-03T01:48:19.051Z","subject":{"id":"john","resourceType":"Patient"}}QuestionnaireResponse

4. Get Observations

Let's see what Observations were created from this QuestionnaireResponse:

REST Send Cells run only inside Aidbox. Use Run in Aidbox above to open this notebook in your own instance.
GET /fhir/Observation
Response: Body
Status: 200
{
  "resourceType": "Bundle",
  "type": "searchset",
  "meta": {
    "versionId": "0"
  },
  "total": 2,
  "link": [
    {
      "relation": "first",
      "url": "http://localhost:8080/fhir/Observation?page=1"
    },
    {
      "relation": "self",
      "url": "http://localhost:8080/fhir/Observation?page=1"
    }
  ],
  "entry": [
    {
      "resource": {
        "meta": {
          "lastUpdated": "2025-02-03T01:48:20.770479Z",
          "versionId": "33",
          "extension": [
            {
              "url": "ex:createdAt",
              "valueInstant": "2025-02-03T01:48:20.770479Z"
            }
          ]
        },
        "derivedFrom": [
          {
            "reference": "QuestionnaireResponse/111ff2cb-bd1f-4f6c-b8f4-5784929500c9"
          }
        ],
        "resourceType": "Observation",
        "effectiveDateTime": "2025-02-03T01:48:19.051Z",
        "status": "final",
        "id": "1313bd70-9d01-4bdd-8706-02159e6fa6f5",
        "code": {
          "coding": [
            {
              "code": "135820002",
              "system": "http://snomed.info/sct",
              "display": "Not sure of general health"
            }
          ]
        },
        "valueCodeableConcept": {
          "coding": [
            {
              "code": "373066001",
              "system": "http://snomed.info/sct",
              "display": "Yes"
            }
          ]
        },
        "subject": {
          "reference": "Patient/john"
        }
      },
      "search": {
        "mode": "match"
      },
      "fullUrl": "http://localhost:8080/Observation/1313bd70-9d01-4bdd-8706-02159e6fa6f5",
      "link": [
        {
          "relation": "self",
          "url": "http://localhost:8080/Observation/1313bd70-9d01-4bdd-8706-02159e6fa6f5"
        }
      ]
    },
    {
      "resource": {
        "meta": {
          "lastUpdated": "2025-02-03T01:48:20.770479Z",
          "versionId": "34",
          "extension": [
            {
              "url": "ex:createdAt",
              "valueInstant": "2025-02-03T01:48:20.770479Z"
            }
          ]
        },
        "derivedFrom": [
          {
            "reference": "QuestionnaireResponse/111ff2cb-bd1f-4f6c-b8f4-5784929500c9"
          }
        ],
        "valueQuantity": {
          "value": 27.469135802469136
        },
        "resourceType": "Observation",
        "effectiveDateTime": "2025-02-03T01:48:19.051Z",
        "status": "final",
        "id": "bd21d14d-b8aa-44c5-8ad5-04ff5a3e5c98",
        "code": {
          "coding": [
            {
              "code": "181195007",
              "system": "http://snomed.info/sct",
              "display": "Entire nose"
            }
          ]
        },
        "subject": {
          "reference": "Patient/john"
        }
      },
      "search": {
        "mode": "match"
      },
      "fullUrl": "http://localhost:8080/Observation/bd21d14d-b8aa-44c5-8ad5-04ff5a3e5c98",
      "link": [
        {
          "relation": "self",
          "url": "http://localhost:8080/Observation/bd21d14d-b8aa-44c5-8ad5-04ff5a3e5c98"
        }
      ]
    }
  ]
}

Final

Using Aidbox Forms, we successfully created the NCD/CVD Risk Assessment Form with calculated expressions and Observation-based extraction.

We verified that:

  • The form works as expected.
  • Data is stored in Aidbox as a QuestionnaireResponse resource.
  • Extracted data is saved in Observation resources.

The form is now ready for use and integration into clinical workflows. Here is the final NCD/CVD Risk Assessment Form — you can upload it to test.