Build a flow

Eventlayer / Build a flow

Build a check-in app

Connect a staff lookup or scanner interface to Eventlayer's atomic ticket check-in.

What you will build

Build a small staff interface that looks up a ticket and asks your backend to check it in. Eventlayer validates the ticket lifecycle and records admission; your application handles staff access, the interface, and any scanner hardware.

The flow you will build
  1. 01Staff scanner
  2. 02Your backend
  3. 03Check-in API
  4. 04Admit / explain

Prerequisites

  • A test event with an active ticket type and assigned, disposable tickets.
  • An authenticated staff page and a backend with your Eventlayer API key.
  • Optional barcode-scanning software. Start with ticket-ID lookup to test the flow.

Check-in is one-time and cannot be reversed. Use fresh test tickets, not real attendee admissions. This flow requires an online connection; it does not implement offline validation or repeated entry on one ticket.

1. Configure the door's access rules

Save the event ID and allowed ticket type IDs for each entry point in your backend. A VIP label does not automatically grant workshop access. Use separate tickets for separate admissions when that is your event model.

Authenticate staff and authorize them for the selected event before processing any lookup or check-in. Keep the API key on the server, never in a browser, mobile bundle, or scanner.

2. Add a ticket lookup screen

Create a form with a labelled ticket-ID field and a lookup button. Your backend fetches the ticket, its ticket type, and, if assigned, its attendee. Show the attendee name, access type, and current status so staff can confirm the admission.

You can add scanning later to populate the same lookup. Inspect your configured Wallet barcode format and decode only the supported payload into a ticket ID; do not assume every barcode is a raw ID or navigate to arbitrary scanned URLs. Treat scanned content as untrusted input and revalidate it on your server.

3. Validate scope and request check-in

Here is the core server-side operation. eventId and allowedTypeIds must come from your authorized door configuration, not be accepted blindly from the scanner.

check-in.ts · server only
import { Eventlayer } from "eventlayer";

const eventlayer = new Eventlayer(process.env.EVENTLAYER_KEY!, { maxRetries: 0 });

// Authenticate and authorize staff before calling this function.
export async function admitTicket(
  ticketId: string,
  eventId: string,
  allowedTypeIds: string[],
) {
  const ticket = await eventlayer.tickets.get({ ticketId: ticketId });
  if (ticket.error) throw ticket.error;
  const type = await eventlayer.ticketTypes.get({
    ticketTypeId: ticket.data.ticket_type_id,
  });
  if (type.error) throw type.error;
  if (
    type.data.event_id !== eventId ||
    !allowedTypeIds.includes(type.data.id)
  ) {
    return { admitted: false, message: "Not valid at this entry point" };
  }

  const result = await eventlayer.tickets.checkIn({ ticketId: ticketId });
  if (result.error) {
    if (result.error.code === "TICKET_ALREADY_CHECKED_IN") {
      return {
        admitted: false,
        message: "Already checked in — ask staff to review",
      };
    }
    throw result.error;
  }
  return { admitted: true, message: "Checked in", ticket: result.data };
}

The check-in API, not your earlier lookup, is authoritative about whether the ticket can transition. It requires an assigned ticket and an active ticket type. Two door devices may look up the same valid ticket; only one can complete its first check-in. Don't show success just because a lookup said "assigned".

4. Handle the result at the door

Show a distinct success state only when admitted is true. Give already-used, wrong-event, unavailable, and invalid-ticket results a clear non-success state. Log request IDs server-side for unexpected API errors without leaking credentials or attendee data into public logs.

If the network drops, show "Check-in result unknown" rather than approving entry or automatically issuing a replacement. Re-fetch the ticket and let staff reconcile the result. A ticket now marked checked-in could have been admitted by another device, so it is not proof that this attempt succeeded.

Test and recover

  1. Look up a fresh assigned ticket and confirm the displayed attendee and type.
  2. Check it in. Confirm a success state and checked_in in the dashboard.
  3. Try it again. Show "already checked in", not another success.
  4. Try a ticket from another event or a disallowed type. Reject it before admission.
  5. Try an unassigned ticket and one with an inactive type. Neither should be admitted.
  6. Submit one fresh ticket from two devices simultaneously. Only one should succeed.
  7. Simulate a lost response. Confirm the interface uses the unknown-result recovery path.

Next steps

Subscribe to ticket.checked_in to update your CRM and schedule a follow-up email. Neither integration should block the door's check-in response.