Skip to main content
This walkthrough builds a custom public event page (your own marketing site, an embedded widget on a partner site, a printable poster) that reads from Orgo without requiring visitors to log in. It uses only public endpoints — no Api-Token, no JWT. Who is this for: marketing teams that own a custom landing page outside Orgo’s stock event-page template, partner organizations that want to embed Orgo events on their site, or event-aggregator integrations.

What’s public, what’s not

Anything visitor-facing is in the public set. Anything that mutates the event itself requires auth.

Prerequisites

The event must be:
  • status: PUBLISHED
  • isPublic: true
Anonymous reads return 404 for draft or non-public events. This is intentional — the public surface only exposes what the admin has chosen to share.

Step 1 — Fetch event details

Response:
attendeeCount and maxCapacity are the inputs for rendering a “87 of 200 seats taken” indicator. Everything else is straightforward — render as you like.

Step 2 — Check live availability

attendeeCount from Step 1 is correct at fetch time, but stale within seconds on busy events. For real-time availability:
Call this on render and whenever the page is brought back into focus. For sold-out events, show “join waitlist” instead of the registration form (see WaitlistEntry).

Step 3 — Hold tickets while the buyer fills the form

For paid events, hold tickets the moment the buyer starts filling the form — otherwise two people could submit checkout at the same time and only one’s payment succeeds.
Response:
Holds expire after 15 minutes. If the buyer abandons the form, the hold releases automatically and the seats are returned to the pool. You can release explicitly:

Step 4 — Save attendee details

Once the buyer fills in the form (name, email, ticket-type selection), submit:
For free events, you can skip the hold step entirely and call save-attendees directly — the seat reservation happens here in one shot.

Step 5 — Take payment (paid events only)

The save-attendees response includes a Stripe checkout URL. Redirect the buyer:
For free events, save-attendees completes the registration immediately — no checkout step. Each attendee gets a QR code by email. For paid events, Stripe redirects back to your success_url configured on the checkout session (or Orgo’s default attendee-confirmation page). At that point the ProductPayment is SUCCESS and you can finalize:
The complete call cross-checks the Stripe session, confirms attendance, sends the confirmation email + QR code, and returns the attendee IDs.

Step 6 — Show “thanks for registering” with the QR

After completion, fetch the attendee record to render the QR code (or the email contains a deep link to a public view):
The hash is unique per attendee and is in the confirmation email link. Show this on a “your ticket” page they can save or screenshot.

Showing capacity and time-zone correctly

dateTimeBegin and dateTimeEnd are ISO 8601 timestamps in UTC. The event also includes timezone (an IANA name like America/New_York). Render the date in the event’s timezone (it’s an in-person event), not the visitor’s:

Adding to-calendar buttons

Build .ics manually from the public event data. Don’t link to a hosted Orgo .ics — there’s no public endpoint for it; visitors building their own client are expected to generate locally:

Common gotchas

Cache the event details (Step 1) for ~5 minutes. Never cache availability (Step 2) — call it fresh on every render. The capacity number can change second-to-second.
Browser JS pop-up blockers can swallow the window.location redirect to Stripe. Use a server-side redirect (302) instead of client-side window.location = checkoutUrl. Or use a regular <a href> link styled as a button.
For paid events, attendance is PENDING until payment completes via /complete. The admin UI hides pending until they pay (or filters them under “abandoned carts”). Wait for the event_attend.updated webhook with status: NEW to know the registration is confirmed.
Each attendee gets a magic-link in their confirmation email. The link uses X-Contact-Hash auth (see Authentication) and gives access to the attendee’s own record only. Build a public page that consumes those endpoints if you want a self-service “update my details” surface.

What to do next