Skip to main content

Termination Scripts (Optional)

Termination scripts allow you to automatically end a survey for respondents who meet certain criteria, such as being detected as duplicates or having low quality scores.


📌 Overview

Termination scripts are optional and should only be used if your research policy allows early termination. They help maintain data quality by automatically terminating surveys for respondents based on DQC Toolbox results.

Key Points:

  • Optional: Use only if your research policy permits early termination
  • ⚠️ CRITICAL Placement: Termination blocks MUST be placed after your second question's <suspend/> tag (recommended). This ensures DQC data has been collected before termination checks occur.
  • How it works: Termination uses Decipher's <term> element to check values in the dqc_data holder. When conditions are met, the survey ends.

Quick Reference

TypeFieldOriginal RangeDecipher RangeDefault Threshold
Duplicatedqc_data.dup.valTrue/FalseTrue/FalseN/A
Device Scoredqc_data.dcs.val0-1000-4040
Data Trust Scoredqc_data.dts.val0-10000-420420

Lower scores = higher risk. Termination occurs when score <= threshold.


Prerequisites

Before implementing termination scripts, complete the General Setup steps:

  1. ✅ Added the DQC Toolbox initialization script after the <survey> tag (see Step 2.1)
  2. ✅ Added the dqc_data data holder at the end of your survey (included in Step 2.1)
  3. IMPORTANT: Place the termination script after your second question's <suspend/> tag (recommended - ensures DQC data is collected)

Termination Types

Termination by Duplicate

Automatically ends the survey for respondents who have already participated in the same survey (based on survey ID).

Checks: dqc_data.dup.val field. Terminates when value is 'True'.

Implementation:

⚠️ IMPORTANT: Add the following termination block after your second question's <suspend/> tag (recommended):

<term 
label="DQC_Duplicate_Term"
cond="dqc_data.dup.val == 'True'"
markers="terminated, dqc_duplicate_termination"
sst="0">
DQC Duplicate Termination
</term>

Termination by Device Score

Ends the survey for respondents whose device score is at or below a specified threshold.

Score range: 0-100 (original), displayed as 0-40 in Decipher. Lower scores indicate higher risk.

Checks: dqc_data.dcs.val field. Terminates when device_score <= threshold (excluding API placeholders).

Implementation:

⚠️ IMPORTANT: Add the following termination block after your second question's <suspend/> tag (recommended):

Tip: Use the slider below to adjust the threshold. The code block updates automatically.

<term 
label="DQC_Device_Score_Term"
cond="(dqc_data.pid.val and isinstance(dqc_data.pid.val, str) and dqc_data.dcs.val is not None and (float(str(dqc_data.dcs.val)) le 40) and dqc_data.pid.val not in ('Could not process','Submission too quick, data not processed'))"
markers="terminated, dqc_device_score_termination"
sst="0">
DQC Device Score Termination
</term>

Termination by Data Trust Score

Ends the survey for respondents whose data trust score falls below a specified threshold.

Score range: 0-1000 (original), displayed as 0-420 in Decipher. Lower scores indicate higher risk.

Checks: dqc_data.dts.val field. Terminates when data_trust_score <= threshold (excluding API placeholders).

Implementation:

⚠️ IMPORTANT: Add the following termination block after your second question's <suspend/> tag (recommended):

Tip: Use the slider below to adjust the threshold. The code block updates automatically.

<term 
label="DQC_Data_Trust_Score_Term"
cond="(dqc_data.pid.val and isinstance(dqc_data.pid.val, str) and dqc_data.dts.val is not None and (float(str(dqc_data.dts.val)) le 420) and dqc_data.pid.val not in ('Could not process','Submission too quick, data not processed'))"
markers="terminated, dqc_data_trust_score_termination"
sst="0">
DQC Data Trust Score Termination
</term>

Threshold Configuration

Understanding Thresholds

  • Higher threshold = More aggressive: Terminates more respondents (e.g., threshold 30 terminates scores 0-30)
  • Lower threshold = More lenient: Terminates fewer respondents (e.g., threshold 10 terminates scores 0-10)
  • Default values: Device Score = 40, Data Trust Score = 420 (maximum recommended values)

Adjusting Thresholds

Device Score examples:

  • Threshold 10: Only terminates very low scores (0-10) - lenient
  • Threshold 25: Terminates moderate to low scores (0-25) - balanced
  • Threshold 40: Terminates all below-average scores (0-40) - aggressive

Data Trust Score examples:

  • Threshold 50: Only terminates very low scores (0-50) - lenient
  • Threshold 200: Terminates low to moderate scores (0-200) - balanced
  • Threshold 420: Terminates all below-average scores (0-420) - aggressive

Customization

The termination code automatically excludes API placeholder values (Could not process, Submission too quick, data not processed) to prevent false terminations.

You can customize the termination message by editing the text inside the <term> element.


Using Multiple Termination Types

You can combine multiple termination types in the same survey. The survey will terminate if any condition is met.

Here's a complete example with all three termination types (using default recommended termination values):

