Migration: Areas to Inventory Items
Migration: Areas to Inventory Items
Guide for migrating from the legacy GET /api/v4/products/{productId}/areas and detailed availability endpoints to the new GET /api/v3/events/{eventId}/occurrences/{occurrenceId}/inventory-items endpoint.
For the full v4 inventory reference, see Product Areas on the legacy portal.
Endpoint Comparison
What Changed
One call, not two
The legacy flow used /detailed availability to size up a performance, then /areas to pull seats and price bands. v3 replaces both with a single call per occurrence that returns every purchasable item — seats and general admission alike.
You need the occurrence id first — get it from GET /api/v3/events/{eventId}/occurrences (see Availability → Occurrences).
The legacy quantity carries over as the optional ?quantity= query parameter: the response then only includes inventory a party of that size can buy together. Omit it to see all inventory, and call again when the customer changes the ticket count.
From areas and price bands to typed items
Legacy nested seats inside areas, and areas inside price bands, controlled by groupBy (lump, priceBand). v3 returns a flat list. Each item carries an inventoryVariant with a _type that tells you what it is:
Switch on _type for rendering and quantity logic. For the full type reference, see Inventory Types.
Pricing: all-in sellPrice, not face value plus fees
Legacy split price into faceValue, orderFee, and an includesBookingFee flag, with a percentageDiscount on the side. You had to add them up. v3 gives you sellPrice — the all-in price the customer pays, fees included. When there’s a discount, listPrice carries the original for a strikethrough.
Price tiers become price options
Legacy price bands were a property of the area. v3 attaches priceOptions[] to each item — one entry per category (Adult, Child, Senior). Each has its own id, which you pass when you add the item to a cart.
Money format
Both are minor units, but v3 drops decimalPlaces — derive the scale from the currency code with your i18n library. See Money Format.
Seat attributes are always on
Legacy hid seat attributes behind includeSeatsAttributes=true. v3 always returns attributes[], each tagged with a category (POSITIVE, NEGATIVE, ACCESSIBILITY, NEUTRAL, FEATURED) so you can badge them consistently. See Inventory Types.
Response Shape
New (v3)
Key differences:
- The response is paginated — items are in
data[], with apaginationblock (limitdefault 50, max 1000). Page withlimit/offsetuntiloffset >= pagination.total. See Pagination. - The item
idis a versioned, opaque token (v1_…) — pass it whole, with apriceOptionId, toPOST /api/v3/carts.priceOptionIdhas no prefix. Never build either by hand. - Inventory item and price option IDs are ephemeral — re-fetch inventory to get fresh ones (see IDs)
inventoryVariant.idis stable across occurrences — the same seat returns the same variant ID on every date, safe to cache for seating charts
Migration Checklist
- Replace the two-call area/detailed flow with one
inventory-itemscall per occurrence - Get the occurrence
idfirst fromGET /api/v3/events/{eventId}/occurrences - Switch on
inventoryVariant._typeinstead of walking areas and price bands - Read
sellPriceas the all-in price — stop summingfaceValueandorderFee - Show
listPricestruck through when it’s present; there’s nopercentageDiscountto apply - Read each item’s
priceOptions[]for tiers; keep thepriceOptionIdfor the cart step - Drop
decimalPlaces— derive the scale from the currency code - Store the item
id(the wholev1_…token) andpriceOptionIdas opaque, ephemeral values; re-fetch to refresh them - Page the response with
limit/offsetuntil you’ve readpagination.totalitems
Next Steps
With inventory in hand, continue the Purchase Flow:
- Create Cart —
POST /api/v3/carts(see Baskets → Carts) - Checkout —
POST /api/v3/orders(see Checkout → Orders)