SEATING CHART API + SDK

Seating chart API and SDKs for web and native apps.

Embed a seat picker in your web or mobile app and keep your own checkout. SeatLayer runs the seat map, seat holds, live availability and booking, from a 300-seat theatre to a 200,000-seat stadium. Start with the interactive seat map guide or the quickstart.

SeatLayer builds this seat map engine and sells tickets on it too. Already selling on Hosted Ticketing? Keep the same account and charts and add the SDK for new events. How it compares

200,000-seat stadium · 100,000-seat arena · Renderer measurements

$0to go live
100free sold seats every month
10¢ → 5¢per sold seat after that; credits never expire
$ npm install @seatlayer/js $ npm install @seatlayer/react
01 CONNECT02 HOLD03 BOOK04 WEBHOOK
■ free ■ held ■ booked
PUBLIC BROWSER → TRUSTED SERVER → SIGNED DELIVERYlocal example · ready
  • 200,000seats on one map, ready in 1.95 sOpen the stadium →
  • 100,000seats in a public arena you can tryOpen the arena →
  • 10,000buyers on one event, zero server errors
  • 9 msto hold a seat under that load (p99)

Tested on public venue files with simulated buyers, September 2026. How we measured loading · How we measured buyers · Every run on GitHub

SeatLayer owns inventory. Your product owns the customer.

  1. The picker loadsThe SDK loads the chart and live seats with your event id and public key. Your server is not involved yet.
  2. The buyer holds seatsAt checkout, onCheckout hands your server a holdId. The seats stay held while the buyer pays.
  3. Your server booksYour checkout takes payment, then books with a stable bookingRef. A signed webhook confirms the result.

Private audiences replace the public key with a buyer-access provider on your server.

import { SeatPicker } from '@seatlayer/js';

const picker = new SeatPicker({
  container: '#seat-picker',
  event: '<YOUR_EVENT_KEY>', // change this at runtime
  publicKey: '<YOUR_PUBLIC_KEY>', // publishable; public sale only
  onCheckout: async (_, __, handoff) => {
    await fetch('/api/checkout', {
      method: 'POST',
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify({ holdId: handoff.holdId }),
    });
  },
});
picker.render();

SeatPicker

Buyer surface with the map, selection, cart, tiers, and hold timer.

SeatPicker reference →

SeatingChart

Headless map for products that build their own cart, timer and controls.

Headless seating chart reference →

SeatManager

The control panel: a live board your organizers use to track and run each event in real time.

See the control panel ↓

Sales channels

Set aside exact seats for sponsors, partners, presales or the box office, each with its own access.

See the allocation workflow →

Optional 3D

Let buyers open a 3D view of the venue. Booking works the same with or without it.

See the view contract ↓

PerformanceGroupPicker

Buyers pick the same seats across every date in a run. Your checkout and tickets stay yours.

Performance Groups guide →
Embed the control panel · SDK

Embed the control panel, just like the Designer. Organizers track every seat in real time.

The control panel is a live board for each event. Add it to your admin with the SDK and your organizers watch sales, holds and blocks as they happen, and run the event without leaving your product. Each person sees only the tools you allow.

  • Real-time trackingSold, held and free seats, sales heat and live activity, updated as buyers act.
  • Block and releaseHold seats with a reason and release them at a set time.
  • Open or close sectionsClose, hide or schedule a section or zone.
  • Change this event onlyMove seats between price levels, and sell tables whole or by the chair.
  • Sales channelsSee and manage seats set aside for partners and presales.
  • Reports and auditBooking history, breakdowns, downloads and a full audit trail.

Your server decides each operator's tools; no secret key reaches the browser. Embedded control panel guide ↗

Control panel · Grand TheatreFri 7:30 PM · live
optional buyer 3Dbuyer-view.js
const picker = new SeatPicker({
  container: '#seat-picker',
  event: eventKey,
  publicKey,
  enable3D: true,
  seatView: true,
  onBuyerViewChange: ({ view, seatId }) => {
    syncBuyerRoute({ view, seatId });
  },
});

await picker.render();
syncViewToggle(picker.getBuyerView());

// Open 3D and fly to the selected seat; your route restores it.
picker.setBuyerView('venue3d', { flyToSeatId: selectedSeat.id });
RELEASED BUYER-VIEW CONTRACT

3D changes the view, not the inventory owner.

The same picker keeps the seats, selection and hold. Your app decides whether the buyer sees the map, the 3D overview or the view from one seat.

