Skip to main content

Tickets

Once an event has dates and a location, you set up the ticket SKUs people will buy. The schema models four distinct concepts here that often get conflated — keep them straight:

  • TicketSpecification — the SKU. "Member ticket — 250 DKK". You configure these.
  • EventTicket — one purchased ticket. Created when someone buys.
  • BuyOrder — the cart-like order that produced one or more tickets. Tracks payment state.
  • EventTicketHolder — the buyer (a platform user) — surfaced for this event by the ticketHolders query.

Plus inspectors, who validate tickets at the gate.

TicketSpecification​

Fields:

  • id, name, description.
  • price — in øre / cents (i.e. 25000 = 250 DKK). Type NonNegativeInt (a non-negative integer scalar).
  • includeVat — resolver field; true when VAT is included in the price (currently any non-zero VAT means "included with 25%").
  • ticketPlatFormFee, ticketPercentageFee, percentageFeeAmount — Unioo's platform fees.
  • numberOfTicketsForSale — quota for this SKU (or null for unlimited).
  • maximumNumberOfTicketsPerUser — per-buyer cap.
  • numberOfTicketsSold — resolver field; live count of sold tickets for this spec.
  • isActive — whether this SKU is currently for sale.

Validation on create / edit:

  • price (when set and non-zero) must be >= 1000 (minimum 10 DKK).
  • numberOfTicketsForSale must be >= maximumNumberOfTicketsPerUser if both are set.
  • editTicketSpecification only works while the spec is inactive and the event is draft. Once you flip isActive: true (via editTicketSpecificationActiveState), prices and quotas freeze.
  • removeTicketSpecification requires no tickets sold/reserved against the spec.

Adding the first paid ticket specification (price > 0) automatically enables the organization's billing profile for events.

EventTicket and EventTicketDate​

A purchased ticket. Fields:

  • id, purchaseDate.
  • ticketSpecification — back-reference to the SKU.
  • eventDates — [EventTicketDate!] — one entry per date the ticket grants access to. Each carries id, isRedeemed, timeOfRedemption, redeemedBy (the inspector who scanned).
  • isRefunded, isRefundInProgress.

BuyOrder​

Wraps the purchase. Fields:

  • id, state (Pending, Paid, Expired), comment.
  • created, expires — pending orders auto-expire if not paid in time.
  • eventId, eventTickets, tickets.
  • chargeSessionId — the payment processor session ID.
  • ticketHolder — reference back to the EventTicketHolder.

tickets and eventTickets distinguish the line items the buyer requested (eventTickets: [BuyOrderEventTicketItem!] — { id, ticketSpecificationId, ticketSpecification, amount }) from the actual ticket rows issued (tickets: [EventTicket!]). For paid orders these align; pending orders only have line items.

EventTicketHolder​

The buyer-side projection — one row per platform user who's purchased at least one ticket for the event. Fields: id, issueTime, userId, user, tickets, buyOrders. Buy orders are filterable by state.

User exposes name, email, phone, and an avatar URL. See Querying ticket holders for the full projection.

TicketInspector (interface)​

Someone authorized to validate (scan) tickets. Two concrete types:

  • ExternalTicketInspector — a one-off person not on the board (e.g. door staff). Created with a name, email, phoneNumber.
  • BoardMemberTicketInspectorType — a board member, identified at create time by an internal boardMemberId. The server pulls name/email/phone from the linked board-member's user record automatically.

Common fields exposed on the interface: id, name, email, phoneNumber.

Note: boardMemberId refers to an internal Administrator record — not the same thing as a Member you see in the members query. The administrator IDs are managed in the Unioo platform; you'll need to obtain them through the platform UI or a separate channel before you can call addTicketInspector with type: BoardMember. For typical integrations, prefer external inspectors with explicit name/email/phone unless you have a workflow that produces the administrator ID.

You can't remove a ticket inspector who has already checked in tickets — the server rejects with Cannot remove ticket inspector, who has already checked-in tickets.

Where to query / mutate​