View Complete XML with All Terminations
<?xml version="1.0" encoding="UTF-8"?>
<survey
alt="Quality Tools Integration - Testing"
autosave="0"
builder:wizardCompleted="1"
builderCompatible="1"
compat="154"
delphi="1"
extraVariables="source,record,decLang,list,userAgent"
fir="on"
html:showNumber="0"
mobile="compat"
mobileDevices="smartphone,tablet,desktop"
name="Survey"
secure="1"
setup="term,decLang,time"
ss:disableBackButton="1"
ss:enableNavigation="1"
ss:hideProgressBar="0"
state="testing">

<style name="global.page.head" wrap="ready"><![CDATA[
(async () => {
try {
const { DQCToolBox } = await import('https://api.dqco-op.com/tools/toolbox/DQC_API_KEY');
await DQCToolBox.getIdentity();
} catch (error) {
console.error('Error in client code:', error);
}
})();
]]></style>
<suspend/>

<exec when="init">
defaultAnswer = 'Submission too quick, data not processed'
defaultSurveyMetricsAnswer = 'No Data'
def save_dqc_data():
defaultDeviceFailuresAnswer = 'None' if getattr(p, 'client_dqc_participant_id', '') else defaultAnswer
dqc_data.rid.val = getattr(p, 'client_dqc_request_id', '') or defaultAnswer
dqc_data.pid.val = getattr(p, 'client_dqc_participant_id', '') or defaultAnswer
dqc_data.per.val = getattr(p, 'client_dqc_persona', '') or 'NONE'
dqc_data.dts.val = getattr(p, 'client_dqc_data_trust_score', '') or '0'
dqc_data.dcs.val = getattr(p, 'client_dqc_device_score', '') or '0'
dqc_data.cty.val = getattr(p, 'client_dqc_country_code', '') or defaultAnswer
dqc_data.sub.val = getattr(p, 'client_dqc_subdivision_name', '') or defaultAnswer
dqc_data.dup.val = getattr(p, 'client_dqc_is_duplicate', False)
dqc_data.sid.val = getattr(p, 'client_dqc_survey_id', '') or defaultAnswer
dqc_data.dfc.val = getattr(p, 'client_dqc_device_failures', '') or defaultDeviceFailuresAnswer
</exec>

<exec when="submit">
save_dqc_data()
</exec>

<text
cond="0"
label="dqc_data"
optional="0"
size="10"
translateable="0"
where="execute,survey,report">
<title>DQC Data Holder</title>
<row label="rid">dqc-request-id</row>
<row label="pid">dqc-participant-id</row>
<row label="dts">dqc-data-trust-score</row>
<row label="per">dqc-persona</row>
<row label="dcs">dqc-device-score</row>
<row label="dup">dqc-is-duplicate</row>
<row label="cty">dqc-country</row>
<row label="sub">dqc-subdivision</row>
<row label="sid">dqc-survey-id</row>
<row label="dfc">dqc-device-failures</row>
</text>

<suspend/>

<radio
label="Q1">
<title>Q1: Are you human?</title>
<comment>Select one</comment>
<row label="r1">Yes</row>
<row label="r2">No</row>
</radio>

<suspend/>

<radio
label="Q2">
<title>Q2: Are you a duplicate?</title>
<comment>Select one</comment>
<row label="r1">Yes</row>
<row label="r2">No</row>
</radio>

<suspend/>


<term
label="DQC_Duplicate_Term"
cond="dqc_data.dup.val == 'True'"
markers="terminated, dqc_duplicate_termination"
sst="0">
DQC Duplicate Termination
</term>
<term
label="DQC_Device_Score_Term"
cond="(dqc_data.pid.val and isinstance(dqc_data.pid.val, str) and dqc_data.dcs.val is not None and (float(str(dqc_data.dcs.val)) le 40) and dqc_data.pid.val not in ('Could not process','Submission too quick, data not processed'))"
markers="terminated, dqc_device_score_termination"
sst="0">
DQC Device Score Termination
</term>
<term
label="DQC_Data_Trust_Score_Term"
cond="(dqc_data.pid.val and isinstance(dqc_data.pid.val, str) and dqc_data.dts.val is not None and (float(str(dqc_data.dts.val)) le 420) and dqc_data.pid.val not in ('Could not process','Submission too quick, data not processed'))"
markers="terminated, dqc_data_trust_score_termination"
sst="0">
DQC Data Trust Score Termination
</term>


<radio
label="Q3">
<title>Q3: You made it to the end of the example survey</title>
<comment>Select one</comment>
<row label="r1">Yay</row>
<row label="r2">Bummer</row>
</radio>

<suspend/>


</survey>

✅ Summary

  • Termination scripts are optional - use only if your research policy allows early termination
  • ⚠️ CRITICAL: Place termination blocks after your second question's <suspend/> tag (recommended - DQC data must be collected first)
  • Higher thresholds = more aggressive termination (terminates more respondents)
  • Lower thresholds = more lenient termination (terminates fewer respondents)
  • Start with lower (more lenient) thresholds and adjust based on your data quality needs

Additional Resources

For complete, labeled survey examples with all integration components, see Decipher — Full Examples.