Sell tickets on your website
Ticketlayer gives you three things to build with: a drop-in script that turns plain HTML tags into a ticket shop, npm packages for React and Next.js, and two APIs (Live for buyers, Backstage for management). Card details never touch your page: checkout opens in a hosted iframe.
1. The one-line embed (HTML, Webflow, Framer, any site builder)
Add the loader with your channel's publishable key, then place elements anywhere on the page:
<script src="https://cdn.ticketlayer.com/v1/ticketlayer.js"
data-publishable-key="tlpk_..."></script>
<tl-event-list columns="3"></tl-event-list>
<tl-buy-tickets-button event-id="evt_..."></tl-buy-tickets-button>
<tl-event-list> lists the events your channel sells. <tl-buy-tickets-button>
opens the buy flow (date, tickets, cart) and hands off to the hosted checkout.
Every tag is documented in the Elements reference.
The loader reads its configuration from data-* attributes on the script tag
(live-sdk/src/auto.ts). Until the production hostnames exist, the defaults
do not point anywhere useful, so a working embed against staging is:
<script src="https://cdn.staging.t9r.dev/v1/ticketlayer.js"
data-publishable-key="tlpk_..."
data-api-url="https://live.staging.t9r.dev"
data-checkout-base="https://hbo.staging.t9r.dev"
data-elements-url="https://cdn.staging.t9r.dev/elements/v1/ticketlayer-elements/ticketlayer-elements.esm.js"></script>
| Attribute | Required | What it is |
|---|---|---|
data-publishable-key | yes | The channel's tlpk_ key. Without it the loader does nothing. |
data-api-url | yes | The Live API base URL. The loader logs an error and stops without it. |
data-checkout-base | in practice | Where the hosted checkout is served. Defaults to your own page origin, which has no checkout, so set it. |
data-elements-url | on staging | The Elements bundle. Defaults to the production CDN, so staging needs it spelled out. |
data-elements | no | "false" skips loading Elements when you bundle them yourself. |
The plan is for the two URL attributes to default to production so the snippet has one attribute; that is tracked in the platform plan and not done.
The HTML quickstart is a complete page with an event list, a buy button, a cart badge and an order confirmation.
2. npm, for React, Next.js and Vite
npm install @ticketlayer/live @ticketlayer/elements @ticketlayer/elements-react
@ticketlayer/live is the buyer-facing SDK: it creates the session, owns the
cart, applies the channel theme and opens the checkout modal.
@ticketlayer/elements is the web components; @ticketlayer/elements-react
wraps them as React components with typed onTl... event props.
import { createLiveClient } from '@ticketlayer/live';
import { defineCustomElements, TlEventList, TlBuyTicketsButton } from '@ticketlayer/elements-react';
// Once, after hydration:
defineCustomElements();
await createLiveClient({
baseUrl: 'https://live.staging.t9r.dev',
publishableKey: 'tlpk_...',
checkout: { mode: 'modal', embedBaseUrl: 'https://hbo.staging.t9r.dev' },
});
// Anywhere in the tree:
<TlEventList columns={3} onTlEventClick={(e) => navigate(`/events/${e.detail.eventId}`)} />
<TlBuyTicketsButton eventId="evt_..." />
For Next.js there is a server-side client, @ticketlayer/live/server, that
reads listings and event detail in server components with no DOM and no
session. See the Next.js quickstart and the
Vite + React quickstart.
Only @ticketlayer/backstage (the management API client) is on the public
npm registry. @ticketlayer/live, @ticketlayer/elements and
@ticketlayer/elements-react are built in their repositories and publish
once their release workflows run; an npm install of them fails right now.
The CDN build is deployed and is what the quickstarts fall back to.
3. Get a key
A publishable key (tlpk_...) identifies one sales channel of your
organisation. It is safe in a browser: it can list what the channel sells,
open a cart and start a checkout, and nothing else.
Where it comes from today: in Backstage, open Sales channels, pick
the channel (or create one of type website), and under Keys create a
Publishable (browser) key. Secret keys (tlsk_) are for servers and are
shown once.
There is no public sign-up yet: organisations are created by Ticketlayer, and
Backstage on staging (backstage.staging.t9r.dev) is reachable only from the
team tailnet. If you are building against Ticketlayer now, ask the team for
an organisation and a publishable key. The planned flow (ticketlayer.com/start:
register, an organisation with a default website channel and key, a sample
event, test mode) is described in the platform plan and will replace this
paragraph when it ships.
For server-side work (creating events, reading orders, registering webhooks)
you use an organisation API key (tlak_...) with the Backstage API; see
Keys and authentication.
What happens when someone buys
- The page loads the Live SDK, which creates nothing until the customer acts: browsing uses the publishable key alone.
- The customer picks a date and tickets in the buy modal; the SDK creates a Live session and a cart (a timed reservation) on the first add.
- Checkout opens the hosted box office in an iframe modal on your page. The iframe inherits the session, so it sees the same cart, and takes payment on its own origin.
- On success the SDK emits
checkout:completedwith the order; the modal closes, and you can send the customer to a page with<tl-order-confirmation>(it reads?orderId=from the URL) or show<tl-order-tickets>inline. - Your server hears about it through webhooks
(
order.confirmed,ticket.issued).
Keep going
- HTML quickstart, Next.js quickstart, Vite + React quickstart
- Elements reference: every tag, attribute, event and theme token
- Live API and Backstage API references, and the OpenAPI documents at /openapi/live.json and /openapi/backstage.json
- Connect an AI agent to manage events from Claude Code, Cursor or Claude Desktop
- Building with an AI tool? Point it at /llms.txt.