Migration: Baskets to Carts
Migration: Baskets to Carts
Guide for migrating from the legacy PATCH /api/v1/baskets flow to the new POST /api/v3/carts flow.
For the full v1 basket reference, see Baskets on the legacy portal.
Endpoint Comparison
What Changed
The server owns the cart ID
In v1 you supplied a unique reference and a checksum password, then PATCHed the same basket to build it up. In v3 you POST the items you want and the server returns a cartId. There’s no reference to invent and no checksum to manage — the API key authenticates you.
From reservations to items
Legacy grouped tickets into reservations, each with a productId, a quantity, and opaque aggregateReference item tokens that bundled the price inside them. v3 takes a flat items list. Each item names the occurrence, the inventory item, and the price option separately.
Get inventoryItemId and priceOptionId from the inventory step (see Areas → Inventory Items). All items must belong to the same occurrence.
The hold timer is explicit
Legacy baskets held inventory, but the expiry wasn’t part of the response. v3 returns expiresAt (UTC) on the cart — show a countdown. When it passes, the hold is released and GET /api/v3/carts/{cartId} returns 404. Create a new cart to continue. To release a hold early, DELETE /api/v3/carts/{cartId} (idempotent, returns 204).
Discounts move to a voucher endpoint
Legacy applied a coupon inline on the basket or through applyPromotion. v3 has a dedicated pair:
The discount shows up in the cart’s receiptLines[] and total.
Changing seats means a new cart
Legacy let you drop a single reservation with DELETE .../reservations/{reservationId}. In v3 a cart’s seats are fixed once created — to change them, create a new cart. Only extras can be added to a live cart, with POST /api/v3/carts/{cartId}/items (see Purchase Flow).
Money format
Both are minor units; v3 drops decimalPlaces — derive the scale from the currency. A cart owns its currency: it’s set at creation (base, or the body’s currency when supported) and switched with PATCH /api/v3/carts/{cartId} { "currency": "EUR" }. See Currency.
Totals come from the server
Don’t compute the total yourself. Read total and render receiptLines[] in order — each line has a sign (positive = charge, negative = credit). You’ll pass total straight through as expectedTotal at checkout.
Response Shape
New (v3)
Key differences:
idis the server-generated cart ID — stable, safe to store (see IDs)expiresAtis the hold deadline in UTC — drive a countdown from itoptions.extraslists add-ons you can attach; the key is absent when the event offers noneoptions.currencieslists the currencies the cart can be priced in
Migration Checklist
- Replace
PATCH /api/v1/basketswithPOST /api/v3/carts; let the server return thecartId - Drop the self-assigned
referenceandchecksum; authenticate with the API key - Convert
reservationsto a flatitemslist keyed byoccurrenceId,inventoryItemId, andpriceOptionId - Keep all items in one cart to a single occurrence
- Read
expiresAtand show a countdown; handle the404on expiry by creating a new cart - Move promo codes to
POST /api/v3/carts/{cartId}/vouchers - Replace single-reservation removal with “create a new cart”; use
DELETEto release a hold - Read
totalandreceiptLines[]from the server — don’t recompute; dropdecimalPlaces
Next Steps
With a cart held, continue the Purchase Flow:
- Add Extras (optional) —
POST /api/v3/carts/{cartId}/items - Checkout —
POST /api/v3/orders(see Checkout → Orders)