A publishable key serves one portal — the same identity realm and the same catalog as that portal’s hosted site. A buyer who signs in on your storefront and on the hosted portal is the same account, with the same registrations and orders.
Two keys, two shapes
The two are mutually exclusive on the wire: a publishable key on
/v1 answers the same 401 as an invalid key, and a secret key on /storefront/v1 does too.
A leaked publishable key can read the published catalog, place rate-limited orders, and trigger rate-limited OTP emails — nothing more. It cannot read anyone’s account (that takes a proven inbox), see numeric availability, or touch the Developer API. Revoking it works like revoking any key: immediately.
Setup
1
Create a publishable key
On the API keys page choose Publishable key, pick the portal it serves (your Business Unit’s own portal by default) and list the origins your site runs on —
https://tickets.your-site.com, one per line (http://localhost:… is fine for development). The key appears in full in the list, any time — there is no one-time secret ceremony, because the key is public.2
Publish the portal
The key serves traffic only while its portal is published — that is the one go-live switch, even if you never use the hosted portal pages. An unpublished portal answers
412 with an explanation.3
Call from the browser
Attendee sign-in — OTP by the platform
Your site gets accounts without owning any auth. The platform emails the code and issues the session:- The answer to
/auth/otpis identical for known and unknown addresses — an account exists the moment its inbox is proven, so there is nothing to enumerate. Codes last 10 minutes, allow 5 attempts, and re-sending is throttled to once a minute per address. - The token (
oat_…) is the person’s session on this portal: 30 days on a Business Unit portal, 12 hours on a standalone event’s. Keep it in memory or storage your frontend controls;POST /auth/logoutrevokes it server-side. - Wrong, expired, spent and over-guessed codes are all the same refusal — which one it was is not the guesser’s information.
The account area
Behind the token, four reads power a complete “my tickets” page:Catalog and checkout
The catalog is the hosted portal’s, shape for shape:GET /events lists the portal’s published events, GET /events/{publicId} answers everything a sales page needs — ticket types (soldOut is a boolean, never a count), add-ons, bundles, the open agenda, speakers, published registration forms. Hidden ticket types are absent; GET /events/{publicId}/redemption-codes/lookup?code= is the one road to them, and every invalid code answers the same 404.
The sale window is public information: on-sale types carry opensAt/closesAt, and upcomingTicketTypes lists types announced but not yet on sale — name, price, perks, and the opensAt instant your countdown ticks toward. Announcement is all it is: placing an order for an upcoming type still refuses until the window opens.
Checkout is the same three steps as everywhere on the platform — place, confirm, poll — now callable from the page itself:
email in the body is all it takes, exactly like the hosted portal. A buyer already registered is acknowledged with alreadyRegistered: true, never sold a second seat. Return URLs must be absolute https (plain http allowed on localhost).
Interactive reference
The surface describes itself:$BASE/storefront/openapi.json is the full OpenAPI 3.1 document and $BASE/storefront/docs the try-it reference. Every endpoint also has a page in the Storefront endpoints group in this site’s sidebar. Date versioning works exactly as on the Developer API: the key pins its creation-time version, Orriven-Version overrides per request.
Rules to know
- Never numbers. This surface answers
soldOut: true/falseand nothing else about capacity. Live counts belong to the Developer API’savailability, behind the secret key. - 404, not 403. A draft event, another portal’s event and a nonexistent id are indistinguishable from this side.
- Rate limits protect the mailer. OTP requests are limited per key and per visitor IP on top of the per-address throttle; order-number reads carry the hosted portal’s own per-IP wall.
- Storefront traffic is request-logged, not audited. Calls appear in the console’s developer log for debugging, but OTP requests and checkouts are the buyer’s actions and do not enter the organization audit log. Automations still fire on fulfilment exactly as always.
Related
API keys
Creating publishable keys and managing their origins.
Headless checkout (secret key)
The server-side flow — for when you do run a backend.