> ## 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.

# Enums and error codes

> Standard enums and error codes used across Headout APIs.

export const CurrencyTable = () => {
  const CACHE_KEY = "headout_currencies";
  const CACHE_TTL = 7 * 24 * 60 * 60 * 1000;
  const API_URL = "https://api.headout.com/api/v1/currency/list";
  const MAX_RETRIES = 2;
  const RETRY_DELAY = 1000;
  const FALLBACK = [{
    code: "EUR",
    currencyName: "Euro"
  }, {
    code: "GBP",
    currencyName: "British Pound"
  }, {
    code: "AED",
    currencyName: "United Arab Emirates Dirham"
  }, {
    code: "USD",
    currencyName: "United States Dollar"
  }, {
    code: "SGD",
    currencyName: "Singapore Dollar"
  }, {
    code: "AUD",
    currencyName: "Australian Dollar"
  }, {
    code: "THB",
    currencyName: "Thai Baht"
  }, {
    code: "INR",
    currencyName: "Indian Rupee"
  }, {
    code: "HKD",
    currencyName: "Hong Kong Dollar"
  }, {
    code: "KRW",
    currencyName: "South Korean Won"
  }, {
    code: "CAD",
    currencyName: "Canadian Dollar"
  }, {
    code: "JPY",
    currencyName: "Japanese Yen"
  }, {
    code: "NZD",
    currencyName: "New Zealand Dollar"
  }, {
    code: "CHF",
    currencyName: "Swiss Franc"
  }, {
    code: "ZAR",
    currencyName: "South African Rand"
  }, {
    code: "MYR",
    currencyName: "Malaysian Ringgit"
  }, {
    code: "BRL",
    currencyName: "Brazilian Real"
  }, {
    code: "SEK",
    currencyName: "Swedish Krona"
  }, {
    code: "IDR",
    currencyName: "Indonesia Rupiah"
  }, {
    code: "ISK",
    currencyName: "Icelandic Krona"
  }, {
    code: "MOP",
    currencyName: "Macanese Pataca"
  }, {
    code: "CNY",
    currencyName: "Chinese Yuan Renminbi"
  }, {
    code: "TWD",
    currencyName: "Taiwan New Dollar"
  }, {
    code: "MXN",
    currencyName: "Mexican Peso"
  }, {
    code: "EGP",
    currencyName: "Egyptian Pound"
  }, {
    code: "QAR",
    currencyName: "Qatari Riyal"
  }, {
    code: "SAR",
    currencyName: "Saudi Arabian Riyal"
  }, {
    code: "DKK",
    currencyName: "Danish Krone"
  }, {
    code: "ALL",
    currencyName: "Albanian Lek"
  }, {
    code: "ARS",
    currencyName: "Argentine Peso"
  }, {
    code: "AZN",
    currencyName: "Azerbaijan New Manat"
  }, {
    code: "BHD",
    currencyName: "Bahrain Dinar"
  }, {
    code: "CLP",
    currencyName: "Chilean Peso"
  }, {
    code: "COP",
    currencyName: "Colombian Peso"
  }, {
    code: "CRC",
    currencyName: "Costa Rican Colon"
  }, {
    code: "CZK",
    currencyName: "Czech Koruna"
  }, {
    code: "DOP",
    currencyName: "Dominican Peso"
  }, {
    code: "FJD",
    currencyName: "Fijian Dollar"
  }, {
    code: "HUF",
    currencyName: "Hungary Forint"
  }, {
    code: "ILS",
    currencyName: "Israeli New Shekel"
  }, {
    code: "LBP",
    currencyName: "Lebanese Pound"
  }, {
    code: "MAD",
    currencyName: "Moroccan Dirham"
  }, {
    code: "MUR",
    currencyName: "Mauritian Rupee"
  }, {
    code: "NOK",
    currencyName: "Norwegian Krone"
  }, {
    code: "PEN",
    currencyName: "Peruvian Nuevo Sol"
  }, {
    code: "PLN",
    currencyName: "Polish Zloty"
  }, {
    code: "RON",
    currencyName: "Romanian Leu"
  }, {
    code: "TRY",
    currencyName: "Turkey Lira"
  }, {
    code: "VND",
    currencyName: "Viet Nam Dong"
  }];
  const readCache = (checkExpiry = true) => {
    try {
      const raw = localStorage.getItem(CACHE_KEY);
      if (!raw) return null;
      const {data, timestamp} = JSON.parse(raw);
      if (checkExpiry && Date.now() - timestamp > CACHE_TTL) return null;
      return data;
    } catch {
      return null;
    }
  };
  const writeCache = data => {
    try {
      localStorage.setItem(CACHE_KEY, JSON.stringify({
        data,
        timestamp: Date.now()
      }));
    } catch {}
  };
  const [currencies, setCurrencies] = useState(() => readCache());
  useEffect(() => {
    if (currencies) return;
    let cancelled = false;
    const controller = new AbortController();
    const delay = ms => new Promise(r => setTimeout(r, ms));
    const fetchCurrencies = async () => {
      for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
        if (cancelled) return;
        if (attempt > 0) await delay(RETRY_DELAY * attempt);
        try {
          const res = await fetch(API_URL, {
            signal: controller.signal
          });
          if (!res.ok) throw new Error(`HTTP ${res.status}`);
          const data = await res.json();
          if (!cancelled) {
            writeCache(data);
            setCurrencies(data);
          }
          return;
        } catch (err) {
          if (cancelled || err.name === "AbortError") return;
        }
      }
      if (!cancelled) setCurrencies(readCache(false) || FALLBACK);
    };
    fetchCurrencies();
    return () => {
      cancelled = true;
      controller.abort();
    };
  }, []);
  if (!currencies) return <p aria-busy="true">Loading currencies...</p>;
  return <table aria-label="Supported currency codes">
      <thead>
        <tr>
          <th scope="col">Code</th>
          <th scope="col">Currency</th>
        </tr>
      </thead>
      <tbody>
        {currencies.map(c => <tr key={c.code}>
            <td><code>{c.code}</code></td>
            <td>{c.currencyName}</td>
          </tr>)}
      </tbody>
    </table>;
};

