Build a flow

Eventlayer / Build a flow

Add events to your website

Connect your registration form to Eventlayer and issue an attendee's first ticket.

What you will build

Keep your event page and registration experience on your own website. Your form sends a request to your backend, which creates an attendee and their ticket in Eventlayer. You do not need to build ticket storage or the check-in lifecycle.

The flow you will build
  1. 01Registration form
  2. 02Your backend
  3. 03Attendee + ticket
  4. 04Confirmation

Prerequisites

  • An Eventlayer account and a website with a server-side endpoint.
  • A test event and a way to store registration records in your application.
  • Node.js with TypeScript support for the SDK examples.

For a paid event, use the payment guide before issuing the ticket. Submitting a form alone must not grant paid admission.

1. Configure the event

In Dashboard → Events → New event, enter the name, date, timezone, and venue. Open the event and review Ticket Types. Keep General Admission or create the access type you want to offer. Copy the event and ticket type IDs.

Your website can show your own event copy and design. If you want to read event details dynamically, fetch them on your server with eventlayer.events.get({ eventId: eventId }) and render only the public fields visitors need.

2. Connect your backend

Create a key under Dashboard → API Keys. Install the SDK in your backend:

npm install eventlayer

Store the following in your server environment, replacing the placeholders:

EVENTLAYER_KEY=sk_your_key
EVENTLAYER_EVENT_ID=ev_your_event
EVENTLAYER_TICKET_TYPE_ID=tt_your_ticket_type

Create a server-only module. Disable automatic retries on this client because creating resources is not an atomic, retry-safe registration transaction:

website-registration.ts · server only
import { Eventlayer } from "eventlayer";

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

export async function createAttendee(name: string, email: string) {
  const { data, error } = await eventlayer.attendees.create({
    eventId: process.env.EVENTLAYER_EVENT_ID!,
    name,
    email,
  });
  if (error) throw error;
  return data;
}

export async function issueTicket(attendeeId: string) {
  const { data, error } = await eventlayer.tickets.create({
    eventId: process.env.EVENTLAYER_EVENT_ID!,
    ticketTypeId: process.env.EVENTLAYER_TICKET_TYPE_ID!,
    attendeeId: attendeeId,
  });
  if (error) throw error;
  return data;
}

3. Add the registration form

This HTML posts to an endpoint you implement, not an Eventlayer-hosted form:

<form action="/api/register" method="post">
  <label for="name">Name</label>
  <input id="name" name="name" autocomplete="name" required maxlength="120" />
  <label for="email">Email</label>
  <input id="email" name="email" type="email" autocomplete="email" required />
  <button type="submit">Register</button>
</form>

In /api/register, validate the form again on the server. Enforce your event's capacity, registration deadline, and eligibility rules there. Add rate limiting and appropriate CSRF or origin protection; browser validation is not security. Use server-configured event and ticket type IDs, not arbitrary IDs from the form.

4. Save progress and issue the ticket

Implement this sequence in your endpoint using your database:

  1. Create or find a registration record with a stable booking ID. Enforce a unique submission key and serialize concurrent work on the same booking.
  2. If it has no attendee ID, call createAttendee(name, email) and persist the returned ID immediately.
  3. If it has no ticket ID, call issueTicket(attendeeId) and persist its ID.
  4. Redirect to a confirmation page protected by the registrant's session or a private, unguessable confirmation token. Show success only after saving the ticket.

These are separate API calls. If ticket creation fails, keep the attendee ID and resume from that step. If a request times out, the write may have succeeded: reconcile the event's attendee/ticket records before issuing again. A local duplicate-submission check alone does not solve a crash between an API write and saving its ID. Do not claim exactly-once issuance without that recovery path.

Return a friendly failure message to the browser and log the SDK error's requestId on your server. Do not expose credentials or raw infrastructure errors. Do not automatically retry the entire registration flow on every failure.

Test and recover

  1. Register with a test name and email. Confirm one attendee and one assigned ticket appear under the event in the dashboard.
  2. Submit again using the same booking key. Your endpoint should return the existing confirmation, not create another ticket.
  3. Try an invalid email and an ineligible booking. Neither should issue a ticket.
  4. Simulate a ticket API failure after attendee creation. Confirm your saved registration retains the attendee ID and can resume safely.
  5. Visit another person's confirmation URL without authorization. Access should fail.

Next steps

Offer an Apple Wallet pass, send a confirmation email, or record registration in your CRM. Each builds on the ticket ID you saved here.