diff --git a/src/assets/qualtrics/flow-add-element.png b/src/assets/qualtrics/flow-add-element.png
new file mode 100644
index 0000000000000..706c20093f321
Binary files /dev/null and b/src/assets/qualtrics/flow-add-element.png differ
diff --git a/src/assets/qualtrics/flow-branch.png b/src/assets/qualtrics/flow-branch.png
new file mode 100644
index 0000000000000..950d0403be936
Binary files /dev/null and b/src/assets/qualtrics/flow-branch.png differ
diff --git a/src/assets/qualtrics/flow-embedded-data.png b/src/assets/qualtrics/flow-embedded-data.png
new file mode 100644
index 0000000000000..b7f8e5ac0a608
Binary files /dev/null and b/src/assets/qualtrics/flow-embedded-data.png differ
diff --git a/src/assets/qualtrics/flow-end-of-survey-options.png b/src/assets/qualtrics/flow-end-of-survey-options.png
new file mode 100644
index 0000000000000..e1527b5ec79ab
Binary files /dev/null and b/src/assets/qualtrics/flow-end-of-survey-options.png differ
diff --git a/src/assets/qualtrics/flow-no-token-branch.png b/src/assets/qualtrics/flow-no-token-branch.png
new file mode 100644
index 0000000000000..84acadf06040f
Binary files /dev/null and b/src/assets/qualtrics/flow-no-token-branch.png differ
diff --git a/src/assets/qualtrics/flow-overview.png b/src/assets/qualtrics/flow-overview.png
new file mode 100644
index 0000000000000..948a0dc02f252
Binary files /dev/null and b/src/assets/qualtrics/flow-overview.png differ
diff --git a/src/assets/qualtrics/flow-web-service.png b/src/assets/qualtrics/flow-web-service.png
new file mode 100644
index 0000000000000..b437b9aff16a8
Binary files /dev/null and b/src/assets/qualtrics/flow-web-service.png differ
diff --git a/src/assets/qualtrics/gate-page.png b/src/assets/qualtrics/gate-page.png
new file mode 100644
index 0000000000000..0f8fe8081a8a5
Binary files /dev/null and b/src/assets/qualtrics/gate-page.png differ
diff --git a/src/assets/qualtrics/portal-site.png b/src/assets/qualtrics/portal-site.png
new file mode 100644
index 0000000000000..93f4a0dd78f2f
Binary files /dev/null and b/src/assets/qualtrics/portal-site.png differ
diff --git a/src/assets/qualtrics/response-data.png b/src/assets/qualtrics/response-data.png
new file mode 100644
index 0000000000000..21e86a8c128c9
Binary files /dev/null and b/src/assets/qualtrics/response-data.png differ
diff --git a/src/assets/qualtrics/survey-blocked.png b/src/assets/qualtrics/survey-blocked.png
new file mode 100644
index 0000000000000..78a22b9f21424
Binary files /dev/null and b/src/assets/qualtrics/survey-blocked.png differ
diff --git a/src/assets/qualtrics/survey-passed.png b/src/assets/qualtrics/survey-passed.png
new file mode 100644
index 0000000000000..d7f5abc9a1a8b
Binary files /dev/null and b/src/assets/qualtrics/survey-passed.png differ
diff --git a/src/assets/qualtrics/survey-security-check.png b/src/assets/qualtrics/survey-security-check.png
new file mode 100644
index 0000000000000..41b356184c704
Binary files /dev/null and b/src/assets/qualtrics/survey-security-check.png differ
diff --git a/src/content/docs/en/integrations/qualtrics.mdx b/src/content/docs/en/integrations/qualtrics.mdx
new file mode 100644
index 0000000000000..83da44bf3093f
--- /dev/null
+++ b/src/content/docs/en/integrations/qualtrics.mdx
@@ -0,0 +1,281 @@
+---
+title: Qualtrics
+description: Stop bots from taking your Qualtrics surveys. Respondents pass Procaptcha first, and Qualtrics checks the result with Prosopo before it shows any questions.
+i18nReady: true
+---
+import { Image } from 'astro:assets';
+import PortalSite from '~/assets/qualtrics/portal-site.png';
+import SurveySecurityCheck from '~/assets/qualtrics/survey-security-check.png';
+import GatePage from '~/assets/qualtrics/gate-page.png';
+import FlowAddElement from '~/assets/qualtrics/flow-add-element.png';
+import FlowEmbeddedData from '~/assets/qualtrics/flow-embedded-data.png';
+import FlowNoTokenBranch from '~/assets/qualtrics/flow-no-token-branch.png';
+import FlowWebService from '~/assets/qualtrics/flow-web-service.png';
+import FlowBranch from '~/assets/qualtrics/flow-branch.png';
+import FlowEndOfSurveyOptions from '~/assets/qualtrics/flow-end-of-survey-options.png';
+import FlowOverview from '~/assets/qualtrics/flow-overview.png';
+import SurveyPassed from '~/assets/qualtrics/survey-passed.png';
+import SurveyBlocked from '~/assets/qualtrics/survey-blocked.png';
+import ResponseData from '~/assets/qualtrics/response-data.png';
+
+This guide adds Procaptcha to a [Qualtrics](https://www.qualtrics.com/) survey. People who pass the check see your
+questions. Bots, and anyone who tries to skip the check, are sent straight to the end of the survey.
+
+You don't need to write code, host anything, or have JavaScript enabled on your Qualtrics licence.
+
+## How it works
+
+1. The respondent opens your normal Qualtrics survey link. The first page asks them to start a security check.
+2. The link takes them to a Prosopo page that shows the Procaptcha widget.
+3. When they pass, they are sent back to your survey with a one-time token added to the link.
+4. Before showing any questions, the survey's **Survey Flow** sends that token and your secret key to Prosopo's
+ [`siteverify`](/en/basics/server-side-verification/) endpoint.
+5. If Prosopo answers `verified: true`, the survey continues. Otherwise the survey ends.
+
+A token works once and expires after a few minutes, so a copied or shared link stops working after it has been used.
+The check happens on Qualtrics' servers, not in the respondent's browser, so it cannot be skipped by editing the page
+or adding `captcha_verified=true` to the link.
+
+## What you need
+
+- A Qualtrics licence that includes the **Web Service** element in Survey Flow. To check, open **Survey flow**, select
+ **Add a New Element Here**, and look for **Web Service**.
+- A Prosopo site key and secret key from the [Prosopo portal](https://portal.prosopo.io).
+
+## 1. Create a site in the Prosopo portal
+
+1. Log in to the [Prosopo portal](https://portal.prosopo.io) and open **Site Management**.
+2. Select **Create New Site** and give it a name, such as `qualtrics-survey`.
+3. Under **Allowed Domains**, add `js.prosopo.io`. This is where the Procaptcha widget is shown.
+4. Copy the **Site Key** and the **Secret Key**.
+
+
Before you start, please complete a quick security check.
+ +``` + +The respondent sees this: + +Please complete the security check below.
+ + + + +``` + +Never put your secret key in this page. Anyone can read it. + +## Showing the widget inside the survey + +If your Qualtrics licence lets you add JavaScript to questions, you can show the widget directly on the first page of +the survey. Free and trial Qualtrics accounts cannot do this. To check, select a question and look for **JavaScript** +under **Question behavior**. + +1. In the Prosopo portal, add your Qualtrics domain (for example `yourorg.qualtrics.com`) to the site's **Allowed + Domains**. +2. In the `Security check` question, replace the link with a short instruction, such as "Please complete the security + check below to continue." +3. Select **Question behavior** → **JavaScript** and replace its contents with the code below. Replace + `YOUR_SITE_KEY` with your site key. + + ```javascript + Qualtrics.SurveyEngine.addOnReady(function () { + var question = this; + var container = document.createElement("div"); + question.getQuestionContainer().appendChild(container); + question.hideNextButton(); + + function render() { + window.procaptcha.render(container, { + siteKey: "YOUR_SITE_KEY", + callback: function (token) { + Qualtrics.SurveyEngine.setJSEmbeddedData("procaptcha_token", token); + question.showNextButton(); + }, + "expired-callback": function () { + Qualtrics.SurveyEngine.setJSEmbeddedData("procaptcha_token", ""); + question.hideNextButton(); + }, + }); + } + + if (window.procaptcha) { + render(); + return; + } + var script = document.createElement("script"); + script.type = "module"; + script.src = "https://js.prosopo.io/js/procaptcha.bundle.js"; + script.onload = render; + document.head.appendChild(script); + }); + ``` + +4. In the Survey Flow: + - In the Embedded Data element, rename `procaptcha_token` to `__js_procaptcha_token`. Qualtrics adds the `__js_` + prefix to values set by `setJSEmbeddedData`. + - Remove the branch around `Security check`, so the block always shows. + - Change the Web Service `token` value to `${e://Field/__js_procaptcha_token}`. + +The order is: Embedded Data → `Security check` block → Web Service → Branch with End of Survey → your questions. + +Hiding the **Next** button only helps real people. The Web Service check is what stops bots, so keep it in place. + +## Notes + +- Qualtrics records a response for every visit, including blocked ones. Flagging them as screened-out (see above) + keeps them out of your completed responses. +- Bots can still open your survey link over and over, creating a screened-out response each time. To cut this down, + go to **Survey options** → **Security** and turn on **In Survey: Prevent multiple submissions**. +- If Prosopo cannot be reached, `captcha_verified` stays `false` and the survey ends. Nobody gets in without a valid + token. +- To change how strict the check is, see [CAPTCHA types](/en/basics/captcha-types/) and + [Traffic Filter](/en/advanced/traffic-filter/). diff --git a/src/i18n/en/nav.ts b/src/i18n/en/nav.ts index f31f6a84ed3d0..80729b1526fe0 100644 --- a/src/i18n/en/nav.ts +++ b/src/i18n/en/nav.ts @@ -174,6 +174,12 @@ export default [ slug: 'framework-integrations/vue-integration', key: 'framework-integrations/vue-integration', }, + {text: 'Platform integrations', header: true, type: 'learn', key: 'integrations'}, + { + text: 'Qualtrics', + slug: 'integrations/qualtrics', + key: 'integrations/qualtrics', + }, {text: 'Demos', header: true, type: 'learn', key: 'demos'}, { text: 'HTML Frontend Client Example',