This guide explains how to use the Patient API to build a custom flow for submitting a patient's answers to a pre-built medical questionnaire. The process begins with creating a draft consultation and concludes when the patient's completed answers are submitted to the system.
Pre-requisites
Before you begin, ensure you have the following:
- JWT Authentication Token: You need to have a valid token to access the Care Portals API. See the Authentication guide for instructions on how to generate one.
Flow Overview
The consultation flow consists of three primary steps that use the /consultations endpoint to draft, update, and submit the questionnaire.
- Initiate a Consultation: Draft a new questionnaire for a patient.
- Save Questionnaire Progress: Update the questionnaire with the patient's answers as they progress.
- Submit the Consultation: Finalize and submit the completed questionnaire.
Step 1: Initiate a Consultation
To begin, you must first create a new draft consultation by calling the Create a Consultation endpoint with a POST Request. In the request body, ensure that you send the type and answer parameters. They are mandatory for every consultation request.
curl -X POST 'https://patient-api.portals.care/consultations' \
-H 'accept: application/json, text/plain, */*' \
-H 'authorization: Bearer {{token}}' \
--data-raw '{"type":"wlusmonthly","answers":{"states":{},"wlusFollowup_genderIdentify":{"wlusFollowup_genderIdentify_male":true}},"status":"incomplete"}'{
"_id": "<CONSULTATION_ID>",
"organization": "appgen_demo",
"type": "wlusmonthly",
"internal": false,
"customer": {
"_id": "67af63646cd80339c6272590",
"organization": "appgen_demo",
"uname": "userportals.care#appgen_demo",
"email": "[email protected]",
"phone": "+11231231231",
"firstName": "User",
"lastName": "Portals",
"gender": "other",
"dob": "1992-11-11",
"addresses": [],
"defaultAddress": {
"province": "AB",
"provinceCode": "AB",
"address1": "",
"address2": "",
"city": "",
"countryCode": "CA",
"postalCode": ""
},
"referrer": "6284163a67726a1dde82d5ef",
"identifiers": [],
"notificationsCount": 0,
"watchlist": [],
"usedCoupons": [],
"source": "signup",
"assignedQuestionnaires": [],
"providers": [],
"groups": [],
"isInsuranceAvailable": false,
"createdAt": "2025-02-14T15:38:12.516Z",
"updatedAt": "2025-09-03T21:47:53.022Z",
"__v": 0,
"stripeId": "cus_Rwr5mZerq1Q2VL",
"acceptMarketing": false,
"passwordReset": {
"code": "da6a85ef5f89e9e04e07affe85d428f650a11ffc",
"expiry": 1756979273021,
"createdAt": 1756936073021
}
},
"status": "incomplete",
"statusHistory": [],
"answers": {
"states": {},
"wlusFollowup_genderIdentify": {
"wlusFollowup_genderIdentify_male": true
}
},
"orderIds": [],
"_id": "68bb1d6b31fa46bf659c8c60",
"createdAt": "2025-09-05T17:27:07.925Z",
"updatedAt": "2025-09-05T17:27:07.925Z",
"__v": 0
}The response will contain the complete consultation object, including the _id, which we'll refer to as the <CONSULTATION_ID>. This ID is needed to perform any subsequent updates to the consultation.
Step 2: Save Questionnaire Progress
As the user moves through the questionnaire, you can save their progress on each step by calling the Update a Consultation endpoint with PUT request, updating the consultation record with the answers provided in the current step.
curl -X PUT https://patient-api.portals.care/consultations/<CONSULTATION_ID>' \
-H 'organization: <ORG_ID>' \
-H 'Content-Type: application/json' \
--data-raw '{"type":"wlusmonthly",
"answers":{"states":{},"wlusFollowup_genderIdentify":{
"wlusFollowup_genderIdentify_male":true},
"wlusFollowup_weightAndHeight2025":{
"heightUnit":"centimeters",
"weightUnit":"kilograms",
"weight":90,
"height":175}},
"status":"incomplete"
}'{
"_id": "68bb1d6b31fa46bf659c8c60",
"organization": "appgen_demo",
"type": "wlusmonthly",
"internal": false,
"customer": {
"_id": "67af63646cd80339c6272590",
"organization": "appgen_demo",
"uname": "[email protected]#appgen_demo",
"email": "[email protected]",
"phone": "+11231231231",
"firstName": "User",
"lastName": "Portals",
"gender": "other",
"dob": "1992-11-11",
"addresses": [],
"defaultAddress": {
"province": "AB",
"provinceCode": "AB",
"address1": "",
"address2": "",
"city": "",
"countryCode": "CA",
"postalCode": ""
},
"referrer": "6284163a67726a1dde82d5ef",
"identifiers": [],
"notificationsCount": 0,
"watchlist": [],
"usedCoupons": [],
"source": "signup",
"assignedQuestionnaires": [],
"providers": [],
"groups": [],
"isInsuranceAvailable": false,
"createdAt": "2025-02-14T15:38:12.516Z",
"updatedAt": "2025-09-03T21:47:53.022Z",
"__v": 0,
"stripeId": "cus_Rwr5mZerq1Q2VL",
"acceptMarketing": false,
"passwordReset": {
"code": "da6a85ef5f89e9e04e07affe85d428f650a11ffc",
"expiry": 1756979273021,
"createdAt": 1756936073021
},
"verifications": {}
},
"status": "incomplete",
"statusHistory": [],
"answers": {
"states": {},
"wlusFollowup_genderIdentify": {
"wlusFollowup_genderIdentify_male": true
},
"wlusFollowup_weightAndHeight2025": {
"heightUnit": "centimeters",
"weightUnit": "kilograms",
"weight": 90,
"height": 175
}
},
"orderIds": [],
"createdAt": "2025-09-05T17:27:07.925Z",
"updatedAt": "2025-09-05T17:29:54.688Z",
"__v": 0
}The API returns the complete and most recent consultation object in the response body.
Anytime you modify the questionnaire, the API returns the latest consultation object. Always use the most recent response as the source of truth for your application to avoid status drift.
Step 3: Submit the Consultation
Once the user has answered all the questions, you can submit the completed form using the same Update a Consultation endpoint as in the previous step. To submit the questionnaire, you need to update the status parameter from incomplete to new along with any final answers.
{
"type": "wlusmonthly",
"answers": {
"states": {},
"wlusFollowup_genderIdentify": {
"wlusFollowup_genderIdentify_male": true
},
"wlusFollowup_weightAndHeight2025": {
"heightUnit": "centimeters",
"weightUnit": "kilograms",
"weight": 90,
"height": 175
},
"wlusFollowup_healthChangesMedicationChanges2025": {
"yes": true
},
"wlusFollowup_tellUsMoreAboutTheChangesInYourHealth": {
"wlusFollowup_tellUsMoreAboutTheChangesInYourHealth": "qwe"
},
"wlusFollowup_whenDidYouLastTakeYourPrescribedWeightLossMedication": {
"wlusFollowup_whenDidYouLastTakeYourPrescribedWeightLossMedication_itHasBeenOverAMonth": true
},
"wlusFollowup_dateOfLastUse": {
"wlusFollowup_dateOfLastUse": "qwe"
},
"wlusFollowup_identifyClosestDose": {
"semaglutide_0.2mg": true
},
"wlusFollowup_haveYouExperiencedSideEffectsFromYourCurrentMedication": {
"wlusFollowup_haveYouExperiencedSideEffectsFromYourCurrentMedication_no": true
},
"wlusFollowup_medicationExperience2025": {
"no_weightloss_yes_sideEffects": true
},
"wlusFollowup_ineligible": {}
},
"status": "new"
}{
"_id": "<CONSULTATION_ID>",
"organization": "appgen_demo",
"type": "facesheet",
"internal": false,
"customer": {
"_id": "67b4751a88fcbf517941f3b1",
"organization": "appgen_demo",
"uname": "[email protected]#appgen_demo",
"email": "[email protected]",
"phone": "+11231231231",
"firstName": "John",
"lastName": "Doe",
"gender": "male",
"dob": "2000-11-11",
"addresses": [
{
"address1": "qweqwe",
"address2": "qweq",
"city": "qwe",
"provinceCode": "",
"postalCode": ""
},
{
"address1": "karak street",
"address2": "eastren",
"city": "Amman",
"provinceCode": "AB",
"postalCode": "a2a2a2",
"countryCode": "CA"
}
],
"defaultAddress": {
"address1": "123 Main Street 12",
"address2": "building 33",
"city": "Springfield",
"provinceCode": "IL",
"postalCode": "62704",
"countryCode": "US"
},
"referrer": "",
"identifiers": [],
"notificationsCount": 0,
"watchlist": [],
"usedCoupons": [
"total50p",
"test095"
],
"source": "signup",
"assignedQuestionnaires": [],
"providers": [],
"groups": [],
"isInsuranceAvailable": false,
"createdAt": "2025-02-18T11:55:06.293Z",
"updatedAt": "2025-09-02T12:58:51.219Z",
"__v": 0,
"credit": {
"amount": 0,
"history": [
{
"amount": 50,
"previousAmount": 0,
"createdAt": "2025-02-28T17:50:46.350Z",
"type": "referrer",
"orderId": "67c1f772237314f29d4a621d",
"note": "received from customer#67c1f720237314f29d4a620a for order#67c1f772237314f29d4a621d"
},
{
"amount": -50,
"previousAmount": 50,
"createdAt": "2025-04-11T01:42:39.001Z",
"type": "withdrawal",
"orderId": "426",
"note": "$50 used for order #426"
}
]
},
"extras": {
"dosespotId": "78836454",
"pharmetikaContactId": 773795,
"pharmetikaPatientId": 8103918
},
"stripeId": "cus_Rwr5mZerq1Q2VL",
"verifications": {
"email": "verified"
}
},
"status": "new",
"statusHistory": [
{
"prevStatus": "incomplete",
"newStatus": "new",
"updatedAt": "2025-04-11T02:09:06.089Z",
"userId": "customer"
}
],
"answers": {
"states": {},
"conditions": {
"asthma": true
},
"surgeries": {
"vasectomy": true
},
"medications": {
"isNo": true
},
"supplements": {
"isNo": true
},
"allergies": {
"isNone": true
}
},
"orderIds": [],
"createdAt": "2025-04-11T02:08:57.302Z",
"updatedAt": "2025-04-11T02:09:06.090Z",
"__v": 0
}The API returns the final consultation object in the response body, with the status parameter set as new.
