---
title: "Orders"
description: "Read the orders SeatLayer checkout took, across events and seasons, with their tickets; refund, cancel or resend an event order with a secret key."
---

When SeatLayer checkout takes the money (hosted checkout, the box office, a
season sale or renewal), SeatLayer keeps the order. These routes let your
server read those orders and act on an event's orders with your secret key.
The key's mode decides what you see: a test key never reads a live order.

Orders of your own checkout (`provider: "external"`) are not SeatLayer orders
and never appear here.

## Every order

<ApiEndpoint method="GET" path="/v1/orders" auth="Secret key" />
<ApiEndpoint method="GET" path="/v1/orders/:orderId" auth="Secret key" />
<ApiEndpoint method="GET" path="/v1/orders/:orderId/tickets" auth="Secret key" />

`GET /v1/orders` lists orders newest first, 50 a page (`limit` up to 100).
Filter with `eventKey`, `seasonKey`, `holderRef`, `status`, and `from` / `to`
in epoch milliseconds on when the order was created. Pass `nextCursor` back as
`cursor`; it is `null` on the last page.

```json title="200"
{
  "orders": [{
    "orderId": "ord_01JC…",
    "displayRef": "#7284 7528",
    "status": "confirmed",
    "kind": "season",
    "eventKey": null,
    "seasonKey": "sea_a245…",
    "holderRef": "ord_01JC…",
    "customerId": null,
    "buyer": { "name": "Hanna Holder", "email": "hanna@example.org" },
    "amounts": { "currency": "GBP", "subtotalMinor": 18000, "bookingFeeMinor": 0, "totalMinor": 18000, "refundedMinor": 0 },
    "mode": "live",
    "createdAt": 1793664000000,
    "confirmedAt": 1793664012000
  }],
  "nextCursor": null
}
```

| `kind` | The sale |
|---|---|
| `event` | One event's online sale. `eventKey` names it. |
| `season` | A season sale. `seasonKey` names the season; it admits to every date. |
| `renewal` | A season renewal paid through SeatLayer. |
| `box_office` | A sale at your box office counter. |

`holderRef` is the holder the order is for, in the references your
[holder routes](/server-api/holders/) take: a season sale's is its own order id,
a renewal's is the reference its offer was made to, and event and box office
orders have none (`null`). Filter with `holderRef` to list one holder's season
orders and renewals. `customerId` names the customer linked to the order, and
is `null` when there is none. `buyer.email` is `null` for a box office sale
taken without an email address.

`GET /v1/orders/:orderId` adds the order's `lines` (seat or ticket, price,
quantity). `GET /v1/orders/:orderId/tickets` lists the order's tickets, earliest
date first, with its date and a `scanUrl`.

<Aside type="caution" title="A scan link is a ticket">
  The token in `scanUrl` lets whoever has it be scanned in. Show it only to the
  ticket's holder, and never log it.
</Aside>

## One event's orders

<ApiEndpoint method="GET" path="/v1/events/:key/orders" auth="Secret key, dashboard session, or event:orders:read manage token" />
<ApiEndpoint method="GET" path="/v1/events/:key/orders.csv" auth="Secret key, dashboard session, or event:orders:read manage token" />
<ApiEndpoint method="GET" path="/v1/events/:key/orders/:orderId" auth="Secret key, dashboard session, or event:orders:read manage token" />

These are the routes the dashboard's Orders screen uses, for an event that
sells through SeatLayer checkout. The list searches with `q` (name, email,
order number or seat) and filters with `status`, `paidBy`, `from` and `to`; it
answers `matchedCount` and event-wide `totals` with each page. `orders.csv`
exports every match, one price line per row. One order answers with its lines,
tickets, guests and booking answers.

## Refund, cancel, resend

<ApiEndpoint method="POST" path="/v1/events/:key/orders/:orderId/refund" auth="Secret key, dashboard session, or event:refund manage token" />
<ApiEndpoint method="POST" path="/v1/events/:key/orders/:orderId/cancel" auth="Secret key, dashboard session, or event:refund manage token" />
<ApiEndpoint method="POST" path="/v1/events/:key/orders/:orderId/resend" auth="Secret key, dashboard session, or event:tickets:send manage token" />

**Refund** sends money back through the payment provider: `{}` refunds what is
left, `{ "amountMinor": 2500 }` part of it. Send an `Idempotency-Key`: a retry
with the same key answers the first result. `202` means the provider has not
confirmed yet; retry with the same key to read it.

**Cancel** voids the tickets and frees the seats without SeatLayer moving
money, for a payment you settled elsewhere or a lost dispute. It needs a
`reason` (`lost_dispute`, `refunded_elsewhere`, `other`).

**Resend** emails the order's live tickets again, to the buyer or to `email`.

To follow event orders as they happen, subscribe to
[`order.paid`, `order.refunded` and `order.cancelled`](/webhooks/events/#event-orders).
Season orders send `season.order.*` and have their own routes with the same
actions; see [Seasons](/server-api/seasons/). The event routes above answer
`404` for a season order, even on the season's first date. No server SDK wraps
these routes; call them from any language.