---
title: "Inventory and availability"
description: "Control event hold duration, section visibility, scheduled release, and demand-triggered inventory."
---

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.

## 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](/server-api/blocking) |

## Read availability rules

<ApiEndpoint method="GET" path="/v1/events/:key/availability" auth="Secret key, dashboard session, or event:view manage token" />

```bash
curl -s "https://api.seatlayer.io/v1/events/ev_9f3a/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

<ApiEndpoint method="POST" path="/v1/events/:key/availability" auth="Secret key, dashboard session, or event:block manage token" />

This 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.

```bash title="Open the balcony at 80% sold"
curl -sX POST "https://api.seatlayer.io/v1/events/ev_9f3a/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.

<Aside type="note" title="Reveals are one-way">
  When a timed or threshold condition fires, SeatLayer deletes that rule and
  records a `reveal` action. Create a new rule if the section must be held back
  again.
</Aside>

## Set the buyer hold window

<ApiEndpoint method="GET" path="/v1/events/:key/hold-ttl" auth="Secret key, dashboard session, or event:view manage token" />

<ApiEndpoint method="POST" path="/v1/events/:key/hold-ttl" auth="Secret key, dashboard session, or event:block manage token" />

```json
{
  "holdTtlMs": 600000
}
```

The per-event override is clamped to 1–60 minutes and applies to future holds.
Send `{"holdTtlMs": null}` to restore the 15-minute default. Existing holds keep
their current expiry unless extended separately.

## Immediate section states

Use event metadata for a direct state change:

```bash
curl -sX PATCH "https://api.seatlayer.io/v1/events/ev_9f3a" \
  -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.

## 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](/server-api/blocking),
[best available](/buyer-sdk/best-available), and
[embedded control room](/platform/embedded-control-room).