Always a fallbackTurn 3D off, or let older devices stay on the 2D map. Checkout never needs 3D.
Your routesonBuyerViewChange tells you the current view and seat, so your URL and back button keep working.
Honest viewsBuyers can tell a real venue photo from the live 3D view. A view is a guide, not a sightline guarantee.
Open the complete quickstart →

Find your seating chart package and source.

Install the official JavaScript, React, Vue, Angular or mobile package. Each entry links its registry, matching quickstart and GitHub source. Server SDKs handle trusted bookings and webhooks; REST and OpenAPI cover other backends.

Web buyer SDKs

SeatPicker, headless SeatingChart, and real-time inventory. PerformanceGroupPicker handles multi-performance runs; SeasonPicker handles published Fixed Renewable Season Plans.

STABLE
RuntimeInstallResources
JavaScript / TypeScript@seatlayer/jsnpm ↗JavaScript seat map SDK ↗GitHub ↗
React@seatlayer/reactnpm ↗React seating chart SDK ↗GitHub ↗
Vue 3@seatlayer/vuenpm ↗Vue seating chart SDK ↗GitHub ↗
Angular 17+@seatlayer/angularnpm ↗Angular seating chart SDK ↗GitHub ↗
Other web frameworks@seatlayer/js lifecycleJavaScript SDK integration ↗Source ↗

Server SDKs

Trusted provisioning, inventory inspection, booking, webhooks and operations. Every backend can use the canonical REST contract, including the published Seasons API.

SUPPORTED

Mobile buyer SDKs

Supported native and cross-platform packages for production reserved seating in mobile products.

PRODUCTION
RuntimeInstallResources
React Native@seatlayer/react-nativenpm ↗React Native seat map SDK ↗GitHub ↗
Flutterseatlayerpub.dev ↗Flutter seat map SDK ↗GitHub ↗
iOS / Swiftseatlayer-ios.git via Swift Package ManageriOS seat map SDK ↗GitHub ↗
Android / Kotlinio.seatlayer:seatlayer-android via Maven CentralMaven Central ↗Android seat map SDK ↗GitHub ↗

Start from a running app: the React and Vite example renders the headless seating chart with best available, holds and a checkout handoff, and the Next.js 15 App Router example adds an /api/hold server route. Add your event key and public key to .env.local and deploy from the README buttons.

VIEW ALL ON GITHUB ↗

Choose how much of the buyer interface you own.

From a ready-made picker to a bare map. Every level uses the same live seats and the same checkout handoff.

  1. Ready pickerShip the map, selection, cart and hold timer together.SeatPicker
  2. Custom controlsReplace buyer controls, appearance and validation messages.SeatPicker + options
  3. Composed native layoutPlace Flutter, React Native, SwiftUI or Compose controls around the shared map.Mobile SDKs
  4. Raw mapBuild your own cart, filters and checkout around lower-level selection APIs.SeatingChart

Selection rules (minimum, consecutive, no single-seat gaps) and hold recovery work at every level. Picker policies · Flutter custom layout · React Native components · JavaScript guide

Buyer WebMCP · opt-in

Let a buyer's AI assistant find seats on your map.

Turn on WebMCP in the JavaScript browser SDK and a compatible in-browser assistant can describe the event, find seats together within a budget, select them and read the selection. Holding is optional and uses the normal checkout handoff. There is no payment tool: it cannot set trusted prices or complete a booking.

Buyer agent tools ↗
  • seatlayer_describe_event
  • seatlayer_find_seats
  • seatlayer_select_seats
  • seatlayer_get_selection
  • seatlayer_hold_selectionoptional

Snapshot first. Deltas after. Trusted decisions stay server-side.

Every buyer gets a snapshot of the seats when the map opens, then live updates as others hold and buy. Holds and bookings for one event are processed in order, so two buyers can never get the same seat. Public pickers start with { event, publicKey }; booking always happens on your server with a secret sk_ key.

  • Reconnects are safeAfter a dropped connection the buyer gets a fresh snapshot, then live updates again.
  • One seat, one winnerEvery change to an event goes through one place, in order.
  • Tested under a rush30 buyers tried to hold the same seat at once: one got it, the other 29 were told it was taken.
wss://api.seatlayer.io/pub/events/ev_9f3a/subscribe
// on connect
{ "type": "snapshot", "seats": {
  "A-1": "free", "A-2": "booked",
  "C-14": "free" } }

// then, as buyers act
{ "type": "delta", "changes": [
  { "label": "C-14", "status": "held" } ] }
