Skip to content
Ultimate Software Solutions

Check-in

The code is dead before it reaches the car park.

A member opens the app and it draws a fresh QR. Sixty seconds later that code is refused, everywhere, including at the desk it was made for. Screenshot it and send it to a friend and the friend gets turned away — not by a staff member making a judgement call, by the server declining an expired signature.

01 / The code

Four values and a deadline

It is not a picture of a member number. It is a signed token, and the four things inside it are the four things the desk needs to decide.

The app asks the server for a code. The server builds a JSON Web Token, signs it with its own key, and stamps it to expire sixty seconds from that moment. The app renders that string as a QR.

Nothing about the code is guessable and nothing about it is durable. A member cannot make one for somebody else, because the signature is the server's. A member cannot bank one for later, because the clock is inside the token rather than inside the app.

The two gym ids matter more than they look. home_fc_id is where the membership lives. scan_fc_id is the gym the code was asked for. When those differ, the desk is looking at a visiting member and the software knows to check All-Access rules instead of ordinary ones.

The signature is checked, not the picture. A photograph of a valid QR is a valid QR — for the rest of its sixty seconds. This stops a code being shared on a group chat and reused all week. It does not stop somebody standing next to the scanner at that exact moment. Nothing short of a fingerprint does, which is why most gyms run both.

What is inside the token

customer_id
The member record
cust_user_id
The login behind it
home_fc_id
Where the membership lives
scan_fc_id
Where the code was asked for
exp
Issued time plus 60 seconds
Signature
HS256, server key
60s then refused
Drawn here, not photographed. A screenshot of the real screen with its timer running is on the list of assets we have asked the owner for.

02 / The scan

What happens in the two seconds at the desk

Five checks, in this order. Any one of them failing is a refusal with a reason on the screen, not a silent nothing.

  1. The app asks for a code

    One call, one token, sixty seconds on the clock. The same response tells the app how many All-Access sessions the member has left, so the member sees that on the same screen as the code rather than finding out at a strange gym's counter.

  2. The desk scans it

    Staff hit one endpoint with the scanned string. There is no shared secret in the scanner and nothing to configure per till.

  3. The signature and the clock are checked first

    A token that has been edited fails the signature. A token older than sixty seconds fails the clock. Both are refused before the member is looked up at all.

  4. The member's own row is locked

    Two staff double-tapping the same code, or a phone retrying on a bad connection, would otherwise write two attendance rows. The check-in takes a database lock on that member's profile, so the second attempt reads the first one and stops. One check-in per member per gym per day, and the second gets told the member is already in.

  5. If it is not their gym, All-Access rules apply

    The scanning gym has to be switched on for visiting members, the member's plan has to have sessions left, and one session is consumed per day per gym — not per scan. An audit row records which gym used which session, so the settlement between branches is a report rather than an argument.

03 / How much of this has actually happened

Counted off the production database, 23 August 2026

These are queries, not estimates, and they cover every check-in path together — QR, gym code, fingerprint, face and card. Ask us to run them again in front of you.

12,370,692

member check-ins recorded since December 2023

1,529,290

of them in the last thirty days

191

fitness centres that checked somebody in during the last ninety days

305

fitness centres on the platform in total, busy and quiet alike

We are showing you both centre numbers on purpose. 305 is everyone with an account. 191 is everyone who put a real person through a door in the last quarter. The second number is the one that means anything, and most software companies only print the first.

04 / When the camera will not play

Three ways in, and what each one costs you

Bad light, a cracked lens, a member who left their phone in the car. The QR is the good path, not the only one.

Member-side check-in paths, and the limit on each.
Path What the member does The honest limit
Dynamic QR Opens the app, holds up the code, staff scan it Sixty seconds of life. Needs a working camera at the desk.
Gym code Types the gym's short code into their own app No scanner involved, so nobody at the desk sees it happen. The same All-Access rules, session deduction and once-a-day rule still apply.
Open the gate from the app Presses a button; the command is queued onto the gym's terminals At their own gym, no location check. At a partner gym, their phone's GPS has to be within 150 metres of the pinned address or it is refused.

All three write to the same attendance table, so the footfall report does not care which one a member used.

05 / The part nobody advertises

Your internet goes down. Does an expired member get in?

On most systems, yes. Blocking an expired member is a command sent to the door terminal, and if the terminal cannot reach the server there is no command. Two terminals in our own fleet sat offline for two and three weeks with hundreds of queued commands behind them. For those weeks, expired members walked in.

The fix is to stop sending the block and send the calendar instead. When a membership is sold or renewed, the member's start and end dates are written into the terminal itself, in advance. On the expiry date the terminal refuses the finger on its own, with nothing plugged in and nobody watching. A renewal re-opens the window the same way.

Verified live on 18 August 2026 against a ZAM180-NF50VA running push firmware 2.0.33S: the window was accepted, and a re-read of the device's own roster confirmed it had stuck.

The validity window

Sent
When a plan is sold, renewed or expires
Carries
Start date, end date, enforce flag
Enforced by
The terminal, offline
Cleared by
A renewal, which reopens the window
This one is opt-in and you should know that before you buy. The validity window belongs to the newer check-in path, where eSSL and ZKTeco terminals talk to us directly instead of through a middleware service. That path is switched off for every gym by default and has to be enabled per gym. Ask us on the call whether your hardware is on it. If it is not, expiry is still enforced — but only while the terminal can reach us.

Bring the awkward question

The demo is a screen share on live software, not a slide deck. Ask us to generate a code and let it die on camera. Ask what happens when the internet drops. We will answer with the screen, or we will tell you it is not built.

Or email crm.sales@proultimate.com directly.