Skip to navigation

Migration: Search to Events

Guide for moving from the Encore API’s GET /api/v4/search endpoint to GET /api/v3/events in the TTG Storefront API v3, the newer API. The two APIs number their versions separately.

For the full v4 search reference, see Search on the legacy portal.

Endpoint Comparison

Legacy (v4)New (v3)
MethodGETGET
Path/api/v4/search/api/v3/events
AuthNone — the optional affiliateId header only picks the retailerX-TT-API-Key, X-TT-Retailer and X-TT-Platform headers
ScopeFree-text query across all productsEvents the retailer sells in one market, with an optional free-text query
PaginationNot built inlimit / offset with a pagination block

What Changed

The v4 endpoint took a query string and searched across every product. The v3 endpoint returns the events your retailer is set up to sell, scoped to one market, and takes an optional query to narrow that list.

locationId is required and picks the market (e.g. New York, London). Get the IDs from GET /api/v3/locations.

query is optional. It matches against event name, venue, category, cast and search keywords, up to 50 characters. Omit it, or send it blank, to list the whole catalog for the market.

# Legacy — text search
GET /api/v4/search?query=hamilton
# New — the retailer's events in one market
GET /api/v3/events?locationId=1
# New — the same list, narrowed by a search term
GET /api/v3/events?locationId=1&query=hamilton

Authentication

Legacy search needed no key; the optional affiliateId header only picked the retailer. v3 needs the three headers in Authentication & Headers on every call. The events you get back are the ones your retailer can sell.

Pagination

v3 lists come one page at a time, with a pagination block that says when to stop. See Pagination.

Terminology

Legacy (v4)New (v3)Notes
ProductEventSame concept — a show or experience
venue.idlocationNot a rename — location is the market (e.g. New York), not the venue. Venue detail comes back per-occurrence, not on the event.
typeproductTypeUpper-case enum values: ATTRACTION, BUS_TOUR, GIFT_CARD, SHOW, STREAMING
bookingStarts / bookingEndsstartDate / endDateThe run’s date range (YYYY-MM-DD)
onSale(implicit)Only events the retailer can sell are listed; fromPrice: null means nothing is on sale right now

Response Shape

Legacy (v4)

{
"id": 123,
"name": "Hamilton",
"type": "show",
"venue": { "id": "789" },
"onSale": "true",
"bookingStarts": "2026-03-01T00:00:00Z",
"bookingEnds": "2026-12-31T00:00:00Z"
}

New (v3)

{
"data": [
{
"id": "123",
"name": "Hamilton",
"productType": "SHOW",
"slug": "hamilton-broadway",
"fromPrice": { "amount": 8900, "currency": "USD" },
"maxDiscountPercentage": 25,
"orderLimit": { "min": 1, "max": 8 },
"startDate": "2026-03-01",
"endDate": "2026-12-31",
"location": { "id": "1", "name": "New York", "country": "US", "slug": "nyc" }
}
],
"pagination": { "limit": 50, "offset": 0, "total": 1 }
}

Key differences:

  • id is an opaque string — pass it to GET /api/v3/events/{eventId}/occurrences, never parse it (see IDs)
  • startDate and endDate are both nullable — an open-ended run returns null for either. Handle both explicitly.
  • The market is a location object with id, name, country, and slug, not a bare venue.id
  • slug is the event’s URL path segment on the TodayTix website; it can be null for events without one
  • name is the event’s full title — use it on the product card
  • fromPrice is the lowest regular ticket price on sale across the event’s occurrences (its dates and times), as a Money object in the event’s base currency (see Currency). It is null when no regular tickets are on sale (sold out, off sale, or not yet on sale).
  • maxDiscountPercentage is the best discount on sale as a whole number (25 means “Save 25%”). It is omitted, not null, when there is no discount or the event does not present savings as a percentage.
  • orderLimit gives the min and max ticket quantity a single order may contain. It is set per event and applies to every occurrence; each occurrence also carries the same orderLimit.

Migration Checklist

  1. Send X-TT-API-Key, X-TT-Retailer and X-TT-Platform on every call; drop affiliateId
  2. Look up the market you sell with GET /api/v3/locations, then pass it as ?locationId=
  3. Keep passing your search term as query, now alongside locationId
  4. Treat id as an opaque string — store it, don’t parse it
  5. Read startDate / endDate instead of bookingStarts / bookingEnds; both can be null
  6. Render product cards from name, fromPrice and maxDiscountPercentage, and bound the quantity selector with orderLimit
  7. Page with limit / offset until offset >= pagination.total

Next Steps

After listing events, continue with the full Purchase Flow:

  1. Browse Occurrences — GET /api/v3/events/{eventId}/occurrences (see Availability → Occurrences)
  2. Browse Inventory — GET /api/v3/events/{eventId}/occurrences/{occurrenceId}/inventory-items
  3. Create Cart — POST /api/v3/carts
  4. Checkout — POST /api/v3/orders