Skip to navigation

Inventory Types

Every inventory item contains an inventoryVariant with a _type field that determines what kind of item it represents. This guide explains the four types and how to handle them.

Seats and general admission come from the inventory list of an occurrence (one date and time of an event). Extras (merchandise, drinks, parking) are offered per cart — they appear under options.extras on the cart response, not in the occurrence inventory. Gift cards come from the inventory list of a gift-card event (productType: GIFT_CARD), one item per denomination.

Inventory Item

Each inventory item carries these fields, whatever its type:

FieldDescription
idInventory item ID — send it as inventoryItemId when you add the item to a cart
inventoryVariantWhat the item is; its _type is one of the four types below
priceOptionsThe prices the item can be bought at (see Price Options)
quantityAvailableHow many units are in stock. 0 marks a sold-out general admission area kept on display: its priceOptions is empty, so show it as unavailable and don’t add it to a cart.
maxQuantityPerOrderMost units of this item one order may hold. Omitted when there is no cap.
minQuantityPerOrderExtras only: the fewest units one order may hold (see Extra). Omitted when there is no minimum above 1.
selectionGroup, selectionBlockedAssigned seats only: how to sell the seat to a party (see Seats for a party)
requirementsExtras with their own schedule only: requirements.occurrence gives the earliestStart and latestStart of the occurrence the customer must pick for it (see Add Extras)

The Four Types

_typeWhat It Representsquantity RuleTickets on Order
AssignedSeatA specific seat (section, row, seat number)Always 11 ticket
GeneralAdmissionEntry to a GA area (e.g., Standing, Balcony)1 to quantityAvailable, within the event’s orderLimit1 per person
ExtraAn add-on such as merchandise, drinks, or parking1 up to quantityAvailable and maxQuantityPerOrder1 per unit
GiftCardOne gift-card denomination (e.g., a £50 card)Always 1, one gift card per cartNone — the order item carries giftCards[]

Discriminator Pattern

All types share a common base (id, _type, name, attributes) and the _type field tells you which one you’re dealing with. Any type can also carry description (plain text) and extendedDescription (rich text that may hold HTML or Markdown — sanitize it before rendering). Each type adds its own fields:

_typeAdds
AssignedSeatsection, row, seat; images when inventory is requested with include=IMAGES; entrance on orders
GeneralAdmissionvenueAreaIds
ExtraimageUrl, caption
GiftCardvalue

section, row, seat and value are always sent. The optional fields (images, entrance, venueAreaIds, imageUrl, caption) are left out when they have no value.

{
"inventoryVariant": {
"_type": "AssignedSeat",
"id": "ORCHESTRA-A-101",
"name": "Orchestra A 101",
"section": "Orchestra",
"row": "A",
"seat": "101",
"attributes": []
}
}
{
"inventoryVariant": {
"_type": "GeneralAdmission",
"id": "DANCE FLOOR",
"name": "Dance Floor",
"attributes": []
}
}
{
"inventoryVariant": {
"_type": "Extra",
"id": "ICE CREAM",
"name": "Ice Cream",
"attributes": []
}
}
{
"inventoryVariant": {
"_type": "GiftCard",
"id": "TODAYTIX GIFT CARD-5000",
"name": "TodayTix Gift Card",
"value": { "amount": 5000, "currency": "GBP" },
"attributes": []
}
}

Key rule: switch on _type to determine your rendering and quantity logic. Treat unknown _type values gracefully — new types may be added in the future.

AssignedSeat

Represents a specific seat in a venue. Adds these fields:

FieldDescriptionExample
sectionSeating section"Orchestra"
rowRow identifier"A"
seatSeat number"101"
imagesViews of the stage from the seat, each with a url. Only on inventory requested with include=IMAGES; empty for a seat with none.[{ "url": "https://…" }]
entranceWhere the ticket holder enters, such as a door or gate. Only on orders, and left out when the venue assigns none."Door 4"

Quantity is always 1 — each seat is a separate inventory item. To buy several seats, add one cart item per seat:

