Migration: Availability to Occurrences

Guide for migrating from the legacy GET /api/v4/availability/products/{productId}/... endpoint to the new GET /api/v3/events/{eventId}/occurrences endpoint.

Endpoint Comparison

Legacy (v4)New (v3)
MethodGETGET
Path/api/v4/availability/products/{productId}/quantity/{quantity}/from/{fromDate}/to/{toDate}/api/v3/events/{eventId}/occurrences
AuthX-TT-API-Key headerX-TT-API-Key header
FilteringDate range and quantity in URL pathOptional quantity, startDate, endDate query parameters

What Changed

Simplified URL

The v4 endpoint encoded filters (quantity, date range) in the URL path. The v3 endpoint moves these to optional query parameters.

# Legacy
GET /api/v4/availability/products/123/quantity/2/from/2026-03-15/to/2026-03-31
# New (all filters optional)
GET /api/v3/events/123/occurrences?quantity=2&startDate=2026-03-15&endDate=2026-03-31
# New (no filters — returns all upcoming occurrences)
GET /api/v3/events/123/occurrences

Terminology

Legacy (v4)New (v3)Notes
ProductEventSame concept — a show or experience
productIdeventIdUse the same ID value
AvailabilityOccurrenceEach date/time slot is now an “occurrence”
Date slotsstartsAt / endsAtISO 8601 with venue timezone offset
Price (major units)fromPrice (minor units)$85.00 becomes { amount: 8500, currency: "USD" }

Quantity and Date Range Are Now Optional Query Parameters

In v4, quantity, from, and to were required path segments. In v3, they are optional query parameters:

v4 (path)v3 (query param)Notes
/quantity/{quantity}?quantity=2Optional. Filters to occurrences with at least this many tickets available. Omit to return all.
/from/{fromDate}?startDate=2026-03-15Optional. Inclusive start date (ISO 8601 YYYY-MM-DD). Interpreted in the event’s local timezone.
/to/{toDate}?endDate=2026-03-31Optional. Inclusive end date (ISO 8601 YYYY-MM-DD). Interpreted in the event’s local timezone.

All parameters can be combined freely or omitted entirely:

# Equivalent to v4 call with all filters
GET /api/v3/events/123/occurrences?quantity=2&startDate=2026-03-15&endDate=2026-03-31
# Only filter by date range
GET /api/v3/events/123/occurrences?startDate=2026-03-15&endDate=2026-03-31
# Only filter by quantity
GET /api/v3/events/123/occurrences?quantity=2
# No filters — all upcoming occurrences
GET /api/v3/events/123/occurrences

Money Format

Prices changed from decimal (major units) to integer (minor units) with explicit currency.

Legacy (v4):

1{ "price": 85.00 }

New (v3):

1{ "fromPrice": { "amount": 8500, "currency": "USD" } }

All monetary values in v3 use minor units (cents for USD, pence for GBP). Divide by 100 for display.

Availability Status

Legacy (v4)New (v3) Equivalent
Available dates returnedfromPrice is non-null
Sold-out dates excludedfromPrice: null — filter these out in browse UI
Off-sale dates excludedfromPrice: null — same as sold out from client perspective

Discount Information

The v3 endpoint adds discount data not available in v4:

  • maxDiscountPercentage — Best available % discount (e.g., 29 = “Up to 29% off”)
  • maxDiscountAmount — Best available amount discount (e.g., { amount: 5000, currency: "USD" } = “Save up to $50”)

These fields are optional — omitted when no discount exists.

Response Shape

Legacy (v4)

1{
2 "data": [
3 {
4 "date": "2026-03-15",
5 "time": "19:30",
6 "price": 85.00,
7 "currencyCode": "USD",
8 "available": true
9 }
10 ]
11}

New (v3)

1{
2 "data": [
3 {
4 "id": "123",
5 "startsAt": "2026-03-15T19:30:00-05:00",
6 "endsAt": "2026-03-15T22:30:00-05:00",
7 "fromPrice": {
8 "amount": 8500,
9 "currency": "USD"
10 },
11 "maxDiscountPercentage": 29
12 }
13 ]
14}

Key differences:

  • Each occurrence has an id you’ll need for subsequent calls (inventory, cart)
  • startsAt includes timezone offset — no separate date/time fields
  • endsAt is nullable (some events have no fixed end time)
  • fromPrice is null instead of available: false

Migration Checklist

  1. Replace productId with eventId in your integration
  2. Update the endpoint URL from v4 path to GET /api/v3/events/{eventId}/occurrences
  3. Move quantity from URL path to ?quantity= query parameter (now optional)
  4. Move date range from URL path to ?startDate= and ?endDate= query parameters (now optional)
  5. Update price parsing: divide fromPrice.amount by 100 for display (or appropriate factor for the currency)
  6. Store the occurrence id — you need it for inventory browsing and cart creation
  7. Filter out occurrences where fromPrice is null (sold out or off-sale)
  8. Optionally display discount badges using maxDiscountPercentage or maxDiscountAmount

Next Steps

After migrating the browse step, continue with the full Purchase Flow:

  1. Browse InventoryGET /api/v3/events/{eventId}/occurrences/{occurrenceId}/inventory-items
  2. Create CartPOST /api/v3/carts
  3. CheckoutPOST /api/v3/orders