Skip to main content
Google Forms cannot run a check before it shows a question. It has no hidden fields, no branching on a link parameter, and no way to ask an outside service anything while a respondent is looking at it. So HumanCheck holds the line in two places instead of one. The check happens on our side, before anyone reaches your form. The clean-up happens in your own spreadsheet, the moment somebody submits. Together they mean only verified people reach your questions, and anything that slips past by going straight to your form URL is removed from your results within seconds.
Somebody who skipped the check can still open your form and press submit. What they cannot do is leave a trace in your data or get paid for it. If you need unverified people to be unable to load the page at all, Qualtrics and Alchemer can do that and Google Forms cannot.
1

Build your form

In Google Forms, exactly as you normally would, with two additions.
  1. Add a Short answer question called Verification code. Mark it Required and put it on the first page. Capitals and spacing do not matter.
  2. Underneath it, write something like “Filled in automatically, please leave this alone.”
  3. Open the Responses tab and click the Sheets icon to send your responses to a Google Sheet. The rest of the setup lives in that sheet.
  4. In Settings, open Responses and turn off “Allow response editing.” Without this, somebody could submit and then edit a valid code in afterwards.

You now have: a normal Google Form with a code box on page one, and a spreadsheet collecting the answers.

2

Connect your study in VerifyYou

In your VerifyYou dashboard, open a verification and go to the Integration tab.
  1. Make sure the method is One-time passwords. If it is set to something else, click Switch method and choose it.
  2. Set how many one-time passwords you need. Ask for at least twenty percent more than the respondents you expect. Passwords cost nothing, and running out mid-study screens out real people.
  3. Click Copy list to copy your passwords. You need them in step four.

You now have: your study link, which is the one you share, and your one-time passwords.

3

Add the script to your spreadsheet

Open the Google Sheet your responses go to, not the form.
  1. Open Extensions, then Apps Script.
  2. Delete anything already in the editor and paste in the script from the bottom of this page.
  3. Click Save.
  4. Click Deploy, then New deployment. Click the gear beside “Select type” and choose Web app.
  5. Set Execute as: Me and Who has access: Anyone, then click Deploy and approve the permissions.
  6. In the function dropdown choose setUp and click Run.
When Google warns that it has not verified this app, click Advanced, then Go to (your project), then Allow. That message appears because this is a private script you own and have not published to anyone else.Your spreadsheet now has a tab called VerifyYou codes. Cell G5 holds your access link, which you need in step five.

You now have: a spreadsheet that checks every submission, and an access link that fills the code box on its own.

4

Paste in your passwords

On the VerifyYou codes tab.
  1. Paste your passwords into column A, starting at A2.
  2. Type Unused beside each one in column B.
That tab is your ledger. Status moves from Unused, to Issued when we hand somebody that password, to Used when they actually submit. It is also how you check the gate is running: if people are completing your survey and nothing is moving to Used, something is wrong.Keep this spreadsheet private. Anyone who can read your passwords can use them.

You now have: a study that accepts a response only when it arrives with a valid, unused password.

5

Share your VerifyYou link, not your form link

Two links to keep straight. In VerifyYou, set the destination for verified people to the access link from cell G5. Then the link you hand out to respondents is the study link from VerifyYou, never your Google Form link.Anyone who opens the raw form link skips the check, so only ever share the VerifyYou link, in your panel, your sample provider, or your invite email.

You now have: a fielded study where everyone who reaches your questions came through the check. That’s the whole setup.

Your respondent goes straight from the check into your survey with nothing to click. The survey runs inside the access link’s own page, so the address bar keeps saying script.google.com while they answer. Underneath the form there is a small “Survey not loading? Open it in a new page” line, for the rare case where a form will not display nested.

Test it before you field

The script starts in a safe mode where nothing is deleted. It writes what it would have done into a column called VerifyYou status in your responses sheet. Stay in that mode until all six behave.
Open your access link with ?vyt=test123 on the end. You should go straight into your survey with the code already filled in, without clicking anything. One password should now say Issued. Submit, and the status column should say verified while that password flips to Used.
Open the exact same link again. You should get the same password back, not a new one. This is what stops somebody who abandons your survey and returns from consuming two.
Open your plain form URL, leave the code box empty, and submit. The status should say REJECTED: no code.
Type any invented string into the code box and submit. The status should say REJECTED: code not in pool.
Submit once from a prefilled link, then open that same link again and submit a second time. The first should say verified. The second should say REJECTED: code already used. This is the check that proves one password cannot buy two responses, which is the whole reason the pool exists.
Rename the VerifyYou codes tab, submit anything, then rename it back. The status should say unchecked, and never verified. This one matters most: it proves that if your setup breaks, it tells you rather than quietly waving everybody through.
When all six behave, change onInvalid near the top of the script from 'FLAG' to 'DELETE' and click Save. That takes effect straight away, because the check that runs on each submission always uses your latest saved code. Deploying is a separate thing, and it is the step people lose an hour to. Anything that changes how your access link behaves goes live only when you click Deploy, then Manage deployments, then the pencil icon, then set Version to New version, then Deploy. Save the file without doing that and you will still be served the old version, and conclude the change did not work.

When something looks wrong

The script is not running. Run setUp again from the script editor.
Your codes tab is named something other than VerifyYou codes, or it is empty. Check the tab name matches exactly.
The passwords in your sheet are not the ones being handed out. Copy your list again and paste it in fresh.
It depends what you changed. onInvalid takes effect the moment you save, because the submission check always runs your latest saved code. Anything that changes how your access link behaves needs a new deployed version: Deploy, Manage deployments, the pencil icon, then Version: New version.
Your form is not displaying nested inside the access link. They can click that line to carry on, and you should tell us, because it means we should move you to the button version instead.
Your organisation’s Google administrator has switched off public web apps. You will need their help, or an account without that restriction.
Run vyPoolStatus in the script editor any time. It reports how many are unused, how many we issued that nobody submitted, and how many people spent.

Your data stays yours

Your passwords and your responses live in your Google account. What we hold is a list of verification sessions with no survey answers attached to any of them. There is no point at which we have both halves, so we could not connect a person to their answers even if we were asked to. If your ethics board asks how the two are kept apart, that is the answer, and you are welcome to point them at this page. The script makes no connections outside your Google account.

The script

Paste this whole thing into Extensions, then Apps Script, on your responses spreadsheet. The only line you ever change is onInvalid, and only when you finish testing.
HumanCheck backstop

What happens next