Skip to main content

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.

Two more attributes are required today

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>
AttributeRequiredWhat it is
data-publishable-keyyesThe channel's tlpk_ key. Without it the loader does nothing.
data-api-urlyesThe Live API base URL. The loader logs an error and stops without it.
data-checkout-basein practiceWhere the hosted checkout is served. Defaults to your own page origin, which has no checkout, so set it.
data-elements-urlon stagingThe Elements bundle. Defaults to the production CDN, so staging needs it spelled out.
data-elementsno"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.

Which packages are on npm today

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.

Self-serve sign-up is planned, not built

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

  1. The page loads the Live SDK, which creates nothing until the customer acts: browsing uses the publishable key alone.
  2. 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.
  3. 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.
  4. On success the SDK emits checkout:completed with 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.
  5. Your server hears about it through webhooks (order.confirmed, ticket.issued).

Keep going