# Types

URL: https://docs.sparklayer.io/developers/javascript-sdk/reference/types

Every TypeScript type in the SparkLayer JavaScript SDK, from Cart, Product and UpdateCart to SparkLayerOptions and Spark, and where each one is used.

> **For AI assistants:** what to know before writing SparkLayer JavaScript SDK code.
>
> - **What it is:** `window.spark`, added to the storefront by the SparkLayer Core Script (version 4.x). On Shopify the SparkLayer app embed loads it; elsewhere it's `<script async src="https://sparkcdn.io/sparkjs/<SITE_ID>/<live|test>"></script>` in the theme's `<head>`. The old `cdn.sparklayer.io/spark.latest.js` and `spark.1.x.js` files are legacy: never use them.
> - **Options:** Configure it with `window.sparkOptions`, set before the Core Script loads. Extend the object rather than replacing it: `window.sparkOptions = { ...window.sparkOptions, … }`, or the Site ID and other snippets' hooks are lost. Headless only: `window.initSpark(options)` is defined when `window.sparkOptions` isn't set.
> - **When to call it:** Only after SparkLayer is ready: inside the `onReady(spark)` hook, or after a promise resolved from it. Most methods are async; prices and the cart are only available to signed-in B2B customers (check `await spark.isLoggedIn()`).
> - **Products and prices:** Products are looked up by the platform's parent product ID (on Shopify, `product.id`) and variants by SKU: `getPricingForVariant(parentProductId, sku)`, `calculatePricingForVariant(parentProductId, sku, qty)`, `getPackSizeForVariant(parentProductId, sku)`. For instant recalculation, fetch once with `getVariant` and call `calculatePricingForVariantData(variant, qty)`.
> - **Cart:** `updateCart({ products: [{ sku, adjustQuantity }] })` adds or removes relative to what's in the cart (also `customAttributes: [{ key, value }]`, `clearCart: true`). It resolves to the results, or `null` after showing its own error message; it doesn't throw. `getCart()` reads the cart; `openDrawer('cart')` opens it.
> - **Hooks:** `onCartUpdate(cart, results)`, `onCartLoad(cart)`, `onLogout()`, `preCartUpdateListener(input)` (async: return the possibly changed input) and `onCheckoutValidation(cart, cartUiState)` (return `[{ message }]` to block checkout, or `null`). When adding a hook, call any existing one first.
> - **Customising:** Build around SparkLayer or customise its own components, including their HTML. Prefer documented options, hooks, CSS variables and custom slots where they fit; keep direct HTML changes targeted and re-check them after SparkLayer updates.
> - **Docs:** The reference: methods https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md, hooks https://docs.sparklayer.io/developers/javascript-sdk/reference/hooks.md, options https://docs.sparklayer.io/developers/javascript-sdk/reference/options.md, types https://docs.sparklayer.io/developers/javascript-sdk/reference/types.md (or the same types as a file: https://docs.sparklayer.io/developers/javascript-sdk/spark.d.ts). Setup and waiting for SparkLayer: https://docs.sparklayer.io/developers/javascript-sdk/setup.md. Use only what the reference documents.

