Skip to content

Authentication and environments

Keep secret keys on your server, choose public or scoped Buyer SDK access, and separate test, live, staging, and production traffic.

Updated View as Markdown

SeatLayer has two authentication contexts because the buyer and your backend have different authority.

Surface Credential Capability
Managed public/unlisted Buyer SDK Event key Anonymous Public-sale render, select, hold, release
Platform/SDK Public sale Event key + pk_test_… or pk_live_… Direct, origin-bound Public-sale bootstrap
Private/login/presale/channel Buyer SDK Event key + short-lived bse_… Only the audience scope your backend granted
Server API sk_test_… or sk_live_… Inspect holds, book, manage inventory, provision resources, report

Secret keys belong on your server

Create keys in the dashboard and store the secret immediately—the complete value is shown once.

server/seatlayer-request.jsjs
export async function seatlayerRequest(path, init = {}) {
  return fetch(`https://api.seatlayer.io${path}`, {
    ...init,
    headers: {
      authorization: `Bearer ${process.env.SEATLAYER_SECRET_KEY}`,
      "content-type": "application/json",
      ...init.headers,
    },
  });
}

Use your deployment platform’s encrypted server-secret mechanism. Fail startup or the server operation clearly when the variable is missing; do not silently fall back to a client credential.

Test and live mode

Every secret key has one immutable mode:

sk_test_… creates and manages sandbox events. Sandbox holds, conflicts, realtime updates, and webhooks behave like production, but bookings consume no credits and payloads carry livemode: false.

sk_live_… creates and manages live inventory. Real bookings consume credits and payloads carry livemode: true.

An event inherits the mode of the key that creates it. Mode cannot be changed later.

403 responsejson
{
  "error": "mode_mismatch"
}

A test key cannot act on a live event, and a live key cannot act on a sandbox event. Secret-key event lists are filtered to the key’s mode; dashboard sessions list both modes. A list with no matching events returns 200 and an empty events array. Direct same-organization access to an opposite-mode event returns the 403 mode_mismatch response above. Build the complete journey with a test key, then create real events using a live key.

Environment routing

A key may also carry an environment tag such as dev, staging, or prod.

  • Events inherit the creating key’s environment.
  • Webhook subscriptions can filter delivery by environment.
  • Environment is routing metadata, not an event, tenant, or workspace authorization boundary.
  • On webhook management routes, an environment-tagged key can manage only subscriptions in that routing scope.
  • An unset subscription environment behaves as a wildcard.

Recommended setup:

Application environment SeatLayer key Event mode Webhook route
Local/CI Dedicated test key Test Test receiver or fixture
Staging Staging test key Test Staging endpoint
Production Production live key Live Production endpoint

Do not use an environment tag as proof of tenant or workspace ownership.

Buyer SDK authentication

The Buyer SDK never receives an account secret. For an ordinary Public-sale Platform event, give it the event key and the publishable half of your API key:

browser/public-picker.jsjs
const picker = new seatlayer.SeatPicker({
  container: "#picker",
  event: "ev_9f3a",
  publicKey: "pk_test_…",
});

await picker.render();

On first render, the SDK sends the public key directly to SeatLayer and repeats that bootstrap only when its in-memory session needs renewal. SeatLayer verifies that the key belongs to the event, its test/live mode matches, and the browser’s exact origin is registered for the account. A successful bootstrap returns a Public-sale-only bse_… bearer together with the chart and compact inventory status. The SDK keeps the bearer in memory and reuses it for holds, assets, and live updates. A public key is publishable, but it is not buyer identity and can never reveal private channel inventory or authorize booking.

For a login, presale, partner, or other private audience, use an explicit buyer access token provider backed by your authenticated server:

browser/picker.jsjs
const picker = new seatlayer.SeatPicker({
  container: "#picker",
  event: "ev_9f3a",
  buyerAccessTokenProvider: async ({ reason }) => {
    const response = await fetch("/api/seatlayer/buyer-access", {
      method: "POST",
      credentials: "same-origin",
      cache: "no-store",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ reason }),
    });
    if (!response.ok) throw new Error("Unable to open seat selection");
    return response.json();
  },
});

await picker.render();

buyerAccessTokenProvider and buyerAccessToken always take precedence over publicKey. This lets one integration keep the public key in its normal embed while switching known buyers onto deliberately scoped inventory without any anonymous fallback.

Browser buyer routes are rate-limited and intentionally limited to buyer-safe operations. The audience token can read/select only its event scope and cannot book; permanent booking remains unavailable without a server secret.

Browser-scoped session tokens

Three credentials exist that are neither a secret key nor an event key. They are bound to one origin, short lived, revocable, and stored only as hashes — SeatLayer cannot read them back out of its own database. Your trusted backend requests dse_…, mse_…, and private-audience bse_… sessions with sk_…. The Public-sale SDK bootstrap is the narrow exception: SeatLayer creates a Public-only bse_… after validating the publishable key and registered origin.

Prefix What it authorizes Issued through
mse_ An operator in the embedded control room, limited to an explicit capability list POST /v1/events/:key/manage-sessions
dse_ A designer in the embedded chart editor POST /v1/designer/sessions
bse_ A buyer on one event; either Public-only bootstrap or an explicit sales-channel scope Direct SDK bootstrap for Public sale, or POST /v1/events/:key/buyer-access-sessions for scoped audiences

mse_ and bse_ are not interchangeable, and neither is a weaker secret key. An operator token grants organizer capabilities on an event; a buyer token grants nothing but the right to see and select a particular audience’s inventory. A buyer token can never book — booking stays with your server.

Send a buyer token as Authorization: Bearer bse_… on buyer routes after bootstrap. The SDK handles that header. A Platform/SDK Public-sale embed obtains its token directly with publicKey; private/login/presale/channel inventory still requires a token/provider backed by your server. Omitting both from a Platform event returns the same 404 as an unknown event. Managed public/unlisted events retain their anonymous Public-sale flow. Sending a bad token is always an error, never a downgrade: an expired, revoked, wrong-origin, or wrong-event token fails with a specific code rather than quietly becoming an anonymous shopper.

Rotation checklist

  • Create the replacement key in the same mode and environment.
  • Store it in the server secret manager.
  • Deploy the backend using the replacement.
  • Exercise an authenticated read or sandbox booking.
  • Confirm relevant webhook routing.
  • Revoke the old key after traffic has moved.
  • Investigate logs if rotation followed suspected exposure.

Common mistakes

  • Using a PUBLIC_, NEXT_PUBLIC_, or VITE_ environment variable for the secret.
  • Creating a live event during staging tests.
  • Assuming the visible key prefix is the enforcement mechanism.
  • Treating an environment or externalRef as tenant authorization.
  • Logging the complete Authorization header during request debugging.

Continue to Install the Buyer SDK or start the Quickstart.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close