Keys and authentication
Ticketlayer has three kinds of credential. Pick by where the code runs.
| Credential | Prefix | Where it runs | What it can do | Header |
|---|---|---|---|---|
| Publishable key | tlpk_ | Browsers, mobile apps, site builders | Read what one sales channel sells, create a cart and start checkout through the Live API | Authorization: Bearer tlpk_... (or X-Channel-Key) |
| Organisation API key | tlak_ | Your server | Everything the key's scopes allow on the Backstage API: events, orders, customers, webhooks, embed sessions | Authorization: Bearer tlak_... plus X-Ticketlayer-Org: <slug> |
| Staff access token | JWT | Backstage, staff tools, MCP agents | Whatever the signed-in person's role allows | Authorization: Bearer <jwt> plus X-Ticketlayer-Org: <slug> |
A channel also has secret keys (tlsk_), server-only siblings of the
publishable key for a backend that talks to the sales surface on a customer's
behalf. They are shown once when created and must never reach a browser.
Publishable keys (browser)
The Live SDK and the CDN loader take the key once and send it on every request; you do not write the header yourself.
<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"></script>
import { createLiveClient } from '@ticketlayer/live';
const tl = await createLiveClient({ baseUrl: 'https://live.staging.t9r.dev', publishableKey: 'tlpk_...' });
Calling the Live API directly:
curl https://live.staging.t9r.dev/sales/listings \
-H "Authorization: Bearer tlpk_..."
Browsing needs nothing more. The first cart creates a Live session; the SDK
holds its id and sends it as X-Live-Session (or a cookie on a hosted
storefront). Customer sign-in is a magic link: POST /sales/customer-auth/magic-link,
then POST /sales/customer-tokens with the code; <tl-login> does both.
Where to get one: Backstage, Sales channels, the channel, Keys, Create key, Publishable (browser). Self-serve sign-up is not built yet; see Get a key.
Organisation API keys (server)
An organisation API key is created by a staff user in Backstage (or with
POST /v1/api-keys while signed in) with a name and a list of scopes such as
events.write, orders.read, saleschannels.write. The key material is
returned once.
curl https://api.staging.t9r.dev/v1/events \
-H "Authorization: Bearer tlak_..." \
-H "X-Ticketlayer-Org: your-org-slug"
With the SDK:
import { BackstageClient } from '@ticketlayer/backstage';
const backstage = new BackstageClient({
baseUrl: 'https://api.staging.t9r.dev',
accessToken: process.env.TICKETLAYER_API_KEY, // tlak_...
organisationSlug: 'your-org-slug',
});
const { events } = await backstage.events.list({ limit: '20' });
Rules the API applies to a tlak_ bearer:
- The key is looked up by hash; revoked or expired keys get
401. - The
X-Ticketlayer-Orgheader must name the key's own organisation. - Each route checks the key's scopes; a missing scope is
404, not403(the platform never confirms that something exists to a caller who cannot see it). - Routes that are for signed-in people only (
/v1/me/*,/v1/api-keys) refuse API keys.
API keys also mint embed sessions (POST /v1/embed/sessions): short-lived
tokens pinned to one account that let you mount Backstage widgets in your own
app with @ticketlayer/backstage/embed. See the Backstage SDK
getting started.
Staff tokens (Stagedoor OAuth)
People sign in through Stagedoor, Ticketlayer's identity service, with
OAuth 2.1 (authorization code + PKCE). Backstage, the box office and the
MCP server all use it. A third-party app registers a
client with Stagedoor (MCP clients do this automatically through Dynamic
Client Registration), sends the person to /oauth/authorize, and exchanges
the code for an access token that carries the organisation they chose at
login. Tokens are short-lived and refreshed with the refresh token.
The API also documents POST /v1/auth/login (email and password). It exists
for first-party tooling; integrations should use API keys for servers and
Stagedoor for people.
Environments
| Staging | Production | |
|---|---|---|
| Backstage API | https://api.staging.t9r.dev/v1 | https://api.ticketlayer.com/v1 (not yet deployed) |
| Live API | https://live.staging.t9r.dev | https://live.ticketlayer.com (not yet deployed) |
| Hosted checkout | https://hbo.staging.t9r.dev | https://checkout.ticketlayer.com (not yet deployed) |
| CDN | https://cdn.staging.t9r.dev | https://cdn.ticketlayer.com (not yet deployed) |
Staging's Backstage and Stagedoor are on the team tailnet; the API, Live API, hosted checkout and CDN are public.
Versioning
Every request may carry TL-Version: 2026-06-13 (the dated API version). The
SDKs send it for you; a request without it gets the organisation's default,
so generated code keeps working across releases. See
API versions.