<Tabs>
  <Tab title="Enums">
    ## Reference data

    <AccordionGroup>
      <Accordion title="Language codes" icon="globe">
        Supported language codes for API localization.

        | Code      | Language              |
        | --------- | --------------------- |
        | `EN`      | English               |
        | `ES`      | Spanish               |
        | `FR`      | French                |
        | `IT`      | Italian               |
        | `DE`      | German                |
        | `PT`      | Portuguese            |
        | `NL`      | Dutch                 |
        | `PL`      | Polish                |
        | `KO`      | Korean                |
        | `JA`      | Japanese              |
        | `ZH_HANS` | Chinese (Simplified)  |
        | `ZH_HANT` | Chinese (Traditional) |
        | `AR`      | Arabic                |
        | `DA`      | Danish                |
        | `NO`      | Norwegian             |
        | `RO`      | Romanian              |
        | `RU`      | Russian               |
        | `SV`      | Swedish               |
        | `TR`      | Turkish               |

        <Note>If a translation is not available for the requested language, content falls back to English (`EN`).</Note>
      </Accordion>

      <Accordion title="Currency codes" icon="circle-dollar-sign">
        <CurrencyTable />
      </Accordion>

      <Accordion title="City codes" icon="map-pin">
        Supported cities are returned dynamically by the [**City API**](/docs/api-partner/v2/cities). This list may change over time, so always handle cities dynamically rather than hardcoding values.

        See: [List Cities](/docs/api-partner/v2/cities/list) · [List Collections](/docs/api-partner/v2/collections/list) · [List Categories](/docs/api-partner/v2/categories/list) · [List Subcategories](/docs/api-partner/v2/subcategories/list) · [List Products](/docs/api-partner/v2/products/list)
      </Accordion>

      <Accordion title="Media types" icon="image">
        Supported media types in product details.

        | Type    | Description  |
        | ------- | ------------ |
        | `IMAGE` | Image media  |
        | `VIDEO` | Video media  |
        | `PDF`   | PDF document |

        See: [List Products](/docs/api-partner/v2/products/list) · [Get Product](/docs/api-partner/v2/products/get)
      </Accordion>

      <Accordion title="Product types" icon="package">
        Supported product types within product details.

        | Type               |
        | ------------------ |
        | `TOUR`             |
        | `ACTIVITY`         |
        | `EVENT`            |
        | `ATTRACTION`       |
        | `TRANSFER`         |
        | `AIRPORT_TRANSFER` |
        | `ADD_ON`           |

        See: [List Products](/docs/api-partner/v2/products/list) · [Get Product](/docs/api-partner/v2/products/get)
      </Accordion>

      <Accordion title="Listing price types" icon="tag">
        Pricing types used in product listings. The price type determines how inventory pricing is structured and how booking requests must be formed.

        | Type         | Description                                                                                                                                                                                                                 |
        | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
        | `PER_PERSON` | Price is charged per individual. Inventory returns person types (e.g., `ADULT`, `CHILD`, `SENIOR`) each with their own price point. The booking request must include one guest object per person with a valid `personType`. |
        | `PER_GROUP`  | A single price covers a group. Inventory returns pricing tiers by group size (e.g., 1-4 people = $100, 5-7 = $120, 8-10 = \$150). The booking request does not require a `personType` per guest.                            |

        See: [List Products](/docs/api-partner/v2/products/list) · [Get Product](/docs/api-partner/v2/products/get)
      </Accordion>

      <Accordion title="Inventory types" icon="calendar">
        Defines how a variant's start time and duration are structured. This affects how `startDateTime` and `endDateTime` in inventory slots should be interpreted, and what kind of date/time picker to show the user.

        | Type                               | Description                                                                                                                                                                       | Example                                                 |
        | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
        | `FIXED_START_FIXED_DURATION`       | Starts at a precise time and lasts a fixed duration. `startDateTime` = actual start, `endDateTime` = actual end.                                                                  | A Broadway show at 7:00 PM lasting 2.5 hours            |
        | `FIXED_START_FLEXIBLE_DURATION`    | Starts at a fixed time but the customer stays as long as they wish. `startDateTime` = entry time, `endDateTime` = venue closing time.                                             | An observation deck visit with a timed entry slot       |
        | `FLEXIBLE_START_FIXED_DURATION`    | Customer can arrive any time during operating hours but the experience lasts a fixed duration once started. `startDateTime` = opening time, `endDateTime` = latest allowed entry. | A hot-air balloon ride (1 hour) during a morning window |
        | `FLEXIBLE_START_FLEXIBLE_DURATION` | Open entry and open-ended duration — customer arrives and leaves whenever they want within the day. `startDateTime` = opening time, `endDateTime` = closing time.                 | A theme park day pass                                   |

        <Note>For `FLEXIBLE_START_*` types, `startDateTime` represents the opening time of the venue, not a specific entry time for the customer.</Note>

        See: [List Inventory](/docs/api-partner/v2/inventory/list-by-tour)
      </Accordion>

      <Accordion title="Inventory availability" icon="circle-check">
        Availability status within inventory slots, for `inventorySelectionType: NORMAL` products only. Determines whether and how many bookings can still be made for a given slot.

        | Status      | Description                                                                                                                                  |
        | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
        | `LIMITED`   | Limited spots remaining — check the `remaining` field for the exact count before booking.                                                    |
        | `UNLIMITED` | No cap on bookings — the slot can be booked any number of times. `remaining` is a sentinel value (`1000`) and does not reflect a real count. |
        | `CLOSED`    | The slot is unavailable and cannot be booked.                                                                                                |

        `SEATMAP` products don't return this status field — availability is expressed purely through `remaining` (top-level and per-section). See [`remaining` count and `availability` status](/docs/guide/key-concepts#remaining-count-and-availability-status).

        See: [List Inventory](/docs/api-partner/v2/inventory/list-by-tour)
      </Accordion>

      <Accordion title="Inventory selection types" icon="layout-grid">
        Inventory selection types for booking interfaces.

        | Type      | Description                  |
        | --------- | ---------------------------- |
        | `NORMAL`  | Standard selection interface |
        | `SEATMAP` | Seat map selection interface |

        See: [List Inventory](/docs/api-partner/v2/inventory/list-by-tour)
      </Accordion>

      <Accordion title="Person types" icon="users">
        Person types valid for booking variants.

        | Type      |
        | --------- |
        | `ADULT`   |
        | `CHILD`   |
        | `INFANT`  |
        | `SENIOR`  |
        | `GENERAL` |
        | `STUDENT` |
        | `YOUTH`   |

        <Note>Additional types such as `RESIDENT`, `NON_EUR_CHILD`, etc. may appear dynamically.</Note>

        See: [List Inventory](/docs/api-partner/v2/inventory/list-by-tour) · [Create Booking](/docs/api-partner/v2/bookings/create) · [Get Booking](/docs/api-partner/v2/bookings/get) — see [Pax Types](https://docs.google.com/spreadsheets/d/1KYpqKTNvp17WV-huEURDxfcqwF2Iz_Cu357QFAZfVco/edit?gid=0#gid=0)
      </Accordion>
    </AccordionGroup>

    ## Input fields

    <AccordionGroup>
      <Accordion title="Input field types" icon="square-pen">
        Input field types for variant-specific customer information.

        | Field                            | Description                                       |
        | -------------------------------- | ------------------------------------------------- |
        | `NAME`                           | Customer name                                     |
        | `EMAIL`                          | Email address                                     |
        | `PHONE`                          | Phone number                                      |
        | `ADDRESS`                        | Address information                               |
        | `AGE_`                           | Age-related fields                                |
        | `COUNTRY_`                       | Country information                               |
        | `DATE_OF_BIRTH_`                 | Date of birth                                     |
        | `DROP_OFF_LOCATION_`             | Drop-off location                                 |
        | `FULL_NAME_`                     | Full name fields                                  |
        | `GENDER_`                        | Gender information                                |
        | `IDENTITY_DOCUMENT_DETAILS_`     | ID document details                               |
        | `LANGUAGE_`                      | Language preference                               |
        | `NATIONALITY_`                   | Nationality                                       |
        | `PASSPORT_DETAILS_`              | Passport information                              |
        | `PHYSICAL_INFORMATION_-_HEIGHT_` | Physical characteristics                          |
        | `PICK_UP_DETAILS_`               | Pickup information                                |
        | `PICKUP_LOCATION`                | Pickup location                                   |
        | `CUSTOM_*`                       | Custom dynamic fields provided by supply partners |

        <Note>Many more values may appear dynamically from supply partners. Always handle unknown values gracefully.</Note>

        See: [Get Product](/docs/api-partner/v2/products/get) · [List Inventory](/docs/api-partner/v2/inventory/list-by-tour) — see [Input Fields](https://docs.google.com/spreadsheets/d/1KYpqKTNvp17WV-huEURDxfcqwF2Iz_Cu357QFAZfVco/edit?gid=1706272551#gid=1706272551)
      </Accordion>

      <Accordion title="Input field data types" icon="database">
        Data types an input field can have. Use this to drive form validation and rendering on your end.

        | Data Type  | Description                                                                                                                                                                                                                      | Validation                                                                                    |
        | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
        | `STRING`   | Free-form text (e.g., `John Doe`)                                                                                                                                                                                                | Apply `regex`, `minLength`, `maxLength` from the `validation` object if present               |
        | `ENUM`     | One of a predefined set of string literals (e.g., `MALE`, `FEMALE`, `OTHER`)                                                                                                                                                     | Value **must** be one of the entries in `validation.values` (always `string[]` for this type) |
        | `BOOL`     | Boolean flag — submit as the string `"true"` or `"false"`                                                                                                                                                                        | —                                                                                             |
        | `INT`      | Whole-number value (e.g., `25`)                                                                                                                                                                                                  | Apply `minValue`, `maxValue` from `validation` if present                                     |
        | `FLOAT`    | Decimal number (e.g., `25.50`)                                                                                                                                                                                                   | Apply `minValue`, `maxValue` from `validation` if present                                     |
        | `LOCATION` | Pickup or drop-off location. When `validation.values` is non-empty, items are **predefined location objects** (not strings) — the customer must select one. When `validation.values` is null, accept a free-form address string. | See predefined location object shape below                                                    |

        <Note>There is no dedicated `DATE` dataType. Date and date-time fields (such as `DATE_OF_BIRTH_*`) are submitted as `STRING`, with the expected format enforced by `validation.regex` on the field.</Note>

        #### `validation.values` — Polymorphic Field

        The type of items in `validation.values` depends on the field's `dataType`:

        * **`ENUM`** — `validation.values` is `string[]`. The submitted value must be an exact match.
          ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
          "values": ["VEGETARIAN", "VEGAN", "GLUTEN_FREE", "NONE"]
          ```

        * **`LOCATION` with predefined options** — `validation.values` is an array of **location objects**. Render these as a dropdown and submit either the selected object's `id` or its `displayName` as the field value.
          ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
          "values": [
            {
              "id": 24698,
              "latitude": 36.112946,
              "longitude": -115.176507,
              "address": "3600 S Las Vegas Blvd, Las Vegas, NV 89109, USA",
              "displayName": "Bellagio",
              "timingConfig": {
                "startTime": "10:30",
                "endTime": "11:00",
                "minPeriod": null,
                "maxPeriod": null
              },
              "note": null
            }
          ]
          ```

        * **All other types** — `validation.values` is `null`.

        #### Predefined location object fields

        | Field                    | Type            | Description                                                                                                                        |
        | ------------------------ | --------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
        | `id`                     | integer         | Unique identifier for this location. Submit this value or the location's `displayName` as the field value when creating a booking. |
        | `latitude`               | number          | Latitude of the pickup/drop-off point in decimal degrees.                                                                          |
        | `longitude`              | number          | Longitude of the pickup/drop-off point in decimal degrees.                                                                         |
        | `address`                | string          | Full street address of the location.                                                                                               |
        | `displayName`            | string          | Short human-readable label for display in a dropdown (e.g., `"Bellagio"`).                                                         |
        | `timingConfig.startTime` | string \| null  | Earliest pickup time for this location (HH:mm format). Null if no restriction.                                                     |
        | `timingConfig.endTime`   | string \| null  | Latest pickup time for this location (HH:mm format). Null if no restriction.                                                       |
        | `timingConfig.minPeriod` | integer \| null | Minimum notice required for this pickup in minutes. Null if no restriction.                                                        |
        | `timingConfig.maxPeriod` | integer \| null | Maximum advance booking window in minutes. Null if no restriction.                                                                 |
        | `note`                   | object \| null  | Additional instruction for this pickup location. Null if no note. Contains `content` (string) and `language` (language code).      |

        See: [Get Product](/docs/api-partner/v2/products/get) · [List Inventory](/docs/api-partner/v2/inventory/list-by-tour)
      </Accordion>
    </AccordionGroup>

    ## Booking lifecycle

    <AccordionGroup>
      <Accordion title="Cashback types" icon="coins">
        Cashback value types for promotional offers. The `value` field on the cashback object should be interpreted according to this type.

        | Type         | Description                                            | Example                                                              |
        | ------------ | ------------------------------------------------------ | -------------------------------------------------------------------- |
        | `ABSOLUTE`   | Fixed cashback amount in the product's native currency | `value: 10` → customer receives \$10 cashback                        |
        | `PERCENTAGE` | Cashback as a percentage of the total variant price    | `value: 10` → customer receives 10% of the booking total as cashback |

        See: [List Products](/docs/api-partner/v2/products/list) · [Get Product](/docs/api-partner/v2/products/get)
      </Accordion>

      <Accordion title="Booking status" icon="circle-check">
        Booking lifecycle statuses. `PENDING` and `COMPLETED` can still move to `CANCELLED` — e.g. customer cancellation within policy, or Headout-initiated cancellations like venue closures.

        | Status             | Description                                                                                                                                                                                   |
        | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
        | `UNCAPTURED`       | Booking entry has been created but payment has not been captured. **Does not lock inventory or price.** Never sent via webhook.                                                               |
        | `PENDING`          | Payment captured. **Booking is confirmed with the supplier** — show it to the customer as confirmed. Ticket generation may still be in progress.                                              |
        | `COMPLETED`        | Ticket has been generated and is available in the `tickets` array.                                                                                                                            |
        | `CANCELLED`        | Booking was cancelled — by the partner, customer, or Headout (e.g. venue closures). Reachable from `PENDING` or `COMPLETED`.                                                                  |
        | `FAILED`           | Capture was attempted but rejected. The booking cannot move to any other status — create a new booking if the customer still wants to proceed.                                                |
        | `CAPTURE_TIMEDOUT` | `UNCAPTURED` booking was not captured within 1 hour and can no longer be captured. The booking cannot move to any other status — create a new booking if the customer still wants to proceed. |

        **Transitions**

        * From `UNCAPTURED`: remains `UNCAPTURED` until captured, → `PENDING` on successful capture, → `FAILED` on rejected capture, → `CAPTURE_TIMEDOUT` if no capture within 1 hour.
        * From `PENDING`: → `COMPLETED` when the ticket is generated, → `CANCELLED` if cancelled before fulfilment.
        * From `COMPLETED`: → `CANCELLED` if cancelled after fulfilment (e.g. venue closure).
        * From `FAILED` or `CAPTURE_TIMEDOUT`: no further transitions.

        See: [Create Booking](/docs/api-partner/v2/bookings/create) · [List Bookings](/docs/api-partner/v2/bookings/list) · [Get Booking](/docs/api-partner/v2/bookings/get) · [Update Booking](/docs/api-partner/v2/bookings/update) · [Create Webhook](/docs/api-partner/v2/webhooks/create)
      </Accordion>

      <Accordion title="Ticket types" icon="ticket">
        Ticket delivery formats returned in the `tickets` array of a booking.

        | Type                | Description                            |
        | ------------------- | -------------------------------------- |
        | `PDF_URL`           | URL to a downloadable PDF ticket       |
        | `HTML_URL`          | URL to an HTML ticket page             |
        | `QRCODE`            | QR code data for scanning at the venue |
        | `BARCODE`           | Barcode data for scanning at the venue |
        | `TEXT`              | Plain text ticket information          |
        | `APPLE_WALLET_URL`  | URL to add ticket to Apple Wallet      |
        | `GOOGLE_WALLET_URL` | URL to add ticket to Google Wallet     |

        See: [Get Booking](/docs/api-partner/v2/bookings/get)
      </Accordion>

      <Accordion title="Input field level" icon="layers">
        Defines who a given input field should be collected for. Use this to drive form rendering — only show and collect fields appropriate for each level.

        | Level              | Description                                                                                                                                                                                               | Typical Fields                                                                    |
        | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
        | `PRIMARY_CUSTOMER` | Collected once, from the lead guest only. There is always exactly one primary customer per booking. Submit inside the `isPrimary: true` customer's `inputFields`.                                         | Name, email, phone, address                                                       |
        | `ALL_CUSTOMER`     | Collected from every guest in the booking, including the primary customer. Submit inside every customer's `inputFields`.                                                                                  | Weight, height, meal preference, date of birth                                    |
        | `BOOKING`          | Applies to the booking as a whole — not tied to any individual guest. Collected once regardless of pax count. Submit in the booking-level `variantInputFields` array, **not** inside any customer object. | Language preference, group name on the reservation, special accessibility request |

        <Note>`level` (who you collect from) and `dataType` (what shape the value takes) are independent axes. A `BOOKING`-level field can be any dataType, and a `LOCATION` dataType field can be at any level.</Note>

        See: [Get Product](/docs/api-partner/v2/products/get) · [List Inventory](/docs/api-partner/v2/inventory/list-by-tour)
      </Accordion>

      <Accordion title="Cancellation reasons" icon="circle-x">
        Permitted cancellation reasons for partner cancellation requests.

        | Value                            | Description                                      |
        | -------------------------------- | ------------------------------------------------ |
        | `TICKETS_NOT_RECEIVED`           | Tickets or voucher not received by the customer  |
        | `CHANGE_OF_TRAVEL_PLANS`         | Customer changed travel plans                    |
        | `MODIFY_EXISTING_RESERVATION`    | Customer wants to modify an existing reservation |
        | `FOUND_CHEAPER_OPTION_ELSEWHERE` | Customer found a cheaper alternative             |
        | `OTHER`                          | Other reason not listed above                    |

        See: [Cancel Booking](/docs/api-partner/v2/bookings/cancel)
      </Accordion>
    </AccordionGroup>
  </Tab>

  <Tab title="Error codes">
    ## Error code reference

    <Accordion title="Error code reference (JSON)" icon="braces">
      ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
      {
        "CAL_0000": "Unknown error occurred",
        "CAL_0100": "Unknown error occurred",
        "CAL_0101": "Tour information is not legitimate",
        "CAL_0102": "Tour or language does not exist",
        "CAL_0103": "Tour's addon does not exist",
        "CAL_0104": "Price information is not legitimate",
        "CAL_0105": "Itinerary item does not exist",
        "CAL_0106": "Price of the item has changed",
        "CAL_0107": "No ADULT in free booking",
        "CAL_0108": "Children not permitted without adult",
        "CAL_0109": "Minimum number of tickets not selected",
        "CAL_0110": "Maximum number of tickets exceeded",
        "CAL_0111": "Max 2 children per 1 Adult/Student/Senior",
        "CAL_0112": "Minimum number of pax not selected",
        "CAL_0113": "Maximum number of pax exceeded",
        "CAL_0114": "Book now pay later not eligible",
        "CAL_0120": "Slot not available anymore",
        "CAL_0121": "Tour not available anymore",
        "CAL_0122": "Pricing has changed",
        "CAL_0123": "Selected date-time closed or invalid",
        "CAL_0130": "Duplicate booking attempt within 30 min",
        "CAL_0200": "Unknown booking error",
        "CAL_0201": "Could not create booking, retry",
        "CAL_0202": "Reserved for use",
        "CAL_0220": "No recent order found",
        "CAL_0221": "Booking currency mismatch",
        "CAL_0222": "Itinerary vs booking currency mismatch",
        "CAL_0223": "Reservation failed via plugin",
        "CAL_0231": "Tour prices have changed",
        "CAL_0241": "Unsupported operation for API version",
        "CAL_0310": "City not found",
        "CAL_0600": "Incorrect user field",
        "CAL_0601": "Missing last name",
        "CAL_0602": "Missing mandatory user fields",
        "CAL_0603": "Invalid phone number",
        "CAL_0604": "Primary customer details missing",
        "CAL_0900": "Error in Calipso Product",
        "CAL_1000": "Valid API key not found",
        "CAL_1300": "Count doesn't match number of customers",
        "CAL_1400": "Invalid date range (from > to)",
        "CAL_1401": "Booking does not exist",
        "CAL_1402": "Could not fetch voucher; booking missing",
        "CAL_1403": "Unsupported itinerary type (combo)",
        "CAL_1404": "Authentication failed for voucher",
        "CAL_1405": "Temporary error fetching booking",
        "CAL_1406": "Booking does not belong to user",
        "CAL_1600": "Invalid body/query/path parameters",
        "CAL_1801": "Failed to cancel ticket",
        "CAL_1802": "Could not fetch booking (server error)",
        "CAL_1803": "Failed to reschedule booking",
        "CAL_1804": "Live inventory not available for reschedule",
        "CAL_1900": "Vendor audio guide not found",
        "CAL_1901": "Could not add audio guide",
        "CAL_1902": "Audio guide expired",
        "CAL_1903": "Share limit exceeded",
        "CAL_1904": "Audio guide unavailable",
        "CAL_1905": "Unsupported form type",
        "CAL_1906": "Non-nullable attribute is null",
        "CAL_1907": "Quote not found",
        "CAL_1908": "Tour user fields not found"
      }
      ```
    </Accordion>

    ## Generic

    <AccordionGroup>
      <Accordion title="Generic" icon="triangle-alert">
        | Code       | Description            |
        | ---------- | ---------------------- |
        | `CAL_0000` | Unknown error occurred |
      </Accordion>

      <Accordion title="Cart / itinerary" icon="shopping-cart">
        **General**

        | Code       | Description            |
        | ---------- | ---------------------- |
        | `CAL_0100` | Unknown error occurred |

        **Legitimacy**

        | Code       | Description                               |
        | ---------- | ----------------------------------------- |
        | `CAL_0101` | Tour information is not legitimate        |
        | `CAL_0102` | Tour or language does not exist           |
        | `CAL_0103` | Tour's addon does not exist               |
        | `CAL_0104` | Price information is not legitimate       |
        | `CAL_0105` | Itinerary item does not exist             |
        | `CAL_0106` | Price of the item has changed             |
        | `CAL_0107` | No ADULT in free booking                  |
        | `CAL_0108` | Children not permitted without adult      |
        | `CAL_0109` | Minimum number of tickets not selected    |
        | `CAL_0110` | Maximum number of tickets exceeded        |
        | `CAL_0111` | Max 2 children per 1 Adult/Student/Senior |
        | `CAL_0112` | Minimum number of pax not selected        |
        | `CAL_0113` | Maximum number of pax exceeded            |
        | `CAL_0114` | Book now pay later not eligible           |

        **Expiration**

        | Code       | Description                          |
        | ---------- | ------------------------------------ |
        | `CAL_0120` | Slot not available anymore           |
        | `CAL_0121` | Tour not available anymore           |
        | `CAL_0122` | Pricing has changed                  |
        | `CAL_0123` | Selected date-time closed or invalid |

        **Duplicate Booking**

        | Code       | Description                             |
        | ---------- | --------------------------------------- |
        | `CAL_0130` | Duplicate booking attempt within 30 min |
      </Accordion>
    </AccordionGroup>

    ## Booking

    <AccordionGroup>
      <Accordion title="Booking" icon="calendar-check">
        **Pre Booking**

        | Code       | Description                     |
        | ---------- | ------------------------------- |
        | `CAL_0200` | Unknown booking error           |
        | `CAL_0201` | Could not create booking, retry |
        | `CAL_0202` | Reserved for use                |

        **Booking Results**

        | Code       | Description                            |
        | ---------- | -------------------------------------- |
        | `CAL_0220` | No recent order found                  |
        | `CAL_0221` | Booking currency mismatch              |
        | `CAL_0222` | Itinerary vs booking currency mismatch |
        | `CAL_0223` | Reservation failed via plugin          |

        **Expiration**

        | Code       | Description              |
        | ---------- | ------------------------ |
        | `CAL_0231` | Tour prices have changed |

        **Unsupported Operations**

        | Code       | Description                           |
        | ---------- | ------------------------------------- |
        | `CAL_0241` | Unsupported operation for API version |

        **Fetch & Update**

        | Code       | Description                                 |
        | ---------- | ------------------------------------------- |
        | `CAL_1802` | Could not fetch booking (server error)      |
        | `CAL_1803` | Failed to reschedule booking                |
        | `CAL_1804` | Live inventory not available for reschedule |
      </Accordion>
    </AccordionGroup>

    ## Other domains

    <AccordionGroup>
      <Accordion title="Cancellation" icon="circle-x">
        | Code       | Description             |
        | ---------- | ----------------------- |
        | `CAL_1801` | Failed to cancel ticket |
      </Accordion>

      <Accordion title="Cities" icon="map-pin">
        | Code       | Description    |
        | ---------- | -------------- |
        | `CAL_0310` | City not found |
      </Accordion>

      <Accordion title="Customer fields" icon="user">
        | Code       | Description                      |
        | ---------- | -------------------------------- |
        | `CAL_0600` | Incorrect user field             |
        | `CAL_0601` | Missing last name                |
        | `CAL_0602` | Missing mandatory user fields    |
        | `CAL_0603` | Invalid phone number             |
        | `CAL_0604` | Primary customer details missing |
      </Accordion>

      <Accordion title="Products" icon="package">
        | Code       | Description              |
        | ---------- | ------------------------ |
        | `CAL_0900` | Error in Calipso Product |
      </Accordion>

      <Accordion title="Partner" icon="handshake">
        | Code       | Description                             |
        | ---------- | --------------------------------------- |
        | `CAL_1000` | Valid API key not found                 |
        | `CAL_1300` | Count doesn't match number of customers |
      </Accordion>

      <Accordion title="Reservations" icon="list">
        | Code       | Description                              |
        | ---------- | ---------------------------------------- |
        | `CAL_1400` | Invalid date range (`from > to`)         |
        | `CAL_1401` | Booking does not exist                   |
        | `CAL_1402` | Could not fetch voucher; booking missing |
        | `CAL_1403` | Unsupported itinerary type (combo)       |
        | `CAL_1404` | Authentication failed for voucher        |
        | `CAL_1405` | Temporary error fetching booking         |
        | `CAL_1406` | Booking does not belong to user          |
      </Accordion>

      <Accordion title="Malformed requests" icon="code">
        | Code       | Description                        |
        | ---------- | ---------------------------------- |
        | `CAL_1600` | Invalid body/query/path parameters |
      </Accordion>

      <Accordion title="Audio guide" icon="headphones">
        | Code       | Description                    |
        | ---------- | ------------------------------ |
        | `CAL_1900` | Vendor audio guide not found   |
        | `CAL_1901` | Could not add audio guide      |
        | `CAL_1902` | Audio guide expired            |
        | `CAL_1903` | Share limit exceeded           |
        | `CAL_1904` | Audio guide unavailable        |
        | `CAL_1905` | Unsupported form type          |
        | `CAL_1906` | Non-nullable attribute is null |
        | `CAL_1907` | Quote not found                |
        | `CAL_1908` | Tour user fields not found     |
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
