Skip to content

Book held seats

Resolve a buyer hold and permanently book reserved seats from your trusted server with safe retries and conflict handling.

Updated View as Markdown
POST/v1/events/:eventKey/bookSecret key

Booking turns a temporary buyer hold into a permanent sale. This endpoint is server-only and accepts sk_test_… or sk_live_… credentials whose mode matches the event.

Request

HTTP requesthttp
POST /v1/events/ev_9f3a/book HTTP/1.1
Host: api.seatlayer.io
Authorization: Bearer sk_test_••••••••
Content-Type: application/json

{
  "holdId": "hold_01J8F2A7MRQ4",
  "bookingRef": "order_1842"
}
Field Type Required Description
holdId string Yes Opaque hold identifier returned by the buyer SDK.
bookingRef string Yes Your order or payment reference. Makes safe retries idempotent.

Responses

Every requested seat is now booked.

200 responsejson
{
  "ok": true,
  "booked": ["STALLS-A-12", "STALLS-A-13"]
}

On an idempotent replay, booked is empty because no new inventory transition was needed:

200 replay responsejson
{
  "ok": true,
  "booked": []
}

Nothing is booked when any requested seat is unavailable.

409 responsejson
{
  "error": "conflict",
  "conflicts": [
    {
      "label": "STALLS-A-13",
      "status": "booked"
    }
  ]
}

A test key cannot book live inventory, and a live key cannot book a sandbox event.

403 responsejson
{
  "error": "mode_mismatch"
}

Safe retry behavior

bookingRef is your idempotency key. Repeating the same request after a timeout succeeds without creating a second booking or spending credits twice. A replay may return an empty booked array because the seats were already booked by the same reference.

server/book.jsjs
const response = await fetch(
  "https://api.seatlayer.io/v1/events/ev_9f3a/book",
  {
    method: "POST",
    headers: {
      authorization: `Bearer ${process.env.SEATLAYER_SECRET_KEY}`,
      "content-type": "application/json",
    },
    body: JSON.stringify({ holdId, bookingRef: order.id }),
  },
);

if (response.status === 409) {
  return redirectBuyerToPicker();
}

if (!response.ok) {
  throw new Error(`SeatLayer booking failed: ${response.status}`);
}
Navigation

Type to search…

↑↓ navigate↵ selectEsc close