Integrate Verisoul with Decipher (XML Editor)
Last updated: July 7, 2026
Estimated time: ~10-30 minutes
Who can do this: Decipher project owner or Admin comfortable with the XML editor
Goal
Send every Decipher Respondent ID (and optional survey context) to Verisoul so fraud signals are tied to the right user and survey run.
Verisoul Groups must be enabled on the project. See https://docs.verisoul.ai/integration/advanced/multi-accounting-groups
Native Decipher API Call with <logic> (Real-Time, No Backend)
Decipher has a built-in API call mechanism using the <logic> element with api: attributes. This lets you call Verisoul's /session/authenticate endpoint directly from within the survey — no separate backend required.
The flow
Front-end (Decipher page) gets a fresh
session_idfrom the Verisoul SDK.A
<suspend/>block stores thesession_idvariable locally in Decipher.An
<exec>block builds the API headers and JSON payload.A
<logic>element withapi:attributes POSTs to Verisoul's/session/authenticateendpoint server-side.A follow-up
<exec>block reads the response and acts on the risk verdict (block, route to re-contact, etc.).
1 – Front-end snippet: Load the Verisoul SDK and capture the session ID
Add this to your survey to load the Verisoul SDK and store the session_id in a Decipher variable:
xml
<style mode="after" name="respview.client.js"><![CDATA[
<script src="https://js.verisoul.ai/prod/bundle.js"
verisoul-project-id="YOUR-PROJECT-ID"></script>
<script>
(async () => {
try {
const { session_id } = await window.Verisoul.session();
// Store session_id in a Decipher hidden variable
// Option 1: Plain-vanilla JS:
document.querySelector('[name="client_session_id"]').value = session_id;
// Option 2: Using JQuery selector:
// $("[name='client_session_id']").val(session_id);
} catch (err) {
console.error('Verisoul.session() error', err);
}
})();
</script>
]]></style>
<suspend/>Make sure you have a hidden variable defined in your survey to capture the session ID:
xml
<text label="client_session_id" where="execute" optional="1" size="200"/>Make sure to load Verisoul JS SDK on all pages - put at the app/"head" level if possible.
2 – Build the API request with <exec>
Use an <exec> block to set up the headers and JSON payload. Important: inside <exec> you are writing Python, so reference Decipher variables directly (e.g., p.client_session_id) — do not use the ${...} interpolation syntax, which only works in Decipher's XML/HTML context.
xml
<exec>p.APIHeader = {
"Content-Type": "application/json",
"x-api-key": "YOUR-API-KEY"
}
p.APIData = '{"session_id": "' + str(p.client_session_id) + '", "account": {"id": "' + str(p.uuid) + '", "group": "YOUR-SURVEY-ID"}}'
</exec>
<exec>
p.APIHeader = {
"Content-Type": "application/json",
"x-api-key": "YOUR-API-KEY"
}
# Dynamically get Decipher survey ID
survey_group = gv.survey.path.split("/")[-1]
p.APIData = '{"session_id": "' + str(client_session_id.unsafe_val) + '", "account": {"id": "' + str(p.uuid) + '", "group": "' + str(survey_group) + '"}}'
</exec>
<suspend/>Notes:
Replace
YOUR-API-KEYwith your Verisoul API key (from Verisoul → Settings → API Keys).survey_groupwill populate with your Decipher survey ID and be sent to Verisoul as the group.
3 – Make the API call with <logic>
The <logic> element with api: attributes makes the server-side HTTP request:
xml
<logic label="verisoul" api:data="p.APIData" api:headers="p.APIHeader" api:method="POST" api:params="" api:url="https://api.prod.verisoul.ai/session/authenticate" uses="api.1"/>4 – Handle the response
After the <logic> call, the response is available on the verisoul object (matching the label of the <logic> element). Use a follow-up <exec> to read the result:
xml
<exec>
print p.APIData
if verisoul.status == 200:
print(verisoul.r)
# API response status is top level
vs_status.val = verisoul.status
# Store Verisoul's decision (Real/Fake/Suspicious) as Decipher survey response.
# This requires parsing the API response in Python
vs_decision.val = verisoul.r.get("decision", "")
# To fetch nested API response properties such as session->network->ip_address
vs_ip_address.val = ((verisoul.r.get("session") or {}).get("network") or {}).get("ip_address", "")
</exec>
<suspend/>Remember to create <text> tags for each Verisoul response property you'd like stored in Decipher. E.g. for a property you name vs_decision:
<text
label="vs_decision"
optional="0"
size="25"
where="execute,survey,report">
<title>VS Decision</title>
<comment></comment>
</text>You can then branch on the response to terminate fraudulent respondents, route them to a re-contact flow, or store the verdict in a hidden variable for later analysis.
Common pitfalls
Don't use
${p.variable}inside<exec>blocks. The${...}syntax is for Decipher's XML/HTML rendering context. Inside<exec>you're writing Python — reference variables directly asp.variable.Watch for variable name typos. The variable name in
<exec>must exactly match what you reference in the<logic>element'sapi:headersandapi:dataattributes.Build JSON as a string, not a Python dict. The
api:dataattribute expects a JSON string. Use string concatenation as shown above to embed dynamic values.Confirm your
<suspend/>placement. If you need the front-end to capture thesession_idbefore the API call fires, make sure there is a page break (<suspend/>) between the SDK capture step and the<exec>/<logic>blocks so the respondent advances and the value is committed.
Need help?
Email support@verisoul.ai with:
• Survey link
• Snippet screenshot
• Whether you want dashboard‑only or full API integration
We’ll get you sorted fast.