The objects you pass to the SDK and get back from it, written in TypeScript and listed A to Z. In JavaScript, they describe the shape of those objects. Every block on this page goes into [spark.d.ts](https://docs.sparklayer.io/developers/javascript-sdk/spark.d.ts), which you can download for autocomplete and type checking in your editor.

The cart, product and pricing types come from SparkLayer's GraphQL API. Their field types and nullability are inferred from how the SDK uses them, so treat a field as possibly `null` unless you're sure it's set.

## AccountSectionId

The sections of the My Account panel, used in [`display.sectionConfiguration`](#displayoptions) to reorder or hide them.

```typescript
type AccountSectionId =
  | "spark-slot-my-account"
  | "recent-activity"
  | "shopping-lists"
  | "favourites"
  | "financials"
  | "my-details"
  | "reports"
  | "address-book"
  | "company-users";
```

**Used by:** [`DisplayOptions`](#displayoptions)

## AnalyticsEventName

The B2B events SparkLayer can send to your analytics. See [Event tracking for analytics](https://docs.sparklayer.io/developers/frontend/technical-information.md#event-tracking-for-analytics-google-analytics-ga4) for what each event means.

```typescript
type AnalyticsEventName =
  | "addToCart"
  | "cartUpdate"
  | "shoppingListSave"
  | "shoppingListLoad"
  | "shoppingListDelete"
  | "csvUpload"
  | "quickAdd"
  | "finalStageCheckout"
  | "shippingUpdate"
  | "beginCheckout"
  | "purchase"
  | "viewCart";
```

**Used by:** [`AnalyticsOptions`](#analyticsoptions)

## AnalyticsOptions

The type of the `analytics` option: the providers to send events to, and which events each one gets. See [Event tracking for analytics](https://docs.sparklayer.io/developers/frontend/technical-information.md#event-tracking-for-analytics-google-analytics-ga4).

```typescript
type AnalyticsOptions = {
  providers: {
    // "ga" for Google Analytics (GA4), "gtm" for Google Tag Manager, or your own function
    handler: "ga" | "gtm" | ((eventName: AnalyticsEventName, eventParams: unknown) => void);
    // The events to send to this provider
    events: Partial<Record<AnalyticsEventName, boolean>>;
  }[];
};
```

**Used by:** the [`analytics`](https://docs.sparklayer.io/developers/javascript-sdk/reference/options.md#authentication-and-analytics) option

## Cart

The B2B cart.

```typescript
type Cart = {
  cartUuid: string;
  intent: string; // For example "ORDER"
  canCreateOrder: boolean;
  canCreateQuote: boolean;
  hasLaunched: boolean;
  lockedByUserId: string | null;
  lockedByUserLastAccessedAt: string | null;
  loadedFromPurchaseAt: string | null;
  loadedFromPurchaseType: string | null;
  items: CartItem[];
  validationErrors: CartValidationError[];
  taxInclusiveDisplay: boolean;
  totals: CartTotals;
  currencyCode: string;
  totalWeight: number | null;
  customerAddresses: { id: string; description: string }[];
  deliveryAddressId: string | null;
  customerReference: string | null;
  poNumber: string | null;
  shippingRequestedDate: string | null;
  customFields: { name: string; value: string }[];
  approvingFor: { name: string } | null;
  discounts: {
    id: string;
    slug: string;
    name: string;
    appliedCouponCodes: string[];
    amount: { net: number; gross: number; currencyCode: string };
  }[];
  discountsAreAvailable: boolean;
  couponCodes: string[];
  removedCouponCodes: string[];
  quote: {
    statusSlug: string;
    statusUpdated: string;
    expiry: string | null;
    assignedAgent: { id: string } | null;
    message: string | null;
    note: string | null;
  } | null;
};
```

**Used by:** [`getCart()`](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#getcart), [`getCartCache()`](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#getcartcache), [`addCustomLineItem()`](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#addcustomlineitem), [`onCartLoad`](https://docs.sparklayer.io/developers/javascript-sdk/reference/hooks.md#oncartload), [`onCartUpdate`](https://docs.sparklayer.io/developers/javascript-sdk/reference/hooks.md#oncartupdate), [`onCheckoutValidation`](https://docs.sparklayer.io/developers/javascript-sdk/reference/hooks.md#oncheckoutvalidation)

## CartItem

One line in the cart. It has every [`ProductVariant`](#productvariant) field (`sku`, `name`, `price` and so on) plus these:

```typescript
type CartItem = ProductVariant & {
  type: string;
  itemKey: string; // Identifies the line in updateCart
  quantity: number;
  customAttributes: { key: string; value: string; type?: string | null }[];
  lineTotal: CartLineAmount;
  lineTotalPreDiscounts: CartLineAmount;
  lineTotalDiscountAmount: CartLineAmount;
  unitTotal: CartLineAmount;
  unitTotalPreDiscounts: CartLineAmount;
  unitTotalDiscountAmount: CartLineAmount;
  quotedPrice: string | null;
  preorderQuantityDisplay: number | null;
};
```

**Used by:** [`Cart`](#cart) (`items`), [`calculatePricingForVariantData()`](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#calculatepricingforvariantdata)

## CartItemInput

One product in an [`UpdateCart`](#updatecart). Identify the line by `sku` or `itemKey`, and set the quantity with `adjustQuantity` (added to the current quantity; negative to remove) or `quantity` (the exact quantity; `0` removes the line).

```typescript
type CartItemInput = {
  sku?: string;
  itemKey?: string; // From a CartItem
  adjustQuantity?: number;
  quantity?: number;
  customAttributes?: { key: string; value: string; type?: string }[];
};
```

For a file, `value` is a JSON string of an array of file GIDs from [`uploadFile()`](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#uploadfile).

**Used by:** [`UpdateCart`](#updatecart) (`products`)

## CartLineAmount

An amount on a cart line, such as its total or unit price.

```typescript
type CartLineAmount = {
  net: number;
  gross: number;
  currencyCode: string;
  taxInclusiveDisplay: boolean;
};
```

**Used by:** [`CartItem`](#cartitem)

## CartMoney

An amount in the cart's totals.

```typescript
type CartMoney = { number: string };
```

**Used by:** [`CartTotals`](#carttotals)

## CartResults

The result for one product line in an `updateCart` call. See [What updateCart returns](https://docs.sparklayer.io/developers/javascript-sdk/cart.md#what-updatecart-returns) for the `messages` types.

```typescript
type CartResults = {
  messages: { type: string }[];
  requestedQuantity: number;
  resultantQuantity: number;
  itemKey: string;
  sku: string;
  name: string;
};
```

**Used by:** [`updateCart()`](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#updatecart), [`onCartUpdate`](https://docs.sparklayer.io/developers/javascript-sdk/reference/hooks.md#oncartupdate)

## CartTotals

The cart's totals. Each amount is a [`CartMoney`](#cartmoney) object with a `number`.

```typescript
type CartTotals = {
  subTotal: {
    preDiscount: { net: CartMoney; gross: CartMoney };
    discount: { net: CartMoney; gross: CartMoney };
    charge: { net: CartMoney; gross: CartMoney };
  };
  shipping: {
    preDiscount: { net: CartMoney };
    discount: { net: CartMoney };
    charge: { net: CartMoney };
  };
  total: {
    charge: { gross: CartMoney; tax: CartMoney };
    discount: { net: CartMoney };
    preDiscount: { gross: CartMoney };
  };
};
```

**Used by:** [`Cart`](#cart) (`totals`)

## CartUIState

The current checkout step.

```typescript
type CartUIState = "cart" | "shipping" | "quote-details" | "payment" | "thanks";
```

**Used by:** [`onCheckoutValidation`](https://docs.sparklayer.io/developers/javascript-sdk/reference/hooks.md#oncheckoutvalidation)

## CartValidationError

A reason the cart can't be checked out yet, such as an order minimum that hasn't been met. Each error has a `type` code (for example `quantity-unavailable` or `pricing-unavailable`) and the fields for its kind.

The `type` is one of the cart validation codes the API uses: `maximum-order-item-quantity`, `maximum-order-totals`, `maximum-parent-quantity`, `maximum-variant-quantity`, `minimum-order-item-quantity`, `minimum-order-totals`, `minimum-parent-quantity`, `minimum-variant-quantity`, `pack-size`, `pricing-unavailable`, `pricing-unavailable-for-selected-qty` or `quantity-unavailable`.

```typescript
type CartValidationError = {
  type: string;
  amount?: number;
  amountGross?: number;
  minimum?: number;
  maximum?: number;
  productName?: string;
  parentSKU?: string;
  variantSKU?: string;
  packSize?: number;
  availableQuantity?: number;
  overridden?: boolean;
};
```

| Kind of error (GraphQL type) | Fields |
| --- | --- |
| `CartValidationErrorMinimumOrderTotals`, `CartValidationErrorMaximumOrderTotals` | `amount`, `amountGross` |
| `CartValidationErrorMinimumOrderItemQuantity` | `minimum` |
| `CartValidationErrorMaximumOrderItemQuantity` | `maximum` |
| `CartValidationErrorMinimumParentQuantity`, `CartValidationErrorMaximumParentQuantity` | `minimum` or `maximum`, `productName`, `parentSKU`, `overridden` |
| `CartValidationErrorMinimumVariantQuantity`, `CartValidationErrorMaximumVariantQuantity` | `minimum` or `maximum`, `variantSKU`, `overridden` |
| `CartValidationErrorPackSize` | `packSize`, `variantSKU`, `overridden` |
| `CartValidationErrorQuantityUnavailable` | `variantSKU`, `availableQuantity` |
| `CartValidationErrorPricingUnavailable`, `CartValidationErrorPricingUnavailableForSelectedQty` | `variantSKU` |

**Used by:** [`Cart`](#cart) (`validationErrors`)

## CheckoutElementConfig

One entry in `checkoutCustomElements`: a standard field by `id`, or a custom field by `name`. See [Custom field settings](https://docs.sparklayer.io/help/ordering/checkout-fields.md#custom-field-settings) for every key and [Standard checkout fields](https://docs.sparklayer.io/help/ordering/checkout-fields.md#turn-on-standard-checkout-fields) for the IDs.

```typescript
type CheckoutElementConfig = {
  // A standard field
  id?: "customer-reference" | "po-number" | "shipping-requested-date";
  // A custom field (required unless id is set)
  name?: string;
  // Customer-facing text, keyed by language code
  translations?: Record<string, { title: string; detail?: string; [messageKey: string]: string | undefined }>;
  // HTML attributes such as type, required, min, max, maxlength and pattern
  attributes?: Record<string, string | number | boolean>;
  // For select fields: the drop-down options, optionally in groups
  options?: {
    translations?: Record<string, { groupName: string }>;
    items: { value: string; translations: Record<string, { label: string }> }[];
  }[];
  // Returns a message key from translations if the value is invalid
  onChange?(value: string, element: HTMLElement): string | null | undefined;
};
```

**Used by:** the [`checkoutCustomElements`](https://docs.sparklayer.io/developers/javascript-sdk/reference/options.md#checkout-and-account) option

## CustomAccountDetailLinkType

Formats a `customAccountDetails` value as a link of this kind.

```typescript
type CustomAccountDetailLinkType = "email" | "phone" | "sms" | "website";
```

**Used by:** the [`customAccountDetails`](https://docs.sparklayer.io/developers/javascript-sdk/reference/options.md#checkout-and-account) option

## CustomLineItemInput

A custom line item: a free-text name, price and quantity not tied to a SKU.

```typescript
type CustomLineItemInput = {
  // The name shown on the custom line item
  name: string;
  // The price of a single unit, as a decimal string
  quotedPrice: string;
  quantity: number;
};
```

**Used by:** [`addCustomLineItem()`](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#addcustomlineitem)

## DisplayOptions

The type of the `display` option.

```typescript
type DisplayOptions = {
  orderListShowShippingAddress: boolean;
  customerReferenceHidden: boolean; // deprecated
  customerReferenceRequired: boolean; // deprecated
  customerReferenceMaxLength?: number; // deprecated
  darkTheme: boolean;
  savingsUseRrp: boolean;
  roundPriceBreakPercentages: boolean;
  showPriceBreakSavings: boolean;
  sectionConfiguration: {
    "my-account"?: {
      order?: AccountSectionId[];
      hide?: AccountSectionId[];
    };
  };
  showSlots: string[];
  showRrpToggle: boolean;
  showFavouritesLists: boolean;
  showShoppingLists: boolean;
  showSkus: boolean;
  hideFinancials?: boolean;
};
```

| Property | Default | What it does |
| --- | --- | --- |
| `sectionConfiguration` | `{}` | Reorder (`order`) or hide (`hide`) My Account sections by [`AccountSectionId`](#accountsectionid). See [My account](https://docs.sparklayer.io/help/storefront/interfaces/my-account.md). |
| `showSlots` | `[]` | Custom slots to show. See [Custom slots](https://docs.sparklayer.io/help/storefront/interfaces/custom-slots.md). |
| `showFavouritesLists` | `true` | Whether to show the favourites lists feature. |
| `showShoppingLists` | `true` | Whether to show the shopping lists feature. |
| `showSkus` | `true` | Whether to show product SKUs on cart line items. |
| `darkTheme` | `false` | Use the dark theme. See [Customising design](https://docs.sparklayer.io/help/storefront/customising-design.md). |
| `savingsUseRrp` | `false` | Calculate savings against the RRP. |
| `roundPriceBreakPercentages` | `true` | Round price break percentages. |
| `showPriceBreakSavings` | `true` | Show savings on price breaks. |
| `showRrpToggle` | `false` | Show the RRP toggle. |
| `orderListShowShippingAddress` | `false` | Show the shipping address in the purchases list. |
| `hideFinancials?` | – | Hide the Financials section of My Account. |
| `customerReferenceHidden`, `customerReferenceRequired`, `customerReferenceMaxLength?` | `false`, `false`, – | Deprecated. Use a `{ id: 'customer-reference' }` entry in `checkoutCustomElements` instead. |

**Used by:** the [`display`](https://docs.sparklayer.io/developers/javascript-sdk/reference/options.md#display-language-and-translations) option

## DrawerUIState

A tab of the SparkLayer drawer.

```typescript
type DrawerUIState = "dashboard" | "browse-catalog" | "cart" | "sales-agent" | "account";
```

**Used by:** [`openDrawer()`](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#opendrawer), the [`view-update`](https://docs.sparklayer.io/developers/javascript-sdk/reference/events-and-components.md#view-update) event

## ErrorOf

The error type of a GraphQL query or mutation passed to `fetch`. For a plain query string, it's [`GraphqlError`](#graphqlerror).

```typescript
type ErrorOf<Q> = Q extends { readonly __graphqlTypes?: { error: infer TError } }
  ? TError
  : GraphqlError;
```

**Used by:** [`fetch()`](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#fetch)

## FetchResponse

The response returned by `fetch`: a standard `Response` whose `json()` resolves to the GraphQL response.

```typescript
interface FetchResponse<TData = unknown, TError = GraphqlError> extends Response {
  json(): Promise<{ data: TData; errors: TError[] }>;
}
```

**Used by:** [`fetch()`](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#fetch)

## GraphqlError

An entry in the `errors` array of a GraphQL response.

```typescript
type GraphqlError = {
  message: string;
  path?: (string | number)[];
  extensions?: { code?: string; [key: string]: unknown };
};
```

**Used by:** [`FetchResponse`](#fetchresponse), [`fetch()`](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#fetch)

## GraphqlExtensionError

A [`GraphqlError`](#graphqlerror) with a `code` in `extensions` that identifies the error.

```typescript
type GraphqlExtensionError = GraphqlError & {
  extensions: { code: string; [key: string]: unknown };
};
```

**Used by:** [`fetch()`](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#fetch)

## GraphqlQueryOrMutation

The query you pass to `fetch`. In JavaScript, pass it as a string, and the variables as a plain object. In TypeScript, a typed query can also carry its response, variables and error types, which [`ResponseOf`](#responseof), [`VariablesOf`](#variablesof) and [`ErrorOf`](#errorof) read back.

```typescript
type GraphqlQueryOrMutation<
  TResponse = unknown,
  TVariables = Record<string, unknown>,
  TError = GraphqlError,
> = string & {
  // Type-only: never set at runtime
  readonly __graphqlTypes?: { response: TResponse; variables: TVariables; error: TError };
};
```

**Used by:** [`fetch()`](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#fetch)

## PaymentMethodName

The payment methods you can list in `paymentMethodsOrder`.

```typescript
type PaymentMethodName = "paymentOnAccount" | "paymentByInvoice" | "upfrontPayment" | "quote";
```

**Used by:** the [`paymentMethodsOrder`](https://docs.sparklayer.io/developers/javascript-sdk/reference/options.md#checkout-and-account) option

## Product

A product, with its variants.

```typescript
type Product = {
  id: string;
  externalId: string; // Your platform's product ID
  slug: string;
  variants: ProductVariant[];
};
```

**Used by:** [`getProduct()`](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#getproduct), [`getProductBySlug()`](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#getproductbyslug), the [`spark-variant-change`](https://docs.sparklayer.io/developers/javascript-sdk/reference/events-and-components.md#spark-variant-change) event

## ProductVariant

One variant of a product, and the base of each [`CartItem`](#cartitem).

```typescript
type ProductVariant = {
  id: string;
  externalId: string; // Your platform's variant ID
  parentExternalId: string; // Your platform's product ID
  stockDisplay: {
    status: string; // For example "out_of_stock" or "backorder"
    units: number | null;
    available: unknown;
  } | null;
  restockDate: string | null;
  cartImageUrl: string | null;
  position: number;
  sku: string;
  barcode: string | null;
  slug: string;
  name: string;
  price: VariantPrice | null;
  rrp: unknown; // Legacy: use rrpV2
  rrpV2: { number: string; currency: string } | null;
  priceBreaks: VariantPriceBreak[];
  // Product settings, such as packSize, minOrderQuantity and maxOrderQuantity
  settings: { key: string; value: unknown }[];
  // The variant's options, such as { group: "Size", value: "M" }
  options: { group: string; value: string }[];
};
```

**Used by:** [`getVariant()`](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#getvariant), [`Product`](#product) (`variants`), [`CartItem`](#cartitem), [`calculatePricingForVariantData()`](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#calculatepricingforvariantdata), the [`spark-variant-change`](https://docs.sparklayer.io/developers/javascript-sdk/reference/events-and-components.md#spark-variant-change) event

## ProductVariantDataPricing

The variant data `calculatePricingForVariantData` needs. A [`ProductVariant`](#productvariant) or [`CartItem`](#cartitem) has these fields.

```typescript
type ProductVariantDataPricing = {
  priceBreaks: VariantPriceBreak[] | null;
  rrpV2?: { number: string; currency: string } | null;
  unitTotal?: { currencyCode: string } | null; // Cart items only
};
```

**Used by:** [`calculatePricingForVariantData()`](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#calculatepricingforvariantdata)

## ProductVariantPricing

The price for a quantity of a variant: the total, the unit price at that quantity and the price breaks.

```typescript
type ProductVariantPricing = {
  totalPrice: number | null; // unitPrice × quantity
  totalRrpPrice: number | null;
  hasPriceBreaks: boolean;
  unitPrice: number | null; // The unit price at this quantity
  basePrice: number | null; // The unit price before price breaks
  priceBreaks: VariantPriceBreak[];
  priceBreakSavingsPercentage: number | null;
  rrpV2: { number: string; currency: string } | null;
  currencyCode: string;
  unitPriceBreakdown: {
    items: {
      unitOfMeasure: string | null;
      price: number;
      quantity: number;
      uomQuantity: number;
    }[];
  };
};
```

**Used by:** [`calculatePricingForVariant()`](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#calculatepricingforvariant), [`calculatePricingForVariantData()`](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#calculatepricingforvariantdata)

## ResponseOf

The `data` type of a GraphQL query or mutation passed to `fetch`. For a plain query string, it's `unknown`.

```typescript
type ResponseOf<Q> = Q extends { readonly __graphqlTypes?: { response: infer TResponse } }
  ? TResponse
  : unknown;
```

**Used by:** [`fetch()`](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#fetch)

## SimplifiedProductPrice

The "from" price across a product's variants, and how many different prices there are.

```typescript
type SimplifiedProductPrice = {
  numberOfPrices: number;
  numberOfPricesExcludingBreaks: number;
  numberOfRrpPrices: number;
  fromPrice: number | null;
  fromPriceExcludingBreaks: number | null;
  currencyCode: string;
  hasPriceBreaks: boolean;
  rrpPrice: number | null;
  rrpCurrencyCode: string | null;
  taxInclusiveDisplay: boolean;
};
```

If `numberOfPrices` is more than 1, show "from" before `fromPrice`.

**Used by:** [`getPriceForProduct()`](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#getpriceforproduct)

## Spark

The `window.spark` object. See [Methods](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md) for each one.

```typescript
type Spark = {
  options: SparkLayerOptions;
  isLoggedIn(): Promise<boolean>;
  switchImpersonatingCustomer(customerId: string | null): Promise<UserData | null>;
  refreshGlobalData(): Promise<UserData | null>;
  getActiveCustomerVerificationToken(): Promise<string | null>;
  setActiveCompanySection(sectionId: string): Promise<boolean>;
  getProduct(parentProductId: string): Promise<Product>;
  getProductBySlug(slug: string): Promise<Product>;
  getVariant(parentProductId: string, variantSku: string): Promise<ProductVariant>;
  getPriceForProduct(parentProductId: string): Promise<SimplifiedProductPrice>;
  getPricingForVariant(
    parentProductId: string,
    variantSku: string,
  ): Promise<{
    price: number | null;
    rrp: number | null;
    rrpCurrencyCode: string | null;
    priceBreaks: VariantPriceBreak[];
    currencyCode: string;
  }>;
  getRrpPriceForVariant(
    parentProductId: string,
    variantSku: string,
  ): Promise<{ rrp: number | null; currencyCode: string | null }>;
  getPackSizeForVariant(parentProductId: string, variantSku: string): Promise<number>;
  calculatePricingForVariant(
    parentProductId: string,
    variantSku: string,
    qty: number,
    qtyAcrossVariants?: number | null,
  ): Promise<ProductVariantPricing>;
  calculatePricingForVariantData(
    variant: ProductVariantDataPricing,
    qty: number,
    qtyAcrossVariants?: number | null,
  ): ProductVariantPricing;
  getCart(): Promise<Cart | null>;
  getCartCache(): Cart | null;
  updateCart(
    input: Partial<UpdateCart>,
    cartSuccessHandledLocally?: boolean,
    cartErrorsHandledLocally?: boolean,
  ): Promise<CartResults[] | null>;
  addCustomLineItem(customItem: CustomLineItemInput): Promise<Cart | null>;
  externalClearBasket(): Promise<void>;
  openDrawer(initialTab?: DrawerUIState): void;
  closeDrawer(): void;
  uploadFile(fileName: string, fileData: Blob): Promise<string>;
  fetch<Q extends GraphqlQueryOrMutation<unknown, Record<string, unknown>, GraphqlError | GraphqlExtensionError>>(
    query: Q,
    variables?: VariablesOf<Q>,
    useImpersonatingCustomer?: boolean,
    bypassAppProxy?: boolean,
    signal?: AbortSignal,
  ): Promise<FetchResponse<ResponseOf<Q>, ErrorOf<Q>>>;
};
```

**Used by:** `window.spark`, [`window.initSpark()`](https://docs.sparklayer.io/developers/javascript-sdk/setup.md#manual-initialisation-headless-only), [`onReady`](https://docs.sparklayer.io/developers/javascript-sdk/reference/hooks.md#onready), [`onLoad`](https://docs.sparklayer.io/developers/javascript-sdk/reference/hooks.md#onload)

## SparkLayerOptions

The type of `window.sparkOptions` and the options you pass to `window.initSpark()`. See [Options](https://docs.sparklayer.io/developers/javascript-sdk/reference/options.md) and [Hooks](https://docs.sparklayer.io/developers/javascript-sdk/reference/hooks.md) for each one.

```typescript
type SparkLayerOptions = {
  sparkDomain: "app.sparklayer.io" | "test.app.sparklayer.io";
  platform: "base" | "bigcommerce" | "shopify" | "wix" | "woocommerce" | "magento";
  siteId: string;
  rootUrl: string;
  accountRedirect: {
    urlRegex?: RegExp;
    goTo?: string;
  };
  cartRedirect: {
    urlRegex?: RegExp;
    goTo?: string;
  };
  wordpressSiteUrl?: string;
  accountButtonSelectors: string;
  logoutButtonSelectors: string;
  cartButtonSelectors: string;
  loginButtonSelectors: string;
  display: DisplayOptions;
  termsAndConditionsLink: string;
  language: string;
  locale: string | null;
  translations: Translations;
  showTranslations: boolean;
  checkoutCustomElements: CheckoutElementConfig[];
  paymentMethodsOrder: PaymentMethodName[];
  saveToAddressBookDefault: boolean;
  productLink: string;
  customAccountDetails: {
    title: string;
    value: string | number;
    displayText?: string;
    type?: CustomAccountDetailLinkType;
  }[];
  onCheckoutValidation(
    cart: Cart,
    cartUiState: CartUIState,
  ): Promise<{ message: string }[] | null>;
  onCartUpdate(cart: Cart, results: CartResults[]): Promise<void>;
  onCartLoad(cart: Cart): Promise<void>;
  preCartUpdateListener(input: Partial<UpdateCart>): Promise<Partial<UpdateCart>>;
  onReady?(spark: Spark): Promise<void>;
  onLoad?(spark: Spark): Promise<void>;
  onLogout?(): Promise<void>;
  shopify?: {
    useAppProxy?: boolean;
  };
  bigcommerce?: {
    appClientId?: string;
  };
  auth: {
    user?: string;
    token?: string;
  };
  authLogoutUri: string | null;
  analytics?: AnalyticsOptions;
  igniteCheckoutContext?: Record<string, unknown>;
};
```

**Used by:** `window.sparkOptions`, [`window.initSpark()`](https://docs.sparklayer.io/developers/javascript-sdk/setup.md#manual-initialisation-headless-only), [`Spark`](#spark) (`options`)

## Translations

The type of the `translations` option: text overrides keyed by language code, then by translation key. See [Change text in the Core Script](https://docs.sparklayer.io/help/storefront/languages-and-international.md#change-text-in-the-core-script).

```typescript
type Translations = Record<string, Record<string, string>>;
```

**Used by:** the [`translations`](https://docs.sparklayer.io/developers/javascript-sdk/reference/options.md#display-language-and-translations) option

## UpdateCart

A change to the cart. Every field is optional: send only what you want to change. See [Cart](https://docs.sparklayer.io/developers/javascript-sdk/cart.md).

```typescript
type UpdateCart = {
  clearCart?: boolean;
  products?: CartItemInput[];
  deliveryAddressId?: string;
  customerReference?: string;
  poNumber?: string;
  shippingRequestedDate?: string;
  customFields?: { name: string; value: string }[];
  cartIntent?: string;
};
```

SparkLayer adds the impersonated customer and company section for you.

**Used by:** [`updateCart()`](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#updatecart), [`preCartUpdateListener`](https://docs.sparklayer.io/developers/javascript-sdk/reference/hooks.md#precartupdatelistener)

## UserData

The active customer. This lists the fields most integrations need; the object has more.

```typescript
type UserData = {
  id: string;
  email: string;
  name: string;
  companyName: string | null;
  customerVerificationToken: string | null;
  salesAgent: boolean;
  parentAccount: { id: string; name: string; email: string } | null;
  companySections: { id: string; name: string }[];
};
```

**Used by:** [`switchImpersonatingCustomer()`](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#switchimpersonatingcustomer), [`refreshGlobalData()`](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#refreshglobaldata)

## VariablesOf

The variables type of a GraphQL query or mutation passed to `fetch`. For a plain query string, it's any plain object.

```typescript
type VariablesOf<Q> = Q extends { readonly __graphqlTypes?: { variables: infer TVariables } }
  ? TVariables
  : Record<string, unknown>;
```

**Used by:** [`fetch()`](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#fetch)

## VariantPrice

A variant's price for the customer.

```typescript
type VariantPrice = {
  taxRate: number;
  net: number;
  gross: number;
  currencyCode: string;
  taxInclusiveDisplay: boolean; // If true, show gross; otherwise net
};
```

**Used by:** [`ProductVariant`](#productvariant) (`price`), [`VariantPriceBreak`](#variantpricebreak)

## VariantPriceBreak

One price break (tier) for a variant: the price per unit from `quantity` upwards.

```typescript
type VariantPriceBreak = {
  quantity: number;
  price: VariantPrice;
  unitOfMeasure: string | null;
};
```

**Used by:** [`getPricingForVariant()`](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#getpricingforvariant), [`ProductVariant`](#productvariant), [`ProductVariantPricing`](#productvariantpricing)

## Next steps

- [Methods](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md): Every window\.spark method, with the types it takes and returns.
- [Hooks](https://docs.sparklayer.io/developers/javascript-sdk/reference/hooks.md): The functions SparkLayer calls with a Cart, CartResults or the Spark object.
- [Cart](https://docs.sparklayer.io/developers/javascript-sdk/cart.md): Build an UpdateCart and handle the CartResults it returns.
