---
title: "Cancellations and box office"
description: "Return booked inventory safely and book free seats directly from a trusted point-of-sale backend."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.seatlayer.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Cancellations and box office

SeatLayer separates seat state from your money workflow. Refund payment in your
system, then unbook with the original booking reference. At the box office,
take payment first according to your policy and book free seats without a buyer
hold.

## Cancel a booking

**POST /v1/events/:key/unbook** — Authentication: Secret key, dashboard session, or event:cancel manage token

```bash
curl -sX POST "https://api.seatlayer.io/v1/events/ev_9f3a/unbook" \
  -H "authorization: Bearer $SEATLAYER_SECRET_KEY" \
  -H "content-type: application/json" \
  -d '{
    "labels": ["A-1","A-2"],
    "bookingRef": "order_5567"
  }'
```

Every label must still be booked under that exact `bookingRef`. The operation
is all-or-nothing:

### Success

```json
{
  "ok": true,
  "unbooked": ["A-1", "A-2"],
  "conflicts": []
}
```
### Booking mismatch

```json
{
  "error": "booking_mismatch",
  "conflicts": [
    {
      "label": "A-2",
      "status": "booked"
    }
  ]
}
```

The booking reference guard prevents a delayed refund job from freeing a seat
that has since been resold under another order.

> **Unbook is not a refund**
>
> Return money in your payment system. `unbook` only changes SeatLayer
> inventory. The original booked-seat credit is not returned, and a later
> resale of the same unit is not metered again.

## Book at the box office

**POST /v1/events/:key/box-book** — Authentication: Secret key or dashboard session

```bash
curl -sX POST "https://api.seatlayer.io/v1/events/ev_9f3a/box-book" \
  -H "authorization: Bearer $SEATLAYER_SECRET_KEY" \
  -H "content-type: application/json" \
  -d '{
    "labels": ["C-14","C-15"],
    "bookingRef": "pos_88213"
  }'
```

`box-book` transitions inventory directly from `free` to `booked`. There is no
hold and no browser checkout handoff. The requested labels are atomic; a
conflict leaves all of them unchanged.

The route is idempotent by `bookingRef`. A replay succeeds with
`{"ok":true,"booked":[]}` rather than repeating the sale.

## Recommended cancellation workflow

1. Load your order by the stable booking reference.
2. Lock or idempotently claim the cancellation in your database.
3. Refund or void payment according to your business policy.
4. Call `unbook` with the exact labels and original booking reference.
5. Record the response and reconcile any mismatch instead of broadening the
   release.
6. Let `seat.released` update downstream systems.

If inventory must be guaranteed free before refunding, reverse steps 3 and 4
and implement compensation for a failed refund. Choose one policy explicitly.

## Recommended box-office workflow

1. Read current availability in your operator surface.
2. Choose free labels and calculate payment in the trusted POS.
3. Create a stable POS order reference.
4. Call `box-book`.
5. On `409`, reload inventory and ask the operator to reselect.
6. Persist the successful response and issue the ticket.

## Effects

Successful actions update all mounted views in real time, write the event audit
log, and emit signed webhooks:

| Operation | Webhook |
|---|---|
| `box-book` | `seat.booked`; possibly `event.soldout` |
| `unbook` | `seat.released` |

Continue to [reports](/server-api/reports),
[webhook events](/webhooks/events), and
[idempotency and conflicts](/server-api/idempotency-and-conflicts).

Source: https://docs.seatlayer.io/server-api/cancellations-and-box-office/index.mdx