{
"items": [
{
"occurrenceId": "456",
"inventoryItemId": "v1_eyJwcm92aWRlcklkIjoxMDAwLCJzZWF0SWQiOiJPUkNIRVNUUkEtQS0xMDEifQ",
"priceOptionId": "eyJwcm92aWRlckNvZGUiOiJGVUxMUFJJQ0UiLCJob2xkQ29kZSI6IjE1NzM5In0",
"quantity": 1
},
{
"occurrenceId": "456",
"inventoryItemId": "v1_eyJwcm92aWRlcklkIjoxMDAwLCJzZWF0SWQiOiJPUkNIRVNUUkEtQS0xMDIifQ",
"priceOptionId": "eyJwcm92aWRlckNvZGUiOiJGVUxMUFJJQ0UiLCJob2xkQ29kZSI6IjE1NzM5In0",
"quantity": 1
}
]
}

Copy each ID whole from the inventory response, and never build one by hand. See IDs.

Seats for a party

List inventory with the party size as ?quantity= (see Party Size). Each seat in the response then says how to sell it:

The seat carriesWhat to do
selectionGroup.inventoryItemIdsWhen the customer picks this seat, add every id in the list to the cart, one item per seat. The list includes the seat itself and is not always quantity seats long.
selectionBlocked.chainSizeThe seat is in stock but isn’t sold to a party of this size. Show it as unavailable, keep its price on display, and don’t add it to a cart. chainSize is the party size that would make it buyable.
NeitherThe seat can’t be picked at this party size, for example because taking it would leave a single seat stranded. Show it as unavailable.

Other seats a party of this size can’t buy are left out of the list.

Without quantity, selectionBlocked is never sent and most seats carry no selectionGroup. A seat sold only in a fixed group, such as a box of four, carries its group either way: add the whole group whenever one is sent.

When a seat selection is refused

A selection that would leave a single empty seat on its own is refused with 409 ORPHANED_SEATS. The seats are free, but the venue’s ticketing system won’t sell them that way, so ask the customer to pick different seats. The venue’s system makes this check when the seats are held, so it can refuse a selection that followed selectionGroup.

GeneralAdmission

Represents entry to a general admission area. Adds one field:

FieldDescriptionExample
venueAreaIdsThe seating-chart areas this item sells into, matching the area ids on the venue’s seating chart so you can highlight them. Left out when the item isn’t tied to chart areas.["1204", "1205"]

Quantity can be 1 to quantityAvailable — a single inventory item covers multiple people. To buy 3 GA tickets, set quantity: 3 on one cart item.

{
"items": [
{
"occurrenceId": "456",
"inventoryItemId": "v1_eyJwcm92aWRlcklkIjoxMDAwLCJzZWF0SWQiOiJEQU5DRSBGTE9PUiJ9",
"priceOptionId": "eyJpc0dBIjp0cnVlLCJwcm92aWRlclBhcmFtcyI6Int9IiwicHJpY2VUeXBlSWQiOiJBRFVMVCJ9",
"quantity": 3
}
]
}

On the order, you’ll receive one ticket per person (3 tickets in this example). Each ticket’s barcode is null until the venue releases it — see After Checkout.

Extra

Represents an add-on sold alongside tickets — merchandise, drinks, parking, and similar. Adds these fields, each left out when the seller hasn’t set it:

FieldDescriptionExample
imageUrlA picture of the extra"https://images.example.com/wine.jpg"
captionA short label, such as a serving size"175ml"

Extras are discovered on the cart, not on the occurrence. After you create a cart, the cart response lists the extras you can add under options.extras, each in the same inventory-item shape as seats and GA. An extra with its own schedule (a guided tour, parking) is found there too; its categories and prices for the time the customer picks come from that occurrence’s inventory-items. Add one or several with POST /api/v3/carts/{cartId}/items, change how many with PATCH /api/v3/carts/{cartId}/items/{itemId}, and drop one with DELETE /api/v3/carts/{cartId}/items/{itemId} — see Purchase Flow.