WSS://API.SEATLAYER.IO · SPRING GALA · SEAT C-3INTERACTIVE EXAMPLE

An illustration of how two buyers racing for one seat are handled. Read the live-inventory guide.

The seat map API: snapshot, deltas and signed webhooks

Three kinds of key, each with a clear job. The public key loads the picker in the browser. The buyer session holds and releases seats. The secret key, kept on your server, books seats and manages the event. Reuse the same bookingRef if a booking result is unknown, and it will never book twice.

credentialswho may do what
CredentialWhere it livesCanCannot
Event keyBrowser, mobile appIdentify one eventAuthorize Platform/SDK chart or inventory routes by itself
pk_test_ pk_live_Browser, mobile appWith event, bootstrap Public-sale chart and inventory for a registered origin and matching modeRead private channels, identify a buyer, inspect a hold, or book
bse_ (public bootstrap)SDK memory; minted by SeatLayerRender, subscribe, select, hold and release Public-sale inventory for one event and originPersist safely, access private channels, inspect holds, or book
bse_ (private audience)SDK memory; returned by your backend token providerExpose the exact event, origin and private channels your server authorizesBook, persist safely, or stand in for an account secret
dse_Embedded Designer; minted by your serverOpen one origin-, workspace- and chart-scoped Designer session with explicit actionsOperate SeatManager, buyer inventory or account APIs
mse_SeatManager; minted by your serverOpen one event-scoped operator surface with explicit capabilitiesOpen the Designer, book as an account, or provision resources
sk_test_Your serverEverything on sandbox events; livemode: false, no credits usedTouch a live event (403 mode_mismatch)
sk_live_Your serverInspect holds, book, block, provision, report on live eventsTouch a sandbox event
EndpointAuthDoes
POST/pub/events/:key/bootstrappublic key + OriginPublic chart + inventory + internal buyer session
WS/pub/events/:key/subscribebse_Snapshot + delta stream
POST/pub/events/:key/holdbse_Hold seats or GA atomically
POST/pub/events/:key/releasebse_Release a hold
POST/pub/events/:key/best-availablebse_Find and hold seats together
POST/v1/events/:key/booksecret keyFinalize a sale idempotently
POST/v1/events/:key/blocksecret keyBlock or unblock house seats
POST/v1/seasonssecret keyCreate a Fixed Renewable Season and immutable Plan
POST/v1/webhookssessionManage webhook endpoints
POST/v1/keyssessionCreate, rotate or revoke keys
errors + retries409 · 429 · timeouts
// POST /v1/events/:key/book with a different bookingRef,
// an expired hold or missing inventory: nothing is newly booked
HTTP 409
{ "error": "conflict",
  "conflicts": [ { "label": "A-12", "status": "booked" } ] }

// same holdId + bookingRef after a timeout: idempotent replay
HTTP 200
{ "ok": true, "booked": [] }
  • bookingRefis the idempotency key. One immutable reference per order; a replay never books or charges twice.
  • 409is a real answer, not a retry. Refresh, reselect, or surface the conflicting labels. Mutations are atomic.
  • 429on holds carries retryAfterSeconds. Budgeted per secret key, not per IP; releases are never rate-limited. Server SDKs throw a typed RateLimitError.

Eight published event types

  • seat.bookeda seat sold
  • seat.releasedhold released
  • seat.blockedheld back
  • hold.createdbuyer selected
  • hold.extendedexpiry moved
  • hold.expiredtimed out
  • event.createdevent opened
  • event.soldoutlast seat gone
  • SignatureX-SeatLayer-Signature: sha256=<hex>
  • AlgorithmHMAC-SHA256 over the raw body
  • Attempt10-second attempt timeout
  • Retriesfirst attempt plus up to three retries
  • Lognewest 200 attempts · 30-day cleanup

Fixed Renewable Seasons add structure, Plan, sales, hold, booking, amendment and renewal lifecycle webhooks under season.*. Read the Seasons API contract.

Explore the event API →

Agent tools for integration and chart design.

Your coding assistant can read our docs and SDK reference. Designer MCP lets an authorized AI client build a whole venue from one Venue Spec, then edit it for your review. Publishing stays with a person. Buyer-side assistants are covered with the seat picker above.

EMBEDDED DESIGNER · ORGANIZER SCOPE

Create and publish charts inside your product

Your backend checks workspace and chart ownership, then mints a short-lived dse_… session for an exact origin. EmbeddedDesigner handles iframe lifecycle, validated messages, relaunch and teardown.

