Study Modules Embed Library

API Specification

The Study Modules JavaScript embed library enables third-party developers to integrate with OneStudyTeam’s Study Modules pre-screening forms.

The API described in this document is meant to provide a high-level integration guideline.

A note on nomenclature: Study Websites/Study Modules were previously called "Microsites"

Types of Study Modules

1) Site Map

This module type displays a list of participating sites along side a map showing their location.

When the user clicks "See if You Pre-Qualify", the following form flow appears:

This form will allow the user to answer questions about themselves and submit their contact information to the participating site that they have selected.

2) Prescreener Form

The prescreener form flow displays only the form to submit user information for a site. It does not include the map or list of sites.

Installation

CDN

The JavaScript library will be provided via a CDN (content delivery network) and can be installed by adding a <script> tag to the page where the form will be displayed. We expose additional functions for more control in various use-cases:

<script src="https://<trial name>.<studymodule_sub_domain_name>/embed.js" async defer></script>

<button id="button">See if I Prequalify</button>

<div id="wrapper"></div>

<script>
document.querySelector('#button').onclick = window.StudyTeamForm.display({
  container: document.getElementById('wrapper'),
  sponsorSiteId: "1066",
  tracking: {
    utm_source: "My UTM Source",
    utm_campaign: "My UTM Campaign",
    utm_medium: "My UTM Medium"
  }
});
</script>

Configuration Options

NameTypeDescriptionDefault Value
containerHTMLelement
(required)
HTML element where the iframe will be rendered as a child node.N/A
sponsorSiteId string (required for Prescreener Form) The sponsorSiteId ID (Will be provided by OneStudyTeam)
Required for formFlow, unused for site map view
N/A
localestring Alpha-2 language and country code to specify localization language for module to display in. Codes come from ISO-639-1 and ISO-3166-1 and are of the form:
"en-US" - US English
"es-US" - US Spanish
"es-ES" - Spain Spanish
en-US
iframePropsJSON objectAttribute key value pairs that will be set on the element. See here for the full list of attributes.undefined
tracking JSON object UTM query string parameters passed to the form for downstream consumption. Note: including this data helps us provide more insight on the source of referrals, so it is highly recommended to include this data.

tracking: { utm_source: "google", utm_campaign: "marketing1", utm_medium: "search" }
undefined
initialValues JSON objectIf you already have the respondent's information, you can feed that data in using initialValues. The format of this object is a key value map of question field name to the initial value
{ "age": 42 , "hadSurgeries": “yes”, “otherTreatments”: [“treatment1”, “treatment2”] }
undefined
sessionId string (required for external prescreener confirmation page)Identifier to fetch external prescreener confirmation dataundefined
onReady Javascript functionJavascript callback that triggers when the integration has loaded undefined
onStateChangeJavascript functionJavascript callback that triggers when form changes state such as advancing external prescreener confirmation -> prescreen questions, prescreen questions -> contact info, referral being submitted, user filling out prescreener and failing, etc. undefined
onClose Javascript function Javascript callback that triggers when the integration iframe is closed in Prescreen Form Flow or the prescreen popup is closed in Site Map View undefined

Pre-filled Answer Format

In order to pre-fill answers to certain questions, our API will allow passing in initial data to be used as default values for existing fields. The question IDs and values required to select specific options will be provided by OneStudyTeam. Additionally, other data can be passed into Studyteam by adding extra keys and arbitrary values (e.g. extraData, extraData2).

initialValues: {
  singleSelectQuestionId: 'questionValue',
  multiselectQuestionId: ['option1', 'option3'],
  numberQuestionId: '2', //or 2
  stringQuestionId: 'value',
  phoneNumberQuestionId: '15551237654',
  extraData: 'value',
  extraData2: true,
}

Callbacks

In order to inform the host website of user progression through the form flow, we allow registering callbacks that will trigger at various stages. Callbacks return a correlation ID so threads of user activity can be traced without identifying specific users in StudyTeam as well as more detailed information about user progression.

<script>
...
document.querySelector('#button').onclick =
    stForm.display({
      ...
      onReady: (correlationId) => {
        console.log('form ready for ', correlationId);
      },
      onStateChange: (correlationId, eventType, eventState) => {
        console.log('forms submitted with id:', correlationId,
                    'event type:', eventType, ' event state:', eventState);
      }
      onClose: (correlationId) => {
        console.log('form close for ', correlationId);
      },
      ...options
      ,})
...
</script>

Callback methods and argument descriptions

Callback TypeDescriptionArguments
onReady()Indicates integration solution has loadedN/A
onStateChange(correlationId, eventType, eventState)Indicates a user event that changes state.correlationId (string): An anonymous identifier to tie together events for a particular user flow. This ID remains constant for one user's session.

eventType (string):
A string representing the type of state change occurring. See the table below for more details.

eventState (string):
When eventType is "PRESCREEN_QUESTION_CHANGE", this argument is the page number that the user has navigated to.
onClose()In Form Flow, indicates the integration iframe was closed.
In Site Map view, prescreen form was closed.
N/A

Values of eventType for onStateChange

