---
title: "Authentication and environments"
description: "Keep secret keys on your server, use the keyless buyer SDK, and separate test, live, staging, and production traffic."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.seatlayer.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication and environments

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

| Surface | Credential | Capability |
|---|---|---|
| Buyer SDK | Event key; no account secret | Render, subscribe, select, hold, release |
| 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.

```js title="server/seatlayer-request.js"
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,
    },
  });
}
```

> **Never ship a secret key to a client**
>
> Do not put `sk_…` in browser bundles, mobile applications, public environment variables, page source, analytics, logs, or screenshots. Anyone who obtains it may perform server-authorized operations for your account.

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:

### Test

`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`.
### Live

`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.

```json title="403 response"
{
  "error": "mode_mismatch"
}
```

A test key cannot act on a live event, and a live key cannot act on a sandbox event. 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 authorization boundary.
- 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 needs an event key, not an account secret:

```js title="browser/picker.js"
const picker = new seatlayer.SeatPicker({
  container: "#picker",
  event: "ev_9f3a",
});

await picker.render();
```

Public buyer routes are rate-limited and intentionally limited to buyer-safe operations. Booking is unavailable without a server secret.

The SDK currently accepts a `publicKey` option for forward compatibility, but it is not required for runtime requests and does not grant additional authority.

## 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](/buyer-sdk/install) or start the [Quickstart](/start/quickstart).

Source: https://docs.seatlayer.io/start/authentication/index.mdx
