Ulsav Docs
Check-in

Credentials

What a Participant QR contains, how versions invalidate old codes, and how personal links differ

Every Participant holds a credential, and that credential is what a QR encodes. It is a signed value, not a database lookup key: the server can verify it before touching a row. This page explains what is inside it, when it stops working, and how a personal link differs from the QR itself.

  • Form

    Signed static token

    Starts with ulsav1_

  • Contains

    Kind, id, version

    No name, email, or Event

  • Stored

    Never

    Derived from a server secret on demand

  • Changes on

    Claim or removal

    The version goes up

  • Personal link

    Separate token

    Also versioned, and turned off on claim

  • Works offline

    No

    The scanner always submits online

What is inside the QR

The token carries three things and a signature:

PartMeaning
KindParticipant or Account
IdThe Participant or Account identifier
VersionA counter that starts at 1
SignatureA truncated HMAC over the first three parts

The value is rendered on demand from a server secret. A database leak yields no usable credential, because the token is never stored.

The scanner checks the signature first. A random QR, a competitor's QR, or a hand-edited value fails before any lookup.

Static means shareable

The Participant credential does not rotate on a timer. It is the same value until the version changes.

That makes it work on paper, in a screenshot, and in an email. It also means a screenshot can be forwarded. Ulsav's protection is the duplicate rule: the first successful online check-in wins, and a second presentation at the same session returns Already Checked In with the original time and operator.

The scanner's "This QR code has expired" message is a client-side check for scanned values that carry a timestamp. A normal Participant QR carries none, so a printed pass does not expire on its own.

When a credential stops working

The version is the switch. Two actions increase it:

  • A Participant claims the place with an Account.
  • A Participant is removed.

Claiming increases both the QR version and the link version, and turns the personal link off. Removing increases the QR version and disables the link. Any older QR or link then fails as an invalid credential.

There is no separate rotate button

The organizer product does not expose a rotate or revoke action. A credential changes when the person claims the place or is removed. If you need to invalidate a shared screenshot without removing the person, there is no supported path today.

When the QR is shown

A Participant page renders a QR only when the Registration is confirmed, the personal form is submitted, and the person has a name. A pending entry or an incomplete place shows the outstanding steps instead.

This is deliberate. A draft or pending Registration never hands out a working pass, and a guest place cannot arrive before its details are done.

The buyer receives a link per unclaimed Participant after confirmation. The link is a bearer URL, not the QR value.

Opening it shows the current Participant details, the personal form when it is still open, and the QR. The link cannot see the Order, change the roster, or manage money.

The link has its own version. A claim turns it off, and a removal invalidates it. The buyer cannot regenerate a guest link after the person claims the place.

The Account QR

A scanner also accepts an Account credential. It resolves the Account, then finds the Participants this session would accept.

Candidates foundResult
NoneNo Accepted Pass
Exactly oneThat person is checked in
More than oneThe operator chooses from a list

The candidate list only includes people this session admits. An Account credential does not expose unrelated Event history, and an unclaimed guest place does not resolve through it.

Account QR codes are a scanner capability. The participant-facing pages show the per-Participant QR, so in practice most doors see the personal code.

Manual lookup is not a credential

Typing an email, phone, or name is a search, not a credential check. It can return no match or several matches, and the operator resolves it.

A successful manual admission is recorded with the manual method. A failed lookup is still recorded as an attempt, so an operator can explain why someone was sent to the help desk.

Privacy

Only a fingerprint of the presented value is stored on the attempt. Raw QR values, personal links, and secrets are not written to the attempt log or to application logs.

The fingerprint is a one-way hash with a prefix. It is enough to tell two presentations apart and useless for reconstructing the pass.

Failure paths

  • A QR from a cancelled entry. The scan finds the person but the Registration is cancelled, so the result is Registration Cancelled.
  • A QR from a replaced person. The old Participant is removed and its version bumped, so the old code is an invalid credential.
  • A QR for another Event's Pass. The session does not accept that Pass, so the result is Pass Not Accepted.
  • A QR after a claim. The old QR and the old link both fail; the person should use their Account or the page they now see.
  • A printed pass at a second session. It works. Sessions are independent, so a main gate and a meal counter both admit.

On this page