This guide covers SeatLayer Platform/SDK infrastructure: the buyer SDK creates a short hold, then your server turns that hold into a permanent inventory booking. Your application continues to own payment, commercial Orders, tickets, delivery, refunds, and check-in.
Create an event
Publish a chart in the Designer, then create a sandbox event from your server.
const response = await fetch("https://api.seatlayer.io/v1/events", {
method: "POST",
headers: {
"content-type": "application/json",
authorization: `Bearer ${process.env.SEATLAYER_SECRET_KEY}`,
},
body: JSON.stringify({
chartId: "ch_grand_theatre",
name: "Dress rehearsal",
}),
});
const { meta } = await response.json();
console.log(meta.key); // ev_9f3aInstall the buyer SDK
Use the CDN directly or add the JavaScript package to your app.
npm i @seatlayer/js@0yarn add @seatlayer/js@0pnpm add @seatlayer/js@0bun add @seatlayer/js@0Authorize Public-sale browser access
Keep the pk_test_… public half of the key pair you used to create the
event, and register your buyer site’s exact HTTPS origin under Embed
domains in the dashboard. The public key is safe to publish in browser
code; the matching sk_test_… is not.
On first render the SDK sends the event key, public key, and browser-provided origin directly to SeatLayer. SeatLayer verifies their account and test/live mode, creates a short-lived Public-sale-only session, and returns its in-memory bearer together with the chart and compact inventory status. There is no customer-backend token round trip on this path.
A public key cannot reveal presale, login, partner, or channel inventory.
Those audiences still use an authenticated
buyerAccessTokenProvider; an explicit
provider or token always takes precedence over publicKey.
Embed the picker
Choose the integration that matches your frontend. All variants return the same holdId checkout handoff.
<div id="picker" style="height: 640px"></div>
<script src="https://cdn.seatlayer.io/seatlayer-js@0/seatlayer-buyer.js"></script>
<script>
const picker = new seatlayer.SeatPicker({
container: "#picker",
event: "ev_9f3a",
publicKey: "pk_test_…",
onCheckout: async (_, __, handoff) => {
await fetch("/api/checkout", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ holdId: handoff.holdId }),
});
},
});
picker.render();
</script>import { SeatPicker } from "@seatlayer/js";
const picker = new SeatPicker({
container: "#picker",
event: "ev_9f3a",
publicKey: "pk_test_…",
onCheckout: async (_, __, handoff) => {
await fetch("/api/checkout", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ holdId: handoff.holdId }),
});
},
});
await picker.render();import { SeatPicker } from "@seatlayer/react";
export function Checkout() {
return (
<SeatPicker
event="ev_9f3a"
publicKey="pk_test_…"
style={{ height: 640 }}
onCheckout={async (_, __, handoff) => {
await fetch("/api/checkout", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ holdId: handoff.holdId }),
});
}}
/>
);
}Book inventory from your server
Resolve authoritative inventory and configured prices from the hold, complete your payment logic, then book inventory with the secret key. After success, create and deliver tickets from your own platform.
const eventKey = "ev_9f3a";
const headers = {
authorization: `Bearer ${process.env.SEATLAYER_SECRET_KEY}`,
"content-type": "application/json",
};
const holdResponse = await fetch(
`https://api.seatlayer.io/v1/events/${eventKey}/holds/${holdId}`,
{ headers },
);
if (!holdResponse.ok) throw new Error("Hold is no longer active");
const hold = await holdResponse.json();
// Price from trusted hold items—not values posted by the browser.
const order = await createPaidOrder(hold.items);
const bookResponse = await fetch(
`https://api.seatlayer.io/v1/events/${eventKey}/book`,
{
method: "POST",
headers,
body: JSON.stringify({
holdId,
bookingRef: order.id,
}),
},
);
if (!bookResponse.ok) await handleBookingFailure(bookResponse, order);Next
Use the complete checkout example as an implementation template, then read integration best practices before going live.
If you would rather have SeatLayer run checkout, tickets and the door instead of building them yourself, follow your first managed event for the direct-organizer route.