Width.ai

QR Code for a Google Form: How to Make One, and What to Do After the Scan | n8n workflows

Width.ai
·
September 20, 2026

Making a QR code for a Google Form takes about thirty seconds. Copy the form's share link, paste it into any free generator, download the image, print it. People scan it, the form opens, responses arrive in your spreadsheet. For collecting responses this is a solved problem, and it works exactly as well as it sounds like it should.

Then somebody uses the same trick for event check-in, and thirty seconds of setup meets a door. A staff member scans a ticket. The phone thinks for a moment and shows a page that says the response has been recorded. The attendee is standing there waiting. The queue is standing behind the attendee. And nobody on that door knows whether the ticket was real, whether it was refunded last Tuesday, or whether somebody walked in twenty minutes ago holding a screenshot of the same code.

That is not a setup mistake. A form submission confirms receipt, not validity. The form's job ends the moment the answer is written down, and every check worth running happens afterwards, in a spreadsheet nobody at the door is looking at. The scan and the verdict end up in two different places, and only one of them is at the door.

So there are two jobs here and only one of them is hard. Making the code is a paragraph, and it is the next section. Making the scan answer back, on the same phone, inside the two seconds a queue will tolerate, with something a staff member can act on, is everything after that. There is a working n8n workflow for it that you can import.

Key Takeaways

  • A QR code for a Google Form is an encoded URL and nothing more, so no generator produces a better one than another. Free tools are fine.
  • Collecting responses and checking credentials are different jobs. The first needs a form. The second needs a verdict returned to the person holding the scanner.
  • A confirmation page cannot tell door staff anything useful, because validation runs after the submission has already been accepted.
  • Ticket sharing is caught by history, not by the code itself. Without a scan log, a screenshot of an already-admitted ticket passes every time.
  • The workflow below returns a full-screen VALID, ALREADY USED, INVALID or NOT ALLOWED page to the scanning phone, checked against a Google Sheet, with no ticketing hardware.
  
    ✂️ Definition    

What is a QR code for a Google Form?

    

A QR code for a Google Form is a scannable image that encodes the form's share link, so that pointing a phone camera at it opens the form. Because the code contains only a URL, any generator produces an identical result, and the code itself carries no information about who scanned it or whether they were allowed to. Anything beyond opening the form, such as validating a ticket, checking for duplicate entries or showing a pass or fail result to the person scanning, has to be handled by a workflow behind the form rather than by the QR code.

  

Diagram of an n8n QR ticket check-in workflow showing the scan, validation against Google Sheets, logging, and the four result paths

How to Make a QR Code for a Google Form

Four steps, none of which need a paid tool.

  • Open the form, click Send, choose the link icon, tick Shorten URL, and copy the address.
  • Paste it into any QR code generator. The output encodes that URL and nothing else, so the generators are interchangeable for this purpose.
  • Download it as a PNG for screens or an SVG for anything printed larger than a postcard, since the SVG stays sharp at poster size.
  • Print it at final size and scan it from where people will actually be standing, which is the only test that matters.

Three things go wrong often enough to be worth naming. Do not run the link through a second shortener, because two redirects is one more thing that can fail and the code is already as small as it needs to be. Check the form's access setting, because a form restricted to your organization sends everyone outside it to a login wall, which reads as a broken code to the person scanning. And give the code quiet space around it, since contrast and margin matter more than size for a reliable scan.

That is the whole of the easy half. Everything below is about what happens next.

What Happens After the Scan Is the Actual Problem

A form is built to accept answers. Used as a check-in scanner it does that faithfully, which is the problem, because accepting an answer and approving an entry are not the same act. Four things break, in roughly the order they will hurt you.

Staff see a receipt, not a verdict. The confirmation page is identical for a valid ticket, a fabricated code, and one that was refunded on Tuesday. The person on the door has to either wave everybody through or go and look at a spreadsheet between scans, and at a real door they will do the first one.

Nothing checks history. A QR code is a string. It does not get consumed by being scanned, and a screenshot of it forwards perfectly over any messaging app. Catching a reused ticket means comparing this scan against every previous scan, which is a lookup the form never performs.

Nothing checks the ticket's own rules. Cancelled, refunded, valid only on Saturday, general admission trying to enter a VIP area. All of that lives in your participant sheet as columns nobody is reading at the moment of entry.

There is one door and one rule set. A main entrance and a VIP area need different answers for the same ticket, and a single form submission has no idea which door it came from.

Each of these is fixable. None of them is fixable inside the form, because all four need something to happen between the scan and the screen.

A Real Check-In System: What It Takes

The workflow below runs on n8n and uses an n8n form rather than a Google Form for one reason: the form submission and the page that comes back are the same workflow run, so the result of the lookup can be rendered onto the phone that did the scanning. Everything else stays where it already is. The participant list is a Google Sheet, the scan log is a Google Sheet, and the hardware is whatever Android phones your staff already carry.

  

At a glance

  

