Use event availability rules for whole sections and zones. Use blocking for individual production holds. Both update mounted buyer and operator surfaces through SeatLayer’s live event stream, so a mounted seating chart redraws without a reload.
Section states or availability rules?
| Need | Use |
|---|---|
| Open, close, or hide a section immediately | PATCH /v1/events/:key with sectionStates |
| Reveal a section at a fixed time | Availability rule with mode: "timed" |
| Reveal after the on-sale house reaches a sold percentage | Availability rule with mode: "threshold" |
| Take specific seats off sale | Blocking |
Read availability rules
/v1/events/:key/availabilitySecret key, dashboard session, or event:view manage tokencurl -s "https://api.seatlayer.io/v1/events/<YOUR_EVENT_KEY>/availability" \
-H "authorization: Bearer $SEATLAYER_SECRET_KEY"The response is {"rules": {...}}. Rules already revealed are deleted rather
than retained as completed history; use the audit log for their history.
Replace availability rules
/v1/events/:key/availabilitySecret key, dashboard session, or event:block manage tokenThis endpoint replaces the event’s complete rule set. The rules object is
required: a missing or malformed object is rejected and never interpreted as a
clear. Any section or zone id absent from rules is on sale. Send the explicit
{"rules": {}} to clear every rule.
curl -sX POST "https://api.seatlayer.io/v1/events/<YOUR_EVENT_KEY>/availability" \
-H "authorization: Bearer $SEATLAYER_SECRET_KEY" \
-H "content-type: application/json" \
-d '{
"rules": {
"sec-boxes": {
"mode": "hidden"
},
"sec-lounge": {
"mode": "closed"
},
"sec-balcony": {
"mode": "timed",
"revealAt": 1767204000000
},
"zone-upper": {
"mode": "threshold",
"thresholdPct": 80
}
}
}'SeatLayer derives member labels from the event’s pinned chart for recognized section, zone, and bookable-object ids. Send ids from your chart or section metadata rather than maintaining a separate label list.
When an event map is refreshed, active rule memberships are re-derived inside the same inventory update before the refreshed map is exposed. New inventory under a recognized target inherits its rule. If a rule’s id no longer resolves, only labels that still exist remain restricted rather than retargeting the rule from a stale label list.
| Mode | Buyer result | Ends when |
|---|---|---|
hidden |
Section inventory is not shown | You replace or clear the rule |
closed |
Visible but unavailable | You replace or clear the rule |
timed |
Hidden | Epoch-ms revealAt is reached |
threshold |
Hidden | Visible on-sale inventory reaches thresholdPct sold |
timed requires a finite epoch-ms revealAt; threshold requires a finite
thresholdPct from 0 through 100. Invalid rules reject the whole replacement,
so a malformed window can never silently reveal previously restricted
inventory. Hidden and closed inventory is excluded
from the sold-percentage denominator, so held-back capacity cannot prevent its
own reveal.
Set the buyer hold window
/v1/events/:key/hold-ttlSecret key, dashboard session, or event:view manage token/v1/events/:key/hold-ttlSecret key, dashboard session, or event:block manage token{
"holdTtlMs": 600000
}The per-event override is clamped to 1–60 minutes, takes priority over a browser
widget’s ttlMs, and applies to future holds. Trusted server hold calls may
still request a deliberate per-hold override. Send {"holdTtlMs": null} to use
the caller’s requested duration, or the 15-minute default when none is sent.
Existing holds keep their current expiry unless extended separately.
Immediate section states
Use event metadata for a direct state change:
curl -sX PATCH "https://api.seatlayer.io/v1/events/<YOUR_EVENT_KEY>" \
-H "authorization: Bearer $SEATLAYER_SECRET_KEY" \
-H "content-type: application/json" \
-d '{
"sectionStates": {
"sec-stalls": "open",
"sec-balcony": "closed",
"sec-boxes": "hidden"
}
}'open removes the holdback for that id. closed keeps the section visible but
off sale. hidden removes its buyer-visible inventory.
Resale
Resale lets a booked seat be sold again on the same event. It moves seats, not money: SeatLayer records which booking holds each seat, and your system decides the resale price, takes the new buyer’s payment, and refunds or pays the original holder.
How a listed seat behaves:
- Only booked seats can be listed. A free seat is already on sale, and a held or blocked seat cannot be listed.
- The original booking stays in place while the seat is listed. Booked counts, reports, and sold-out checks still count it as booked.
- Buyer and operator seat maps show it with the status
resale. Buyers can select it; Best Available never picks it. - A listing is bought whole. Seats listed under one
listingIdmust be held together, so a buyer cannot take half of a pair. - If a buyer’s hold on a listed seat is released or expires, the seat goes back on the resale market, not to free.
- When the new buyer’s booking succeeds, the seat moves to the new
bookingRefand leaves the market. It never passes throughfree, so no third buyer can take it in between.
List seats for resale
/v1/events/:key/actions/put-up-for-resaleSecret key, dashboard session, or event:block manage tokencurl -sX PUT "https://api.seatlayer.io/v1/events/<YOUR_EVENT_KEY>/actions/put-up-for-resale" \
-H "authorization: Bearer $SEATLAYER_SECRET_KEY" \
-H "content-type: application/json" \
-d '{
"objects": ["A-11", "A-12"],
"listingId": "resale-order-42"
}'{
"ok": true,
"listed": ["A-11", "A-12"],
"listingId": "resale-order-42"
}objects takes 1 to 500 object labels. listingId is optional, up to 120
characters. Leave it out and SeatLayer creates an rsl_… id for the call.
Listing a seat that is already listed keeps its existing listing id, so a retry
cannot regroup seats a buyer may already be holding.
| Status | error |
Meaning |
|---|---|---|
400 |
objects_required |
No usable labels in objects |
404 |
not_found |
Unknown event, or it belongs to another account or mode |
409 |
not_booked |
At least one label is not booked; conflicts lists each one |
409 |
order_edit_in_progress |
An order edit is changing one of these seats; retry shortly |
409 |
resale_unsupported_on_seatlayer_checkout |
See the caution above |
422 |
invalid_listing_id |
listingId is empty or longer than 120 characters |
Take seats off the market
/v1/events/:key/actions/remove-from-resaleSecret key, dashboard session, or event:block manage tokencurl -sX PUT "https://api.seatlayer.io/v1/events/<YOUR_EVENT_KEY>/actions/remove-from-resale" \
-H "authorization: Bearer $SEATLAYER_SECRET_KEY" \
-H "content-type: application/json" \
-d '{ "objects": ["A-11", "A-12"] }'{
"ok": true,
"unlisted": ["A-11", "A-12"],
"listingIds": ["resale-order-42"]
}The original booking is not touched. A seat that a buyer is holding right now
stays listed until that hold ends, and is left out of unlisted. Call again
after the hold is released or expires.
Read current listings
/v1/events/:key/resale-listingsSecret key, dashboard session, or event:view manage token{
"listings": [
{ "label": "A-11", "listingId": "resale-order-42", "bookingRef": "order_42", "held": false },
{ "label": "A-12", "listingId": "resale-order-42", "bookingRef": "order_42", "held": true }
]
}bookingRef is the booking the seat will leave when it sells. held: true
means a buyer is holding it and nobody else can select it.
Count the market
/v1/events/:key/resale-summarySecret key, dashboard session, or event:view manage token{ "listed": 12, "listings": 9, "held": 2, "resold": 3, "since": 1790121600000 }listed is the seats on the market now, listings how many listings they
form, and held how many of them a buyer is holding. resold counts the seats
that changed hands through resale at or after since, in milliseconds since
the epoch. Leave since out for the last 24 hours, or send your own midnight
to count today. A since in the future, negative or not a whole number is
refused with 400 invalid_since.
Resale webhooks and credits
| Webhook | Sent when | Payload |
|---|---|---|
object.resale.listed |
A put-up-for-resale call lists seats | eventId, labels, listingId |
object.resale.unlisted |
A remove call takes at least one seat off | eventId, labels, listingIds |
object.resale.sold |
A booking includes listed seats | eventId, bookingRef, at, sold[] with label, listingId, previousBookingRef |
The new buyer’s booking also sends the usual seat.booked. Use
previousBookingRef from object.resale.sold to find the original order in
your system and settle with its holder. Payloads are in the
webhook event reference.
Listing and delisting use no credits. Reselling a seat does not use a second credit, because a seat is metered only the first time it is sold. See credits.
Operational safety
- Fetch the current rules before replacing them.
- Use one writer or optimistic application coordination to avoid overwriting a concurrent operator change.
- Use epoch milliseconds in UTC and show the intended local time in your UI.
- Verify the real chart id or zone id; do not invent ids from visible labels.
- Test threshold behavior with hidden capacity excluded.
- Keep payment and booking independent from visibility controls.
Continue to blocking, best available, and embedded control room.