Skip to main content

Data Models

This page describes the data structures used in the Storefront API.

Basket​

The basket represents the shopping cart state.

interface Basket {
items: LineItem[];
promoCode: string | null;
stage: BasketStage;
}

Properties​

PropertyTypeDescription
itemsLineItem[]Array of line items in the basket
promoCodestring | nullThe currently applied promotional code
stageBasketStageThe current stage of the basket

BasketStage​

ValueDescription
BasketThe basket is active and accepts modifications
SettledThe order has been completed; the basket can no longer be modified

Product​

A product represents a voucher that can be added to the basket. Products are retrieved using the GetVouchers method.

interface Product {
id: string;
catalogueId: string;
name: string;
venueName: string | null;
price: Money;
isPrivate: boolean;
limitedAvailability: unknown | null;
marketingDescription: string;
detailedDescription: string;
images: string[];
parentPath: string[];
tags: string[];
terms: string;
validity: Validity;
version: number;
reservationEmail: string;
reservationPhone: string;
reservationWebsite: string | null;
reservationInstructions: string | null;
isActive: boolean;
}

// Validity can be either month-based or date-based
type Validity = MonthBasedValidity | DateBasedValidity;

interface MonthBasedValidity {
validMonths: number;
}

interface DateBasedValidity {
startDate: string; // ISO 8601 date string
endDate: string; // ISO 8601 date string
}

Validity​

The validity field can have two different formats:

Month-based validity - The voucher is valid for a number of months from the purchase date:

{
"validity": {
"validMonths": 12
}
}

Date-based validity - The voucher is valid between specific dates:

{
"validity": {
"startDate": "2024-04-02T00:00:00Z",
"endDate": "2025-04-02T00:00:00Z"
}
}

Properties​

PropertyTypeDescription
idstringUnique product identifier (UUID) - use this for AddItem
catalogueIdstringThe catalogue this product belongs to
namestringDisplay name of the product
venueNamestring | nullOptional venue name
priceMoneyThe product price
isPrivatebooleanWhether the product is private
limitedAvailabilityunknownAvailability constraints, if any
marketingDescriptionstringShort description for marketing purposes
detailedDescriptionstringFull product description
imagesstring[]Array of image URLs
parentPathstring[]Category hierarchy (array of UUIDs)
tagsstring[]Product tags for filtering/categorization
termsstringTerms and conditions (HTML)
validityValidityVoucher validity period
versionnumberProduct version number
reservationEmailstringEmail for reservations
reservationPhonestringPhone number for reservations
reservationWebsitestring | nullWebsite for reservations
reservationInstructionsstring | nullSpecial reservation instructions
isActivebooleanWhether the product is currently available

Example​

// Format validity for display
function formatValidity(validity) {
if (validity.validMonths) {
return "Valid for " + validity.validMonths + " months";
}

if (validity.startDate && validity.endDate) {
const start = new Date(validity.startDate);
const end = new Date(validity.endDate);
return "Valid from " + start.toLocaleDateString() + " to " + end.toLocaleDateString();
}

return "";
}

// Display a product card
function renderProductCard(product) {
const formatter = new Intl.NumberFormat("en-US", {
style: "currency",
currency: product.price.currency,
});

return (
'<div class="product-card">' +
'<img src="' + product.images[0] + '" alt="' + product.name + '">' +
"<h3>" + product.name + "</h3>" +
"<p>" + product.marketingDescription + "</p>" +
'<p class="price">' + formatter.format(product.price.amount) + "</p>" +
'<p class="validity">' + formatValidity(product.validity) + "</p>" +
'<button data-product-id="' + product.id + '">Add to Cart</button>' +
"</div>"
);
}

LineItem​

A line item represents a single product instance in the basket.

interface LineItem {
lineItemId: string;
productId: string;
productName: string;
retailPrice: Money;
quotedPrice: Money;
}

Properties​

PropertyTypeDescription
lineItemIdstringUnique identifier for this line item (UUID)
productIdstringThe product identifier
productNamestringDisplay name of the product
retailPriceMoneyThe original price before discounts
quotedPriceMoneyThe price after applying discounts

Understanding Line Items​

Each AddItem call creates a new line item. If a customer adds the same product twice, there will be two line items with the same productId but different lineItemId values.

To display quantity in your UI, group line items by productId:

function groupItemsByProduct(items) {
const grouped = {};

items.forEach((item) => {
if (!grouped[item.productId]) {
grouped[item.productId] = {
...item,
quantity: 0,
lineItemIds: [],
};
}
grouped[item.productId].quantity++;
grouped[item.productId].lineItemIds.push(item.lineItemId);
});

return Object.values(grouped);
}

Money​

Represents a monetary value with currency.

interface Money {
amount: string | number;
currency: string;
}

Properties​

PropertyTypeDescription
amountstring | numberThe monetary amount
currencystringISO 4217 currency code (e.g., "USD", "GBP", "EUR")
note

The amount field may be returned as a string in some responses (e.g., from GetVouchers). Always use parseFloat() or Number() when performing arithmetic operations.

Formatting Example​

function formatPrice(money) {
return new Intl.NumberFormat("en-US", {
style: "currency",
currency: money.currency,
}).format(parseFloat(money.amount));
}

// Usage
const item = basket.items[0];
console.log(formatPrice(item.retailPrice)); // "$50.00"
console.log(formatPrice(item.quotedPrice)); // "$45.00"

Error​

Represents an error returned by the SomethingHappened event.

interface Error {
errorCode: string;
message: string;
}

Properties​

PropertyTypeDescription
errorCodestringMachine-readable error identifier
messagestringHuman-readable error description

Error Codes​

CodeDescription
PromoCodeDoesntExistThe provided promotional code is invalid or has expired
UnavailableProductThe product is not available for purchase
OrderWasProcessedThe basket has already been settled and cannot be modified

ResumeShopping Response​

The response returned by the ResumeShopping method.

interface ResumeShoppingResponse {
result: Basket | null;
}

Properties​

PropertyTypeDescription
resultBasket | nullThe basket state, or null if no basket exists