Value of eventTypeMeaning
"FLOW_STATE_OPENED"Only in the Site Map view, triggered when the user clicks CTA button (See if you Prequalify) and starts the prescreen form flow.
"FLOW_STATE_CHANGED"Advance from External Prescreener Confirmation to Prescreen, Prescreen to Prescreen fail/Contact Info, Contact Info to Referral Submitted page.
"ELIGIBLE_PATIENT_SUBMITTED"The patient’s information has been successfully submitted into StudyTeam after meeting eligibility requirements.
"NON_ELIGIBLE_PATIENT"User failed prescreener and is presented with fail message screen
"PRESCREEN_QUESTION_CHANGE"Where prescreener is not a single page, triggers on navigating forward/backward in pages.
Will also give an event state with the resultant page number

How to get the necessary IDs and values?

Study Module Subdomain Name

This is a subdomain ending in .studyteamapp.com . This domain is unique to a trial. OneStudyTeam will provide this domain. One such domain might look like trialname.partnername.studyteamapp.com.

Multiple Trials per Study Module

If you have multiple trials linked to the same study module they will be differentiated by using a different subdomain in the URL of the embed.js script. For example:

https://<trial name>.<studymodule_sub_domain_name>/embed.js

https://trial1.aSponsor.studyteamapp.com/embed.js
https://trial2.aSponsor.studyteamapp.com/embed.js

OneStudyTeam will provide all needed subdomains for the module.

sponsorSiteId

When integrating with a Prescreener Form Module, one of the required fields is sponsorSiteId. This ID is unique to a site, and will be provided by OneStudyTeam for you to use in window.StudyTeamForm.display.

Get Sites API.

Alternatively, the Study Websites GET sites API can be used to return a list of site fields, including the sponsorSiteIds. See Using the Study Websites GET Sites API for more details. This endpoint is useful for dynamically retrieving the sponsorSiteId values for all sites on a trial.

initialValues

initialValues expects an object with specific keys to be used for each pre-filled question. These keys will also be provided by OneStudyTeam. OneStudyTeam will also provide the valid set of values for each question. See Pre-filled Answer Format for more information.

Security Considerations

Content Security policy: For security purposes, embedding on unsecured pages is disallowed. Pages must use HTTPS, not HTTP.

Supported Form Input Types

The following input types are supported for both the Prescreener Form and the Site Map Module types:

  • Single select - radio button
  • Multi select - checkbox list
  • Number - support integers
  • String - free text
  • Phone number - basic phone number validation with country select
  • Email - basic validation

Code Examples

Note: these examples contain some placeholder values in angle brackets <> that must be replaced with the values mentioned in How to get the necessary IDs and values

Site Map Module

<!DOCTYPE html>

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
    <script onload=displayStudyModule() src="<trial name>.<studymodule_sub_domain_name>.studyteamapp.com/embed.js" async defer></script>
    <script>
        function displayStudyModule() {
            window.StudyTeamForm.display({
                container: document.getElementById('wrapper'),
                sessionId: "<session id>",
                tracking: getUtmParams(),
                locale: 'en-US',
                iframeProps: {
                    style: {
                        overflow: 'auto'
                    }
                },
                initialValues: {
                    "age": 42,
                    "hadSurgeries": "yes",
                    "otherTreatments": ["treatment1", "treatment2"]
                },
                onReady: (correlationId) => {
                    console.log('form ready: ', correlationId);
                },
                onStateChange: (correlationId, eventType, eventState) => {
                    console.log('state change, type: ', eventType, ' state: ', eventState, 'correlation id: ', correlationId);
                },
                onClose: (correlationId) => {
                    console.log('form closed: ', correlationId);
                }
            });
        }
        function getUtmParams() {
            const urlParams = new window.URLSearchParams(window.location.search)
            const utmParams = {}
            for (const [key, value] of urlParams) {
                if (key.startsWith('utm_') && value !== '') {
                    utmParams[key] = value
                }
            }
            return utmParams
        }
    </script>
</head>

<body>
    <div>
        <div id="wrapper"></div>
    </div>
</body>

</html>

Prescreener Form Module

<!DOCTYPE html>

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
    <script src="<trial name>.<studymodule_sub_domain_name>.studyteamapp.com/embed.js" async defer></script>
    <script>
        function displayStudyModule() {
            window.StudyTeamForm.display({
                container: document.getElementById('wrapper'),
                sponsorSiteId: "<sponsor site id>", //known as siteId in the previous implementations
                sessionId: "<session id>",
                tracking: getUtmParams(),
                locale: 'en-US',
                iframeProps: {
                    style: {
                        overflow: 'auto'
                    }
                },
                initialValues: {
                    "age": 42,
                    "hadSurgeries": "yes",
                    "otherTreatments": ["treatment1", "treatment2"]
                },
                onReady: (correlationId) => {
                    console.log('form ready: ', correlationId);
                },
                onStateChange: (correlationId, eventType, eventState) => {
                    console.log('state change, type: ', eventType, ' state: ', eventState, 'correlation id: ', correlationId);
                },
                onClose: (correlationId) => {
                    console.log('form closed: ', correlationId);
                }
            });
        }
        function getUtmParams() {
            const urlParams = new window.URLSearchParams(window.location.search)
            const utmParams = {}
            for (const [key, value] of urlParams) {
                if (key.startsWith('utm_') && value !== '') {
                    utmParams[key] = value
                }
            }
            return utmParams
        }
    </script>
</head>

<body>
    <div>
        <div id="wrapper"></div>
        <button id="button" onclick="displayStudyModule()"">
            See If I Prequalify
        </button>
    </div>
</body>

</html>