Purchase Flow
Four-step flow to browse, reserve, and purchase tickets via the TTG API.
1. Browse Occurrences
Returns dates with pricing summaries. fromPrice: null means sold out or off-sale — filter these out.
The discount fields (maxDiscountPercentage or maxDiscountAmount) represent the best available discount across all price points. They may come from a different price point than fromPrice.
2. Browse Inventory
Returns purchasable items. Use inventoryVariant._type to determine the type:
Pricing: sellPrice is the all-in price customers pay (fees included). listPrice appears only when a discount exists — display as strikethrough.
Example response (trimmed):
3. Create Cart
Reserves inventory and starts a hold timer. All items must be from the same occurrence.
The response includes expiresAt (UTC) — display a countdown. When the cart expires, inventory is released and GET /api/v3/carts/{cartId} returns 404. Create a new cart to continue.
To release held inventory early: DELETE /api/v3/carts/{cartId} (idempotent, returns 204).
4. Checkout
expectedTotal must match the cart total exactly. If prices changed, the server returns 409 — re-fetch the cart and confirm the new price with the customer.
On success, tickets are in items[].tickets[] — each with a barcode (value, format, optional imageUrl).
Receipt Rendering
Both cart and order responses include receiptLines[]. Render them in order — do not compute totals client-side.
Each line has sign: positive = charge, negative = credit/discount. All total.amount values are positive integers.
Common Errors
For the full error format and retry strategy, see Error Handling.