Sell tickets on your website
One script tag or one npm install puts an event list, a buy button and a hosted checkout on any site. Here is the snippet, the packages, and where the key comes from.
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_..."
data-api-url="https://live.ticketlayer.com"
data-checkout-base="https://checkout.ticketlayer.com"
data-elements-url="https://cdn.ticketlayer.com/elements/v1/ticketlayer-elements/ticketlayer-elements.esm.js"></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.
:::caution Why the loader takes more than a key
The loader reads its configuration from data-* attributes on the script tag
(packages/live/src/auto.ts in ticketlayer/live). It assumes no environment:
data-api-url has no default and data-checkout-base falls back to your own
page origin, so a working embed names both. The snippet above is the whole
configuration.
| 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 | no | The Elements bundle. Defaults to the production CDN; name it to pin a build or to load the bundle from elsewhere. |
data-elements | no | "false" skips loading Elements when you bundle them yourself. |
| ::: |
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.ticketlayer.com',
publishableKey: 'tlpk_...',
checkout: { mode: 'modal', embedBaseUrl: 'https://checkout.ticketlayer.com' },
});
// 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.
:::note Package versions
All four packages are on the public npm registry: @ticketlayer/live,
@ticketlayer/elements, @ticketlayer/elements-react and
@ticketlayer/backstage (the management API client). The CDN build serves the
same Elements bundle for pages with no build step. npm view @ticketlayer/live version is the answer for which version is current; this page does not
restate it.
:::
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. A secret key (tlsk_) names the same channel
and may be held only on a server; the two differ by where they may be held,
not by what they sell. Both are shown once.
:::info Signing up gives you a key and something to sell
Self-service signup is built (POST /v1/signup on the Backstage API). It
creates your organisation in test mode with a website sales channel, a
publishable key marked tlpk_test_, a sandbox payment provider that settles
test orders without touching a network, and a sample event that is genuinely
buyable - on sale, priced, with inventory, and listed on that channel, so it
appears in GET /sales/listings for the key you were handed. The console is
Backstage, at backstage.ticketlayer.com.
:::
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.