Purchase Flow
Five-step flow to browse, reserve, and purchase tickets via the TTG API, plus an optional step to add extras to the cart.
This page documents direct v3 API integration. For TTG-hosted checkout, see Whitelabel Checkout. For agent/reseller flows on the v1/v4 stack, see Powered by TodayTix Agent APIs.
1. List Events
Returns a paginated list of events the authenticated retailer has access to. The locationId query parameter is required — it filters events by market (e.g., New York, London).
Use limit and offset for pagination. Each event includes id, name, startDate, endDate, and location.
2. Browse Occurrences
Returns dates with pricing summaries, sold-out dates included. Use availabilityLevel to drive the calendar UI: SOLD_OUT (nothing to buy on this date — fromPrice is also null), LOW (tickets are running out), or null (no signal — display normally). An occurrence with a null fromPrice is never buyable.
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.
3. Browse Inventory
Returns purchasable items. Use inventoryVariant._type to determine the type:
For full details on each type, attributes, and pricing, see Inventory Types.
Pricing: sellPrice is the all-in price customers pay (fees included). listPrice appears only when a discount exists — display as strikethrough.
Example response (trimmed):
4. Create Cart
Reserves inventory and starts a hold timer. All items must be from the same occurrence. The cart is created in a currency — the event’s base currency unless the body names a currency — and carries it on the response. To pay in another currency, PATCH the cart before checkout (see Currency).
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).
5. Add Extras (optional)
Some events offer extras — add-ons such as merchandise, drinks, or parking. The cart response lists them under options.extras, each in the same inventory-item shape as seats and GA (see Inventory Types). The key is absent when the event offers none.
Add one to the cart with its inventory item ID and one of its price option IDs:
Returns 201 with the updated cart. The extra appears in items[] with an Extra inventory variant, and in the cart total and receiptLines[]. Sending the same extra and price option again increases its quantity.
Rules:
- Only extras can be added to an existing cart. To change seats, create a new cart.
occurrenceIdmust match the cart’s occurrence — a mismatch returns400.- Quantity is capped by the lowest of
quantityAvailable, the item’smaxQuantityPerOrder, and the price option’smaxQuantityPerOrder. - If the extra is no longer available, the request returns
409. If the cart has expired, it returns404— create a new cart.
6. Checkout
expectedTotal is the cart’s total, echoed back exactly — same amount, same currency. GET /api/v3/carts/{cartId} returns:
Send that object straight through as expectedTotal (as above) — don’t recompute it. A value that doesn’t match returns 400 with code EXPECTED_TOTAL_MISMATCH.
The order settles in the cart’s currency; the POST /orders call takes no currency input, so to pay in another currency PATCH the cart first (see Currency).
If the customer is checking out on a device you can see — a browser or a mobile app — describe it with the optional X-TT-Device-Data header, as JSON:
Sending it scores card payments for fraud on more signal, so fewer genuine customers are declined.
Integrating server-to-server? If there’s no end-user device in the request path, leave the header off. It’s optional and the order places normally without it.
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.