Never expose an sk_… secret key to a browser. After your backend authorizes the
signed-in user, ask SeatLayer to mint a short-lived embed session for exactly the
chart editor or event operator surface that user may open.
| Token | Surface | Resource scope | Authorization scope |
|---|---|---|---|
dse_… |
Embedded Designer | One workspace and chart | read-only, edit, or publish |
mse_… |
SeatManager control room | One event | Explicit event capabilities |
Both tokens are bound to an exact browser origin, returned only when created, stored by SeatLayer as hashes, expire automatically, and can be revoked.
BrowserRequests an allowed surface
Your application identifies the signed-in user and the chart or Event they may open.
Your backendAuthorizes the request
It decides the resource, allowed origin, authority, and expiry before making a SeatLayer call.
SeatLayerMints one scoped session
Your server uses its secret key to receive a short-lived dse_ or mse_ token after authorization succeeds.
Your backendReturns only the session
The browser receives the scoped token and expiry, never the account secret key.
BrowserUses scoped operations
The embedded surface works only from the exact allowed origin and within its issued authority.
Shared rules
expiresInSeconds: 300–14,400; default 3,600.allowedOrigin: exact HTTPS origin, with no path, query, fragment, username, or password.- Development allows
http://localhostandhttp://127.0.0.1. - Mint responses carry
Cache-Control: no-store. - Never log a raw token or token-bearing Designer URL.
- Revoking a session invalidates the credential without deleting the chart or changing event inventory.
Buyer bse_… credentials use a separate contract and expiry range. Ordinary
Platform Public sale uses direct publicKey bootstrap; scoped private audiences
use the buyer access session endpoint.
Designer session
/v1/designer/sessionsSecret keycurl -sX POST "https://api.seatlayer.io/v1/designer/sessions" \
-H "authorization: Bearer $SEATLAYER_SECRET_KEY" \
-H "content-type: application/json" \
-d '{
"workspaceId": "ws_organizer_42",
"chartId": "chart_main_hall",
"allowedOrigin": "https://admin.example.com",
"authority": "edit",
"mode": "safe",
"safeModeOptions": {
"allowDeletingObjects": false,
"allowEditingAreaCapacity": false
},
"expiresInSeconds": 3600
}'Designer authority
| Authority | Read | Save draft | Publish |
|---|---|---|---|
read-only |
Yes | No | No |
edit |
Yes | Yes | No |
publish |
Yes | Yes | Yes |
Prefer authority. Legacy canPublish remains compatible, but do not send
conflicting values. When neither is supplied, the session has edit authority.
mode: "safe" restricts destructive editing for a delegated organizer. Its
options can independently allow object deletion or area-capacity edits.
Feature policy can further limit the public Designer feature set; treat the
session response as the effective policy.
The response includes:
{
"session": {
"id": "dsess_1f0e",
"token": "dse_9c1b",
"workspaceId": "ws_organizer_42",
"chartId": "chart_main_hall",
"allowedOrigin": "https://admin.example.com",
"authority": "edit",
"canEdit": true,
"canPublish": false,
"mode": "safe",
"expiresAt": 1767207600000,
"designerUrl": "https://app.seatlayer.io/embed/designer#token=dse_9c1b"
}
}The token is in the URL fragment, so it is not sent as part of the iframe’s initial HTTP request.
Start before the click
The server trust boundary is required; a browser must never receive sk_… or
mint its own dse_…. The extra wait on the final click is not required. Once the
host has authenticated the user and resolved their chart and role, it can start
the no-store session request on route intent or page load while the SDK and
editor shell load. A server-rendered authenticated page may instead include the
short-lived designerUrl in a no-store bootstrap. Keep it in memory, mount it as
soon as the SDK is ready, and revoke it when access ends.
/v1/designer/sessions/:idSecret keyManage session
/v1/events/:key/manage-sessionsSecret key or authorized dashboard sessioncurl -sX POST \
"https://api.seatlayer.io/v1/events/ev_9f3a/manage-sessions" \
-H "authorization: Bearer $SEATLAYER_SECRET_KEY" \
-H "content-type: application/json" \
-d '{
"allowedOrigin": "https://admin.example.com",
"capabilities": ["event:view", "event:block"],
"expiresInSeconds": 3600
}'| Capability | Allows |
|---|---|
event:view |
Live board, section rules, and checkout-window reads |
event:block |
Block/unblock, section availability, and hold-TTL writes |
event:categories:manage |
Event-only object category assignments; reusable chart and existing price snapshots stay unchanged |
event:tables:manage |
Event-only table booking-mode changes for free inventory |
event:cancel |
Booking-reference-guarded cancellation |
event:reports |
Inventory report, CSV, audit log, and configured booked-value projection |
event:channels:view |
Channel inventory, allocation, audit, preview, and channel-report reads |
event:channels:manage |
Channel lifecycle, assignments, and hosted access-link management |
event:orders:read |
Managed Ticketing Order, CSV, detail, and timeline reads |
event:refund |
Managed Ticketing gateway refund |
event:tickets:send |
Managed Ticketing ticket resend |
event:door:view |
Door preflight, attendance, and attendance CSV |
event:door:checkin |
Door check-in mutation |
event:boxoffice |
Managed Ticketing counter inventory and sale |
Omitting capabilities is accepted for compatibility and grants only
event:view. It never grants a mutation, cancellation, report, channel, or
Managed Ticketing capability. Send the smallest explicit non-empty list whenever
the operator needs more than the live read-only board. Empty, null, malformed,
or unknown capability values are rejected.
Managed Ticketing capabilities are available only on a Managed Ticketing event.
Channel and commerce grants remain independent: for example, event:boxoffice
does not allow a token to cross a private allocation without the separately
granted event:channels:manage capability.
/v1/events/:key/manage-sessions/:idSecret keyThe event key in the revoke path is part of the authorization scope. A session
can be revoked only under its exact event. Another event or organization returns
404; a same-organization key in the wrong live/test mode returns
403 mode_mismatch.
Rotate long-running sessions
For SeatManager, pass tokenExpiresAt and onTokenRefresh. Ask SeatLayer for
the replacement from your backend with the same event, origin, and capabilities,
then return {token, expiresAt}. The SDK swaps it without rebuilding the board.
For EmbeddedDesigner, implement onRequestRelaunch, ask SeatLayer for a fresh
Designer session from your backend, and call setDesignerUrl(). Automatic
renewal uses the expiry reported by the embedded app.
Backend session-endpoint pattern
Your own session route must check before it asks SeatLayer to mint:
- the user is authenticated;
- the user belongs to the host tenant;
- the stored SeatLayer workspace/event belongs to that tenant;
- requested authority or capabilities match the user’s role;
- the requested origin is on your allowlist.
Return only the scoped session response. Keep SEATLAYER_SECRET_KEY in the
server runtime.
Continue to embedded Designer or embedded control room.