The elements on your page talk to Live, Live holds the channel's publishable key, and a customer token escalates the Live session without ever reaching the browser.
The common case. Your page loads @ticketlayer/live (or the CDN loader) with
a publishable key, the elements talk to Live, and Live holds
the credentials. The page itself never sends a key on a request.
The credential. Live authenticates every call to the Backstage API with
the channel's publishable key (tlpk_, low trust), held at the edge on
behalf of the browser session. The channel is the key's, so nothing
names it. When the buyer signs in, the customer token is kept in the Live
session and never handed to the browser: it escalates the session; the
publishable key still authenticates.
GET /sales/listings to Live. Live forwards it under the channel key it holds for the session.
tlpk_, held by Live; the channel is the key's
Make an order
POST /sales/carts, add items, POST /sales/carts/{id}/checkout, then POST /sales/orders/{id}/payments. The browser sends its X-Live-Session; Live forwards under the key. The queue gate sits in front of Live when the on-sale is gated.
tlpk_, held by Live
Authenticate a customer
POST /sales/customer-auth/magic-link emails a 15 minute code; POST /sales/customer-tokens with { type: "magic_link", code } exchanges it. Live stores the customer token in the session at the edge.
tlpk_ authenticates; the customer token is carried on top
Read the order back
GET /sales/orders/{id} when the session holds an order access token for it, or GET /sales/my-orders once the session has been escalated with a customer token.
The browser never sees a key. The elements talk to Live over a session,
Live talks to the Backstage API under the key. A page that is a partner's
site builder, a marketing site or a static export all work the same way.
The low-trust surface leaks nothing by construction. Every /sales/*
response is a declared view, so what a buyer can see is a matter of what
the view names, not of what a handler remembered to strip.
Live is the only way in.GET /sales/listings on Live is relayed to
the same operation on the Backstage API, which serves it to Live alone: a
page, an app or a partner's server calls Live.
The customer token is an escalation, never a login. There is no
customer principal. A request for a buyer's orders that carries no
customer token is refused with CUSTOMER_TOKEN_REQUIRED, and identity is
read from the verified token, never from the request body.
Checkout on your page is hosted: the cart hands the session to the hosted
box office's /embed/checkout in an iframe, which collects payment on its
own origin. Sell tickets on your website
walks through the page; the HTML,
Vite and Next.js
quickstarts are the code.