READ EMBEDDED DESIGNER DOCS ↗
SEATMANAGER · EVENT SCOPE

Run live inventory tools inside your admin

Your backend mints an event-scoped mse_… token with explicit capabilities. SeatManager supplies the packaged board; ManageApi exposes the same scoped operations for custom interfaces.

READ CONTROL ROOM DOCS ↗
agent-ready integrationseatlayer-ai-toolkit
# Portable integration guidance
git clone https://github.com/seatlayer/seatlayer-ai-toolkit.git
cd seatlayer-ai-toolkit
node scripts/install.mjs --help

# Read-only integration diagnostics
node scripts/doctor.mjs /path/to/project

# Canonical context for any coding agent
https://docs.seatlayer.io/llms.txt
The Markdown documentation is the source of truth. Agent tooling does not replace authorization, testing or the API reference.
From your agent to one chartDesigner MCP · Available
SeatLayer Designer MCP authority flow A compatible agent connects through OAuth, receives one-chart scope, discovers allowed tools, sends work through Designer MCP, and returns revision-bound evidence for human review. The SeatLayer API remains authoritative. AGENT HOSTCompatibleMCP client OAUTHUser approvaland revocation ONE CHARTCapabilitydiscovery DESIGNER MCPTransportChart-scoped toolsbounded toolsAVAILABLE SEATLAYER APIPolicy · confirmationcanonical revisionvalidation · evidenceAUTHORITATIVE HUMAN REVIEW · PUBLISH REMAINS SEPARATE
SELECT A BOUNDARY

Connect

A compatible MCP client begins at SeatLayer’s authorization screen. The agent does not receive an organization API key.

The agent reasonsIt interprets the request and chooses among tools that are actually available.
The API authorizesIt checks identity, scope, capability state, confirmation, and the exact chart revision.
The user publishesAn agent response is never its own permission to publish or change commercial inventory.
VENUE SPEC · ONE FILE, ONE CALL

Build a whole venue from one Venue Spec

An agent writes a short JSON file that says what the venue has (ticket types and prices, a stage, rows, curved rows, tables, standing, booths, bars, exits, signs, a dance floor) and where, in words. build_from_venue_spec builds it in one call. With checkOnly it reports every problem by field and saves nothing. The file never holds coordinates; SeatLayer places everything.

READ THE VENUE SPEC GUIDE ↗
TOOLSETS · SMALLER TOOL LIST

Connect with ?tools=build

https://mcp.seatlayer.io/mcp?tools=build shows the AI 63 tools for building, editing, pricing, checking and publishing instead of all 132, so each turn carries less. The plain URL keeps every tool. Either way, the grant decides what a call may do, and publishing needs a person's approval.

DESIGNER MCP SETUP ↗
what an agent sendsvenue-spec.json
{
  "$schema": "https://docs.seatlayer.io/schemas/venue-spec-v1.json",
  "seatlayerVenueSpec": 1,
  "name": "Riverside Theatre",
  "categories": [
    { "name": "Premium", "price": 80 },
    { "name": "Standard", "price": 55 }
  ],
  "stage": { "kind": "arc" },
  "items": [
    { "type": "rows", "rowCount": 10,
      "seatsPerRow": 24, "blocks": 2,
      "category": "Premium", "section": "Stalls" },
    { "type": "curvedRows", "rowCount": 5,
      "seatsPerRow": 32, "category": "Standard",
      "section": "Rear Stalls" },
    { "type": "landmark", "role": "entrance",
      "placement": "rear" },
    { "type": "landmark", "role": "bar",
      "near": "Entrance", "side": "left" }
  ]
}
No coordinates: positions are words (front, rear, left, right, next to something named). Not in a Venue Spec: exact positions and custom outlines. Gates and step-free routes are added after the build with place_gate.

Build free. Go live for $0. Scale with your sales.

Test mode is free, with no time limit and no card. On a live account you pay only for confirmed sold seats: rendering, holds, releases, house seats and unsold seats never use a credit. Your checkout and payments stay yours, so there is no revenue share.

After that, credits start at $0.10 per sold seat, around half seats.io Silver’s starting rate. Compare seat map API costs →

See the complete credit ladder →

Need something that is not listed? If you need a payment provider we do not support yet, or an API capability you cannot find here, tell us: gateway and feature requests come straight to the team. Send a request →

TEST MODE Free

No time limit and no card. Prove the complete integration before switching to live.