{
"id": "v1_eyJwcm92aWRlcklkIjoxLCJzZWF0SWQiOiIxOCJ9",
"inventoryVariant": {
"_type": "Extra",
"id": "ICE CREAM",
"name": "Ice Cream",
"attributes": []
},
"priceOptions": [
{ "id": "eyJpc0FkZE9uIjp0cnVlLCJwcmljZVR5cGVJZCI6IjExIn0", "category": { "name": "Adult" }, "sellPrice": { "amount": 4500, "currency": "USD" }, "maxQuantityPerOrder": 4 },
{ "id": "eyJpc0FkZE9uIjp0cnVlLCJwcmljZVR5cGVJZCI6IjEyIn0", "category": { "name": "Child" }, "sellPrice": { "amount": 1500, "currency": "USD" }, "maxQuantityPerOrder": 2 }
],
"quantityAvailable": 20,
"maxQuantityPerOrder": 6
}

Quantity can be more than 1, like GA. The cart refuses a quantity over either of these:

  • quantityAvailable — how many are in stock.
  • maxQuantityPerOrder on a price option — how many units one order may contain at that price option. Omitted when that option has no cap of its own.

The item also carries maxQuantityPerOrder — how many of this extra one order should contain, across all its price options. Omitted when there is no item cap. The cart doesn’t check this one yet, so cap your quantity picker at it yourself.

Some extras also set a floor. minQuantityPerOrder on the item is the fewest units one order may hold, counted across all its price options: with a minimum of 4, 2 Adult and 2 Child is enough. Omitted when the extra has no minimum above 1.

An extra always appears as an order item and on the receipt, with one ticket per unit in tickets[].

GiftCard

Represents one denomination of a gift card. A £25 card and a £50 card are two inventory items. Has one additional field:

FieldDescriptionExample
valueThe balance the card is issued with. Separate from priceOptions[].sellPrice, which is what the customer pays: a card sold at a discount is still worth its full value. Always in the currency the card can be spent in — the event’s base currency, never the one requested with currency.{ "amount": 5000, "currency": "GBP" }

A gift card’s name is the name of its gift-card section, so every denomination shares it — show value to tell them apart. Its id looks like TODAYTIX GIFT CARD-5000, and can carry more after the value when two cards share a denomination. Like every ID, copy it as returned; don’t build or parse it. In carts and orders a gift card’s id is null.

A gift-card event’s occurrence and venue are bookkeeping placeholders. Don’t render a date, a time, or a venue for a gift card.

A cart that breaks one of these rules is refused — see Error Handling:

  • quantity is always 1 (GIFT_CARD_QUANTITY_NOT_SUPPORTED).
  • A cart holds one gift card; place a separate order for each card (MULTIPLE_GIFT_CARDS_NOT_SUPPORTED).
  • Gift cards and tickets check out in separate carts (MIXED_PRODUCT_TYPES_NOT_SUPPORTED).
  • A voucher can’t be applied to a gift-card cart (VOUCHER_NOT_APPLICABLE_TO_GIFT_CARD).

On the order, a gift-card item carries no tickets[]. It carries giftCards[] instead, one entry per card issued: the code the recipient redeems, its face value, the balance left to spend (left out when the card doesn’t track one), and expiresOn, the last day it can be used (left out when the card doesn’t expire). Exactly one of tickets[] and giftCards[] is present on an order item.

{
"giftCards": [
{
"code": "GC123456789",
"value": { "amount": 5000, "currency": "GBP" },
"balance": { "amount": 5000, "currency": "GBP" },
"expiresOn": "2027-10-14"
}
]
}

The code is money: anyone who has it can spend the card. Show it only to the buyer. Your cartId reads the order back, code included, without the buyer signing in, so keep it on your server and never put it in a page, a link or a log.

Inventory Attributes

All types can carry attributes[] — tags that describe characteristics of the inventory. Use these for display purposes (badges, filters, icons).

Each attribute has:

FieldTypeDescription
namestringDisplay label (e.g., "Restricted View", "Premium")
descriptionstring or nullOptional detail (e.g., "Pillar may partially obstruct the stage")
categoryenumRendering hint — see below

