In the event that your use case requires the use of a custom form, the following guide provides insight on how to properly configure and integrate a custom intake form with Tellescope. For a sample form response payload, please reach out to support@tellescope.com.
Form Mapping
Within Tellescope, you will need to create a form with at least one question field. The field can be left blank. The purpose of this form is for mapping responses. You'll need to grab the form ID, which is located in the URL for the form you created.
Webhook URL
The Webhook URL should be formatted as follows:
https://api.tellescope.com/v1/webhooks/formsort/API_KEY_HERE?formId=FORM_ID_HERE
Replace FORM_ID_HERE with the ID for the form you created above. You'll need to generate an API key which can be used to replace API_KEY_HERE.
Endpoint Response
By default, this endpoint returns a 200 status with an empty response body. The endpoint accepts an optional query parameter called "returnJSON". When this attribute is "true", the endpoint returns JSON objects containing the following:
- formResponseId - The ID of the created/found form response
- enduserId - The ID of the enduser
- message (only for form responses that have already been finalized) - "Already Submitted"
Posting Frequency
Our recommendation for posting frequency would be when the form flow is finalized or abandoned, though you can update a form response as needed.
Incomplete Form (Unfinalized Webhook)
- When posting an incomplete form response in the event the form flow is abandoned, you would want to be sure to pass the "finalized" attribute as "false"
- We must have at least one of "email" or "phone" attribute in the payload, or we will ignore the webhook
- We will attempt to match an existing Enduser by matching on email or phone, and if there is no match, will insert a new patient
- Will will store the form response in an "unsubmitted" state (submittedAt is not defined)
- The first "finalized": "false" webhook we receive will update any patient fields that are being mapped to; subsequent "finalized": "false" webhooks will not update patient fields, just the form response
- Each "unfinalized" webhook notification for the same responder_uuid will update the incomplete form with the new responses
- We will not post webhooks or leverage a Form Submitted trigger (see Automation section below)
- Forms which stay in an unsubmitted state are candidates for our Form Unsubmitted trigger to fire (see Automation section below)
Submitted Form (Finalized Webhook)
- When posting a completed form response, you would want to be sure to pass the "finalized" attribute as "true"
- We will attempt to match an existing patient by matching on the "email" or "phone" attributes provided in the payload, and if there is no match, will insert a new patient
- If "email" and "phone" attributes are not provided, we will always create a new Enduser record for handling this response
- Will will store the form response in an "submitted" state (submittedAt is set)
- When we receive the "finalized": "true" webhook, we will update any patient fields that are being mapped to
- Future webhooks for the same responder_uuid will be ignored
- Tellescope will emit our own Webhook for "create" "form_responses"
- Form Submitted triggers will be handled (see Automation section below)
Note on Patient Matching / Insert
Form submissions will create a new patient or match an existing patient in Tellescope. Matching to an existing patient is done by email or phone number, and thus the form response payload must have questions with “email” and “phone” keys accordingly. Keys “first_name” and “last_name” will also be recognized when inserting a new patient to Tellescope by populating the First Name and Last Name fields.
This endpoint accepts an optional query parameter called "matchByName". When this attribute is "true", submission will only match to an existing Enduser if (first name AND last name AND email) are the same OR (first name AND last name AND phone) are the same.
Stripe Matching
It is common to use Stripe to collect a payment during forms. The stripeCustomerId field on Tellescope's Enduser model should be set to ensure that Stripe Webhooks match the correct Enduser in Tellescope. If no Enduser matches to the Stripe Customer ID, customer email will be used for matching instead. This field should be set in Tellescope before any Stripe payments (or other webhook events) have processed.
Variable Mapping to Tellescope Fields
Properly naming the variables in the payload allows Tellescope to sync responses as built-in and custom fields. The following table outlines the naming structure to follow in order to map form responses to Tellescope fields. For secondary insurance, you can use "secondaryInsurance" instead of "insurance".
Variables are automatically saved as "externalId" in Tellescope responses (which can be passed through to OpenLoop integration). To prevent syncing a variable as an externalId on a Tellescope question, prefix the variable with "ts_ignore".
| Variable (case sensitive) | Tellescope Field / Details | Formatting |
|
{ "key": "email", "value": "johndoe@email.com" }, |
||
| phone | Phone Number |
{ "key": "phone", "value": "8008881818" }, |
| first_name | First Name |
{ "key": "first_name", "value": "John" }, |
| last_name | Last Name |
{ "key": "last_name", "value": "Doe" }, |
|
dateOfBirth |
Date of Birth |
{ "key": "dateOfBirth", "value": "1970-03-01" }, |
|
gender |
Gender |
{ "key": "gender", "value": "Male" }, |
| healthie_dietitian_id | The provider ID that should be used if syncing the patient (creating) in Healthie |
{ "key": "healthie_dietitian_id", "value": 1234567 }, |
| height | The patient's full height in inches as a number (e.g. a 6'2'' patient would be 74) |
{ "key": "height", "value": 64 }, |
| weight | The patient's weight in pounds as a number |
{ "key": "weight", "value": 200 }, |
| timezone | Must be a valid timezone like "US/Central" or it will not sync |
{ "key": "timezone", "value": "US/Central" }, |
| address | Syncs to addressLineOne, zipCode, state, etc. |
{ "key": "address", "value": { "address_1": "123 Main St", "city": "Princeton", "state": "NJ", "postal_code": "08540" } }, |
| defaultFromPhone | A phone number (if your account has more than 1) to use as the default |
{ "key": "defaultFromPhone", "value": "8003338888" }, |
| useDefaultFromPhoneInAutomations | boolean, use the above phone number for all automated messages |
{ "key": "useDefaultFromPhoneInAutomations", "value": false }, |
| defaultFromEmail | An email address (if your account has multiple senders) to use as the default |
{ "key": "defaultFromEmail", "value": "name@yourcompany.com" }, |
| useDefaultFromEmailInAutomations | boolean, use the above email for all automated messages |
{ "key": "useDefaultFromEmailInAutomations", "value": false }, |
| language | To sync with Healthie, currently only "Spanish" is supported |
{ "key": "language", "value": "Spanish" }, |
| termsVersion | Version of terms a patient has consented to. A string value "1.0" is the default version for our portal. If the value is "1.0", our portal will not prompt patients to re-consent when they first open it. If you set a different version value in the portal settings, you will want to match the current version value. |
{ "key": "termsVersion", "value": "1.0" }, |
| ts_enduser_customField | A custom field called "customField" |
{ "key": "ts_enduser_customField", "value": "custom field text" }, |
| insurance.memberId | Primary insurance member ID | |
| insurance.payerId | Payer ID | |
| insurance.payerName | Payer (Name) | |
| insurance.groupNumber | Group Number | |
| insurance.relationship | Relationship to Subscriber | |
| insurance.relationshipDetails.fname | Subscriber first name | |
| insurance.relationshipDetails.lname | Subscriber last name | |
| insurance.relationshipDetails.dateOfBirth | Subscriber date of birth | |
| insurance.relationshipDetails.gender | Subscriber gender |
If an existing enduser is matched, these fields will be updated upon form submission.
Responder UUID
It's important to note that every form response should have a responder UUID, a unique string identifier that will be used to tie responses to a patient. The absence of a responder uuid can have many unintended consequences for patient creation, variable mapping, and downstream data sync. While it's not important how the string is generated, it's crucial to include this value in all form responses.
Additionally, by generating a responder UUID for an enduser at the beginning of each session and storing it in the browser's localStorage, the value can be leveraged to allow the enduser to return to the point they left off in a form. The following steps outline how to utilize the responder UUID for this purpose within Tellescope:
NOTE: As a rule, providing a "responder_uuid" with a form response is necessary to identify the response as a unique form session. The "responder_uuid" should be provided at the root level of the payload. In order to further leverage the responder_uuid to help patients return to the point they left off in the form, you will need to send an additional, identical copy of the responder_uuid value but formatted with the key as "ts_enduser_responder_uuid". This duplicate value should be included in the "answers" array of the payload in order for the value to map properly.
- Navigate to Settings > Organization, scroll to the bottom of the page and click the ADD button to create a custom field for all patients.
- Click the 'pencil' icon to edit the field, name the field responder_uuid with an input type of 'Text' and click the SAVE button.
- Navigate to the Templates page and click the CREATE TEMPLATE button.
- Click the 'plus' icon, select the template type 'Link', choose your display text, and use the following URL as a guide to create the link, being sure to replace <FLOW-URL> with the URL specific to your form: https://<FLOW-URL>?responder_uuid={{enduser.responder_uuid}}
Note: {{enduser.responder_uuid}} is a string that will automatically populate the value stored on the patient's profile. - Click the INSERT TEMPLATE VALUE button to insert the link in the template.
- Build out the rest of the Template per your requirements.
- You can now send this template via an automated step in a journey or manually via the Compose button in order for patients to pick up where they left off in the form.
Syncing to Healthie (for OpenLoop Customers)
In the event you need form responses to sync to Healthie as charting notes, ensure that you have the ID of the Heathie charting note listed as the External ID on the Tellescope form as well as the "Sync via OpenLoop" setting enabled.
Automation
Both finalized and unfinalized form responses can be leveraged within Tellescope to trigger events. Some common use cases are outlined below:
- Finalized form responses can activate 'Form Submitted' triggers in Tellescope, when the formId from the webhook URL matches the corresponding placeholder form in Tellescope
- Unfinalized form responses with at least one email or phone number can activate the 'Form Unsubmitted 'trigger for the purpose of reengagement and remarketing
- The placeholder form in Tellescope must have at least one question field in order to be available for a Trigger
- Conditional logic on the responses of a form is not supported for a form submission, but conditional logic on patient/contact fields is supported
Patient Matching in Conjunction with Stripe
One common issue that customers encounter when implementing a custom intake form with an embedded Stripe payment processor is 'split patients' being created. This can occur due to the fact that Tellescope is also receiving webhooks from Stripe. The cause is typically when a patient provides one email in the intake form and a separate email address for the Stripe payment.
When possible (if using Stripe Elements or Stripe Checkout, for example) you can pre-fill some of the Stripe fields with the information provided previously by the patient (primarily name, phone, email). This ensures contact information is not entered into Stripe improperly and saves the patient the extra step of typing in information they've previously provided
Other Best Practices for Custom Intake Forms
- When testing, always use a unique first name, last name, phone number, and email address for each patient and form response to ensure proper creation and mapping of patients in Tellescope
- Within your form flow, capturing the customer's first name, last name, phone, and email as early as possible will not only help with remarketing, but will ensure that Tellescope has the information necessary to insert a new patient or match to an existing a patient
- When possible, avoid 'split intakes', or intake forms in which a payment is processed in the middle of the form flow. It is best to process a payment at the end of the intake flow and have this event coincide with the completion of the form. This significantly reduces the need for outreach, remarketing, and issuing refunds due to missing intake info
- Some additional aspects that are commonly handled within the intake form are file uploads, qualifying/disqualifying patients, and collection of SMS consent.
Comments
0 comments
Article is closed for comments.