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

  1. Front-end (Decipher page) gets a fresh session_id from the Verisoul SDK.

  2. A <suspend/> block stores the session_id variable locally in Decipher.

  3. An <exec> block builds the API headers and JSON payload.

  4. A <logic> element with api: attributes POSTs to Verisoul's /session/authenticate endpoint server-side.

  5. 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-KEY with your Verisoul API key (from Verisoul → Settings → API Keys).

  • survey_group will 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 as p.variable.

  • Watch for variable name typos. The variable name in <exec> must exactly match what you reference in the <logic> element's api:headers and api:data attributes.

  • Build JSON as a string, not a Python dict. The api:data attribute 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 the session_id before 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.