What the check-in workflow runs on

                                                                                                                                                                                                                                                                                                    
Triggern8n form submission, one per scan
ScanningAny Android phone with a keyboard scanner app, such as Scan to Web
Results shown to staffValid, Already used, Invalid, Not allowed
Participant databaseGoogle Sheets
Scan logGoogle Sheets, columns created automatically
Ticket rulesBlocked statuses, valid dates, area access by ticket type, each optional
AlertsGmail, on already used, invalid and not allowed scans
CheckpointsAny number, set with a link parameter
AINone
CredentialsGoogle Sheets, Gmail

n8n workflow canvas for a QR ticket check-in system with action items and trigger

Step 1: Receive the Scan

Two nodes, and the second one exists entirely because of how scanner apps behave.

Ticket Scanner. A mobile-friendly form at /form/ticket-scanner with one required QR code field and a Check Ticket button. A hidden checkpoint field is filled from the link, so appending ?checkpoint=VIP%20Area to the URL is all it takes to turn one phone into a different door.

Clean Scan. Keyboard scanner apps frequently append a trailing space or a line break to what they type, and a code with an invisible character on the end matches nothing. This node trims that, records the checkpoint, defaulting to Main Entrance when the link carried none, and stamps the scan time and date in the workflow's time zone.

The time zone detail matters more than it looks. Scan dates drive both the valid-date rules and the duplicate checks, so a workflow running in the wrong zone will start rejecting tickets a few hours before or after midnight and nowhere else, which is a miserable thing to debug at an event.

Step 2: Validate the Ticket

Three nodes: two reads and the decision.

Read Participant Database pulls your master participant sheet. Date cells are read as serial numbers rather than formatted strings, so valid-date rules behave the same whether the sheet was created in a US or European locale.

Read Scan Results pulls the scan log once, for duplicate checking. An empty sheet is fine and the workflow carries on, which is what happens on the first scan of the day.

Validate Ticket finds the scanned code and decides the outcome. It checks in a fixed order and stops at the first match, which is what makes the result predictable.

  

Validate Ticket

  

Checks run in this order and stop at the first match

                                                                                                                                                            
1INVALIDThe code is not in the participant sheet, or nothing was scanned
2REJECTEDThe ticket exists but breaks a rule: blocked status, wrong date, or wrong area
3ALREADY_USEDThe ticket already has a valid scan at the same checkpoint on the same day
4VALIDNone of the above applies
  

A cancelled ticket presented twice reports the cancellation, not the duplicate, because that is the reason that ends the conversation at the door fastest.

The order is a design decision worth keeping. A cancelled ticket presented twice reports the cancellation rather than the duplicate, because the reason staff need to give at the door is the one that stops the argument fastest.

Ticket Rules Are Optional Columns

Each rule only runs if its column exists in your participant sheet, so the system starts as a plain does-this-code-exist check and gains strictness as you add columns.

STATUS

Rejects tickets marked cancelled, canceled, refunded or void, ignoring case

VALID_DATES

Rejects the ticket on any other day. A date cell, or text such as 2026-09-14, 2026-09-15 for multi-day passes

TICKET_TYPE

At checkpoints listed in CHECKPOINT_ACCESS, rejects types that are not allowed there. Unlisted checkpoints admit everyone

  

Ticket rules

  

Each rule only runs if its column exists in your sheet

                                                                                                
STATUSRejects tickets marked cancelled, canceled, refunded or void, ignoring case
VALID_DATESRejects the ticket on any other day. A date cell, or text such as 2026-09-14, 2026-09-15 for multi-day passes
TICKET_TYPEAt checkpoints listed in CHECKPOINT_ACCESS, rejects types that are not allowed there. Unlisted checkpoints admit everyone
  

With none of these columns present the system is a plain does-this-code-exist check. It gains strictness as you add them.

Why Duplicates Are Scoped Per Checkpoint, Per Day

A naive duplicate check marks a ticket used forever the first time it is seen, which breaks the two most common ticket types you sell. A multi-day pass has to work again tomorrow. A VIP ticket has to scan at the main entrance and then again at the VIP door twenty minutes later. Scoping the check to the same checkpoint on the same day handles both without any extra configuration, and still catches the thing you are actually worried about, which is the same code entering the same door twice.

Step 3: Log and Route

Log Scan appends the scan to the Scan Results sheet. Values are written exactly as given rather than being interpreted, which keeps codes like 00123 from losing their leading zeros and keeps dates as dates. That matters because this sheet is the input to tomorrow's duplicate checks, so a value that gets mangled on the way in stops matching on the way out. New columns are added automatically, so there is nothing to set up beyond an empty tab.

Route by Status sends the scan down one of four paths. Everything after this point is about telling a human what happened.

Every logged row carries the scan time, the scan date used for duplicate checks, the checkpoint, the ticket code, the status, a reason, the attendee's name where the ticket was found, and every column from the participant sheet. The reason field is the one to care about: it holds text like Ticket is cancelled or First scanned at 2026-09-14 09:12:00, which is what turns the log into something you can settle a dispute with after the event.

Step 4: Show the Result and Alert

Four full-screen pages, colour-coded so a staff member reads them at arm's length without focusing.

Valid

Green page with the attendee's name and the checkpoint