Attribute Categories

CategoryMeaningSuggested Rendering
POSITIVEDesirable traitGreen badge or checkmark
NEGATIVELimitation or restrictionWarning icon or amber badge
NEUTRALInformationalPlain text or gray badge
FEATUREDHighlighted / promotedStar or highlight treatment
ACCESSIBILITYAccessibility featureAccessibility icon

Example with attributes:

{
"inventoryVariant": {
"_type": "AssignedSeat",
"id": "Balcony-B-15",
"name": "Balcony B 15",
"section": "Balcony",
"row": "B",
"seat": "15",
"attributes": [
{ "name": "Restricted View", "description": "Pillar may partially obstruct the stage", "category": "NEGATIVE" },
{ "name": "Wheelchair Accessible", "description": null, "category": "ACCESSIBILITY" }
]
}
}

Price Options

Each inventory item has one or more priceOptions[] — the available price categories for that item (e.g., Adult, Child, Senior).

FieldDescription
idPrice option ID (use when creating cart items)
category.idCategory ID, matched by constraints.requiresCategory. Omitted when the item has a single price.
category.nameDisplay name (e.g., "Adult", "Child")
sellPriceAll-in price the customer pays (fees and tax included)
listPriceOriginal price before discount — display as strikethrough. Omitted when there’s no discount, the saving can’t be shown, and on cart and order items.
discountPercentageWhole-number percentage saved, for a “Save 30%” label. Use it rather than working one out from listPrice. Omitted when there’s no saving to show.
discountAmountAmount saved, for when the saving may be shown as an amount but not as a percentage. Never sent with discountPercentage.
feesThe fees inside sellPrice, one per fee type. Never add them to a price. Omitted when the market doesn’t require fee disclosure.
maxQuantityPerOrderMost units one order may contain at this price option. Omitted when the option has no cap.
constraintsSelection rules. constraints.requiresCategory lists category.ids, at least one of which must also be in the order (for example, a Child ticket bought with an Adult one). Omitted when the option can be bought on its own. Only some venues’ systems refuse an order that breaks the rule, so apply it in your own UI.
isDefaulttrue for the option to pre-select. Omitted when false.
promotionThe promotion that applies to this option. Omitted when none does.

When listPrice is present, the customer is getting a deal:

{
"priceOptions": [
{
"id": "eyJwcm92aWRlckNvZGUiOiJGVUxMUFJJQ0UiLCJob2xkQ29kZSI6IjE1NzM5In0",
"category": { "name": "Adult" },
"listPrice": { "amount": 15000, "currency": "USD" },
"sellPrice": { "amount": 12500, "currency": "USD" }
}
]
}

Display: 150.00 USD → 125.00 USD

When there’s no discount, listPrice is absent — just show sellPrice.

Stable Variant IDs

Inventory variant id values are stable across all occurrences of the same event. The same seat returns the same variant id regardless of which date the customer picks. This is important if you’re building seating charts or caching seat metadata. This is inventoryVariant.id, not the inventory item’s own id, which you re-fetch before each cart (see IDs).

A seat or general admission area also has the same inventoryVariant.id in inventory items, carts and orders, so you can match a cart or order line to the item the customer picked.

Rendering Summary

ScenarioDisplay
_type: AssignedSeatShow section, row, seat. Quantity locked to 1. Add the whole selectionGroup when one is sent. With ?quantity=, show a seat without one as unavailable.
_type: GeneralAdmissionShow name. Let customer pick quantity up to quantityAvailable and the event’s orderLimit.max. Show an item with quantityAvailable: 0 as sold out.
_type: ExtraShow name. Cap the quantity picker at the lowest of quantityAvailable, the item’s maxQuantityPerOrder, and the selected price option’s maxQuantityPerOrder. When minQuantityPerOrder is present, show it and don’t let the customer add fewer than that many.
_type: GiftCardShow name and value. Quantity locked to 1. Don’t show a date, time, or venue.
attributes[] presentRender badges/icons using category for styling.
listPrice presentShow strikethrough original price next to sellPrice.