Skip to main content

Event Check-in & Anonymous Identifiers

This document describes the event check-in system, anonymous registration flows, and how anonymous identifiers are used across the platform.

Check-in System Overview

The check-in system supports three primary flows:

Logged-in self check-in

Users with accounts check in from the event page or via token link

Token-based check-in

Anyone with a valid check-in token (QR code or link) can access check-in

Anonymous pick-your-registration

Unauthenticated users with a token search and select their registration to check in

Check-in Settings

Events can configure check-in behavior via checkInSettings:

Check-in Token

Each event with check-in enabled has a checkInToken — a secret hex string used to gate check-in access. The token is:
  • Included in QR codes and check-in links (e.g. /check-in/:eventId/:token)
  • Required for anonymous flows — self-registrations and anonymous check-in endpoints validate the token
  • Not exposed to unauthenticated users except via the check-in URL (e.g. from QR scan)

Check-in Flows

1. Logged-in Self Check-in (no token)

Route: Event page → Check In button
Endpoint: POST /events/:eventId/check-in/self
Auth: Required (verifyToken)
  • User must be logged in
  • No token needed
  • Uses req.user.userId to find/create attendee
  • Validates event time and requireRegistration if set

2. Logged-in Token Check-in

Route: /check-in/:eventId/:token
Endpoint: POST /events/:eventId/check-in
Body: { token }
Auth: Optional (verifyTokenOptional)
  • User is logged in and has the token in the URL
  • Token validates access
  • Same logic as self check-in but with token validation

3. Anonymous Pick-Your-Registration

Route: /check-in/:eventId/:token (user not logged in)
Endpoints:
  • GET /events/:eventId/check-in/self-registrations?token=xxx — list registrations
  • GET /events/:eventId/check-in/registration/:formResponseId?token=xxx — form details
  • POST /events/:eventId/check-in/anonymous — check in by userId or formResponseId
    Auth: None (token validates)
Flow:
  1. User opens check-in link (from QR or event page) with token
  2. Frontend fetches registrations via self-registrations
  3. User searches by name/email and selects their registration
  4. User can “View details” to see their full registration form (anonymous only)
  5. User clicks “Check In” → POST /events/:eventId/check-in/anonymous with { token, formResponseId } or { token, userId }
Anonymous check-in is not locked to the browser. Users can register on one device and check in on another — they only need the token and to find their name in the list.

4. Manual Check-in (Organizer)

Endpoints:
  • POST /events/:eventId/check-in/:userId — check in logged-in attendee
  • POST /events/:eventId/check-in/by-form-response/:responseId — check in anonymous attendee
Auth: Required (verifyToken) + event management permission Organizers use the Event Dashboard Check-in tab to search and manually check in attendees.

Anonymous Registration

FormResponse Model

Anonymous registrations are stored as FormResponse documents with submittedBy: null:

Browser localStorage (anonymousRegistrationStorage)

The frontend uses meridian-anonymous-registrations in localStorage to track when the current browser has registered for an event without an account. Purpose:
  • Show “You are registered” on the event page
  • Verify with server that registration still exists (GET /events/:eventId/check-anonymous-registration?guestEmail=...)
  • Support “Add another registration” — allow multiple anonymous registrations per event from the same browser
Storage shape:
Key functions:
  • hasAnonymousRegistration(eventId) — whether this browser has a stored registration
  • getAnonymousRegistration(eventId) — get stored details
  • saveAnonymousRegistration(eventId, { guestName, guestEmail }) — save after successful registration
  • removeAnonymousRegistration(eventId) — clear when server says registration no longer exists
  • getAllAnonymousRegistrations() — for claim API
localStorage is browser-scoped. It does not gate check-in. Users can check in from any device with the token — the list comes from the server, not localStorage.

Claim Anonymous Registrations

When a user signs up or logs in, the frontend calls POST /claim-anonymous-registrations with { registrations: [ { eventId, guestEmail } ] }. For each matching anonymous FormResponse (same event, submittedBy: null, email match), the backend:
  1. Sets submittedBy to the user’s ID
  2. Updates guestName/guestEmail from the user account if the form collects them
  3. Adds the user to event.attendees if not already present
This links previously anonymous registrations to the new account.

Anonymous Identifiers (Analytics)

Separate from event registration, the analytics platform uses an anonymous_id for tracking events before and after login: See Analytics Platform for the analytics envelope and anonymous_id usage.

API Reference

Public Check-in (token required, no auth)

Authenticated Check-in

Organizer / Management

Anonymous Registration Verification


Frontend Components


Event dashboard

Event management, readiness, and organizer tooling around the same events.

Event management API

REST paths for RSVPs, agendas, and org-event operations used by check-in flows.

Beacon events

Event lifecycle, approvals, and RSVP from the Beacon product lens.

Platform analytics

Event pipeline, envelope schema, and anonymous_id–friendly tracking.

Analytics collected events

Named events and properties emitted by web and mobile clients.

Atlas messaging

Announcements and anonymous recipients tied to event outreach.