PLATFORM / SDK · EVERY MONTH 100 free credits

Use them for real sales, every month, with no subscription.

BEYOND THE ALLOWANCE $0.10 → $0.05

Per confirmed sold seat. $50 buys 500 credits; the rate falls to a $0.05 floor at volume.

UNUSED BALANCE Never expires

Purchased credits stay available until a confirmed sold seat uses them.

Questions before you integrate.

Still have a question? or email hello@seatlayer.io.

SeatLayer targets reserved or assigned seating. GA capacity is supported only as an area inside a reserved-seat chart; pure-GA and chartless events are not supported.

Can I build native buyer controls around the seat map?

Yes. Flutter, React Native, iOS and Android support native buyer UI and layout composition around the shared WebView seat renderer. Use the ready picker, customize its controls, compose your layout or build around the raw map. This is native control over the buying interface, not a claim of a fully native map engine.

Can I use the free seat map API allowance in production?

Yes. Standard Platform/SDK organizations can go live with $0 upfront and 100 free confirmed sold-seat credits each month. Buy non-expiring credits when needed, starting at $50 for 500. Your checkout, payment processing and any separately priced add-ons remain your responsibility.

Which frameworks and languages does the SeatLayer SDK support?

Stable web packages cover JavaScript and TypeScript, React, Vue 3 and Angular 17+. Official server SDKs cover Node.js, Python, PHP, Java, Go, Ruby and .NET, while REST and OpenAPI support other backends. Supported production mobile SDKs cover React Native, Flutter, iOS and Android.

What is the difference between SeatPicker and SeatingChart?

SeatPicker is the complete buyer surface: map, selection, cart, tiers and GA, hold timer, responsive UI, optional 3D and onCheckout handoff. SeatingChart is the headless map for a product that wants to build its own cart, timer, confirmation and surrounding controls.

Does a public seat map wait for my backend to create a buyer token?

No. Pass { event, publicKey } for a public Platform/SDK event. The SDK calls SeatLayer directly and receives chart, inventory and a short-lived public-only bse_ session together; that internal session stays in memory. For a login, presale or private channel, supply a buyer-access token provider instead of publicKey. The provider calls your backend for the narrower bse_ session.

Can a coding agent help integrate SeatLayer?

Yes. SeatLayer publishes LLM-readable Markdown documentation and an open-source AI Toolkit with live-doc routing, a read-only integration doctor and verification guidance. The canonical documentation, your repository architecture and production testing remain the source of truth.

Can an external AI agent work on a SeatLayer chart?

Designer MCP lets a compatible MCP client work through one authorized chart scope. SeatLayer's API still controls permissions, confirmation, chart writes, canonical revisions, validation, and evidence; publication remains a separate human-controlled action.

Is there a real-time seat inventory API?

Yes. Each buyer’s map loads the event’s seats and then gets every change live. Two buyers can never get the same seat, even when thousands click at once. When 30 requests raced for one seat in our published test, one hold succeeded and every other request was told the seat was taken.

What is a seat map API?

A seat map API lets a ticketing product show a venue’s seats, see which are free right now, and hold or sell specific ones. SeatLayer covers all three with web, mobile and server SDKs plus REST and OpenAPI. The browser loads the map with an event id and a public key, your server books seats with a secret key, and live updates keep every buyer’s map current. Comparing providers? See how SeatLayer compares with seats.io.

How do I integrate a seat map into a ticketing platform?

Add the seat picker to your web or mobile app with an event id and a public key; no backend call is needed for a public sale. For private sales, your server hands the picker a buyer token instead. Your server then books seats with a server SDK or REST and a secret key, and listens for signed webhooks. If a booking result is unclear, retry with the same bookingRef and it will never book twice. Test mode is free, with no time limit and no card. The platform SDK quickstart walks through it end to end.

Does the seat map API support temporary seat holds?

Yes. Holding and releasing seats are first-class operations: the browser uses its in-memory bse_ buyer session to select, hold and release, a trusted server-only sk_ key can inspect holds and book them, and holds, releases and expiry all arrive as inventory deltas on every connected session. Holding a seat is not a sale. Rendering charts, holds, releases, house blocks and unsold inventory never consume a credit, and only a confirmed sold seat does. See seat map API pricing.

Prove your complete integration in test mode.

Create test keys, hold and book a seat through your backend, and check a signed webhook before you go live. Want to look first? browse the live seat map demos, or hold a run of performances together in the Performance Group demo.

Start building free Discuss your integration