Already used

Amber page with the attendee's name and when the ticket was first scanned

Invalid

Red page with the scanned code

Not allowed

Red page with the attendee's name and the rule that blocked entry

  

What staff see

  

Four full-screen results, readable at arm's length

                                                                                                                            
ValidGreen page with the attendee's name and the checkpoint
Already usedAmber page with the attendee's name and when the ticket was first scanned
InvalidRed page with the scanned code
Not allowedRed page with the attendee's name and the rule that blocked entry
  

Every page carries a Scan next ticket link that returns to the scanner form at the same checkpoint.

Each page carries a Scan next ticket link that returns to the scanner form at the same checkpoint, so a staff member never has to retype a URL or remember which door they are on.

Send Alert emails the result, reason, code, attendee, checkpoint and time for already used, invalid and not allowed scans. It runs before the result page and is set to continue on error, which is the important part: if Gmail is slow or the credential has expired, the door still gets its answer. An alerting failure should never become an entry failure.

Setting It Up

Import the workflow, then work through these in order. Budget half an hour the first time.

  • Prepare the participant sheet. Only the ticket code column is required, and it is called TIKET by default. NAME, STATUS, VALID_DATES and TICKET_TYPE are optional, and each one switches on the matching feature. Format the ticket code column as plain text before you paste anything in, or codes with leading zeros will be silently converted to numbers.
  • Create an empty Scan Results tab. Same spreadsheet or a different one. The columns write themselves on the first scan.
  • Connect credentials. Google Sheets for Read Participant Database, Read Scan Results and Log Scan. Gmail for Send Alert.
  • Point the nodes at your sheets. Read Scan Results and Log Scan must reference the same sheet. Pointing them at different tabs is the single most common reason Already used never appears, and it fails silently because every individual node still succeeds.
  • Check the settings block. The top of the Validate Ticket code holds TICKET_COLUMN, NAME_COLUMNS, STATUS_COLUMN and BLOCKED_STATUSES, VALID_DATES_COLUMN, and TICKET_TYPE_COLUMN with CHECKPOINT_ACCESS. Change them only if your column names differ from the defaults.
  • Set the time zone. Workflow settings, Timezone. Scan dates, valid-date rules and duplicate checks all read from it.
  • Activate and build the checkpoint links. Copy the production URL from the Ticket Scanner node. The main entrance uses it unchanged, and every other door appends ?checkpoint= followed by the name, which has to match the name used in CHECKPOINT_ACCESS exactly.
  • Set up the phones. Install Scan to Web or another keyboard scanner app, open that door's link in the browser, tap the QR code field and scan. If the app can press Enter after each scan, turn it on so the form submits without a tap.

Then run three test scans before doors open: a known valid ticket, a code that does not exist, and the valid ticket a second time. Those three cover the paths staff will actually hit, and finding a problem in them takes two minutes rather than an argument in front of a queue.

One hardening step worth taking. In the Ticket Scanner node, set Authentication to Basic Auth so the scanner URL is not something an attendee can open and use to test which codes work.

The pattern holds across the workflows we publish: the interesting nodes are the ones that stop something rather than the ones that do the work. Five more of our n8n workflows are written up the same way, guards included.

Conclusion

Making a QR code for a Google Form really is a thirty-second job and nothing here changes that. The gap is between a form that records an answer and a system that returns one. If that is what you actually need, the workflow JSON and the full setup guide are both public.

Import it, point it at a sheet with ten fake tickets in it, and scan the same one twice. That takes about ten minutes and tells you more about whether this fits your event than any amount of reading will.

Need This Wired Into Your Own Stack?

Width.ai builds custom n8n and AI automation systems. This template handles a door with a spreadsheet behind it, and we extend workflows like it with your ticketing platform, your access rules, offline fallbacks and error handling that holds up on the day. Tell us what your check-in looks like now and where it breaks.

  Talk to us about your check-in →

Frequently Asked Questions

Can I use a Google Form for the scanning instead?

You can, and it will record every scan correctly. What it cannot do is show the result to the person scanning, because a Google Form's confirmation page is written before the lookup runs and has no access to the outcome. That is fine if you are collecting attendance for later analysis and nobody is being turned away. It does not work at a door where somebody has to make a decision.

What happens if the venue has no signal?

Scans fail, because every check is a live lookup against Google Sheets. Test the signal at the actual door position rather than in the lobby, and if it is unreliable, a phone on a mobile hotspot is a cheaper fix than a ticketing system. This is the real constraint on the whole approach and it is worth checking before the day.

How many scans can Google Sheets handle?

Each scan makes two reads and one write, so a busy door can reach Google's per-minute quota for one account. If you are moving thousands of people through in a short window, split checkpoints across separate Google accounts or move the participant list somewhere with a higher ceiling.

Does a screenshot of a valid ticket get in?

Once. The first scan of that code at that checkpoint on that day comes back valid, and every scan after it comes back Already used with the time of the first entry, which is the information a staff member needs to have the conversation. There is no way to tell an original from a screenshot by looking at the code, because they are the same code, so the defence is history rather than the image.