Back to Integrations
    SA

    Voice Capture for Sawtooth

    Add voice responses to a Lighthouse Studio survey through a Free Format question. Free Format hands you the HTML of the question, which is all the widget needs — your conjoint design, your logic and your quotas are untouched.

    Available

    Before you start

    • A Voice Capture project and its project key. The Free Trial includes 250 credits and asks for no card.
    • Lighthouse Studio, with permission to add a Free Format question and edit its HTML.
    • The exact name you gave that Free Format question. Every field name in the snippet is derived from it, so a name that does not match is the single most common reason an otherwise correct setup produces an empty column.
    • A hosted survey link to test on. Surveys hosted by Sawtooth work as they are; if you run Lighthouse on your own server, add that domain under Allowed domains in your Voice Capture project.
    • Nothing about your conjoint, MaxDiff or quota setup has to change. The Free Format question sits alongside them like any other question.

    Setup Guide

    1

    Create the Free Format question and its two variables

    In the questionnaire, add a Free Format question and give it a name. That name matters more here than on any other platform: Lighthouse stores a field only when the field's name is the question's own name followed by an underscore. Add two variables to the question — an open-end text variable named <name>_text, which will hold the transcript, and a hidden variable named <name>_sid, which will hold the respondent key. Then paste the HTML block into the question's HTML editor. The block assumes the question is called V1; if you called it something else, change the two names in the HTML and the FF constant in the next step to match.

    Step 1
    <!-- Voice Capture - paste into the Free Format question's HTML -->
    <div id="gv-host"></div>
    
    <textarea name="V1_text" id="V1_text" rows="4" cols="60"></textarea>
    <input type="hidden" name="V1_sid" id="V1_sid" value="">
    2

    Paste the widget script under the HTML

    In the same editor, paste the script block below the markup. It finds the text field by name, mounts the microphone above it and collapses Lighthouse's own box, so the respondent sees one control rather than two. Free Format HTML may not contain html, body or form tags — Lighthouse writes those itself — but a script tag is allowed, which is the reason this integration exists at all. Set FF to the exact question name and leave the rest as it is.

    Step 2
    <script>
    (function () {
      var PROJECT_KEY = 'proj_XXXXXXXX';
      var FF = 'V1';               // EXACT name of this Free Format question
      var RESPONDENT_ID = '';      // optional: your own respondent-number merge code
    
      var TEXT = FF + '_text';     // open-end variable that stores the transcript
      var SID  = FF + '_sid';      // hidden variable that stores the respondent key
    
      // One key per respondent, not per page: Lighthouse turns pages with a full
      // form POST, so anything held in a page-level variable is gone by the next
      // voice question.
      function respondentKey() {
        if (RESPONDENT_ID) return RESPONDENT_ID;
        var fresh = 'lh_' + Date.now() + '_' + Math.random().toString(36).slice(2, 10);
        try {
          var stored = window.sessionStorage.getItem('gv_sid');
          if (stored) return stored;
          window.sessionStorage.setItem('gv_sid', fresh);
        } catch (e) { /* private mode: fall back to a per-page key */ }
        return fresh;
      }
    
      function mount() {
        var field = document.getElementById(TEXT);
        var host = document.getElementById('gv-host');
        if (!field || !host || host.getAttribute('data-gv-done')) return;
        host.setAttribute('data-gv-done', '1');
    
        var sessionId = respondentKey();
        var sf = document.getElementById(SID);
        if (sf) sf.value = sessionId;
    
        host.setAttribute('data-project', PROJECT_KEY);
        host.setAttribute('data-target', '#' + TEXT);
        host.setAttribute('data-session', sessionId);
        host.setAttribute('data-question', FF);
        host.setAttribute('data-lang', 'es');
    
        var s = document.createElement('script');
        s.src = 'https://api.voicecapture.ai/voice.js';
        s.onload = function () {
          if (window.GeniusVoice && GeniusVoice.init) GeniusVoice.init(host);
        };
        document.body.appendChild(s);
      }
    
      if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', mount);
      else mount();
    })();
    </script>
    3

    Give the transcript room in the data file

    Every open-end variable in Lighthouse has a maximum length, and Lighthouse truncates at it without warning. A spoken answer to a good probe tends to run longer than the same answer typed, so set that maximum well above what you would allow for typing — a few thousand characters is a safe starting point — before you go to field. This is worth doing first because a truncated transcript looks exactly like a complete one in the export: the sentence simply stops, and nothing in the file says it was cut.

    4

    Put voice on more than one question

    Each voice question is its own Free Format question, with its own pair of variables and its own copy of the block with FF set to that question's name. You do not have to do anything to keep them together. The respondent key is written to the browser session the first time any of them loads and read back on the ones that follow, so every recording from one respondent carries the same id even though Lighthouse turns a page between them.

    5

    Test on the hosted survey link, not the local preview

    Run your test on the browser link to the hosted survey. A microphone needs a secure connection and a page that is not sitting inside a frame that withholds microphone access, and the local test preview inside Lighthouse Studio does not reliably reproduce either condition. A microphone that fails to appear there tells you nothing about the real survey, and more than one setup has been rebuilt from scratch over a preview that was never going to work.

    6

    Confirm the transcript reaches your data file

    This is the step most setups skip and the one that catches the silent failure. Record fifteen seconds, wait for the upload to finish, move to the next page and finish the interview. The transcript should appear in the Voice Capture dashboard within about half a minute, and it should also be sitting in the open-end variable when you export the study data, with the respondent key in the hidden one. If the dashboard has a perfect transcript and the Sawtooth column is empty, the field name is not what Lighthouse expects — check it against the question name character by character.

    7

    Field it, then join the two exports

    Field the study as you normally would. Recordings upload and transcribe while fieldwork is running, so the open ends are readable before the study closes rather than only at the end. Export from Voice Capture to CSV on any plan, or to Excel on a paid credit pack, and join it to your Lighthouse data file on the respondent key. If the transcript is already in the open-end variable you may not need the join at all — it is there for the cases where you want the audio metadata, the language or the timing alongside the text.

    If something does not work

    The microphone never appears

    Either the FF constant in the script does not match the question name, or the block was pasted somewhere other than that question's HTML editor. Open the hosted survey link with the browser console visible; the widget reports what it could not find.

    The microphone appears but nothing is transcribed

    Check the project key in the block first. If the key is right and you host Lighthouse on your own server rather than with Sawtooth, add that domain under Allowed domains in the project.

    The transcript is in Voice Capture but the Sawtooth column is empty

    This is the naming convention. The input name has to be the question's own name, an underscore, then the variable name, and that variable has to exist in the question's variable list. A field Lighthouse does not recognise is dropped on submit without an error.

    The transcript arrives cut off

    The open-end variable's maximum length is too short. Raise it and re-test; Lighthouse truncates silently, so nothing in the export marks where the answer was cut.

    What this integration does not do

    • Each voice-enabled question needs its own Free Format question and its own copy of the block. A normal open end that is not wrapped this way keeps its typed input.
    • The microphone requires a secure connection, which hosted Sawtooth surveys serve by default.
    • The local test preview inside Lighthouse Studio may not grant microphone access, so testing has to happen on the hosted link.
    • Renaming the Free Format question changes every field name with it, and the block has to be updated to match.
    • No Sawtooth Script is required. If the study already carries its own respondent number, pasting it into RESPONDENT_ID gives a cleaner join than the generated key, but it is optional.

    Need help?

    Our AI assistant can walk you through the setup step by step.

    Open AI Chat

    Your next study deserves better insights

    Set up Voice Capture in under 5 minutes. No credit card. No commitment.

    Get Started Free
    © 2026 Voice Capture. All rights reserved.

    We use cookies to improve your experience and analyze site traffic. Learn more