Get listings
/v1/events/{event_id}/listingsReturns the listings SeatData holds for a single event - active
listings and delisted ones - ordered by listing_id ascending, then
by id ascending (a stable tiebreak for paging; a listing_id can
appear more than once when the marketplace reuses it).
The v1 equivalent of GET /v0.1.1/listings/get. Same rows, same
billing - plus cursor pagination, a JSON response envelope, an
active filter, created_at / updated_at on every row, and
structured JSON errors. active is a JSON boolean here (0/1 on
v0.1.1). Responses are application/json, and v1 never forces gzip
the way v0.1.1 does - any compression is ordinary content negotiation
your HTTP client handles for you. See the
migration guide.
Billing rules
| Scenario | Charged a pull? |
|---|---|
| First page, and the event's listings refreshed since your last charged pull | Yes - 1 pull |
| First page, nothing refreshed since your last charged pull | No |
| Follow-up paginated page (cursor present) | No (continuation) |
| No listings under the filter | No (empty result, free) |
has_refreshed on the first page tells you whether that call was
charged. Refresh state is shared with GET /v0.1.1/listings/get: a
charged pull of an event through either version counts as your last
charged pull for both. Fetching every page through pagination costs
the same single pull as one v0.1.1 call. The active value does not
change what a page costs.
Pagination
Cursor-based. The first page includes total_count, has_refreshed
and last_refreshed_at; continuation pages omit them. next_cursor
is opaque - pass it back verbatim via starting_after; don't parse
it. Cursors are scoped to the event and the active value they were
issued under, and expire after 1 hour. Replaying a cursor with a
different active value returns 400 invalid_cursor. Use one
active value for every page of a walk.
limit applies per request and is not carried by the cursor; send it
again on each continuation.
Pages are not a snapshot. Listings SeatData observes while you page
can appear or change between pages, and total_count is the count at
the first page. A row is never repeated across the pages of one walk.
Example: fetching every page
import requestsbase = "https://seatdata.io/api/v1/events/12345/listings"headers = {"Authorization": "Bearer YOUR_API_KEY"}rows = []params = {"limit": 1000, "active": "true"}while True: response = requests.get(base, params=params, headers=headers) response.raise_for_status() page = response.json() rows.extend(page["data"]) if page["next_cursor"] is None: break params = {"active": "true", "limit": 1000, "starting_after": page["next_cursor"]}print(len(rows), "active listings")Pass Authorization: Bearer <api_key>. Preferred for new integrations.
In: header
Path Parameters
SeatData Event ID (from /v1/events/search) by default. To pass a Marketplace Event ID instead, add ?id_type=marketplace.
Query Parameters
Set to marketplace to interpret the path id as a Marketplace Event ID. Omit to interpret it as a SeatData Event ID.
Value in
- "marketplace"
true returns currently listed rows only; false returns delisted rows only. Omit for both (the v0.1.1 behavior). Exact, lowercase; any other value returns 400 invalid_param, free of charge. An empty value counts as omitted.
Value in
- "true"
- "false"
Max listing rows per page (default 500, max 1000)
value <= 1000500Cursor from a previous response's next_cursor
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/v1/events/225220/listings" \ -H "Authorization: Bearer YOUR_API_KEY"{ "event_id": 225220, "seatdata_event_id": 225220, "sh_event_id": 159009391, "vs_event_id": null, "data": [ { "listing_id": 7300750943, "active": true, "zone": "Upper Level", "section": "216", "row": "12", "quantity_start": 4, "quantity": 2, "price": 66.45, "created_at": "2026-09-12T04:40:40Z", "updated_at": "2026-09-29T09:21:07Z" } ], "has_more": true, "next_cursor": "string", "total_count": 1834, "has_refreshed": true, "last_refreshed_at": "2026-09-30T13:52:10Z"}Get sales data (batch) POST
Returns sales records for up to 100 events per request, combined across both id lists after deduplication. Each row is a real sale transaction. Rows have the same shapes as on `GET /v1/events/{event_id}/sales`, including the per-source key differences described there. The v1 equivalent of `POST /v0.3/salesdata/batch` - same request body, same response shape, same billing. Differences: responses are `application/json` with no forced gzip, rows include `listing_id`, and a malformed body returns a JSON error envelope instead of plain text. See the [migration guide](https://docs.seatdata.io/docs/api/migrating-to-v1/). There is no pagination and no `id_type` parameter here - the two id lists in the body drive the request, and all rows are returned for each event. ## Sources The optional `source` parameter behaves exactly as it does on `GET /v1/events/{event_id}/sales`: `sh` (the default), `vs`, or `all`. Send it on the URL - it is a query-string parameter, not a body field: ``` POST /api/v1/events/sales/batch?source=all ``` The response carries a top-level `sources` object, keyed by the same client-sent event ids as `results`. Each value lists both marketplaces, `sh` first, regardless of the `source` filter. `results` and `errors` are unchanged in shape. An invalid `source` returns `400` `invalid_param` with `param` set to `source`, free of charge. `results` and `errors` are keyed by the exact identifier string you sent: Marketplace Event IDs appear under the marketplace id, SeatData Event IDs under the SeatData id (a SeatData ID and a Marketplace ID that resolve to the same event are echoed under both keys). ## Quantity and price `sh` sales often reach us unenriched, without a quantity or price. For those we derive both from the listing data we hold for that listing; a `quantity` of `0` means it could not be reliably determined. `vs` sales carry both as reported. ## Billing rules | Scenario | Charged a pull? | |---|---| | Event in the batch returns at least one sale | Yes - 1 pull per such event | | Event in the batch has no sales | No (free) | | Balance runs out mid-batch | Events already affordable are served and charged; the rest come back as `payment_required` in `errors` | | No event in the batch is affordable | No data - the request returns 402 |
Get sales data GET
All responses are gzip encoded. You must pass either a **SeatData Event ID** (from the `/v0.3.1/events/search` or `/v1/events/search` endpoints) or a **Marketplace Event ID** (obtained separately). This endpoint returns data from a single marketplace. Multi-source sales data is available on `GET /v1/events/{event_id}/sales`.