SeatDataDocs

API Changelog

Dated record of additive changes to the SeatData REST API

Changes to the SeatData REST API, newest first. Entries here are additive unless stated otherwise.

2026-09-30 — Listings: GET /api/v1/events/{event_id}/listings

The listings endpoint now has a v1 equivalent. GET /api/v0.1.1/listings/get (and v0.1) stay live and fully supported; nothing changes for existing callers. Billing is unchanged: a first page is charged only when the event's listings refreshed since your last charged pull, continuation pages are free, and refresh state is shared between v0.1.1 and v1.

What v1 adds over v0.1.1:

v0.1.1v1
Event selector?event_id= / ?event_id_sh=path id, ?id_type=marketplace for a Marketplace Event ID
Envelope{has_refreshed, last_refresh_timestamp, listings}{event_id, seatdata_event_id, sh_event_id, vs_event_id, data, has_more, next_cursor, total_count, has_refreshed, last_refreshed_at}
Paginationnonecursor pages, limit default 500, max 1000
Filternone?active=true / ?active=false
Rowsactive as 0/1active as a boolean, plus created_at and updated_at
Errorsplain textJSON error envelope

See the migration guide.

2026-09-24 — Sales endpoints: SeatData and Marketplace Event IDs on every response

Both v1 sales endpoints now identify each served event by its SeatData Event ID and by its Marketplace Event ID on each marketplace SeatData observes. This update is additive: no request parameter, pagination, source, id_type, rate limit, or billing change, and no new URL version. Row shape is unchanged. No existing integration needs to change.

Affected endpoints:

  • GET /api/v1/events/{event_id}/sales
  • POST /api/v1/events/sales/batch

On the single-event endpoint the three keys sit directly after event_id on every page, unlike total_count and sources, which stay first-page only:

FieldTypeMeaning
seatdata_event_idintegerAlways the SeatData Event ID, whatever id style the caller used.
sh_event_idinteger | nullThe event's Marketplace Event ID on the sh marketplace. null when SeatData has not matched the event there.
vs_event_idinteger | nullThe event's Marketplace Event ID on the vs marketplace. null when unmatched. Informational only; no endpoint accepts it as input.

The batch endpoint adds one top-level events object, keyed exactly like results and sources by the identifier sent in the request. Each value carries the same three fields. Only served events get an entry: an id that lands in errors has none. A served event_ids_sh value with no matching SeatData event gets seatdata_event_id: null with sh_event_id set to the sent id.

event_id still echoes the id from the request path; with ?id_type=marketplace it equals sh_event_id, and seatdata_event_id gives the internal id.

2026-09-24 — Event search: sh_event_id and vs_event_id on every result

Every item returned by event search now carries the event's Marketplace Event ID on each marketplace SeatData observes. This update is additive: no request parameter, pagination, rate limit, or billing change, and no new URL version. Search remains free. No existing integration needs to change.

Affected endpoint:

  • GET /api/v1/events/search

The two fields appear directly after tm_event_id in every data item:

FieldTypeMeaning
sh_event_idinteger | nullThe event's Marketplace Event ID on the sh marketplace. null when SeatData has not matched the event there.
vs_event_idinteger | nullThe event's Marketplace Event ID on the vs marketplace. null when SeatData has not matched the event there. Informational only; no endpoint accepts this id as input.

Both values are JSON integers, unlike tm_event_id, which is a string.

sh_event_id can be passed straight to the sales endpoints as a Marketplace Event ID: as the path id on GET /api/v1/events/{event_id}/sales with ?id_type=marketplace, and in event_ids_sh on POST /api/v1/events/sales/batch and POST /api/v0.3/salesdata/batch.

The legacy v0.3 and v0.3.1 search endpoints do not gain the fields.

2026-09-17 — Sales endpoints: optional source filter, new row fields, per-event sources metadata

The v1 sales endpoints now return sales observed on more than one marketplace. The URL version does not change, and no existing request changes: this update adds optional inputs and new output fields.

Affected endpoints:

  • GET /api/v1/events/{event_id}/sales
  • POST /api/v1/events/sales/batch

The default is unchanged

Omitting source, or sending source=sh, returns exactly the rows and charges you received before this update. No existing integration needs to change.

Optional source query parameter

Accepted on both endpoints as a query-string parameter. On the batch endpoint it goes on the URL, not in the JSON body.

sourceReturns
omitted, or shThe default. Unchanged rows, unchanged charges.
vsOnly sales observed on the second marketplace.
allBoth, merged newest-first.

Any other value returns 400 with error.code set to invalid_param and error.param set to source. That response is free — it is rejected before any billing or data read.

Pagination cursors are bound to the source they were issued under. Replaying a cursor under a different source returns 400 with error.code set to invalid_cursor. Use one source value for every page of a walk.

New fields on every sale row

Two fields are added to every row, on both endpoints and under every source value:

FieldTypeMeaning
sourcestring"sh" or "vs" — the marketplace the sale was observed on.
all_in_pricenumber | nullFee-inclusive price the marketplace showed. Always null on sh rows.

A vs row carries two more. sh rows carry neither, because their names are the naming space vs rows are translated into and have nothing to translate.

FieldTypeMeaning
norm_zonestringThe zone name used for the same seats in sh sales for that event or venue. Derived by matching, not reported by the marketplace. "" when no match is found.
norm_sectionstringThe same, for the section.

Row key sets differ by source

Read source to tell which shape a row has. On a sh row, listing_id is an integer, all_in_price is always null, and the normalized fields are absent. On a vs row, listing_id is a string, zone is always "", section may combine zone and section into one label, and both normalized fields are present.

To join the two sets, compare a vs row's norm_section against a sh row's section, and its norm_zone against zone. That is what the fields are for.

timestamp, quantity, price, zone, section, row, and listing_id are otherwise unchanged on sh rows. vs sales come from listing changes between pulls, so an event's vs count is a lower bound. Sales whose seat details could not be determined are not returned, and are not counted in total_count.

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.

New sources metadata

The single-event endpoint returns a top-level sources array on the first page. Continuation pages omit it. The batch endpoint returns a top-level sources object keyed by the same client-sent event ids as results; results and errors are unchanged in shape.

sources always carries two entries, sh then vs, whatever source you sent. Each entry has:

  • source — "sh" or "vs"
  • collecting_since — ISO date of the earliest sale observed for this event on that marketplace, or null. It counts sales these endpoints do not return, so it can be older than your oldest returned row.
  • tracked_for_event — whether the event is tracked on that marketplace
  • status — "ok", or "unavailable" when that marketplace could not be read for this request. The response still succeeds, carrying the rows that were available.

total_count on the first page counts rows under the active source filter.

Billing

Unchanged. A first page that returns at least one row is one pull, whichever source produced it. Continuation pages are free. A page with no rows is free. Because the default is sh, a caller who sends no source pays exactly what they paid before.

Not changed

No new URL version. The v0.x endpoints are untouched and remain single-marketplace. The error envelope, cursor format, limit bounds, rate limits, and authentication are all unchanged.

On this page