> ## Documentation Index
> Fetch the complete documentation index at: https://docs.poh.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Decipher integration

This guide shows how to add Proof of Human to a Decipher (Forsta) survey so that every respondent is tracked throughout their survey.

## Before you start

Decipher only makes API calls to whitelisted domains. Contact Forsta support and ask them to whitelist `https://api.poh.org` for your account.

## Loading the tracker

Add the following as a top-level element in your survey XML. Placing it at the top level loads the tracker on every page, so behavior is tracked across the entire survey. Replace `YOUR_SITE_KEY` with your site key from the [Integration script](https://app.poh.org/account/integration) page on the Proof of Human dashboard:

```xml theme={null}
<style name="respview.client.js" mode="after">
<![CDATA[
<!-- Proof of Human API Script -->
<script src="https://cdn.poh.org/v1/rt.js" data-site-key="YOUR_SITE_KEY"></script>
<!-- End Proof of Human API Script -->
]]>
</style>
```

## Capturing the session ID

To retrieve a respondent's data later, you need their session ID. Add the following `<style>` block inside an early question that every respondent sees (for example, the first question of the survey):

```xml theme={null}
<style name="question.after" wrap="ready"><![CDATA[
function saveSid() {
  var sid = window.getRoundtableSessionId && window.getRoundtableSessionId();
  if (!sid) return false;
  Survey.setPersistent('client_roundtable_session_id', sid);
  return true;
}
if (!saveSid()) {
  window.addEventListener('roundtable:ready', saveSid, { once: true });
}
]]></style>
```

This gets the session ID with `window.getRoundtableSessionId()` and makes it available server-side as `p.client_roundtable_session_id`.

<Note>
  Attach this code to a question the respondent answers and submits — not to a terminal or exit page.
</Note>

## Retrieving session data

The question code above saves the session ID to `p.client_roundtable_session_id`. To pull the risk score and flags for a respondent back into your survey, call the session report endpoint from a Decipher API node. Place this after the last page you'd like to track.

### 1. Call the report endpoint

```xml theme={null}
<exec>
p.Params1  = dict(sessionId=p.get('client_roundtable_session_id', ''))
p.Headers1 = dict(Authorization="Bearer YOUR_SECRET_KEY")
</exec>

<logic label="Roundtable_API"
  cond="p.get('client_roundtable_session_id', '') != ''"
  api:params="p.Params1"
  api:headers="p.Headers1"
  api:url="https://api.poh.org/v1/sessions/report"
  uses="api.1"/>
```

Pass the captured session ID as the `sessionId` query parameter, and your secret key as a `Bearer` token in the `Authorization` header. You can get your secret key from the [Secret keys](https://app.poh.org/account/api-keys) dashboard page (it starts with `sk-`).

<Warning>
  Make sure not to put your secret key in client-side JavaScript — it belongs only in the server-side `<exec>` and `<logic>` blocks.
</Warning>

### 2. Save the response

After calling the API, Roundtable\_API.r holds the parsed JSON response. Read the fields you want to track and store them in a hidden text question:

```xml theme={null}
<exec>
def to_ascii(v):
    if isinstance(v, unicode):
        for a, b in [(u'\u2014', '-'), (u'\u2013', '-'), (u'\u2011', '-'),
                     (u'\u2018', "'"), (u'\u2019', "'"),
                     (u'\u201c', '"'), (u'\u201d', '"')]:
            v = v.replace(a, b)
        return v.encode('ascii', 'replace')
    return v

rt_data.d1.val = Roundtable_API.r.get('risk_score', 'NA')
rt_data.d2.val = to_ascii(Roundtable_API.r.get('risk_explanation', 'NA'))
rt_data.d3.val = to_ascii(Roundtable_API.r.get('recommended_action', 'NA'))
</exec>

<text label="rt_data" optional="0" size="25" where="execute,survey,report">
  <title>Roundtable risk data</title>
  <row label="d1">risk_score</row>
  <row label="d2">risk_explanation</row>
  <row label="d3">recommended_action</row>
</text>
```

The API returns the risk score (0–100), risk explanation, recommended action, biometric checks, and device checks for the session. For the full response shape and all available fields, see the [API Reference](api-reference/session-data).
