Documentation

Customer events

Customer-facing event browse, ticket purchase, transfer, check-in, and session participation on /client/events/*.

The customer events API at /client/events/* is what an event-attendee app calls — browse events, buy tickets, transfer them, check in, and access session content. It's separate from the CRM events module, which handles internal appointment scheduling and service-queue flows. This module is for customer-facing ticketed events.

Browse events

GET/client/eventsJWT
GET/client/events/:eventIdJWT
GET/client/events/:eventId/ticket-typesJWT
GET/client/events/:eventId/sessionsJWT
GET/client/events/:eventId/scheduleJWT

Standard browse. ticket-types returns available tiers (general, VIP, early bird) with pricing and availability. sessions and schedule cover multi-session events (conferences) — sessions are individual talks/workshops within an event.

Ticket purchase

POST/client/events/tickets/purchaseJWT
POST/client/events/tickets/confirm-orderJWT

Two-step flow. purchase creates a pending ticket order and a payment intent. confirm-order finalises after payment succeeds.

// Step 1: create order
const { orderId, paymentIntentSecret } = await fetch(
  '/api/client/events/tickets/purchase',
  {
    method: 'POST',
    headers: { orgid: ORG_ID, Authorization: `Bearer ${customerJwt}` },
    body: JSON.stringify({
      eventId: 'evt-spring-2026',
      tickets: [
        { ticketTypeId: 'tt-vip', quantity: 2 },
      ],
    }),
  },
).then(r => r.json());

// Step 2: confirm payment with Stripe Elements

// Step 3: confirm order
await fetch('/api/client/events/tickets/confirm-order', {
  method: 'POST',
  headers: { orgid: ORG_ID, Authorization: `Bearer ${customerJwt}` },
  body: JSON.stringify({ orderId }),
});

Stripe / checkout

GET/client/events/stripe/configJWT
POST/client/events/stripe/intentJWT
POST/client/events/stripe/checkout-sessionJWT

The events module uses Stripe directly for ticket payments rather than going through the storefront. stripe/config returns the publishable key for client-side init. stripe/intent is the embedded-Elements path; stripe/checkout-session is the hosted-checkout path.

My tickets

GET/client/events/tickets/mineJWT
GET/client/events/tickets/:ticketIdJWT
GET/client/events/tickets/:ticketId/qrJWT
GET/client/events/tickets/:ticketId/perksJWT

tickets/mine returns every ticket the customer owns across all events. qr returns the QR code for entry — what the customer shows at the door. perks returns ticket-tier-specific benefits (VIP lounge access, free drink voucher).

Transfer a ticket

POST/client/events/tickets/:ticketId/transferJWT

Transfer the ticket to another email. The recipient receives a claim email; once claimed, the ticket moves to their account. Transfers don't refund — money stays with the original buyer.

Registration

POST/client/events/tickets/registerJWT

For free events or RSVPs without payment. Creates a ticket in confirmed state without going through the payment flow.

Bookings

GET/client/events/bookingJWT

Returns the customer's reservations across all events — used for an "upcoming events" dashboard widget.

Sessions and participation

GET/client/events/:eventId/participantsJWT
GET/client/events/participation/mineJWT
PUT/client/events/participation/:participantId/respondJWT

For multi-session events, customers select which sessions they'll attend. participation/mine returns the customer's session selections; respond accepts/declines an organiser-issued participation invite.

Media

GET/client/events/:eventId/mediaJWT
GET/client/events/:eventId/media/guest/:guestIdJWT
POST/client/events/:eventId/media/uploadJWT
POST/client/events/:eventId/media/upload/:guestIdJWT

Event galleries — attendees upload photos, view others'. The guest/:guestId variant lets non-account holders upload via an invite token (used for wedding photos and similar).

Check-in

Check-in happens through the staff side — POST /events/check-in/:ticketId (see standalone events module). Customers check in by showing the QR code; the staff scanner calls the staff endpoint. Customers don't have a self-service check-in endpoint to prevent ticket fraud.

Tickets are first-class records in the data layer. After purchase, they live in the ticket collection with the customer's sk as the owner. Custom logic (post-event surveys, badge issuance) wires through the Automation module listening for ticket events.