> ## Documentation Index
> Fetch the complete documentation index at: https://partner.headout.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Inventory and pricing

> Date-level availability against slot-level inventory, remaining counts, and how prices are composed.

## Date-level availability vs. slot-level inventory

There is no single "list availabilities" endpoint — which one to call depends on `inventorySelectionType` (`NORMAL` or `SEATMAP`), and which level of detail you need:

| Level | What it answers | `NORMAL` products | `SEATMAP` products |
| :- | :- | :- | :- |
| **Date-level** (which dates are open) | "Does this variant have any availability on this date?" — no time slots yet | [List availabilities - Normal](https://partner.headout.com/docs/api-partner/v2/availabilities/normal-availabilities.md) | [List availabilities - Seatmap](https://partner.headout.com/docs/api-partner/v2/seatmap/availabilities-by-variant.md) |
| **Slot-level** (exact bookable inventory) | "What are the exact time slots, seats, and pax counts on this date?" | [List inventory - Normal](https://partner.headout.com/docs/api-partner/v2/inventory/list-by-tour.md) | [List inventory - Seatmap](https://partner.headout.com/docs/api-partner/v2/seatmap/inventory.md) |

* Use the date-level (Availabilities) call to power a date picker or calendar — it tells you which dates have any open inventory, before the user has picked a time slot.
* Use the slot-level (Inventory) call once a date is picked — it returns the exact time slots, remaining seats/pax, and slot-level pricing needed for checkout.
* **Both levels must always be called in real time** — never cache or reuse availability or inventory responses.
* Inventory is time-slot based and highly dynamic — slots can sell out or open up between the user browsing and completing checkout.

## `remaining` count and `availability` status

`remaining` is present on **every** inventory and availability response — seatmap and non-seatmap alike. It is not restricted to seatmap products.

* **`NORMAL` products** (Availabilities-Normal, Inventory-Normal): each item has both an `availability` status (`LIMITED` / `UNLIMITED` / `CLOSED`) and a `remaining` count. `remaining` is only meaningful when `availability` is `LIMITED` — for `UNLIMITED` slots, `remaining` is a sentinel value (`1000`) and should not be shown as the real seat count.
* **`SEATMAP` products** (Availabilities-Seatmap, Inventory-Seatmap): there is no separate `availability` status field. Availability is expressed purely through `remaining` — at the top level (total across the show), and per `section` (total across that section's seats). `remaining: 0` means sold out; a missing seat/section means it isn't bookable.

#### Pax types

> [!WARNING]
>
> Pax types are **dynamic**. There are more than 400 of them, and new ones are added over time. Don't hardcode them, map them to a fixed enum in your code, or reject values you haven't seen before.

* Pax types are defined at the **time slot level**. They can differ between slots for the same variant
* Fetch pax types as the **last step, once a time slot is selected**. Read them from `pricing.persons[]` on the inventory response for that slot, and build the guest-count selector from that list. Re-read them every time the user picks a different slot
* Treat `persons[].type` as an opaque identifier: show `name` (and `description` when present) to the user, and send `type` back unchanged as `personType` in the booking request
* `persons` is empty for `PER_GROUP` variants. Price those from the `groups` tiers instead of showing a pax type selector
* Common examples: Adult, Child, EU Adult, Non-EU Adult. The actual set varies per slot
* See [Pax Types](https://docs.google.com/spreadsheets/d/1KYpqKTNvp17WV-huEURDxfcqwF2Iz_Cu357QFAZfVco/edit?gid=0#gid=0) for the reference list. Use it to understand what the values look like, not as a list to enumerate in code

**Age eligibility.** Age constraints are **not** implied by a pax type's name — they come from `pricing.persons[].ageFrom` / `ageTo` on the inventory response for that time slot. A type named "Child" doesn't have a fixed age band; check `ageFrom`/`ageTo` on that specific inventory entry to know which ages qualify. `ageTo: null` means no upper age limit.

## Pricing

Pricing surfaces at four levels in the API — product, variant, date, and slot. Which one to show depends on which page you're rendering. They are **not interchangeable**:

| Page in your journey | Use this `pricing` | From | What it represents |
| :- | :- | :- | :- |
| Listing / search results | Product-level `pricing` | `List Products` / `Get Product` | Minimum across **all variants and all their inventories** — the "from" price on a listing card |
| Product detail page (before a variant is picked) | Variant-level `pricing` | `Get Product` (inside each variant) | Minimum across **all inventory slots for that variant** — the starting price on the variant selection screen |
| Date picker / calendar view | Availabilities `pricing` | Availabilities API | Minimum selling price at a **date level** for that variant |
| Time-slot selection & checkout | Inventory `pricing` | Inventory API | **Exact slot-level price** — the only level valid for checkout totals and booking validation |

Fields inside `pricing`:

* `currency` — currency code for the returned price
* `profileType` — `PER_PERSON` or `PER_GROUP`
* `headoutSellingPrice` — the **Headout selling price** (minimum selling price, MSP) — partners must not sell below this, at any page level
* `netPrice` — partner net price (API Partner accounts)
* `commissionAmount` — commission amount (Affiliate accounts)

**"From" / starting price.** The product-level `pricing` is the minimum bookable price across all variants **and** time slots for that product. A product with a single variant can still show different starting prices on different dates because slot-level and supplier-backed inventory varies — treat the starting price as the lowest currently-known starting point, not a fixed quote.

**Deprecated: `listingPrice`.** The older `listingPrice` object (with `minimumPrice`, `bestDiscount`, etc.) is deprecated. It is still returned for backward compatibility but should not be used in new integrations — read `pricing` instead.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.