TM Events API Reference
Base URL: /api/v1
Browse this reference in a browser at /docs. Raw markdown is at /docs.md or GET /api/v1/docs.
All authenticated endpoints require an API key via ?apiKey=<key> query parameter or x-api-key header. Price keys are seperate.
All Routes
| Method | Path | Description | Scopes |
|---|---|---|---|
POST |
/events/ |
List events with filters | events:read |
GET |
/events/:id |
Get single event | events:read |
GET |
/events/third-party/:id |
Get third-party URLs | events:read |
GET |
/events/price/filtered-by-price |
Get events by price range | events:read, price:read |
GET |
/events/:id/sectioned-pricing |
Get per-section pricing | events:read, price:read |
GET |
/events/:id/early-pricing |
Get early host price tiers | events:read, price:read |
GET |
/events/:id/early-seats |
Get configured box-office seat map | events:read, price:read |
GET |
/events/:id/early-codes |
Get early promo codes | events:read, code:read |
GET |
/events/:id/active-price |
Get active price range | events:read, active-price:read |
POST |
/events/active-price |
Get active prices (bulk) | events:read, active-price:read |
GET |
/events/cheapest-tickets |
Get cheapest events | events:read, active-price:read |
GET |
/events/:id/codes |
Get presale codes | events:read, code:read |
GET |
/events/:id/get-ins |
Get historical get-in prices | events:read, get-ins:read |
GET |
/events/:id/seats |
Get seat counts (dropped vs pending) | events:read, stock:read |
GET |
/events/:id/seats/all |
Get all seen seats (priced) for event | events:read, stock:read |
GET |
/events/:id/stock |
Get full live stock | events:read, stock:read |
GET |
/events/:id/limited-stock |
Get stock by price break | events:read, limited-stock:read |
POST |
/sales/ |
List events by sale date | events:read, sales:read |
GET |
/sales/event/:eventId |
Get sales by event | events:read, sales:read |
GET |
/artists/:id/genre |
Get artist genre | events:read, artists:read |
GET |
/secondaries/compare/ticketmaster/:id |
Compare TM vs secondary get-in | secondaries:read |
GET |
/secondaries/all/listings |
Combined marketplace listings | secondaries:read |
GET |
/secondaries/stubhub/listings/:id |
StubHub listings | secondaries:read |
GET |
/secondaries/vividseats/listings/:id |
Vivid Seats listings | secondaries:read |
GET |
/secondaries/gametime/listings/:id |
Gametime listings | secondaries:read |
GET |
/secondaries/seatgeek/listings/:id |
SeatGeek listings | secondaries:read |
Events
Base path: /api/v1/events
All event routes pass through logging and rate-limit middleware.
POST /
List events with filters.
Auth: None (public)
Request Body:
{
"filters": {
"eventStartDate": "2025-06-01",
"eventEndDate": "2025-12-31",
"status": "onsale",
"sort": "date",
"order": "desc",
"page": 0,
"limit": 25,
"onlyTmEvents": false,
"vividStrict": false,
"excludePastEvents": true,
"tmStrict": false,
"maxInventory": 0
}
}
| Field | Type | Description |
|---|---|---|
eventStartDate |
string (YYYY-MM-DD) | Start of date range (default: today) |
eventEndDate |
string (YYYY-MM-DD) | End of date range (default: 1 year from start) |
status |
string | Filter by event status |
sort |
string | "date" or "status" |
order |
string | "asc" or "desc" |
page |
int | Page number (0-indexed) |
limit |
int | Results per page (min 10) |
onlyTmEvents |
bool | Only include events with a TM ID |
vividStrict |
bool | Only include events with a Vivid Seats ID |
excludePastEvents |
bool | Exclude events that have already started |
tmStrict |
bool | Only include events with updated seat inventory |
maxInventory |
int | Max available seats filter (requires tmStrict) |
Response (200):
{
"data": {
"events": [
{
"tm_id": "abc123",
"name": "Event Name",
"start_time": "2025-07-01T20:00:00Z",
"end_time": "2025-07-01T23:00:00Z",
"status": "onsale",
"url": "https://www.ticketmaster.com/...",
"image_url": "https://...",
"currency": "USD",
"category": "Music",
"genre": "Rock",
"venue": {
"name": "Madison Square Garden",
"capacity": 20000,
"street": "4 Pennsylvania Plaza",
"city": "New York",
"state": "NY",
"country": "US"
},
"price": {
"min_price": 49.99,
"max_price": 299.99,
"currency": "USD"
},
"sales": {
"public": {
"start_date_time": "2025-05-01T10:00:00Z",
"end_date_time": "2025-07-01T18:00:00Z",
"start_tbd": false
},
"presales": [
{
"name": "Artist Presale",
"description": "Exclusive artist presale",
"start_date_time": "2025-04-28T10:00:00Z",
"end_date_time": "2025-04-30T22:00:00Z",
"url": "https://...",
"visible": true
}
]
},
"details": {
"stubhub": {
"url": "https://...",
"relevent_id": "...",
"low_price": 55.0,
"high_price": 500.0,
"total_listings": 120,
"total_seats": 350
},
"vivid_seats": { "..." : "..." },
"seat_geek": { "..." : "..." },
"game_time": { "..." : "..." },
"automatiq": { "..." : "..." }
},
"attraction": {
"name": "Artist Name",
"type": "Music",
"upcoming_events": 15,
"url": "https://...",
"seo_name": "artist-name",
"league": ""
}
}
]
},
"total": 1500,
"count": 25,
"page": 0,
"total_pages": 60,
"pages_remaining": 59,
"limit": 25
}
GET /:id
Get a single event by TM ID.
Auth: events:read
Params:
id(path) -- Ticketmaster event IDgetSales(query, optional) --"true"to include Vivid/StubHub sales data
Response (200):
{
"event": { "...EventData..." }
}
Errors:
400-- Invalid event ID404-- Event not found
GET /third-party/:id
Get third-party marketplace URLs for an event.
Auth: None
Response (200):
{
"name": "Event Name",
"ticketmaster": "https://www.ticketmaster.com/...",
"vivid": "https://www.vividseats.com/...",
"stubhub": "https://www.stubhub.com/...",
"seatGeek": "https://www.seatgeek.com/..."
}
GET /price/filtered-by-price
Get events filtered by price range.
Auth: price:read
Query Params:
minPrice(required) -- Minimum pricemaxPrice(optional, default:999999999) -- Maximum pricecountryCode(optional, default:"US") -- Comma-separated country codes
Response (200):
{
"events": [ "...EventData[]..." ],
"total": 42
}
GET /:id/sectioned-pricing
Get per-section min/max pricing for an event (live from websocket monitor).
Auth: events:read, price:read
Response (200):
{
"ticketMapper": {
"ORCH1": {
"section": "ORCH1",
"minPrice": 89.50,
"maxPrice": 350.00
},
"MEZZ2": {
"section": "MEZZ2",
"minPrice": 45.00,
"maxPrice": 120.00
}
}
}
GET /:id/early-pricing
Get the host price scale for an event as soon as the venue box office loads it,
often before the public pricing buffer has anything.
Auth: events:read, price:read
Query:
| Param | Default | Description |
|---|---|---|
availability |
true |
Include live seat counts per tier. |
allTicketTypes |
false |
Include senior/student/group variants; default is base adult only. |
Response (200):
{
"eventId": "150064F581713D8B",
"currency": "USD",
"minPrice": 73.75,
"maxPrice": 133.75,
"totalAvailableSeats": 842,
"pricing": [
{
"faceValue": 129.5,
"fees": 4.25,
"total": 133.75,
"availableSeats": 120,
"maximumContiguousSeats": 8
}
]
}
Errors:
404-- Early pricing is unavailable for this event
GET /:id/early-seats
Get the configured section, row, and seat ranges joined to their preloaded
price codes. This seat map is often available before public onsale and is not
live inventory — a configured range can still be held back when the sale opens.
Auth: events:read, price:read
totalSeats is the venue summary when present, otherwise the sum of parsed
ranges. priceMappedSeatCount is seats that joined to at least one price
code; unpricedSeatCount is the remainder. Ranges with no matching price
code omit pricing. All money fields are major currency units.
Response (200):
{
"eventId": "150064F581713D8B",
"currency": "USD",
"totalSeats": 1840,
"sectionCount": 12,
"seatRangeCount": 86,
"priceMappedSeatCount": 1620,
"unpricedSeatCount": 220,
"sections": [
{
"name": "101",
"description": "Lower Bowl",
"type": "Standard",
"generalAdmission": false,
"seatCount": 48,
"ranges": [
{
"row": "A",
"firstSeat": "1",
"lastSeat": "8",
"seatCount": 8,
"seatIncrement": 1,
"pricing": [
{
"description": "Adult",
"faceValue": 129.5,
"fees": 4.25,
"tax": 0,
"serviceCharge": 0,
"total": 133.75
}
]
},
{
"row": "B",
"firstSeat": "1",
"lastSeat": "8",
"seatCount": 8,
"seatIncrement": 1
}
]
}
]
}
Responses are cached for 2 minutes (Cache-Control: public, max-age=…).
Errors:
400-- Missing event ID404-- Early seats are unavailable for this event
GET /:id/early-codes
Get early promo codes for an event.
Auth: events:read, code:read
Response (200):
{
"eventId": "abc123",
"codes": ["PRESALE"]
}
An event with no matching code returns an empty codes array.
Errors:
404-- Early codes are unavailable for this event
GET /:id/active-price
Get the active (real-time) price range for an event.
Auth: events:read, active-price:read
Response (200):
{
"eventId": "abc123",
"prices": {
"minPrice": 29.99,
"maxPrice": 499.99,
"allInMinPrice": 45.00,
"allInMaxPrice": 525.00,
"allInMinPriceFiltered": 50.00,
"allInMaxPriceFiltered": 510.00,
"facilityFee": 5.50,
"updatedAt": "2025-06-15T14:30:00Z"
}
}
POST /active-price
Get active prices for multiple events at once.
Auth: active-price:read
Request Body:
{
"event_ids": ["abc123", "def456", "ghi789"]
}
Response (200):
{
"data": [
{
"eventId": "abc123",
"prices": {
"minPrice": 29.99,
"maxPrice": 499.99,
"allInMinPrice": 45.00,
"allInMaxPrice": 525.00,
"allInMinPriceFiltered": 50.00,
"allInMaxPriceFiltered": 510.00,
"facilityFee": 5.50,
"updatedAt": "2025-06-15T14:30:00Z"
}
}
]
}
GET /cheapest-tickets
Get cheapest active-priced events within a date range.
Auth: active-price:read
Query Params:
limit(optional, default:25, max:300)startDate(optional, RFC3339, default: yesterday)endDate(optional, RFC3339, default: tomorrow)maxPrice(optional) -- Max all-in min price filter
Response (200):
{
"data": [ "...ActivePriceResponse[]..." ]
}
GET /:id/codes
Get presale/offer codes for an event (live from websocket monitor + database).
Auth: events:read, code:read
Response (200):
[
{
"ID": "...",
"EventID": "abc123",
"Code": "510002",
"Name": "Mastercard presales"
}
]
GET /:id/get-ins
Get historical "get-in" prices for an event.
Auth: events:read, get-ins:read
Response (200):
{
"eventId": "abc123",
"prices": [
{
"price": 55.00,
"market": "primary",
"currency": "USD",
"scrapedAt": "2025-06-10T12:00:00Z"
}
]
}
GET /:id/seats
Get seat counts for an event, split by priced vs unpriced.
Auth: events:read, stock:read
Response (200):
{
"event_id": "abc123",
"total": 5000,
"seen": 3200,
"pending": 1800
}
GET /:id/seats/all
Dump every "seen" seat for an event (rows where list_price > 0). No pagination — returns the full set.
Auth: events:read, stock:read
Response (200):
{
"event_id": "abc123",
"count": 3200,
"seats": [
{
"Section": "111A",
"Row": "29",
"SeatNumber": 14,
"Name": "POTENT",
"Description": "Artist Presale",
"Password": true,
"ListPrice": 119.5,
"FaceValue": 115,
"FacilityFees": 4.5,
"ServiceCharge": 30.45,
"FirstSeenAt": "2025-06-10T12:00:00Z",
"LastUpdatedAt": "2025-06-15T14:30:00Z"
}
]
}
GET /:id/stock
Get full live stock (all available tickets) for an event.
Auth: events:read, stock:read
A numeric :id is a SeatGeek event id (SeatGeek-primary). Those return this
same shape from SeatGeek box-office inventory (open and mercury markets)
and are not looked up as Ticketmaster events. codes is then SeatGeek's
price types, keyed by price type id, with code the price type label. map
is empty. A stored event whose URL is seatgeek.com, or that is neither
Ticketmaster nor AXS and has a SeatGeek id, takes the same path. Every other
event still comes from the Ticketmaster feed.
Query Params:
did(optional, default:"default") -- Display ID
Response (200):
{
"eventId": "abc123",
"availableSeats": 1500,
"platinumSeats": 75,
"map": "https://mapsapi.tmol.io/maps/geometry/3/event/abc123/image?...",
"bySection": {
"ORCH1": 120,
"MEZZ2": 85
},
"codes": {
"Mastercard Presale": {
"code": "Mastercard Presale",
"description": "...",
"quantity": 50
}
},
"stock": [
{
"name": "Standard Ticket",
"section": "ORCH1",
"row": "A",
"seat": "12",
"listPrice": 150.00,
"faceValue": 125.00,
"facilityFee": 10.00,
"serviceCharge": 15.00,
"password": false
}
],
"consecutivePairs": 25,
"pairs": [
[
{ "section": "ORCH1", "row": "A", "seat": "12", "..." : "..." },
{ "section": "ORCH1", "row": "A", "seat": "13", "..." : "..." }
]
]
}
Errors:
404-- No stock available
GET /:id/limited-stock
Get stock summarized by price break (no individual ticket listing).
Auth: limited-stock:read
Query Params:
did(optional, default:"default")
Response (200):
{
"eventId": "abc123",
"availableSeats": 1500,
"priceBreaks": [
{
"listPrice": 150.00,
"faceValue": 125.00,
"facilityFee": 10.00,
"serviceCharge": 15.00,
"quantity": 200
},
{
"listPrice": 85.00,
"faceValue": 70.00,
"facilityFee": 5.00,
"serviceCharge": 10.00,
"quantity": 450
}
]
}
Sales
Base path: /api/v1/sales
Auth (all routes): sales:read
POST /
List events by sale date range (presale/public sale start dates).
Request Body:
{
"filters": {
"eventId": "abc123",
"saleStartDate": "2025-06-01",
"saleEndDate": "2025-06-30",
"status": "onsale",
"sort": "date",
"order": "desc",
"page": 0,
"limit": 25
}
}
Response (200):
{
"data": {
"events": [ "...EventData[]..." ]
},
"total": 100,
"count": 25,
"page": 0,
"total_pages": 4,
"pages_remaining": 3,
"limit": 25
}
GET /event/:eventId
Get sales by event ID.
Response (200):
{
"message": "Get sales by event",
"eventId": "abc123"
}
Artists
Base path: /api/v1/artists
Auth (all routes): artists:read
GET /:id/genre
Get genre classification for an artist by legacy ID.
Response (200):
{
"artist_id": "K8vZ917...",
"artist_name": "Artist Name",
"genre": "Rock",
"sub_genre": "Alternative",
"sub_type": "Band",
"segment": "Music",
"url": "https://..."
}
Secondaries
Base path: /api/v1/secondaries
Auth (all routes): secondaries:read
All secondaries routes pass through logging and rate-limit middleware.
Listings are normalized into a shared shape. Sections are grouped into zones
(100s, 200s, …; sections under 100 become Floor; named areas like GA
stay as-is). getIn is the cheapest listing price; highTicket is the most
expensive.
Single-marketplace listing endpoints populate getIn, highTicket, and
breakdown. GET /all/listings and GET /compare/ticketmaster/:id merge
listings across sources and do not aggregate those top-level fields.
GET /compare/ticketmaster/:id
Compare Ticketmaster dropped-seat (primary) get-in prices per zone against
StubHub, Vivid Seats, Gametime, and SeatGeek get-in prices for the same event.
:id is a Ticketmaster event ID. Linked marketplace IDs are resolved from the
event record (stubhub, vividseats, gametime, and seatgeek when present).
A marketplace with no linked ID is skipped.
percentChange is the change from the primary get-in to the secondary get-in:
positive means the secondary market is more expensive (markup); negative means
it is cheaper than the dropped-seat price.
Auth: secondaries:read
Params:
id(path) -- Ticketmaster event ID
Response (200):
{
"total": 4200,
"totalListings": 980,
"getIn": 0,
"highTicket": 0,
"eventIds": {
"ticketmaster": "abc123",
"stubhub": "104512345",
"vividseats": "3845123",
"seatgeek": "6123456",
"gametime": "gt_abc123"
},
"comparison": [
{
"zone": "100s",
"primaryGetIn": 89.50,
"primaryPriceBreaks": [
{ "price": 89.50, "seats": 24 },
{ "price": 125.00, "seats": 18 }
],
"marketplaces": [
{
"marketplace": "gametime",
"getIn": 112.00,
"difference": 22.50,
"percentChange": 25.14
},
{
"marketplace": "stubhub",
"getIn": 145.00,
"difference": 55.50,
"percentChange": 62.01
},
{
"marketplace": "vividseats",
"getIn": 138.00,
"difference": 48.50,
"percentChange": 54.19
}
]
}
],
"listings": [
{
"marketplace": "stubhub",
"section": "111",
"row": "12",
"qty": 2,
"price": 145.00,
"formattedPrice": "$145.00"
},
{
"marketplace": "ticketmaster",
"section": "111A",
"row": "14",
"qty": 1,
"price": 89.50,
"formattedPrice": "$89.50"
}
]
}
Primary listings use all-in price (faceValue + facilityFees + serviceCharge).
primaryPriceBreaks only count Ticketmaster seats that are currently in stock.
Errors:
400-- Missing event ID500-- Failed to load the event, dropped seats, or marketplace listings
GET /all/listings
Fetch listings from multiple marketplaces in one request and return them as a
single combined list.
At least one of vividId, stubhubId, gametimeId, or seatgeekId is
required. Each marketplace is fetched only when its id is provided.
Auth: secondaries:read
Query Params:
vividId(optional) -- Vivid Seats event IDstubhubId(optional) -- StubHub event IDgametimeId(optional) -- Gametime event IDseatgeekId(optional) -- SeatGeek event IDzoneId(optional) -- StubHub zone/selection filter (selection). Ignored
for Vivid Seats, Gametime, and SeatGeek.
Response (200):
{
"total": 850,
"totalListings": 210,
"getIn": 0,
"highTicket": 0,
"listings": [
{
"marketplace": "vividseats",
"section": "111",
"row": "8",
"qty": 2,
"price": 138.00,
"formattedPrice": "138.00"
},
{
"marketplace": "stubhub",
"section": "111",
"row": "12",
"qty": 2,
"price": 145.00,
"formattedPrice": "$145.00"
},
{
"marketplace": "gametime",
"section": "112",
"row": "4",
"qty": 3,
"price": 112.00,
"formattedPrice": "$112.00"
}
]
}
A marketplace that fails to fetch is omitted from the result (the others still
return). breakdown is not populated on this endpoint.
Errors:
400-- No marketplace event ID was provided
GET /stubhub/listings/:id
Get StubHub listings for an event, with zone-level breakdown.
Auth: secondaries:read
Params:
id(path) -- StubHub event IDzoneId(query, optional) -- Zone/selection filter (selection)
Response (200):
{
"total": 420,
"totalListings": 95,
"getIn": 89.00,
"highTicket": 650.00,
"breakdown": {
"stubhub": {
"count": 420,
"getIn": 89.00,
"highTicket": 650.00,
"zones": {
"100s": {
"seats": 180,
"listings": 40,
"getIn": 145.00,
"highTicket": 425.00
},
"200s": {
"seats": 240,
"listings": 55,
"getIn": 89.00,
"highTicket": 650.00
}
}
}
},
"listings": [
{
"marketplace": "stubhub",
"section": "111",
"row": "12",
"qty": 2,
"price": 145.00,
"formattedPrice": "$145.00"
}
]
}
Errors:
400-- Missing event ID500-- Failed to get listings
GET /vividseats/listings/:id
Get Vivid Seats listings for an event, with zone-level breakdown.
Prices are all-in (aip).
Auth: secondaries:read
Params:
id(path) -- Vivid Seats event ID
Response (200):
{
"total": 310,
"totalListings": 72,
"getIn": 92.00,
"highTicket": 480.00,
"breakdown": {
"vividseats": {
"count": 310,
"getIn": 92.00,
"highTicket": 480.00,
"zones": {
"100s": {
"seats": 140,
"listings": 30,
"getIn": 138.00,
"highTicket": 380.00
}
}
}
},
"listings": [
{
"marketplace": "vividseats",
"section": "111",
"row": "8",
"qty": 2,
"price": 138.00,
"formattedPrice": "138.00"
}
]
}
Errors:
400-- Missing event ID500-- Failed to get listings
GET /gametime/listings/:id
Get Gametime listings for an event, with zone-level breakdown.
Prices are all-in totals (cents converted to dollars).
Auth: secondaries:read
Params:
id(path) -- Gametime event ID
Response (200):
{
"total": 120,
"totalListings": 43,
"getIn": 78.00,
"highTicket": 320.00,
"breakdown": {
"gametime": {
"count": 120,
"getIn": 78.00,
"highTicket": 320.00,
"zones": {
"Floor": {
"seats": 48,
"listings": 16,
"getIn": 210.00,
"highTicket": 320.00
},
"100s": {
"seats": 72,
"listings": 27,
"getIn": 78.00,
"highTicket": 195.00
}
}
}
},
"listings": [
{
"marketplace": "gametime",
"section": "112",
"row": "4",
"qty": 3,
"price": 112.00,
"formattedPrice": "$112.00"
}
]
}
Errors:
400-- Missing event ID500-- Failed to get listings
GET /seatgeek/listings/:id
Get SeatGeek listings for an event, with zone-level breakdown.
:id is a SeatGeek numeric event ID. Every seller channel is included (box
office and resale). price is the all-in price per ticket and qty is the
listing quantity.
SeatGeek sits behind DataDome; challenges are solved transparently. A cold
call takes a couple of seconds, and later calls for the same event reuse the
session.
Auth: secondaries:read
Params:
id(path) -- SeatGeek event ID
Response (200):
{
"total": 3961,
"totalListings": 1064,
"getIn": 89.00,
"highTicket": 1494.72,
"breakdown": {
"seatgeek": {
"count": 3961,
"getIn": 89.00,
"highTicket": 1494.72,
"zones": {
"100s": {
"seats": 2140,
"listings": 612,
"getIn": 89.00,
"highTicket": 1494.72
}
}
}
},
"listings": [
{
"marketplace": "seatgeek",
"section": "105",
"row": "1",
"qty": 2,
"price": 1494.72,
"formattedPrice": "$1494.72"
}
]
}
Errors:
400-- Missing event ID404-- Event not found500-- Failed to get listings
Available Auth Scopes
| Scope | Description | Includes |
|---|---|---|
events:read |
Read event data | — |
price:read |
Read pricing data | events:read |
active-price:read |
Read active/real-time prices | events:read |
stock:read |
Read live stock data | events:read |
limited-stock:read |
Read limited stock (price breaks) | events:read, stock:read |
code:read |
Read presale codes | events:read |
get-ins:read |
Read get-in prices | events:read |
sales:read |
Read sales data | events:read |
artists:read |
Read artist data | events:read |
secondaries:read |
Read secondary-market listings | events:read |
The
Includescolumn lists scopes automatically granted when this scope is subscribed. For example, subscribing toactive-price:readalso grantsevents:readandprice:readat no additional cost — you only pay theactive-price:readtier price.
Scope Pricing
Each scope is priced individually based on the customer's monthly request volume for endpoints covered by that scope. Prices below are in USD per month and represent the flat monthly cost for the included request quota in that tier. Subscribing to any scope automatically grants the bundled scopes listed in the Available Auth Scopes table (e.g. every paid scope includes events:read).
Tiers are billed monthly. A customer subscribes to one tier per scope. Combined / bundled pricing is negotiated separately for Enterprise.
| Scope | Tier 1 — up to 1K req/mo | Tier 2 — up to 10K req/mo | Tier 3 — up to 50K req/mo | Enterprise (100K+ req/mo) |
|---|---|---|---|---|
events:read |
$200 | $500 | $1,000 | Contact sales |
price:read |
$TBD | $TBD | $TBD | Contact sales |
active-price:read |
$300 | $750 | $1,250 | Contact sales |
stock:read |
$400 | $900 | $2,000 | Contact sales |
limited-stock:read |
$450 | $1000 | $2,200 | Contact sales |
code:read |
$300 | $750 | $1,250 | Contact sales |
get-ins:read |
$300 | $750 | $1,250 | Contact sales |
sales:read |
$300 | $750 | $1,250 | Contact sales |
artists:read |
$220 | $525 | $1,050 | Contact sales |
secondaries:read |
$TBD | $TBD | $TBD | Contact sales |
Billing Notes
- A "request" is any successful (
2xx) or client-error (4xx, excluding429) response on an endpoint that requires the given scope. 429(rate-limited) and5xxresponses are not billed.- If an endpoint requires multiple scopes (e.g.
/events/:id/sectioned-pricingrequiresevents:read+price:read), the request counts against each subscribed scope's quota. - Unused quota does not roll over month to month.
- Exceeding a tier's request quota requires upgrading to the next tier for the following billing period.
Common Error Responses
All error responses follow this format:
{
"error": "Description of the error"
}
| Status | Meaning |
|---|---|
400 |
Bad request / missing required parameters |
401 |
Missing or invalid API key |
403 |
Insufficient permissions (wrong scopes) |
404 |
Resource not found |
429 |
Rate limit exceeded |
500 |
Internal server error |
Rate Limit Error (429):
{
"error": "Rate limit exceeded",
"retry_after": 1200.5,
"reset_time": "2025-06-15T15:30:00Z",
"rate_limit": {
"requests_per_window": 100,
"window_duration_seconds": 3600
}
}
Rate limit headers are included on all authenticated responses:
X-RateLimit-Limit-- Max requests per windowX-RateLimit-Remaining-- Remaining requestsX-RateLimit-Reset-- Unix timestamp when window resets