← back to the pad

VTAP REST API

Tap your phone, take your itinerary with you

PythonFlaskpySerialNFC hardware

Built
September – October 2025
Status
In use on kiosk hardware
Stack
Python, Flask, pySerial, python-dotenv
Code
Private — happy to walk through it

Problem

A visitor stands at a kiosk and builds an itinerary — the places they want to see, in the order they want to see them. Then they need to take it with them, because an itinerary stuck on a screen in a lobby is no use to anyone.

The standard answer is a QR code, and the standard answer barely works. Scanning one means getting your phone out, opening the right app, framing the code, and deciding to trust the link — four chances to give up. Adoption was low enough that people were walking away from the kiosk without the thing they had just spent five minutes making.

A VTAP reader removes all four steps: tap the phone, the link opens. But the reader is configured over a serial cable with ASCII commands, which is fine if you set one URL and walk away. Here every visitor needs a different one, changing as they build their plan — and the kiosk application has no business opening a COM port to make that happen.

Solution

A small Flask service that owns the serial port and exposes it as something any application can call. The kiosk builds an itinerary URL for this visitor, posts it, and the next tap hands over exactly that.

Worth noting

Splitting it into a library, a CLI, and a service was the decision that paid off. The same change_url() is what the CLI calls and what the endpoint calls, so testing the hardware and testing the integration are never testing two different code paths.

It also means diagnosing a problem on site starts with one command against the reader, instead of trying to work out whether the kiosk app or the hardware is the one lying to you.