Skip to content
Last updated

Working with dynamic QR code access

Intro

Use case description of how to use the customer access code endpoint to generate dynamic, rotating QR codes for secure gym entry via the Open API.

The access code model:

  • A single GET endpoint returns a short-lived access code per customer.
  • The response contains a content string to be rendered as a QR code, a format descriptor, and an expiresAt timestamp.
  • Codes are dynamic: each call returns a fresh code, and the previous code expires at the time indicated in expiresAt.
  • Depending on the studio's access control configuration, a code may also be invalidated immediately after a successful check-in.

Relevant Endpoints

Dynamic QR code access

The access code endpoint enables partners to build secure, dynamic QR code check-in screens in member-facing apps. The code is not static — it rotates on a schedule and is tied to a single customer, making it unsuitable for sharing or copying.

Core behavior:

  • Each response returns a content string that must be rendered as a QR code using a client-side library. The format field will be QR_CODE.
  • expiresAt is an ISO 8601 date-time string indicating when the current code becomes invalid. This is used to drive countdown timers and auto-refresh logic.
  • Required scope: CUSTOMER_READ.
  • The endpoint takes a single path parameter: customerId (int64).

Recommended use cases:

  • QR code check-in screen in a member app or web portal
  • Kiosk check-in where the app fetches a code for an attended session
  • Any integration requiring time-limited, per-member access credentials

Display and refresh flow

1. Fetch the access code

When the user opens the check-in screen, call GET /v1/customers/{customerId}/access-code.

Use this to:

  • obtain the content string to render as a QR code
  • read expiresAt to start a countdown timer in the UI
  • determine the format — currently always QR_CODE

2. Render the QR code

Pass the content value to a QR code generation library to produce a scannable image.

Use this to:

  • display the QR code as the primary check-in element
  • pair it with a visible countdown so the member knows when to expect a refresh

Best practice:

  • do not display the raw content string to users; render only the visual QR code
  • refresh the display immediately once a new code is fetched, not before the request completes

3. Handle expiry and auto-refresh

Monitor the expiresAt timestamp client-side and trigger a new GET request before the code expires.

Use this to:

  • ensure the member always has a valid code when they reach the turnstile
  • avoid situations where the user is left with an expired code during peak entry times

Best practice:

  • refresh proactively — fetch a new code a few seconds before expiresAt, not after, to account for network latency
  • if expiresAt is absent from the response, apply a conservative fallback refresh interval

4. Handle post-check-in invalidation

Some studio configurations invalidate the code immediately after a successful scan, regardless of expiresAt.

Use this to:

  • detect that a code has been used and prompt the user to fetch a new one if they need to re-enter
  • avoid showing a stale code that will be rejected at the gate on subsequent attempts

Complete workflow examples

Note: The payload examples below are integration-oriented drafts. Validate all field names and structures against the current OpenAPI schema before publishing or implementation.

Example: Display QR code on check-in screen

Scenario: Member opens the app's check-in screen. The app fetches a fresh access code and displays the QR code with a countdown.

  1. User navigates to check-in screen
  2. App calls GET /v1/customers/{customerId}/access-code
  3. App renders content as QR code and starts countdown using expiresAt
  4. When countdown reaches ~5 seconds remaining, app calls the endpoint again
  5. New content replaces the displayed QR code seamlessly

Example GET response shape (illustrative):

{
  "format": "QR_CODE",
  "expiresAt": "2024-06-13T10:33:00Z",
  "content": "0049267681211943991"
}

Common integration challenges

  • Rendering content as plain text: The content value is an opaque string that must be passed to a QR code library. Displaying it as text makes it unreadable at the gate.
  • No expiry handling: Ignoring expiresAt and showing a static code will result in entry failures once the code expires. Always implement timer-driven refresh.
  • Refresh after expiry instead of before: Fetching a new code only after expiresAt has passed means the user faces a brief gap with no valid code. Trigger the refresh a few seconds early.
  • Missing fallback for absent expiresAt: The field is optional in the schema. If it is not present, implement a conservative refresh interval rather than assuming the code is indefinitely valid.
  • Fetching on each render: Calling the endpoint every time the screen is drawn (e.g., on every component mount or page navigation) creates unnecessary load. Fetch once on entry and manage refresh via the timer pattern.

Access code webhook events

Check-in events are triggered when a customer successfully scans their QR code at the gate. Subscribe to these to track entry activity and build real-time dashboards or push notifications.

Event reference: