{
  "openapi" : "3.0.1",
  "info" : {
    "title" : "ThinkReservations API Documentation",
    "description" : "## Overview\n\nThe ThinkReservations External API lets partners and integrators access reservations,\navailability, rates, rooms, room types, and inventory for a specific hotel, and create\nreservations the way the hotel's booking engine does. Booking is two calls: search availability,\nthen send back the `booking` object the search returned, with the guest and a single-use card\nnonce.\n\n## Base URL\n\nAll requests are made to `https://api.thinkreservations.com`.\n\n## Authentication\n\nThe hotel-in-path endpoints accept **either** an **OAuth 2.0** access token **or** a\n**Restricted API Key** (see [Restricted API Keys](#restricted-api-keys) below). The bare\n`GET /v1/hotels` hotel-discovery endpoint is **OAuth-only**.\n\nOAuth 2.0 access tokens are scoped to the hotel(s) you integrate with. The API uses the\n**authorization code** grant: send the user to the authorization endpoint, then exchange the\nreturned code for an access token. Send the token as an `Authorization: Bearer <token>` header on\neach request.\n\n**1. Redirect the user to the authorization endpoint:**\n\n```\nhttps://auth.thinkreservations.com/authorize?response_type=code\n  &client_id=YOUR_CLIENT_ID\n  &redirect_uri=YOUR_REDIRECT_URI\n  &audience=https://api.thinkreservations.com/\n  &scope=offline_access read:reservation read:availability\n```\n\nThe `offline_access` scope makes the token response contain a refresh token. Include it if you\nwant to refresh the access token later.\n\n**2. ThinkReservations redirects back to your `redirect_uri` with a `code`. Exchange it for an access token:**\n\n```bash\ncurl -X POST https://auth.thinkreservations.com/oauth/token \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"grant_type\": \"authorization_code\",\n    \"client_id\": \"YOUR_CLIENT_ID\",\n    \"client_secret\": \"YOUR_CLIENT_SECRET\",\n    \"code\": \"AUTHORIZATION_CODE\",\n    \"redirect_uri\": \"YOUR_REDIRECT_URI\"\n  }'\n```\n\nThe access token expires 24 hours after it is issued. The `expires_in` field of the token\nresponse gives the remaining lifetime in seconds. An expired token no longer authenticates a\nrequest.\n\nThe token response also contains a `refresh_token`, if you requested the `offline_access` scope in\nstep 1. Use it to get a new access token before the old one expires. A refresh does not involve the\nuser. Keep the refresh token secret, and store it as securely as you store your client secret.\n\n**3. Exchange the refresh token for a new access token:**\n\n```bash\ncurl -X POST https://auth.thinkreservations.com/oauth/token \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"grant_type\": \"refresh_token\",\n    \"client_id\": \"YOUR_CLIENT_ID\",\n    \"client_secret\": \"YOUR_CLIENT_SECRET\",\n    \"refresh_token\": \"YOUR_REFRESH_TOKEN\"\n  }'\n```\n\nIf you are a partner looking to integrate with ThinkReservations, contact us at\nproduct@thinkreservations.com to discuss your use case.\n\n### Platform partners (client credentials)\n\nA platform that books on guests' behalf across many hotels, such as a travel agent or an AI\nbooking assistant, does not onboard hotels one at a time. ThinkReservations issues such a partner\none machine-to-machine client after agreement; this is not self-service. Contact\nproduct@thinkreservations.com.\n\nExchange the client credentials for an access token. No user is involved and no redirect occurs:\n\n```bash\ncurl -X POST https://auth.thinkreservations.com/oauth/token \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"grant_type\": \"client_credentials\",\n    \"client_id\": \"YOUR_CLIENT_ID\",\n    \"client_secret\": \"YOUR_CLIENT_SECRET\",\n    \"audience\": \"https://api.thinkreservations.com/\"\n  }'\n```\n\nThe token expires 24 hours after it is issued, like every other token. With it:\n\n- `GET /v1/hotels` returns **every hotel your credential can book**, with address, coordinates,\n  currency, policies and website, so you can find inventory by location.\n- Every `/v1/hotels/{hotelId}/…` endpoint your scopes cover works for **any hotel in that list**.\n  Use each hotel's `externalId` from the list as `{hotelId}`.\n- The scopes on your credential are agreed as part of the integration and appear in the\n  token's `scope` claim. To request more, contact us.\n\nSend a stable `channel` value naming your platform on every reservation you create. It is how\neach hotel sees and reports on bookings that came through you.\n\nAn agent that pays with Stripe shared payment tokens grants the token to the hotel's Stripe\naccount and sends it as `creditCardData` of type `SHARED_PAYMENT_TOKEN` on *Create Reservation*;\nno tokenization step is needed. The token is single-use, so no card stays on file for later\ncharges.\n\n### Restricted API Keys\n\nRestricted API Keys are generated at\n[https://manage.thinkreservations.com/settings/api-keys](https://manage.thinkreservations.com/settings/api-keys).\nEach key is bound to a single hotel, whose ID is shown alongside the key on that page — use that ID\nas the `{hotelId}` path parameter.\n\nPass the key as a bearer token in the `Authorization` header:\n\n```\nAuthorization: Bearer rk_live_…\n```\n\nA Restricted API Key works on the `/v1/hotels/{hotelId}/…` endpoints. It **cannot** call the\nbare `GET /v1/hotels` hotel-discovery list, which is OAuth-only.\n\n## Scopes\n\n| Scope               | Grants                                        |\n|---------------------|-----------------------------------------------|\n| `read:rate`         | Read rate types and daily rate configurations |\n| `read:availability` | Read availability and inventory               |\n| `read:reservation`  | Read reservations                             |\n| `write:reservation` | Create reservations                           |\n| `read:customer`     | Include guest contact details on reservations |\n| `read:room`         | Read rooms and room types                     |\n| `read:hotel`        | Read hotel details                            |\n| `write:rate`        | Update daily rate configurations              |\n\nCreating a reservation charges the rate type's deposit to the guest's card, so request\n`write:reservation` only if your integration books stays on the guest's behalf.\n\nMost scopes grant access to a set of endpoints. `read:customer` is different: it grants no\nendpoints of its own and instead widens the response of `GET /v1/hotels/{hotelId}/reservations`.\nRequest it alongside `read:reservation` if your integration needs guest contact details.\n\nGuest contact details are personal data. Only request `read:customer` if your integration\nactually needs them.\n\nRestricted API Keys carry scopes too — select them when you create the key at\n[https://manage.thinkreservations.com/settings/api-keys](https://manage.thinkreservations.com/settings/api-keys).\nA key's scopes are fixed at creation; to change them, create a new key.\n",
    "contact" : {
      "name" : "API Support",
      "email" : "developers@thinkreservations.com"
    },
    "version" : "1.0"
  },
  "servers" : [ {
    "url" : "https://api.thinkreservations.com",
    "description" : "Production"
  } ],
  "security" : [ {
    "oauth2" : [ "read:rate", "write:rate", "read:availability", "read:reservation", "write:reservation", "read:customer", "read:room", "read:hotel" ]
  }, {
    "apiKey" : [ ]
  } ],
  "tags" : [ {
    "name" : "Rate Types",
    "description" : "Rate types define the prices and booking rules a hotel offers for its room types — for example a\n*Best Available Rate*, a *Non-Refundable* discount, or a negotiated *Corporate* rate.\n\nUse these endpoints to:\n\n- **List rate types** configured for a hotel, including their names and policies.\n- **Read daily rate configurations** for a rate type over a date range (per-day prices, minimum-stay\n  and closed-to-arrival restrictions, and any applied promotions).\n- **Update daily rate configurations** to push pricing and availability rules back to a hotel.\n\n> **Tip:** daily rate configuration responses are keyed by date — request only the range you need to\n> keep payloads small. All monetary values are in the hotel's configured currency.\n"
  }, {
    "name" : "Reservations",
    "description" : "A reservation is a guest's bill at a hotel: the guest, one or more room bookings with their stay\ndates and rate type, any add-on line items, and the computed totals, deposit and payments.\n\nUse these endpoints to:\n\n- **List reservations** for a hotel by stay dates, last-modified time, or creation time, with guest\n  contact details when your token carries `read:customer`.\n- **Create a reservation** the way the hotel's booking engine does: tokenize the guest's card, send\n  the guest and bookings, and the server prices the stay, charges the deposit, assigns a room, and\n  notifies the guest and the hotel.\n\n> **Tip:** ids are shared across the API. A booking's `roomTypeId`, `roomId` and `rateTypeId` are\n> the `id` values returned by the room types, rooms and rate types endpoints.\n"
  } ],
  "paths" : {
    "/v1/hotels/{hotelId}/rate_types/{rateTypeId}/daily" : {
      "get" : {
        "tags" : [ "Rate Types" ],
        "summary" : "Get Daily Rate Configurations by Rate Type Id and Date Range",
        "operationId" : "getDailyRateConfigurationsByRateTypeIdAndDateRange",
        "parameters" : [ {
          "name" : "hotelId",
          "in" : "path",
          "description" : "The hotel's ID. OAuth consumers: use the `externalId` values returned by `GET /v1/hotels`. Restricted API Keys: your hotel ID is shown at https://manage.thinkreservations.com/settings/api-keys.",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "rateTypeId",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "dateRange",
          "in" : "query",
          "required" : true,
          "schema" : {
            "$ref" : "#/components/schemas/StartEndDateRange"
          }
        }, {
          "name" : "room_type_id",
          "in" : "query",
          "required" : false,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "OK",
            "content" : {
              "*/*" : {
                "schema" : {
                  "type" : "array",
                  "items" : {
                    "$ref" : "#/components/schemas/RoomTypeDailyRateConfiguration"
                  }
                }
              }
            }
          }
        },
        "security" : [ {
          "oauth2" : [ "read:rate" ]
        }, {
          "apiKey" : [ ]
        } ]
      },
      "put" : {
        "tags" : [ "Rate Types" ],
        "summary" : "Update Daily Rate Configurations",
        "description" : "Updates the daily rate configurations for a rate type.\n\n## Request body\n\nThe body is the **raw gzip** of a JSON array. Send the compressed bytes as-is with\n`Content-Type: application/gzip`. Do **not** base64-encode them, and do **not** send the JSON array\nitself. A body that is not gzip is rejected with `400`; a body with any other `Content-Type` is\nrejected with `415`.\n\nField names may be given in either spelling. `roomTypeId` is the documented form and matches the\n`GET` response; `room_type_id` is also accepted for backward compatibility. Do not mix spellings\nwithin one request. A field name the endpoint does not recognize is rejected, so a misspelled field\nis reported rather than silently ignored.\n\nThe two identifiers in play are not the same kind of value, which is easy to miss:\n\n| Value | What to send |\n| --- | --- |\n| `{rateTypeId}` in the path | The rate type's numeric id, as returned by `GET /v1/hotels/{hotelId}/rate_types` |\n| `roomTypeId` in each row | The room type's UUID `externalId`, as returned by `GET /v1/hotels/{hotelId}/room_types` |\n\nA row may also carry `rateTypeId`, so a row read from `GET .../daily` can be edited and sent back\nunchanged. It is optional, and the rate type written to is always the `{rateTypeId}` in the path —\na row whose `rateTypeId` differs is rejected. `id` is accepted but ignored.\n\nThe rate type must be one that holds its own rates. A *derived* rate type computes its rates from a\nparent rate type, so a write to it is rejected with `400` and the message names the parent rate type\nto write to instead.\n\n## Omitted fields are left unchanged\n\nEach row updates the stored configuration for its room type and date:\n\n- A field you **omit** keeps its stored value.\n- A field you send as **`null`** is cleared.\n- For a date that has no configuration yet, an omitted field is simply not set.\n\nTo change one field for a day, send that field with `roomTypeId` and `date` and nothing else:\n\n```json\n[{ \"roomTypeId\": \"4b6a486e-85f8-4fb2-b7b0-95998cc9273a\", \"date\": \"2027-08-27\", \"price\": 210.00 }]\n```\n\nSending every field with its current value also works, but note that a field sent as `null` clears\nthe stored value, so only send `null` when that is what you mean.\n\n## Validation happens before the response\n\nThe body is decompressed, parsed and checked in full before anything is queued. A request is either\naccepted whole or rejected whole: when any row is invalid, nothing is written.\n\nProblems with the body as a whole return `400` with a `message`:\n\n```json\n{ \"statusCode\": 400, \"name\": \"Invalid Request\", \"message\": \"The request body must be a JSON array of daily rate configurations.\" }\n```\n\nProblems with individual rows return `400` with an `errorsMap`, keyed by the row's position in the\narray and the field, spelled the way you sent it. Every invalid row is reported, up to 100 errors:\n\n```json\n{\n  \"errorsMap\": {\n    \"[0].roomTypeId\": [\"[9d1c…] was not found for this hotel\"],\n    \"[3].date\": [\"[2027-13-01] is not a valid date; use yyyy-MM-dd\"],\n    \"[7].minimumNightsOnArrivel\": [\"is not a recognized field\"]\n  }\n}\n```\n\nRow checks: `roomTypeId` present and belonging to the hotel; `date` present and in `yyyy-MM-dd`\nform; every field name recognized and every value of the right type; `rateTypeId`, if present,\nequal to the path; and no two rows for the same room type and date.\n\n| Status | Meaning |\n| --- | --- |\n| `202` | The body is valid and has been queued to apply. |\n| `400` | The body or a row is invalid, or the rate type is derived. Nothing was written. |\n| `404` | The hotel or rate type does not exist. |\n| `415` | The `Content-Type` is not `application/gzip`. |\n\n## Applying is asynchronous\n\nA `202` means the body passed validation and was queued; the rows are applied by a background worker\nafter the response is sent, and channel updates follow. Confirm a write by reading the range back with\n`GET /v1/hotels/{hotelId}/rate_types/{rateTypeId}/daily`.\n",
        "operationId" : "updateDailyRateConfigurations",
        "parameters" : [ {
          "name" : "hotelId",
          "in" : "path",
          "description" : "The hotel's ID. OAuth consumers: use the `externalId` values returned by `GET /v1/hotels`. Restricted API Keys: your hotel ID is shown at https://manage.thinkreservations.com/settings/api-keys.",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "rateTypeId",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "requestBody" : {
          "description" : "The gzip of a JSON array of daily rate configurations. Send the raw compressed bytes with `Content-Type: application/gzip` - not base64, and not the JSON array itself. A field you omit keeps its stored value; a field you send as `null` is cleared. The body is validated before it is accepted; see the operation description for the checks and the error shapes.",
          "content" : {
            "application/gzip" : {
              "schema" : {
                "type" : "array",
                "items" : {
                  "$ref" : "#/components/schemas/RoomTypeDailyRateConfigurationUpdate"
                }
              },
              "examples" : {
                "Two nights for one room type" : {
                  "description" : "The JSON to gzip. Only the fields being changed are sent; the rest keep their stored values. Field names may also be given in snake_case (`room_type_id`), which the endpoint continues to accept for backward compatibility.",
                  "value" : [ {
                    "roomTypeId" : "4b6a486e-85f8-4fb2-b7b0-95998cc9273a",
                    "date" : "2027-08-27",
                    "price" : 210.0,
                    "minimumNightsOnArrival" : 2
                  }, {
                    "roomTypeId" : "4b6a486e-85f8-4fb2-b7b0-95998cc9273a",
                    "date" : "2027-08-28",
                    "price" : 225.0,
                    "stopSell" : true
                  } ]
                }
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "202" : {
            "description" : "Accepted"
          }
        },
        "security" : [ {
          "oauth2" : [ "write:rate" ]
        }, {
          "apiKey" : [ ]
        } ],
        "x-codeSamples" : [ {
          "lang" : "curl",
          "label" : "cURL",
          "source" : "cat > rates.json <<'JSON'\n[\n  {\n    \"roomTypeId\": \"4b6a486e-85f8-4fb2-b7b0-95998cc9273a\",\n    \"date\": \"2027-08-27\",\n    \"price\": 210.00,\n    \"minimumNightsOnArrival\": 2\n  },\n  {\n    \"roomTypeId\": \"4b6a486e-85f8-4fb2-b7b0-95998cc9273a\",\n    \"date\": \"2027-08-28\",\n    \"price\": 225.00,\n    \"stopSell\": true\n  }\n]\nJSON\n\n# Fields you leave out keep their stored values. Send a field as null to clear it.\n# Send the raw gzip bytes. Not base64, and not the JSON array itself.\ngzip -c rates.json > rates.json.gz\n\n# A 400 carries either a \"message\" or an \"errorsMap\" keyed by row index and field,\n# for example \"[1].roomTypeId\". Nothing is written unless every row is valid.\ncurl -X PUT \\\n  \"https://api.thinkreservations.com/v1/hotels/$HOTEL_ID/rate_types/$RATE_TYPE_ID/daily\" \\\n  -H \"Authorization: Bearer $ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/gzip\" \\\n  --data-binary @rates.json.gz"
        }, {
          "lang" : "python",
          "label" : "Python (requests)",
          "source" : "import gzip\nimport json\n\nimport requests\n\n# Fields you leave out keep their stored values. Send a field as None to clear it.\nrows = [\n    {\n        \"roomTypeId\": \"4b6a486e-85f8-4fb2-b7b0-95998cc9273a\",\n        \"date\": \"2027-08-27\",\n        \"price\": 210.00,\n        \"minimumNightsOnArrival\": 2,\n    },\n    {\n        \"roomTypeId\": \"4b6a486e-85f8-4fb2-b7b0-95998cc9273a\",\n        \"date\": \"2027-08-28\",\n        \"price\": 225.00,\n        \"stopSell\": True,\n    },\n]\n\n# gzip the encoded JSON and send those bytes as the body. Do not json.dumps()\n# the body a second time, and do not base64-encode it.\nbody = gzip.compress(json.dumps(rows).encode(\"utf-8\"))\n\nresponse = requests.put(\n    f\"https://api.thinkreservations.com/v1/hotels/{hotel_id}/rate_types/{rate_type_id}/daily\",\n    headers={\n        \"Authorization\": f\"Bearer {access_token}\",\n        \"Content-Type\": \"application/gzip\",\n    },\n    data=body,\n)\n\nif response.status_code == 400:\n    # Either {\"message\": \"...\"} for the body as a whole, or\n    # {\"errorsMap\": {\"[1].roomTypeId\": [\"...\"]}} naming each invalid row and field.\n    # Nothing was written.\n    raise ValueError(response.json())\nresponse.raise_for_status()  # 202 Accepted: validated and queued"
        }, {
          "lang" : "javascript",
          "label" : "Node.js (fetch)",
          "source" : "import { gzipSync } from 'node:zlib';\n\n// Fields you leave out keep their stored values. Send a field as null to clear it.\nconst rows = [\n  {\n    roomTypeId: '4b6a486e-85f8-4fb2-b7b0-95998cc9273a',\n    date: '2027-08-27',\n    price: 210.0,\n    minimumNightsOnArrival: 2,\n  },\n  {\n    roomTypeId: '4b6a486e-85f8-4fb2-b7b0-95998cc9273a',\n    date: '2027-08-28',\n    price: 225.0,\n    stopSell: true,\n  },\n];\n\n// gzip the encoded JSON and send those bytes as the body. Not base64, and not\n// the JSON array itself.\nconst body = gzipSync(Buffer.from(JSON.stringify(rows), 'utf-8'));\n\nconst response = await fetch(\n  `https://api.thinkreservations.com/v1/hotels/${hotelId}/rate_types/${rateTypeId}/daily`,\n  {\n    method: 'PUT',\n    headers: {\n      Authorization: `Bearer ${accessToken}`,\n      'Content-Type': 'application/gzip',\n    },\n    body,\n  },\n);\n\nif (response.status === 400) {\n  // Either { message } for the body as a whole, or { errorsMap } naming each\n  // invalid row and field, e.g. \"[1].roomTypeId\". Nothing was written.\n  throw new Error(JSON.stringify(await response.json()));\n}\nif (!response.ok) {\n  throw new Error(`Unexpected ${response.status}`);\n}\n// 202 Accepted: validated and queued"
        } ]
      }
    },
    "/v1/hotels/{hotelId}/reservations" : {
      "get" : {
        "tags" : [ "Reservations" ],
        "summary" : "Get Reservations",
        "description" : "Returns a page of the hotel's reservations, filtered by stay dates, last-modified time, or creation\ntime.\n\n**Guest contact details require the `read:customer` scope.** Each reservation carries a `customer`\nobject holding the guest's name, email, phone numbers, company, address, and notes. That object is\nonly populated when the access token carries `read:customer` in addition to `read:reservation`;\nwithout it, `customer` is returned as `null`.\n\nThe `customerId` field is always returned, with or without the scope, so an integration can still\ntell which reservations belong to the same guest.",
        "operationId" : "getReservations",
        "parameters" : [ {
          "name" : "hotelId",
          "in" : "path",
          "description" : "The hotel's ID. OAuth consumers: use the `externalId` values returned by `GET /v1/hotels`. Restricted API Keys: your hotel ID is shown at https://manage.thinkreservations.com/settings/api-keys.",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "stayOnDateRange",
          "in" : "query",
          "required" : true,
          "schema" : {
            "$ref" : "#/components/schemas/StayOnDateRange"
          }
        }, {
          "name" : "updatedAtDateTimeRange",
          "in" : "query",
          "required" : true,
          "schema" : {
            "$ref" : "#/components/schemas/UpdatedAtDateTimeRange"
          }
        }, {
          "name" : "createdAtDateTimeRange",
          "in" : "query",
          "required" : true,
          "schema" : {
            "$ref" : "#/components/schemas/CreatedAtDateTimeRange"
          }
        }, {
          "name" : "page",
          "in" : "query",
          "required" : false,
          "schema" : {
            "type" : "string",
            "default" : "0"
          }
        }, {
          "name" : "size",
          "in" : "query",
          "required" : false,
          "schema" : {
            "type" : "string",
            "default" : "10"
          }
        }, {
          "name" : "sort",
          "in" : "query",
          "required" : false,
          "schema" : {
            "type" : "string",
            "default" : ""
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "OK",
            "content" : {
              "*/*" : {
                "schema" : {
                  "$ref" : "#/components/schemas/PageReservation"
                }
              }
            }
          }
        },
        "security" : [ {
          "oauth2" : [ "read:reservation" ]
        }, {
          "apiKey" : [ ]
        } ]
      },
      "post" : {
        "tags" : [ "Reservations" ],
        "summary" : "Create Reservation",
        "description" : "Creates a reservation for the hotel and charges the rate type's deposit to the guest's card. This is\nthe same operation the ThinkReservations booking engine performs when a guest completes a booking,\nso the hotel sees the reservation exactly as it would see one from its own website: the guest\nreceives the hotel's confirmation email, the hotel receives its new-reservation notification, and the\nreservation is attributed to the `channel` you send.\n\n## Before you call this endpoint\n\n1. **Search availability.** Call `GET /v1/hotels/{hotelId}/availabilities` with the dates and the\n   party (`number_of_adults`, `number_of_children`, `child_ages`, `number_of_pets`, and a\n   `coupon_code` if the guest has one). Every rate type availability in the response carries a\n   `booking` object priced for exactly that search, alongside its `price`, `taxes`, `deposit` and\n   `total`. Show the guest the totals, and when they choose, **copy that `booking` object into\n   `bookings[]` unchanged.** You never construct a booking yourself: the copy already names the unit\n   the way this hotel sells it (`roomId` for hotels that sell individual rooms, `roomTypeId` for\n   hotels that sell by type), the `rateTypeId`, the dates, the occupancy and the coupon code, and an\n   empty `lineItems` list. To add an add-on, append it to that list.\n2. **Provide the payment.** Card numbers are never sent to this API. `creditCardData` is one of:\n\n   | `type` | Fields | Use when |\n   | --- | --- | --- |\n   | `NONCE` | `nonceId` | The guest gave you their card. Tokenize it first with `POST https://nonce.thinkreservations.com/businesses/{hotelId}/nonces` (the same `{hotelId}` as this API; body `{ \"businessId\": \"{hotelId}\", \"data\": { \"type\": \"MANUAL_ENTRY\", \"cardholderName\", \"number\", \"cvv\", \"expirationDate\" } }`, expiration as `MM/YYYY`) and send only the returned `id`. A nonce expires shortly after it is created and can be used once. |\n   | `SHARED_PAYMENT_TOKEN` | `sharedPaymentToken` (`spt_…`) | You are an AI agent or platform paying with a [Stripe shared payment token](https://docs.stripe.com/agentic-commerce/shared-payment-tokens) granted to this hotel. Send the token directly; there is no tokenization step. Grant it to the hotel's Stripe account, in the hotel's currency, with a `max_amount` that covers the deposit. Only hotels on ThinkPayments accept it. |\n\nThe field reference below describes what the server reads from each booking, for callers that\nassemble one by hand. Prices are recomputed when the reservation is created, so the totals the\nsearch returned are a quote, not a lock.\n\n## Request body\n\nThe body is a reservation with the guest, one or more bookings, optional add-on line items, and\nthe payment. Only the fields below are read; everything else the schema shows\n(`id`, `status`, `confirmationId`, `payments`, `deposit`, `subTotal`, `taxes`, `total`, timestamps)\nis computed by the server and ignored if sent.\n\n| Field | Required | Notes |\n| --- | --- | --- |\n| `acceptedTermsAndConditions` | yes | Must be `true`. Show the hotel's terms to the guest first. |\n| `channel` | no | Free text shown in the hotel's reports, e.g. your integration's name. Defaults to `Online`. |\n| `customer` | yes | See *Guest* below. |\n| `bookings[]` | yes, unless `lineItems[]` is non-empty | See *Bookings* below. |\n| `lineItems[]` | no | Bill-level add-ons; see *Line items* below. |\n| `creditCardData` | yes | `{ \"type\": \"NONCE\", \"nonceId\": \"…\" }` or `{ \"type\": \"SHARED_PAYMENT_TOKEN\", \"sharedPaymentToken\": \"spt_…\" }`. Any other `type` is rejected. |\n| `arrivalTime`, `specialAccommodations`, `dietaryRestrictions`, `additionalGuestNames`, `stayReason` | no | Free text, shown to the hotel on the reservation. |\n| `attributeValues[]` | no | Answers to the hotel's custom booking questions. |\n\n### Guest\n\n`customer` needs `firstName`, `lastName`, `email`, one of `phone` or `cellPhone`, `streetAddress`,\n`locality`, `region`, `country`, `postalCode`, and `agreedToMarketingEmails` (`true` or `false`).\nAn existing guest with the same first name, last name and email is reused; otherwise a new guest is\ncreated. `customer.id` is ignored.\n\n### Bookings\n\nEach booking is one unit for one stay. Sending the `booking` object from the availability search\nfills all of this in; the table is what the server reads if you build one yourself.\n\n| Field | Required | Notes |\n| --- | --- | --- |\n| `roomId` **or** `roomTypeId` | yes | The unit. Hotels that sell individual rooms return the room as the availability `unit` and set `roomId`; hotels that sell by type return the room type and set `roomTypeId`, and the server assigns a room. Only rooms the hotel sells online are eligible. |\n| `rateTypeId` | yes | The rate type's `id` from the availability search (or `GET .../rate_types`). This decides the nightly price, the deposit and the policies. |\n| `startDate`, `endDate` | yes | `yyyy-MM-dd`, check-in and check-out. `startDate` may not be in the past. |\n| `numberOfAdults`, `numberOfChildren`, `numberOfPets` | yes | Integers; send `0` rather than omitting. |\n| `childAges[]` | no | One integer per child. |\n| `lineItems[]` | yes | Add-ons for this booking; send `[]` when there are none. Room and tax charges are computed by the server and must not be sent. |\n| `couponCode` | no | A promotion code the hotel has published. Carried over from the search's `coupon_code`. |\n\n### Line items\n\nA line item is an add-on item or package the hotel sells, at booking level or bill level. It carries\n`billingType` (`other` for an item, `package` for a package), the hotel's `itemId` or `packageId`,\n`quantity`, and `billingDate` (`yyyy-MM-dd`, not in the past). Prices come from the hotel's\nconfiguration; an `amount` you send is ignored. Gift certificates cannot be bought or redeemed\nthrough this endpoint.\n\n## What is charged\n\nThe server computes the bill and the deposit from the rate type's deposit policy. The deposit is\ncharged to the nonce card immediately, and the card is stored on the reservation for the balance.\nIf the hotel's processor is configured to authorize rather than charge, the card is stored and\nnothing is charged. A declined card returns `424` and no reservation is created.\n\nA shared payment token is a single-use grant, so nothing is stored on the reservation after the\ndeposit is charged. Any later charge, such as the balance at check-in, incidentals or a no-show fee,\nneeds a new payment method from the guest. The token is also declined, with `424`, when it was\ngranted in a different currency than the hotel's, when its `max_amount` is below the deposit, when\nit has expired or been revoked, when it was already used, or when the hotel is not on ThinkPayments.\n\n## Response\n\n`201 Created` with the reservation in the same shape `GET /v1/hotels/{hotelId}/reservations`\nreturns, including `confirmationId`, the assigned `roomId` on each booking, the computed\n`subTotal`, `taxes`, `total`, `deposit`, `paid` and `remainingBalance`, and the guest as\n`customer`.\n\n## Errors\n\n| Status | Meaning |\n| --- | --- |\n| `400` | A field is missing or invalid. The body is an `errorsMap` keyed by field path (see below), or a `message` for a date in the past. Nothing was created. |\n| `401` / `403` | The token is missing, expired, or lacks `write:reservation`, or is for a different hotel. |\n| `404` | The hotel does not exist. |\n| `409` | The room or room type is not available for the dates, or the stay does not meet the hotel's minimum-notice rule. |\n| `424` | The card was declined. The message is always `DECLINED`. |\n\n```json\n{\n  \"errorsMap\": {\n    \"customer.email\": [\"Email is required.\"],\n    \"bookings[0].startDate\": [\"Start Date is required.\"],\n    \"creditCardData.type\": [\"Only NONCE or SHARED_PAYMENT_TOKEN credit card data is accepted by this endpoint.\"]\n  }\n}\n```\n\n## Retrying\n\nA successful call charges the deposit, so a retry after a timeout can create a second reservation\nand a second charge. Before retrying, look the reservation up with\n`GET /v1/hotels/{hotelId}/reservations?created_at_start_date_time=…` and check whether it already\nexists.\n",
        "operationId" : "createReservation",
        "parameters" : [ {
          "name" : "hotelId",
          "in" : "path",
          "description" : "The hotel's ID. OAuth consumers: use the `externalId` values returned by `GET /v1/hotels`. Restricted API Keys: your hotel ID is shown at https://manage.thinkreservations.com/settings/api-keys.",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "requestBody" : {
          "description" : "The reservation to create: the guest, one or more bookings, optional add-on line items, and the payment: `creditCardData` is either a `NONCE` from the card tokenization endpoint or, for an agent paying with a Stripe shared payment token granted to this hotel, a `SHARED_PAYMENT_TOKEN`. Ids are the ones the other endpoints return: `rateTypeId` from `GET .../rate_types`, `roomTypeId` from `GET .../room_types`, `roomId` from `GET .../rooms`. Totals, the deposit, and the confirmation id are computed by the server; see the operation description for the fields that are honoured and the error shapes.",
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/BillWithCreditCardData"
              },
              "examples" : {
                "Two nights for two adults" : {
                  "description" : "A room type is given and the server assigns a room that is sellable online. Send `roomId` instead to book a specific room.",
                  "value" : {
                    "channel" : "Online",
                    "acceptedTermsAndConditions" : true,
                    "arrivalTime" : "3:00 PM",
                    "specialAccommodations" : "Ground floor if possible",
                    "customer" : {
                      "firstName" : "Bob",
                      "lastName" : "Evans",
                      "email" : "bob@example.com",
                      "phone" : "222-222-2222",
                      "streetAddress" : "123 ABC St",
                      "locality" : "Seattle",
                      "region" : "WA",
                      "country" : "United States of America",
                      "postalCode" : "98101",
                      "agreedToMarketingEmails" : false
                    },
                    "bookings" : [ {
                      "roomTypeId" : "4b6a486e-85f8-4fb2-b7b0-95998cc9273a",
                      "rateTypeId" : "1",
                      "startDate" : "2027-08-27",
                      "endDate" : "2027-08-29",
                      "numberOfAdults" : 2,
                      "numberOfChildren" : 0,
                      "numberOfPets" : 0,
                      "lineItems" : [ ]
                    } ],
                    "lineItems" : [ ],
                    "creditCardData" : {
                      "type" : "NONCE",
                      "nonceId" : "815898d5-22ad-4bf2-8577-e99444c6265d"
                    }
                  }
                }
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "201" : {
            "description" : "Created",
            "content" : {
              "*/*" : {
                "schema" : {
                  "$ref" : "#/components/schemas/Reservation"
                }
              }
            }
          }
        },
        "security" : [ {
          "oauth2" : [ "write:reservation" ]
        }, {
          "apiKey" : [ ]
        } ],
        "x-codeSamples" : [ {
          "lang" : "curl",
          "label" : "cURL",
          "source" : "# 1. Search. Every rate type availability carries a `booking` priced for this exact search.\n#    Show the guest the totals, then send the chosen `booking` back unchanged.\nAVAILABILITIES=$(curl -s \\\n  \"https://api.thinkreservations.com/v1/hotels/$HOTEL_ID/availabilities?start_date=2027-08-27&end_date=2027-08-29&number_of_adults=2&number_of_children=0&number_of_pets=0\" \\\n  -H \"Authorization: Bearer $ACCESS_TOKEN\")\n\n# Here: the first unit's first rate type. Pick by `unit.name`, `rateType.name`, `total`, `deposit`.\nBOOKING=$(echo \"$AVAILABILITIES\" | jq -c '.[0].rateTypeAvailabilities[0].booking')\necho \"$AVAILABILITIES\" | jq '.[0].rateTypeAvailabilities[0] | {unit: .rateType.name, total, deposit}'\n\n# 2. Tokenize the payment. The card number goes only to the tokenization endpoint,\n#    never to the reservations API. The nonce is single-use and short-lived.\n#    An AI agent paying with a Stripe shared payment token granted to this hotel skips\n#    this step and sends the token in step 3 instead of the nonce:\n#      \"creditCardData\": { \"type\": \"SHARED_PAYMENT_TOKEN\", \"sharedPaymentToken\": \"spt_...\" }\nNONCE_ID=$(curl -s -X POST \"https://nonce.thinkreservations.com/businesses/$HOTEL_ID/nonces\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"businessId\": \"'\"$HOTEL_ID\"'\",\n    \"data\": {\n      \"type\": \"MANUAL_ENTRY\",\n      \"cardholderName\": \"Bob Evans\",\n      \"number\": \"4111111111111111\",\n      \"cvv\": \"123\",\n      \"expirationDate\": \"12/2030\"\n    }\n  }' | jq -r .id)\n\n# 3. Create the reservation: the copied booking, the guest, the nonce.\n#    The deposit is charged to the card on success.\ncurl -X POST \\\n  \"https://api.thinkreservations.com/v1/hotels/$HOTEL_ID/reservations\" \\\n  -H \"Authorization: Bearer $ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"channel\": \"My Integration\",\n    \"acceptedTermsAndConditions\": true,\n    \"customer\": {\n      \"firstName\": \"Bob\",\n      \"lastName\": \"Evans\",\n      \"email\": \"bob@example.com\",\n      \"phone\": \"222-222-2222\",\n      \"streetAddress\": \"123 ABC St\",\n      \"locality\": \"Seattle\",\n      \"region\": \"WA\",\n      \"country\": \"United States of America\",\n      \"postalCode\": \"98101\",\n      \"agreedToMarketingEmails\": false\n    },\n    \"bookings\": ['\"$BOOKING\"'],\n    \"lineItems\": [],\n    \"creditCardData\": { \"type\": \"NONCE\", \"nonceId\": \"'\"$NONCE_ID\"'\" }\n  }'\n\n# 201: the created reservation, with confirmationId and the assigned roomId.\n# 400: {\"errorsMap\": {\"customer.email\": [\"Email is required.\"]}} - nothing created.\n# 409: not available for the dates. 424: card declined (\"DECLINED\")."
        }, {
          "lang" : "python",
          "label" : "Python (requests)",
          "source" : "import requests\n\nBASE = \"https://api.thinkreservations.com\"\nheaders = {\"Authorization\": f\"Bearer {access_token}\"}\n\n# 1. Search. Every rate type availability carries a `booking` priced for this exact search.\navailabilities = requests.get(\n    f\"{BASE}/v1/hotels/{hotel_id}/availabilities\",\n    headers=headers,\n    params={\n        \"start_date\": \"2027-08-27\",\n        \"end_date\": \"2027-08-29\",\n        \"number_of_adults\": 2,\n        \"number_of_children\": 0,\n        \"number_of_pets\": 0,\n    },\n)\navailabilities.raise_for_status()\n\n# Show the guest the options; here we take the first unit's first rate type.\nunit = availabilities.json()[0]\noffer = unit[\"rateTypeAvailabilities\"][0]\nprint(unit[\"unit\"][\"name\"], offer[\"rateType\"][\"name\"], offer[\"total\"], offer[\"deposit\"])\n\n# The booking to send back, unchanged. Append to offer[\"booking\"][\"lineItems\"] for add-ons.\nbooking = offer[\"booking\"]\n\n# 2. Tokenize the payment. The card number goes only to the tokenization endpoint,\n#    never to the reservations API. The nonce is single-use and short-lived.\n#    An AI agent paying with a Stripe shared payment token granted to this hotel skips\n#    this step and sends the token in step 3 instead of the nonce:\n#      \"creditCardData\": {\"type\": \"SHARED_PAYMENT_TOKEN\", \"sharedPaymentToken\": \"spt_...\"}\nnonce = requests.post(\n    f\"https://nonce.thinkreservations.com/businesses/{hotel_id}/nonces\",\n    json={\n        \"businessId\": hotel_id,\n        \"data\": {\n            \"type\": \"MANUAL_ENTRY\",\n            \"cardholderName\": \"Bob Evans\",\n            \"number\": \"4111111111111111\",\n            \"cvv\": \"123\",\n            \"expirationDate\": \"12/2030\",\n        },\n    },\n)\nnonce.raise_for_status()\nnonce_id = nonce.json()[\"id\"]\n\n# 3. Create the reservation: the copied booking, the guest, the nonce.\n#    The deposit is charged to the card on success.\nreservation = {\n    \"channel\": \"My Integration\",\n    \"acceptedTermsAndConditions\": True,\n    \"customer\": {\n        \"firstName\": \"Bob\",\n        \"lastName\": \"Evans\",\n        \"email\": \"bob@example.com\",\n        \"phone\": \"222-222-2222\",\n        \"streetAddress\": \"123 ABC St\",\n        \"locality\": \"Seattle\",\n        \"region\": \"WA\",\n        \"country\": \"United States of America\",\n        \"postalCode\": \"98101\",\n        \"agreedToMarketingEmails\": False,\n    },\n    \"bookings\": [booking],\n    \"lineItems\": [],\n    \"creditCardData\": {\"type\": \"NONCE\", \"nonceId\": nonce_id},\n}\n\nresponse = requests.post(\n    f\"{BASE}/v1/hotels/{hotel_id}/reservations\", headers=headers, json=reservation\n)\n\nif response.status_code == 400:\n    # {\"errorsMap\": {\"customer.email\": [\"Email is required.\"]}} or {\"message\": \"...\"}.\n    # Nothing was created.\n    raise ValueError(response.json())\nif response.status_code == 409:\n    raise RuntimeError(\"Not available for those dates\")\nif response.status_code == 424:\n    raise RuntimeError(\"Card declined\")\nresponse.raise_for_status()\n\ncreated = response.json()  # 201: confirmationId, bookings[].roomId, deposit, paid, ...\nprint(created[\"confirmationId\"])"
        }, {
          "lang" : "javascript",
          "label" : "Node.js (fetch)",
          "source" : "const BASE = 'https://api.thinkreservations.com';\nconst headers = { Authorization: `Bearer ${accessToken}` };\n\n// 1. Search. Every rate type availability carries a `booking` priced for this exact search.\nconst search = new URLSearchParams({\n  start_date: '2027-08-27',\n  end_date: '2027-08-29',\n  number_of_adults: '2',\n  number_of_children: '0',\n  number_of_pets: '0',\n});\nconst availabilitiesResponse = await fetch(\n  `${BASE}/v1/hotels/${hotelId}/availabilities?${search}`,\n  { headers },\n);\nif (!availabilitiesResponse.ok) {\n  throw new Error(`Availability search failed: ${availabilitiesResponse.status}`);\n}\nconst availabilities = await availabilitiesResponse.json();\n\n// Show the guest the options; here we take the first unit's first rate type.\nconst unit = availabilities[0];\nconst offer = unit.rateTypeAvailabilities[0];\nconsole.log(unit.unit.name, offer.rateType.name, offer.total, offer.deposit);\n\n// The booking to send back, unchanged. Push onto offer.booking.lineItems for add-ons.\nconst booking = offer.booking;\n\n// 2. Tokenize the payment. The card number goes only to the tokenization endpoint,\n//    never to the reservations API. The nonce is single-use and short-lived.\n//    An AI agent paying with a Stripe shared payment token granted to this hotel skips\n//    this step and sends the token in step 3 instead of the nonce:\n//      creditCardData: { type: 'SHARED_PAYMENT_TOKEN', sharedPaymentToken: 'spt_...' }\nconst nonceResponse = await fetch(\n  `https://nonce.thinkreservations.com/businesses/${hotelId}/nonces`,\n  {\n    method: 'POST',\n    headers: { 'Content-Type': 'application/json' },\n    body: JSON.stringify({\n      businessId: hotelId,\n      data: {\n        type: 'MANUAL_ENTRY',\n        cardholderName: 'Bob Evans',\n        number: '4111111111111111',\n        cvv: '123',\n        expirationDate: '12/2030',\n      },\n    }),\n  },\n);\nif (!nonceResponse.ok) {\n  throw new Error(`Tokenization failed: ${nonceResponse.status}`);\n}\nconst { id: nonceId } = await nonceResponse.json();\n\n// 3. Create the reservation: the copied booking, the guest, the nonce.\n//    The deposit is charged to the card on success.\nconst reservation = {\n  channel: 'My Integration',\n  acceptedTermsAndConditions: true,\n  customer: {\n    firstName: 'Bob',\n    lastName: 'Evans',\n    email: 'bob@example.com',\n    phone: '222-222-2222',\n    streetAddress: '123 ABC St',\n    locality: 'Seattle',\n    region: 'WA',\n    country: 'United States of America',\n    postalCode: '98101',\n    agreedToMarketingEmails: false,\n  },\n  bookings: [booking],\n  lineItems: [],\n  creditCardData: { type: 'NONCE', nonceId },\n};\n\nconst response = await fetch(`${BASE}/v1/hotels/${hotelId}/reservations`, {\n  method: 'POST',\n  headers: { ...headers, 'Content-Type': 'application/json' },\n  body: JSON.stringify(reservation),\n});\n\nif (response.status === 400) {\n  // { errorsMap: { 'customer.email': ['Email is required.'] } } or { message }.\n  // Nothing was created.\n  throw new Error(JSON.stringify(await response.json()));\n}\nif (response.status === 409) {\n  throw new Error('Not available for those dates');\n}\nif (response.status === 424) {\n  throw new Error('Card declined');\n}\nif (!response.ok) {\n  throw new Error(`Unexpected ${response.status}`);\n}\n\nconst created = await response.json(); // 201: confirmationId, bookings[].roomId, deposit, paid, ...\nconsole.log(created.confirmationId);"
        } ]
      }
    },
    "/v1/hotels" : {
      "get" : {
        "tags" : [ "Hotels" ],
        "summary" : "Get Hotels",
        "description" : "Lists the hotels the caller may access. Use an entry's `externalId` as the `hotelId` path parameter on the `/v1/hotels/{hotelId}` operations.\n\n**Not available to Restricted API Keys.** A restricted API key is bound to a single hotel, so there is no list to discover — requests to this endpoint are rejected. Key holders can find their hotel ID at [https://manage.thinkreservations.com/settings/api-keys](https://manage.thinkreservations.com/settings/api-keys).\n",
        "operationId" : "getHotels",
        "responses" : {
          "200" : {
            "description" : "OK",
            "content" : {
              "*/*" : {
                "schema" : {
                  "type" : "array",
                  "items" : {
                    "$ref" : "#/components/schemas/Hotel"
                  }
                }
              }
            }
          }
        },
        "security" : [ {
          "oauth2" : [ "read:rate" ]
        }, {
          "oauth2" : [ "read:room" ]
        }, {
          "oauth2" : [ "read:reservation" ]
        }, {
          "oauth2" : [ "read:availability" ]
        }, {
          "oauth2" : [ "read:hotel" ]
        } ]
      }
    },
    "/v1/hotels/{hotelId}" : {
      "get" : {
        "tags" : [ "Hotels" ],
        "summary" : "Get Hotel",
        "operationId" : "getHotel",
        "parameters" : [ {
          "name" : "hotelId",
          "in" : "path",
          "description" : "The hotel's ID. OAuth consumers: use the `externalId` values returned by `GET /v1/hotels`. Restricted API Keys: your hotel ID is shown at https://manage.thinkreservations.com/settings/api-keys.",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "OK",
            "content" : {
              "*/*" : {
                "schema" : {
                  "$ref" : "#/components/schemas/Hotel"
                }
              }
            }
          }
        },
        "security" : [ {
          "oauth2" : [ "read:rate" ]
        }, {
          "oauth2" : [ "read:room" ]
        }, {
          "oauth2" : [ "read:reservation" ]
        }, {
          "oauth2" : [ "read:availability" ]
        }, {
          "oauth2" : [ "read:hotel" ]
        }, {
          "apiKey" : [ ]
        } ]
      }
    },
    "/v1/hotels/{hotelId}/rooms" : {
      "get" : {
        "tags" : [ "Rooms" ],
        "summary" : "Get Rooms",
        "operationId" : "getRooms",
        "parameters" : [ {
          "name" : "hotelId",
          "in" : "path",
          "description" : "The hotel's ID. OAuth consumers: use the `externalId` values returned by `GET /v1/hotels`. Restricted API Keys: your hotel ID is shown at https://manage.thinkreservations.com/settings/api-keys.",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "OK",
            "content" : {
              "*/*" : {
                "schema" : {
                  "type" : "array",
                  "items" : {
                    "$ref" : "#/components/schemas/Room"
                  }
                }
              }
            }
          }
        },
        "security" : [ {
          "oauth2" : [ "read:room" ]
        }, {
          "apiKey" : [ ]
        } ]
      }
    },
    "/v1/hotels/{hotelId}/room_types" : {
      "get" : {
        "tags" : [ "Room Types" ],
        "summary" : "Get Room Types",
        "operationId" : "getRoomTypes",
        "parameters" : [ {
          "name" : "hotelId",
          "in" : "path",
          "description" : "The hotel's ID. OAuth consumers: use the `externalId` values returned by `GET /v1/hotels`. Restricted API Keys: your hotel ID is shown at https://manage.thinkreservations.com/settings/api-keys.",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "OK",
            "content" : {
              "*/*" : {
                "schema" : {
                  "type" : "array",
                  "items" : {
                    "$ref" : "#/components/schemas/RoomType"
                  }
                }
              }
            }
          }
        },
        "security" : [ {
          "oauth2" : [ "read:room" ]
        }, {
          "apiKey" : [ ]
        } ]
      }
    },
    "/v1/hotels/{hotelId}/rate_types" : {
      "get" : {
        "tags" : [ "Rate Types" ],
        "summary" : "Get Rate Types",
        "operationId" : "getRateTypes",
        "parameters" : [ {
          "name" : "hotelId",
          "in" : "path",
          "description" : "The hotel's ID. OAuth consumers: use the `externalId` values returned by `GET /v1/hotels`. Restricted API Keys: your hotel ID is shown at https://manage.thinkreservations.com/settings/api-keys.",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "OK",
            "content" : {
              "*/*" : {
                "schema" : {
                  "type" : "array",
                  "items" : {
                    "$ref" : "#/components/schemas/RateType"
                  }
                }
              }
            }
          }
        },
        "security" : [ {
          "oauth2" : [ "read:rate" ]
        }, {
          "apiKey" : [ ]
        } ]
      }
    },
    "/v1/hotels/{hotelId}/rate_types/{rateTypeId}" : {
      "get" : {
        "tags" : [ "Rate Types" ],
        "summary" : "Get Rate Type",
        "operationId" : "getRateType",
        "parameters" : [ {
          "name" : "hotelId",
          "in" : "path",
          "description" : "The hotel's ID. OAuth consumers: use the `externalId` values returned by `GET /v1/hotels`. Restricted API Keys: your hotel ID is shown at https://manage.thinkreservations.com/settings/api-keys.",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "rateTypeId",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "OK",
            "content" : {
              "*/*" : {
                "schema" : {
                  "$ref" : "#/components/schemas/RateType"
                }
              }
            }
          }
        },
        "security" : [ {
          "oauth2" : [ "read:rate" ]
        }, {
          "apiKey" : [ ]
        } ]
      }
    },
    "/v1/hotels/{hotelId}/promotions" : {
      "get" : {
        "tags" : [ "Promotions" ],
        "summary" : "Get Promotions",
        "operationId" : "getPromotions",
        "parameters" : [ {
          "name" : "hotelId",
          "in" : "path",
          "description" : "The hotel's ID. OAuth consumers: use the `externalId` values returned by `GET /v1/hotels`. Restricted API Keys: your hotel ID is shown at https://manage.thinkreservations.com/settings/api-keys.",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "OK",
            "content" : {
              "*/*" : {
                "schema" : {
                  "type" : "array",
                  "items" : {
                    "$ref" : "#/components/schemas/Promotion"
                  }
                }
              }
            }
          }
        },
        "security" : [ {
          "oauth2" : [ "read:rate" ]
        }, {
          "oauth2" : [ "read:room" ]
        }, {
          "oauth2" : [ "read:reservation" ]
        }, {
          "oauth2" : [ "read:availability" ]
        }, {
          "apiKey" : [ ]
        } ]
      }
    },
    "/v1/hotels/{hotelId}/inventory" : {
      "get" : {
        "tags" : [ "Inventory" ],
        "summary" : "Get Room Type Daily Inventory",
        "operationId" : "getRoomTypeDailyInventory",
        "parameters" : [ {
          "name" : "hotelId",
          "in" : "path",
          "description" : "The hotel's ID. OAuth consumers: use the `externalId` values returned by `GET /v1/hotels`. Restricted API Keys: your hotel ID is shown at https://manage.thinkreservations.com/settings/api-keys.",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "dateRange",
          "in" : "query",
          "required" : true,
          "schema" : {
            "$ref" : "#/components/schemas/StartEndDateRange"
          }
        }, {
          "name" : "room_type_id",
          "in" : "query",
          "required" : false,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "OK",
            "content" : {
              "*/*" : {
                "schema" : {
                  "type" : "array",
                  "items" : {
                    "$ref" : "#/components/schemas/RoomTypeDailyInventory"
                  }
                }
              }
            }
          }
        },
        "security" : [ {
          "oauth2" : [ "read:availability" ]
        }, {
          "apiKey" : [ ]
        } ]
      }
    },
    "/v1/hotels/{hotelId}/blackouts" : {
      "get" : {
        "tags" : [ "Blackouts" ],
        "summary" : "Get Blackouts",
        "operationId" : "getBlackouts",
        "parameters" : [ {
          "name" : "hotelId",
          "in" : "path",
          "description" : "The hotel's ID. OAuth consumers: use the `externalId` values returned by `GET /v1/hotels`. Restricted API Keys: your hotel ID is shown at https://manage.thinkreservations.com/settings/api-keys.",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "dateRange",
          "in" : "query",
          "required" : true,
          "schema" : {
            "$ref" : "#/components/schemas/StartEndDateRange"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "OK",
            "content" : {
              "*/*" : {
                "schema" : {
                  "type" : "array",
                  "items" : {
                    "$ref" : "#/components/schemas/Blackout"
                  }
                }
              }
            }
          }
        },
        "security" : [ {
          "oauth2" : [ "read:rate" ]
        }, {
          "oauth2" : [ "read:room" ]
        }, {
          "oauth2" : [ "read:reservation" ]
        }, {
          "oauth2" : [ "read:availability" ]
        }, {
          "apiKey" : [ ]
        } ]
      }
    },
    "/v1/hotels/{hotelId}/availabilities" : {
      "get" : {
        "tags" : [ "Availability" ],
        "summary" : "Get Availabilities",
        "description" : "Returns what the hotel can sell for a stay: one entry per bookable unit, and for each unit the rate\ntypes it can be booked at, with the price for the whole stay, fees, taxes, deposit and total.\n\n## What a unit is\n\nHotels sell either individual rooms or room types. The `unit` is whichever this hotel sells, so its\n`id` is a room id for some hotels and a room type id for others. You do not need to know which:\nthe `booking` object described below already names the unit correctly.\n\n## Booking\n\nEvery `rateTypeAvailabilities[]` entry carries a `booking`. It is the booking the search priced,\nin the exact shape `POST /v1/hotels/{hotelId}/reservations` accepts as an element of `bookings[]`:\nthe unit as `roomId` or `roomTypeId`, the `rateTypeId`, `startDate`, `endDate`, the occupancy and\n`couponCode` you searched with, and an empty `lineItems` list. To book it, copy it into the\nreservation request unchanged, add the guest and the card as a single-use nonce, and send. Append add-on line\nitems to its `lineItems` first if the guest wants any.\n\nThe prices shown are a quote for that booking at the time of the search. The reservation is\nrepriced when it is created.\n\n## Parameters\n\n`start_date` is check-in and `end_date` is check-out, both `yyyy-MM-dd`. The party\n(`number_of_adults`, `number_of_children`, `child_ages`, `number_of_pets`) filters out units that\ncannot hold it and is copied onto every returned `booking`. A `coupon_code` the hotel has published\nis applied to the prices and copied onto the bookings as `couponCode`.\n",
        "operationId" : "getAvailabilities",
        "parameters" : [ {
          "name" : "hotelId",
          "in" : "path",
          "description" : "The hotel's ID. OAuth consumers: use the `externalId` values returned by `GET /v1/hotels`. Restricted API Keys: your hotel ID is shown at https://manage.thinkreservations.com/settings/api-keys.",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "dateRange",
          "in" : "query",
          "required" : true,
          "schema" : {
            "$ref" : "#/components/schemas/StartEndDateRange"
          }
        }, {
          "name" : "number_of_adults",
          "in" : "query",
          "required" : false,
          "schema" : {
            "type" : "integer",
            "format" : "int32",
            "default" : 2
          }
        }, {
          "name" : "number_of_children",
          "in" : "query",
          "required" : false,
          "schema" : {
            "type" : "integer",
            "format" : "int32",
            "default" : 0
          }
        }, {
          "name" : "child_ages",
          "in" : "query",
          "required" : false,
          "schema" : {
            "type" : "array",
            "items" : {
              "type" : "integer",
              "format" : "int32"
            }
          }
        }, {
          "name" : "number_of_pets",
          "in" : "query",
          "description" : "Number of pets in the party. Applied to the search and copied onto each returned `booking`.",
          "required" : false,
          "schema" : {
            "type" : "integer",
            "format" : "int32",
            "default" : 0
          }
        }, {
          "name" : "coupon_code",
          "in" : "query",
          "description" : "A promotion code the hotel has published. Applied to the prices and copied onto each returned `booking` as `couponCode`.",
          "required" : false,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "OK",
            "content" : {
              "*/*" : {
                "schema" : {
                  "type" : "array",
                  "items" : {
                    "$ref" : "#/components/schemas/Availability"
                  }
                }
              }
            }
          }
        },
        "security" : [ {
          "oauth2" : [ "read:availability" ]
        }, {
          "apiKey" : [ ]
        } ]
      }
    }
  },
  "components" : {
    "schemas" : {
      "RoomTypeDailyRateConfigurationUpdate" : {
        "required" : [ "date", "roomTypeId" ],
        "type" : "object",
        "properties" : {
          "roomTypeId" : {
            "type" : "string",
            "description" : "The room type's UUID, as returned in `externalId` by `GET /v1/hotels/{hotelId}/room_types`. Note this is a UUID, unlike the numeric `rateTypeId`.",
            "example" : "4b6a486e-85f8-4fb2-b7b0-95998cc9273a"
          },
          "rateTypeId" : {
            "type" : "string",
            "description" : "The rate type these rates belong to, as returned by `GET /v1/hotels/{hotelId}/rate_types`. Optional, and present so a row read from `GET .../daily` can be edited and sent back unchanged. The rate type written to is always the `{rateTypeId}` in the path; if you supply this it must match that value.",
            "example" : "26243"
          },
          "date" : {
            "type" : "string",
            "description" : "The date this configuration applies to.",
            "format" : "date",
            "example" : "2027-08-27"
          },
          "price" : {
            "type" : "number",
            "description" : "The nightly rate, in the hotel's configured currency.",
            "example" : 210.0
          },
          "minimumNightsOnArrival" : {
            "type" : "integer",
            "description" : "Minimum nights required when a stay arrives on this date.",
            "format" : "int32",
            "example" : 2
          },
          "minimumNightsThrough" : {
            "type" : "integer",
            "description" : "Minimum nights required when a stay passes through this date.",
            "format" : "int32"
          },
          "maximumNightsOnArrival" : {
            "type" : "integer",
            "description" : "Maximum nights allowed when a stay arrives on this date.",
            "format" : "int32"
          },
          "maximumNightsThrough" : {
            "type" : "integer",
            "description" : "Maximum nights allowed when a stay passes through this date.",
            "format" : "int32"
          },
          "closedOnArrival" : {
            "type" : "boolean",
            "description" : "Whether a stay may not arrive on this date.",
            "example" : false
          },
          "closedOnDeparture" : {
            "type" : "boolean",
            "description" : "Whether a stay may not depart on this date.",
            "example" : false
          },
          "stopSell" : {
            "type" : "boolean",
            "description" : "Whether this room type is closed to sale on this date.",
            "example" : false
          }
        },
        "description" : "A single day's rate configuration for one room type. Each row updates the stored configuration for that room type and date. A field you omit keeps its stored value; a field you send as null is cleared."
      },
      "AdditionalGuestLineItem" : {
        "type" : "object",
        "allOf" : [ {
          "$ref" : "#/components/schemas/LineItem"
        } ]
      },
      "Amount" : {
        "type" : "object",
        "properties" : {
          "amount" : {
            "type" : "number"
          },
          "currency" : {
            "type" : "string"
          }
        }
      },
      "Attribute" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "string"
          },
          "type" : {
            "type" : "string",
            "enum" : [ "BILL", "CUSTOMER", "GROUP_RESERVATION" ]
          },
          "name" : {
            "type" : "string"
          },
          "variableName" : {
            "type" : "string"
          },
          "inputType" : {
            "$ref" : "#/components/schemas/InputType"
          },
          "required" : {
            "type" : "boolean"
          },
          "askInBookingEngine" : {
            "type" : "boolean"
          },
          "sortIndex" : {
            "type" : "integer",
            "format" : "int32"
          },
          "inactive" : {
            "type" : "boolean"
          },
          "createdAt" : {
            "type" : "string",
            "format" : "date-time"
          },
          "updatedAt" : {
            "type" : "string",
            "format" : "date-time"
          }
        },
        "discriminator" : {
          "propertyName" : "type"
        }
      },
      "AttributeValue" : {
        "type" : "object",
        "properties" : {
          "attribute" : {
            "$ref" : "#/components/schemas/Attribute"
          },
          "value" : {
            "type" : "string"
          }
        }
      },
      "Authorization" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "string"
          },
          "billId" : {
            "type" : "string"
          },
          "postingDate" : {
            "type" : "string",
            "format" : "date-time"
          },
          "amount" : {
            "type" : "number"
          },
          "creditCardData" : {
            "$ref" : "#/components/schemas/CreditCardData"
          },
          "retainCreditCard" : {
            "type" : "boolean"
          },
          "ccsTransactionId" : {
            "type" : "string"
          },
          "status" : {
            "type" : "string"
          },
          "lastFourDigits" : {
            "type" : "string"
          },
          "cardType" : {
            "type" : "string"
          },
          "createdAt" : {
            "type" : "string",
            "format" : "date-time"
          },
          "updatedAt" : {
            "type" : "string",
            "format" : "date-time"
          }
        }
      },
      "BillWithCreditCardData" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "string"
          },
          "hotelId" : {
            "type" : "string"
          },
          "groupId" : {
            "type" : "string"
          },
          "groupName" : {
            "type" : "string"
          },
          "confirmationId" : {
            "type" : "string"
          },
          "customer" : {
            "$ref" : "#/components/schemas/Customer"
          },
          "status" : {
            "type" : "string",
            "enum" : [ "checked_in", "checked_out", "scheduled", "canceled", "no_show" ]
          },
          "bookings" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/Booking"
            }
          },
          "lineItems" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/LineItem"
            }
          },
          "creditCards" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/CreditCard"
            }
          },
          "attributeValues" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/AttributeValue"
            }
          },
          "acceptedTermsAndConditions" : {
            "type" : "boolean"
          },
          "affiliate" : {
            "type" : "string"
          },
          "arrivalTime" : {
            "type" : "string"
          },
          "dietaryRestrictions" : {
            "type" : "string"
          },
          "specialAccommodations" : {
            "type" : "string"
          },
          "additionalGuestNames" : {
            "type" : "string"
          },
          "stayReason" : {
            "type" : "string"
          },
          "howDidYouHearAboutUs" : {
            "type" : "string"
          },
          "invoiceDate" : {
            "type" : "string",
            "format" : "date-time"
          },
          "channel" : {
            "type" : "string"
          },
          "attribution" : {
            "type" : "string"
          },
          "emailMarketingAttributions" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/EmailMarketingAttribution"
            }
          },
          "authorizations" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/Authorization"
            }
          },
          "payments" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/Payment"
            }
          },
          "deposits" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/Payment"
            }
          },
          "deposit" : {
            "type" : "number"
          },
          "taxes" : {
            "type" : "number"
          },
          "subTotal" : {
            "type" : "number"
          },
          "total" : {
            "type" : "number"
          },
          "paid" : {
            "type" : "number"
          },
          "remainingBalance" : {
            "type" : "number"
          },
          "originalSubtotal" : {
            "type" : "number"
          },
          "originalTaxes" : {
            "type" : "number"
          },
          "originalTotal" : {
            "type" : "number"
          },
          "taxExemptPolicy" : {
            "$ref" : "#/components/schemas/TaxExemptPolicy"
          },
          "canceledAt" : {
            "type" : "string",
            "format" : "date-time"
          },
          "canceledBy" : {
            "type" : "string"
          },
          "cancellationReason" : {
            "type" : "string"
          },
          "createdBy" : {
            "type" : "string"
          },
          "lodgingSafeProtectionId" : {
            "type" : "string"
          },
          "doNotSendAutomaticCommunications" : {
            "type" : "boolean"
          },
          "createdAt" : {
            "type" : "string",
            "format" : "date-time"
          },
          "updatedAt" : {
            "type" : "string",
            "format" : "date-time"
          },
          "giftCertificateKeys" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/GiftCertificateKey"
            }
          },
          "creditCardData" : {
            "$ref" : "#/components/schemas/CreditCardData"
          },
          "lodgingSafeProposalSelection" : {
            "$ref" : "#/components/schemas/LodgingSafeProposalSelection"
          }
        }
      },
      "Booking" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "string"
          },
          "hotelId" : {
            "type" : "string"
          },
          "billId" : {
            "type" : "string"
          },
          "confirmationId" : {
            "type" : "string"
          },
          "roomId" : {
            "type" : "string"
          },
          "roomIds" : {
            "uniqueItems" : true,
            "type" : "array",
            "items" : {
              "type" : "string"
            }
          },
          "roomTypeId" : {
            "type" : "string"
          },
          "rateTypeId" : {
            "type" : "string"
          },
          "rateTypeName" : {
            "type" : "string"
          },
          "room" : {
            "$ref" : "#/components/schemas/Room"
          },
          "doNotMove" : {
            "type" : "boolean"
          },
          "promotionId" : {
            "type" : "string"
          },
          "groupBlockId" : {
            "type" : "string"
          },
          "startDate" : {
            "type" : "string",
            "format" : "date-time"
          },
          "endDate" : {
            "type" : "string",
            "format" : "date-time"
          },
          "numberOfGuests" : {
            "type" : "integer",
            "format" : "int32"
          },
          "numberOfAdults" : {
            "type" : "integer",
            "format" : "int32"
          },
          "numberOfChildren" : {
            "type" : "integer",
            "format" : "int32"
          },
          "childAges" : {
            "type" : "array",
            "items" : {
              "type" : "integer",
              "format" : "int32"
            }
          },
          "numberOfPets" : {
            "type" : "integer",
            "format" : "int32"
          },
          "customerGroup" : {
            "type" : "string"
          },
          "couponCode" : {
            "type" : "string"
          },
          "lineItems" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/LineItem"
            }
          },
          "status" : {
            "type" : "string",
            "enum" : [ "checked_in", "checked_out", "scheduled", "canceled", "no_show" ]
          },
          "channel" : {
            "type" : "string"
          },
          "canceledAt" : {
            "type" : "string",
            "format" : "date-time"
          },
          "createdAt" : {
            "type" : "string",
            "format" : "date-time"
          },
          "updatedAt" : {
            "type" : "string",
            "format" : "date-time"
          },
          "billingPeriod" : {
            "type" : "string",
            "enum" : [ "DAILY", "WEEKLY", "MONTHLY" ]
          }
        }
      },
      "ChildOccupancyRule" : {
        "type" : "object",
        "properties" : {
          "maximumOccupants" : {
            "type" : "integer",
            "format" : "int32"
          },
          "fee" : {
            "type" : "number"
          },
          "minimumAge" : {
            "type" : "integer",
            "format" : "int32"
          },
          "maximumAge" : {
            "type" : "integer",
            "format" : "int32"
          }
        }
      },
      "CreditCard" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "string"
          },
          "tokenId" : {
            "type" : "string"
          },
          "ccsCreditCardId" : {
            "type" : "string"
          },
          "oldTokenId" : {
            "type" : "string"
          },
          "lastFourDigits" : {
            "type" : "string"
          },
          "cardType" : {
            "type" : "string"
          },
          "cardholderName" : {
            "type" : "string"
          },
          "inactive" : {
            "type" : "boolean"
          },
          "ccsEcommerceMerchantAccountId" : {
            "type" : "string"
          },
          "ccsLodgingMerchantAccountId" : {
            "type" : "string"
          },
          "createdAt" : {
            "type" : "string",
            "format" : "date-time"
          },
          "updatedAt" : {
            "type" : "string",
            "format" : "date-time"
          },
          "expirationDate" : {
            "type" : "string"
          }
        }
      },
      "CreditCardData" : {
        "type" : "object",
        "properties" : {
          "type" : {
            "type" : "string"
          }
        },
        "discriminator" : {
          "propertyName" : "type"
        }
      },
      "Customer" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "string"
          },
          "email" : {
            "type" : "string"
          },
          "firstName" : {
            "type" : "string"
          },
          "lastName" : {
            "type" : "string"
          },
          "fullName" : {
            "type" : "string"
          },
          "phone" : {
            "type" : "string"
          },
          "cellPhone" : {
            "type" : "string"
          },
          "workPhone" : {
            "type" : "string"
          },
          "company" : {
            "type" : "string"
          },
          "streetAddress" : {
            "type" : "string"
          },
          "extendedAddress" : {
            "type" : "string"
          },
          "locality" : {
            "type" : "string"
          },
          "region" : {
            "type" : "string"
          },
          "country" : {
            "type" : "string"
          },
          "postalCode" : {
            "type" : "string"
          },
          "notes" : {
            "type" : "string"
          },
          "agreedToMarketingEmails" : {
            "type" : "boolean"
          },
          "agreedToAutomaticMessages" : {
            "type" : "boolean"
          },
          "repeatCustomer" : {
            "type" : "boolean"
          },
          "banned" : {
            "type" : "boolean"
          },
          "tags" : {
            "uniqueItems" : true,
            "type" : "array",
            "items" : {
              "type" : "string"
            }
          },
          "attributeValues" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/AttributeValue"
            }
          },
          "createdAt" : {
            "type" : "string",
            "format" : "date-time"
          },
          "updatedAt" : {
            "type" : "string",
            "format" : "date-time"
          }
        }
      },
      "DefaultLineItem" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "string"
          },
          "itemId" : {
            "type" : "string"
          },
          "overridePrice" : {
            "type" : "number"
          },
          "createdAt" : {
            "type" : "string",
            "format" : "date-time"
          },
          "updatedAt" : {
            "type" : "string",
            "format" : "date-time"
          }
        }
      },
      "DeliveryMethod" : {
        "type" : "object",
        "properties" : {
          "type" : {
            "type" : "string"
          }
        },
        "discriminator" : {
          "propertyName" : "type"
        }
      },
      "EmailMarketingAttribution" : {
        "type" : "object",
        "properties" : {
          "emailMarketingAttributionId" : {
            "type" : "string"
          },
          "createdAt" : {
            "type" : "string",
            "format" : "date-time"
          }
        }
      },
      "GiftCertificate" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "string"
          },
          "billId" : {
            "type" : "string"
          },
          "code" : {
            "type" : "string"
          },
          "salePrice" : {
            "type" : "number"
          },
          "redeemableValue" : {
            "type" : "number"
          },
          "amountRedeemed" : {
            "type" : "number"
          },
          "giftFrom" : {
            "type" : "string"
          },
          "giftTo" : {
            "type" : "string"
          },
          "comments" : {
            "type" : "string"
          },
          "notes" : {
            "type" : "string"
          },
          "expirationDate" : {
            "type" : "string",
            "format" : "date-time"
          },
          "deliveryMethod" : {
            "$ref" : "#/components/schemas/DeliveryMethod"
          },
          "giftCertificateAdjustments" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/GiftCertificateAdjustment"
            }
          },
          "payments" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/Payment"
            }
          },
          "doNotAllowRecipientToRedeemOnline" : {
            "type" : "boolean"
          },
          "createdAt" : {
            "type" : "string",
            "format" : "date-time"
          },
          "updatedAt" : {
            "type" : "string",
            "format" : "date-time"
          }
        }
      },
      "GiftCertificateAdjustment" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "string"
          },
          "giftCertificateId" : {
            "type" : "string"
          },
          "type" : {
            "type" : "string"
          },
          "adjustmentDate" : {
            "type" : "string",
            "format" : "date-time"
          },
          "amount" : {
            "type" : "number"
          },
          "notes" : {
            "type" : "string"
          },
          "createdBy" : {
            "type" : "string"
          },
          "createdAt" : {
            "type" : "string",
            "format" : "date-time"
          },
          "updatedAt" : {
            "type" : "string",
            "format" : "date-time"
          }
        }
      },
      "GiftCertificateKey" : {
        "type" : "object",
        "properties" : {
          "code" : {
            "type" : "string"
          },
          "key" : {
            "type" : "string"
          },
          "redeemableValue" : {
            "type" : "number"
          },
          "amountRemaining" : {
            "type" : "number"
          }
        }
      },
      "GiftCertificateLineItem" : {
        "type" : "object",
        "allOf" : [ {
          "$ref" : "#/components/schemas/LineItem"
        }, {
          "type" : "object",
          "properties" : {
            "giftCertificate" : {
              "$ref" : "#/components/schemas/GiftCertificate"
            }
          }
        } ]
      },
      "Image" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "string"
          },
          "imageName" : {
            "type" : "string"
          },
          "imageUrl" : {
            "type" : "string"
          },
          "bigImageUrl" : {
            "type" : "string"
          },
          "thumbnailUrl" : {
            "type" : "string"
          },
          "altText" : {
            "type" : "string"
          },
          "publicId" : {
            "type" : "string"
          },
          "version" : {
            "type" : "string"
          },
          "imageWidth" : {
            "type" : "integer",
            "format" : "int32"
          },
          "imageHeight" : {
            "type" : "integer",
            "format" : "int32"
          }
        }
      },
      "ImageFile" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "string"
          },
          "parentDirectoryId" : {
            "type" : "string"
          },
          "path" : {
            "type" : "string"
          },
          "type" : {
            "type" : "string",
            "enum" : [ "FILE", "DIRECTORY", "IMAGE", "VIDEO" ]
          },
          "name" : {
            "type" : "string"
          },
          "createdAt" : {
            "type" : "string",
            "format" : "date-time"
          },
          "updatedAt" : {
            "type" : "string",
            "format" : "date-time"
          },
          "contentType" : {
            "type" : "string"
          },
          "bucket" : {
            "type" : "string"
          },
          "key" : {
            "type" : "string"
          },
          "bytes" : {
            "type" : "integer",
            "format" : "int64"
          },
          "width" : {
            "type" : "integer",
            "format" : "int32"
          },
          "height" : {
            "type" : "integer",
            "format" : "int32"
          },
          "altText" : {
            "type" : "string"
          },
          "caption" : {
            "type" : "string"
          }
        }
      },
      "InputType" : {
        "type" : "object",
        "properties" : {
          "type" : {
            "type" : "string"
          }
        },
        "discriminator" : {
          "propertyName" : "type"
        }
      },
      "ItemLineItem" : {
        "type" : "object",
        "allOf" : [ {
          "$ref" : "#/components/schemas/LineItem"
        }, {
          "type" : "object",
          "properties" : {
            "itemId" : {
              "type" : "string"
            },
            "packageInstanceId" : {
              "type" : "string"
            },
            "packageName" : {
              "type" : "string"
            }
          }
        } ]
      },
      "ItemizedTax" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "string"
          },
          "name" : {
            "type" : "string"
          },
          "taxAmount" : {
            "type" : "number"
          },
          "taxExempt" : {
            "type" : "boolean"
          }
        }
      },
      "LineItem" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "string"
          },
          "billId" : {
            "type" : "string"
          },
          "confirmationId" : {
            "type" : "string"
          },
          "customerName" : {
            "type" : "string"
          },
          "bookingId" : {
            "type" : "string"
          },
          "roomId" : {
            "type" : "string"
          },
          "billingDate" : {
            "type" : "string",
            "format" : "date-time"
          },
          "billingType" : {
            "type" : "string"
          },
          "description" : {
            "type" : "string"
          },
          "notes" : {
            "type" : "string"
          },
          "quantity" : {
            "type" : "integer",
            "format" : "int32"
          },
          "amountPerUnit" : {
            "type" : "number"
          },
          "amount" : {
            "type" : "number"
          },
          "discountedAmount" : {
            "type" : "number"
          },
          "manuallyDiscountedAmount" : {
            "type" : "number"
          },
          "actualAmount" : {
            "type" : "number"
          },
          "itemizedTaxes" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/ItemizedTax"
            }
          },
          "canceled" : {
            "type" : "boolean"
          },
          "printed" : {
            "type" : "boolean"
          },
          "fee" : {
            "type" : "boolean"
          },
          "createdBy" : {
            "type" : "string"
          },
          "createdAt" : {
            "type" : "string",
            "format" : "date-time"
          },
          "updatedAt" : {
            "type" : "string",
            "format" : "date-time"
          }
        },
        "discriminator" : {
          "propertyName" : "billingType"
        }
      },
      "LodgingSafeProposalSelection" : {
        "type" : "object",
        "properties" : {
          "acceptedProposalId" : {
            "type" : "string"
          },
          "acceptedOptionalBenefitIds" : {
            "type" : "array",
            "items" : {
              "type" : "string"
            }
          },
          "proposals" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/Proposal"
            }
          }
        }
      },
      "OptionalBenefit" : {
        "type" : "object",
        "properties" : {
          "title" : {
            "type" : "string"
          },
          "description" : {
            "type" : "string"
          },
          "options" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/OptionalBenefitOption"
            }
          }
        }
      },
      "OptionalBenefitOption" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "string"
          },
          "title" : {
            "type" : "string"
          },
          "coverageLimitAmount" : {
            "type" : "number"
          },
          "excessAmount" : {
            "type" : "number"
          },
          "rateType" : {
            "type" : "string"
          },
          "ratePerTypeAmount" : {
            "$ref" : "#/components/schemas/Amount"
          },
          "price" : {
            "$ref" : "#/components/schemas/Amount"
          },
          "preSelected" : {
            "type" : "boolean"
          }
        }
      },
      "PackageLineItem" : {
        "type" : "object",
        "allOf" : [ {
          "$ref" : "#/components/schemas/LineItem"
        }, {
          "type" : "object",
          "properties" : {
            "packageId" : {
              "type" : "string"
            }
          }
        } ]
      },
      "Payment" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "string"
          },
          "parentTransactionId" : {
            "type" : "string"
          },
          "billId" : {
            "type" : "string"
          },
          "confirmationId" : {
            "type" : "string"
          },
          "arAccountId" : {
            "type" : "string"
          },
          "arName" : {
            "type" : "string"
          },
          "customerName" : {
            "type" : "string"
          },
          "paymentDate" : {
            "type" : "string",
            "format" : "date"
          },
          "appliedDate" : {
            "type" : "string",
            "format" : "date"
          },
          "postingDate" : {
            "type" : "string",
            "format" : "date"
          },
          "type" : {
            "type" : "string"
          },
          "description" : {
            "type" : "string"
          },
          "amount" : {
            "type" : "number"
          },
          "creditCardData" : {
            "$ref" : "#/components/schemas/CreditCardData"
          },
          "retainCreditCard" : {
            "type" : "boolean"
          },
          "giftCertificateCode" : {
            "type" : "string"
          },
          "houseAccountCustomerId" : {
            "type" : "string"
          },
          "houseAccountCustomerName" : {
            "type" : "string"
          },
          "directBillARAccountId" : {
            "type" : "string"
          },
          "directBillARName" : {
            "type" : "string"
          },
          "transactionId" : {
            "type" : "string"
          },
          "ccsTransactionId" : {
            "type" : "string"
          },
          "oldTransactionId" : {
            "type" : "string"
          },
          "ccsMerchantAccountId" : {
            "type" : "string"
          },
          "status" : {
            "type" : "string"
          },
          "lastFourDigits" : {
            "type" : "string"
          },
          "cardType" : {
            "type" : "string"
          },
          "createdBy" : {
            "type" : "string"
          },
          "createdAt" : {
            "type" : "string",
            "format" : "date-time"
          },
          "updatedAt" : {
            "type" : "string",
            "format" : "date-time"
          }
        }
      },
      "PetLineItem" : {
        "type" : "object",
        "allOf" : [ {
          "$ref" : "#/components/schemas/LineItem"
        } ]
      },
      "Proposal" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "string"
          },
          "productType" : {
            "type" : "string"
          },
          "productName" : {
            "type" : "string"
          },
          "documentation" : {
            "$ref" : "#/components/schemas/ProposalDocumentation"
          },
          "sellingPointName" : {
            "type" : "string"
          },
          "communications" : {
            "type" : "object",
            "additionalProperties" : {
              "type" : "string"
            }
          },
          "price" : {
            "$ref" : "#/components/schemas/Amount"
          },
          "optionalBenefits" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/OptionalBenefit"
            }
          }
        }
      },
      "ProposalDocumentation" : {
        "type" : "object",
        "properties" : {
          "wordingUrl" : {
            "type" : "string"
          },
          "ipidUrl" : {
            "type" : "string"
          },
          "termsAndConditionsUrl" : {
            "type" : "string"
          }
        }
      },
      "Room" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "string"
          },
          "roomTypeId" : {
            "type" : "string"
          },
          "roomGroupId" : {
            "type" : "string"
          },
          "sortIndex" : {
            "type" : "integer",
            "format" : "int32"
          },
          "roomGroup" : {
            "type" : "string"
          },
          "roomTypeSortIndex" : {
            "type" : "integer",
            "format" : "int32"
          },
          "roomGroupSortIndex" : {
            "type" : "integer",
            "format" : "int32"
          },
          "description" : {
            "type" : "string"
          },
          "image1" : {
            "type" : "string"
          },
          "image2" : {
            "type" : "string"
          },
          "image3" : {
            "type" : "string"
          },
          "image4" : {
            "type" : "string"
          },
          "image5" : {
            "type" : "string"
          },
          "image6" : {
            "type" : "string"
          },
          "image7" : {
            "type" : "string"
          },
          "image8" : {
            "type" : "string"
          },
          "image9" : {
            "type" : "string"
          },
          "image10" : {
            "type" : "string"
          },
          "image11" : {
            "type" : "string"
          },
          "image12" : {
            "type" : "string"
          },
          "image13" : {
            "type" : "string"
          },
          "image14" : {
            "type" : "string"
          },
          "image15" : {
            "type" : "string"
          },
          "images" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/Image"
            }
          },
          "imageFiles" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/ImageFile"
            }
          },
          "name" : {
            "type" : "string"
          },
          "code" : {
            "type" : "string"
          },
          "shortName" : {
            "type" : "string"
          },
          "maximumNumberOfGuestsAllowed" : {
            "type" : "integer",
            "format" : "int32"
          },
          "maximumAdultOccupancy" : {
            "type" : "integer",
            "format" : "int32"
          },
          "maximumChildOccupancy" : {
            "type" : "integer",
            "format" : "int32"
          },
          "childOccupancyRules" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/ChildOccupancyRule"
            }
          },
          "maximumNumberOfPetsAllowed" : {
            "type" : "integer",
            "format" : "int32"
          },
          "numberOfGuestsAllowed" : {
            "type" : "integer",
            "format" : "int32"
          },
          "numberOfAdditionalGuestsAllowed" : {
            "type" : "integer",
            "format" : "int32"
          },
          "additionalGuestFee" : {
            "type" : "number"
          },
          "petFee" : {
            "type" : "number"
          },
          "cleaningFee" : {
            "type" : "number"
          },
          "commissionPercentage" : {
            "type" : "number"
          },
          "commissionType" : {
            "type" : "string"
          },
          "addressLine1" : {
            "type" : "string"
          },
          "addressLine2" : {
            "type" : "string"
          },
          "locality" : {
            "type" : "string"
          },
          "region" : {
            "type" : "string"
          },
          "postalCode" : {
            "type" : "string"
          },
          "country" : {
            "type" : "string"
          },
          "phone" : {
            "type" : "string"
          },
          "notes" : {
            "type" : "string"
          },
          "directions" : {
            "type" : "string"
          },
          "additionalInformation" : {
            "type" : "string"
          },
          "websiteUrl" : {
            "type" : "string"
          },
          "roomRevenueAccountId" : {
            "type" : "string"
          },
          "additionalGuestRevenueAccountId" : {
            "type" : "string"
          },
          "petRevenueAccountId" : {
            "type" : "string"
          },
          "linkedToUnitIds" : {
            "type" : "array",
            "items" : {
              "type" : "string"
            }
          },
          "roomTaxIds" : {
            "type" : "array",
            "items" : {
              "type" : "string"
            }
          },
          "additionalGuestTaxIds" : {
            "type" : "array",
            "items" : {
              "type" : "string"
            }
          },
          "petTaxIds" : {
            "type" : "array",
            "items" : {
              "type" : "string"
            }
          },
          "cleaningFeeTaxIds" : {
            "type" : "array",
            "items" : {
              "type" : "string"
            }
          },
          "amenityIds" : {
            "type" : "array",
            "items" : {
              "type" : "string"
            }
          },
          "numberOfBedrooms" : {
            "type" : "integer",
            "format" : "int32"
          },
          "numberOfFullBaths" : {
            "type" : "integer",
            "format" : "int32"
          },
          "numberOfHalfBaths" : {
            "type" : "integer",
            "format" : "int32"
          },
          "housekeepingStatus" : {
            "type" : "string",
            "enum" : [ "DIRTY", "CLEANING", "CLEAN", "INSPECTING", "INSPECTED" ]
          },
          "adaCompliant" : {
            "type" : "boolean"
          },
          "doNotSellOnline" : {
            "type" : "boolean"
          },
          "isNotARoom" : {
            "type" : "boolean"
          },
          "isBillable" : {
            "type" : "boolean"
          },
          "inactive" : {
            "type" : "boolean"
          },
          "doNotIncludeInOccupancy" : {
            "type" : "boolean"
          },
          "defaultLineItems" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/DefaultLineItem"
            }
          },
          "createdAt" : {
            "type" : "string",
            "format" : "date-time"
          },
          "updatedAt" : {
            "type" : "string",
            "format" : "date-time"
          }
        }
      },
      "RoomLineItem" : {
        "type" : "object",
        "allOf" : [ {
          "$ref" : "#/components/schemas/LineItem"
        } ]
      },
      "TaxExemptPolicy" : {
        "type" : "object",
        "properties" : {
          "type" : {
            "type" : "string"
          }
        },
        "discriminator" : {
          "propertyName" : "type"
        }
      },
      "Reservation" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "string",
            "description" : "Unique identifier of the reservation.",
            "example" : "res_a1b2c3d4"
          },
          "groupId" : {
            "type" : "string",
            "description" : "Identifier of the group this reservation belongs to, if any.",
            "example" : "grp_a1b2c3d4"
          },
          "groupName" : {
            "type" : "string",
            "description" : "Name of the group this reservation belongs to.",
            "example" : "Smith Wedding"
          },
          "confirmationId" : {
            "type" : "string",
            "description" : "Human-readable confirmation identifier.",
            "example" : "ABC123"
          },
          "customerId" : {
            "type" : "string",
            "description" : "Identifier of the customer who owns the reservation.",
            "example" : "cust_a1b2c3d4"
          },
          "customer" : {
            "$ref" : "#/components/schemas/Customer"
          },
          "status" : {
            "type" : "string",
            "description" : "Billing status of the reservation.",
            "enum" : [ "checked_in", "checked_out", "scheduled", "canceled", "no_show" ]
          },
          "bookings" : {
            "type" : "array",
            "description" : "Bookings (room stays) included in the reservation.",
            "items" : {
              "$ref" : "#/components/schemas/Booking"
            }
          },
          "lineItems" : {
            "type" : "array",
            "description" : "Line items associated with the reservation.",
            "items" : {
              "oneOf" : [ {
                "$ref" : "#/components/schemas/AdditionalGuestLineItem"
              }, {
                "$ref" : "#/components/schemas/GiftCertificateLineItem"
              }, {
                "$ref" : "#/components/schemas/ItemLineItem"
              }, {
                "$ref" : "#/components/schemas/PackageLineItem"
              }, {
                "$ref" : "#/components/schemas/PetLineItem"
              }, {
                "$ref" : "#/components/schemas/RoomLineItem"
              } ]
            }
          },
          "attributeValues" : {
            "type" : "array",
            "description" : "Custom attribute values attached to the reservation.",
            "items" : {
              "$ref" : "#/components/schemas/AttributeValue"
            }
          },
          "acceptedTermsAndConditions" : {
            "type" : "boolean",
            "description" : "Whether the guest accepted the terms and conditions.",
            "example" : true
          },
          "arrivalTime" : {
            "type" : "string",
            "description" : "Expected arrival time provided by the guest.",
            "example" : "15:00"
          },
          "dietaryRestrictions" : {
            "type" : "string",
            "description" : "Dietary restrictions noted by the guest.",
            "example" : "Vegetarian, no nuts"
          },
          "specialAccommodations" : {
            "type" : "string",
            "description" : "Special accommodations requested by the guest.",
            "example" : "Ground floor room"
          },
          "additionalGuestNames" : {
            "type" : "string",
            "description" : "Names of additional guests on the reservation.",
            "example" : "Jane Doe, John Doe"
          },
          "deposit" : {
            "type" : "number",
            "description" : "Deposit amount required for the reservation.",
            "example" : 129.0
          },
          "taxes" : {
            "type" : "number",
            "description" : "Total taxes applied to the reservation.",
            "example" : 129.0
          },
          "processingFeePercentage" : {
            "type" : "number",
            "description" : "Processing fee percentage applied to the reservation.",
            "example" : 2.9
          },
          "processingFee" : {
            "type" : "number",
            "description" : "Processing fee amount applied to the reservation.",
            "example" : 129.0
          },
          "subTotal" : {
            "type" : "number",
            "description" : "Subtotal of the reservation before taxes and fees.",
            "example" : 129.0
          },
          "total" : {
            "type" : "number",
            "description" : "Total cost of the reservation.",
            "example" : 129.0
          },
          "paid" : {
            "type" : "number",
            "description" : "Amount paid so far on the reservation.",
            "example" : 129.0
          },
          "remainingBalance" : {
            "type" : "number",
            "description" : "Remaining balance owed on the reservation.",
            "example" : 129.0
          },
          "originalSubtotal" : {
            "type" : "number",
            "description" : "Original subtotal before any modifications.",
            "example" : 129.0
          },
          "originalTaxes" : {
            "type" : "number",
            "description" : "Original taxes before any modifications.",
            "example" : 129.0
          },
          "originalTotal" : {
            "type" : "number",
            "description" : "Original total before any modifications.",
            "example" : 129.0
          },
          "channel" : {
            "type" : "string",
            "description" : "Channel through which the reservation was created.",
            "example" : "website"
          },
          "canceledAt" : {
            "type" : "string",
            "description" : "Timestamp when the reservation was canceled, if applicable.",
            "format" : "date-time",
            "example" : "2026-06-01T15:00:00Z"
          },
          "createdAt" : {
            "type" : "string",
            "description" : "Timestamp when the reservation was created.",
            "format" : "date-time",
            "example" : "2026-06-01T15:00:00Z"
          },
          "updatedAt" : {
            "type" : "string",
            "description" : "Timestamp when the reservation was last updated.",
            "format" : "date-time",
            "example" : "2026-06-01T15:00:00Z"
          }
        },
        "description" : "A reservation, including its customer, bookings, line items, and financial totals."
      },
      "Hotel" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "string",
            "description" : "The unique identifier of the hotel.",
            "example" : "a1b2c3d4"
          },
          "externalId" : {
            "type" : "string",
            "description" : "The hotel's public identifier. Use this value as `{hotelId}` in hotel-scoped endpoint paths.",
            "example" : "a1b2c3d4"
          },
          "name" : {
            "type" : "string",
            "description" : "The name of the hotel.",
            "example" : "Seaside Resort"
          },
          "timeZone" : {
            "type" : "string",
            "description" : "The time zone the hotel operates in.",
            "example" : "America/Los_Angeles"
          },
          "notificationEmail" : {
            "type" : "string",
            "description" : "The email address used for hotel notifications.",
            "example" : "notifications@seasideresort.com"
          },
          "invoiceEmail" : {
            "type" : "string",
            "description" : "The email address used for invoices.",
            "example" : "invoices@seasideresort.com"
          },
          "bccEmail" : {
            "type" : "string",
            "description" : "The email address that receives blind carbon copies of communications.",
            "example" : "bcc@seasideresort.com"
          },
          "websiteUrl" : {
            "type" : "string",
            "description" : "The URL of the hotel's website.",
            "example" : "https://www.seasideresort.com"
          },
          "addressLine1" : {
            "type" : "string",
            "description" : "The first line of the hotel's street address.",
            "example" : "123 Ocean Ave"
          },
          "addressLine2" : {
            "type" : "string",
            "description" : "The second line of the hotel's street address.",
            "example" : "Suite 100"
          },
          "city" : {
            "type" : "string",
            "description" : "The city the hotel is located in.",
            "example" : "Santa Monica"
          },
          "state" : {
            "type" : "string",
            "description" : "The state or province the hotel is located in.",
            "example" : "CA"
          },
          "zip" : {
            "type" : "string",
            "description" : "The postal or ZIP code of the hotel.",
            "example" : "90401"
          },
          "country" : {
            "type" : "string",
            "description" : "The country the hotel is located in.",
            "example" : "US"
          },
          "latitude" : {
            "type" : "number",
            "description" : "The latitude coordinate of the hotel.",
            "format" : "double",
            "example" : 34.0195
          },
          "longitude" : {
            "type" : "number",
            "description" : "The longitude coordinate of the hotel.",
            "format" : "double",
            "example" : -118.4912
          },
          "phone" : {
            "type" : "string",
            "description" : "The contact phone number of the hotel.",
            "example" : "+1-310-555-0100"
          },
          "email" : {
            "type" : "string",
            "description" : "The contact email address of the hotel.",
            "example" : "info@seasideresort.com"
          },
          "termsAndConditions" : {
            "type" : "string",
            "description" : "The terms and conditions applicable to bookings at the hotel.",
            "example" : "Standard terms and conditions apply."
          },
          "cancellationPolicy" : {
            "type" : "string",
            "description" : "The cancellation policy of the hotel.",
            "example" : "Free cancellation up to 48 hours before arrival."
          },
          "privacyPolicy" : {
            "type" : "string",
            "description" : "The privacy policy of the hotel.",
            "example" : "We respect your privacy and protect your data."
          },
          "currencyCode" : {
            "type" : "string",
            "description" : "The ISO currency code used by the hotel.",
            "example" : "USD"
          }
        },
        "description" : "A hotel property, including its identifiers, contact information, address, geographic coordinates, and policies."
      },
      "RoomType" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "string",
            "description" : "The unique identifier of the room type.",
            "example" : "a1b2c3d4"
          },
          "name" : {
            "type" : "string",
            "description" : "The name of the room type.",
            "example" : "Deluxe King"
          }
        },
        "description" : "A category of rooms that share common characteristics, identified by id and name."
      },
      "StayOnDateRange" : {
        "type" : "object",
        "properties" : {
          "stay_on_start_date" : {
            "type" : "string",
            "format" : "date",
            "example" : "2020-02-28"
          },
          "stay_on_end_date" : {
            "type" : "string",
            "format" : "date",
            "example" : "2020-03-28"
          }
        }
      },
      "UpdatedAtDateTimeRange" : {
        "type" : "object",
        "properties" : {
          "updated_at_start_date_time" : {
            "type" : "string",
            "format" : "date-time"
          },
          "updated_at_end_date_time" : {
            "type" : "string",
            "format" : "date-time"
          }
        }
      },
      "CreatedAtDateTimeRange" : {
        "type" : "object",
        "properties" : {
          "created_at_start_date_time" : {
            "type" : "string",
            "format" : "date-time"
          },
          "created_at_end_date_time" : {
            "type" : "string",
            "format" : "date-time"
          }
        }
      },
      "PageReservation" : {
        "type" : "object",
        "properties" : {
          "totalPages" : {
            "type" : "integer",
            "format" : "int32"
          },
          "totalElements" : {
            "type" : "integer",
            "format" : "int64"
          },
          "first" : {
            "type" : "boolean"
          },
          "last" : {
            "type" : "boolean"
          },
          "size" : {
            "type" : "integer",
            "format" : "int32"
          },
          "content" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/Reservation"
            }
          },
          "number" : {
            "type" : "integer",
            "format" : "int32"
          },
          "sort" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/SortObject"
            }
          },
          "numberOfElements" : {
            "type" : "integer",
            "format" : "int32"
          },
          "pageable" : {
            "$ref" : "#/components/schemas/PageableObject"
          },
          "empty" : {
            "type" : "boolean"
          }
        }
      },
      "PageableObject" : {
        "type" : "object",
        "properties" : {
          "offset" : {
            "type" : "integer",
            "format" : "int64"
          },
          "sort" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/SortObject"
            }
          },
          "pageNumber" : {
            "type" : "integer",
            "format" : "int32"
          },
          "paged" : {
            "type" : "boolean"
          },
          "unpaged" : {
            "type" : "boolean"
          },
          "pageSize" : {
            "type" : "integer",
            "format" : "int32"
          }
        }
      },
      "SortObject" : {
        "type" : "object",
        "properties" : {
          "direction" : {
            "type" : "string"
          },
          "nullHandling" : {
            "type" : "string"
          },
          "ascending" : {
            "type" : "boolean"
          },
          "property" : {
            "type" : "string"
          },
          "ignoreCase" : {
            "type" : "boolean"
          }
        }
      },
      "RateType" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "string"
          },
          "name" : {
            "type" : "string"
          },
          "code" : {
            "type" : "string"
          },
          "description" : {
            "type" : "string"
          },
          "parentRateTypeId" : {
            "type" : "string"
          },
          "type" : {
            "type" : "string",
            "enum" : [ "STANDARD", "DERIVED" ]
          },
          "rateModifierType" : {
            "type" : "string",
            "enum" : [ "PERCENT", "FIXED" ]
          },
          "rateModifierAmount" : {
            "type" : "number"
          },
          "roomTypeIds" : {
            "type" : "array",
            "items" : {
              "type" : "string"
            }
          },
          "roomTaxIds" : {
            "type" : "array",
            "items" : {
              "type" : "string"
            }
          },
          "additionalGuestTaxIds" : {
            "type" : "array",
            "items" : {
              "type" : "string"
            }
          },
          "petTaxIds" : {
            "type" : "array",
            "items" : {
              "type" : "string"
            }
          },
          "minimumNights" : {
            "type" : "integer",
            "format" : "int32"
          },
          "maximumNights" : {
            "type" : "integer",
            "format" : "int32"
          },
          "depositType" : {
            "type" : "string"
          },
          "numberOfNightsDeposit" : {
            "type" : "integer",
            "format" : "int32"
          },
          "flatFeeDeposit" : {
            "type" : "number"
          },
          "percentDeposit" : {
            "type" : "number"
          },
          "perPersonDeposit" : {
            "type" : "number"
          },
          "fullDepositOverrideMinimumNights" : {
            "type" : "integer",
            "format" : "int32"
          },
          "includeItemsInDeposit" : {
            "type" : "boolean"
          },
          "includeTaxesInDeposit" : {
            "type" : "boolean"
          },
          "fullDepositRangeInDays" : {
            "type" : "integer",
            "format" : "int32"
          },
          "consolidateGuestView" : {
            "type" : "boolean"
          },
          "doNotAdjustMinimumNights" : {
            "type" : "boolean"
          },
          "minimumNightsLowerLimit" : {
            "type" : "integer",
            "format" : "int32"
          },
          "inactive" : {
            "type" : "boolean"
          }
        }
      },
      "StartEndDateRange" : {
        "required" : [ "end_date", "start_date" ],
        "type" : "object",
        "properties" : {
          "start_date" : {
            "type" : "string",
            "format" : "date",
            "example" : "2020-02-28"
          },
          "end_date" : {
            "type" : "string",
            "format" : "date",
            "example" : "2020-03-28"
          }
        }
      },
      "RoomTypeDailyRateConfiguration" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "string"
          },
          "roomTypeId" : {
            "type" : "string"
          },
          "rateTypeId" : {
            "type" : "string"
          },
          "date" : {
            "type" : "string",
            "format" : "date"
          },
          "price" : {
            "type" : "number"
          },
          "minimumNightsOnArrival" : {
            "type" : "integer",
            "format" : "int32"
          },
          "minimumNightsThrough" : {
            "type" : "integer",
            "format" : "int32"
          },
          "maximumNightsOnArrival" : {
            "type" : "integer",
            "format" : "int32"
          },
          "maximumNightsThrough" : {
            "type" : "integer",
            "format" : "int32"
          },
          "closedOnArrival" : {
            "type" : "boolean"
          },
          "closedOnDeparture" : {
            "type" : "boolean"
          },
          "stopSell" : {
            "type" : "boolean"
          }
        }
      },
      "AllDatePolicy" : {
        "type" : "object",
        "allOf" : [ {
          "$ref" : "#/components/schemas/DatePolicy"
        } ]
      },
      "AllRateTypePolicy" : {
        "type" : "object",
        "allOf" : [ {
          "$ref" : "#/components/schemas/RateTypePolicy"
        } ]
      },
      "AllRoomTypePolicy" : {
        "type" : "object",
        "allOf" : [ {
          "$ref" : "#/components/schemas/RoomTypePolicy"
        } ]
      },
      "DatePolicy" : {
        "type" : "object",
        "properties" : {
          "type" : {
            "type" : "string"
          }
        },
        "description" : "The policy defining which booking dates the promotion applies to.",
        "discriminator" : {
          "propertyName" : "type"
        }
      },
      "DateRangeDatePolicy" : {
        "type" : "object",
        "allOf" : [ {
          "$ref" : "#/components/schemas/DatePolicy"
        }, {
          "type" : "object",
          "properties" : {
            "startDate" : {
              "type" : "string",
              "format" : "date-time"
            },
            "endDate" : {
              "type" : "string",
              "format" : "date-time"
            },
            "dateRangePolicy" : {
              "type" : "string",
              "enum" : [ "AT_LEAST_ONE", "ALL" ]
            }
          }
        } ]
      },
      "DaysOfWeekDatePolicy" : {
        "type" : "object",
        "allOf" : [ {
          "$ref" : "#/components/schemas/DatePolicy"
        }, {
          "type" : "object",
          "properties" : {
            "monday" : {
              "type" : "boolean"
            },
            "tuesday" : {
              "type" : "boolean"
            },
            "wednesday" : {
              "type" : "boolean"
            },
            "thursday" : {
              "type" : "boolean"
            },
            "friday" : {
              "type" : "boolean"
            },
            "saturday" : {
              "type" : "boolean"
            },
            "sunday" : {
              "type" : "boolean"
            },
            "policy" : {
              "type" : "string",
              "enum" : [ "AT_LEAST_ONE", "AT_LEAST_ALL" ]
            }
          }
        } ]
      },
      "DaysOfWeekDateRange" : {
        "type" : "object",
        "properties" : {
          "startDate" : {
            "type" : "string",
            "format" : "date"
          },
          "endDate" : {
            "type" : "string",
            "format" : "date"
          },
          "monday" : {
            "type" : "boolean"
          },
          "tuesday" : {
            "type" : "boolean"
          },
          "wednesday" : {
            "type" : "boolean"
          },
          "thursday" : {
            "type" : "boolean"
          },
          "friday" : {
            "type" : "boolean"
          },
          "saturday" : {
            "type" : "boolean"
          },
          "sunday" : {
            "type" : "boolean"
          },
          "dateRangePolicy" : {
            "type" : "string",
            "enum" : [ "AT_LEAST_ONE", "ALL" ]
          },
          "policy" : {
            "type" : "string",
            "enum" : [ "AT_LEAST_ONE", "AT_LEAST_ALL" ]
          }
        }
      },
      "DaysOfWeekDateRangeDatePolicy" : {
        "type" : "object",
        "allOf" : [ {
          "$ref" : "#/components/schemas/DatePolicy"
        }, {
          "type" : "object",
          "properties" : {
            "dateRanges" : {
              "type" : "array",
              "items" : {
                "$ref" : "#/components/schemas/DaysOfWeekDateRange"
              }
            }
          }
        } ]
      },
      "DiscountPolicy" : {
        "type" : "object",
        "properties" : {
          "discountPolicyType" : {
            "type" : "string",
            "enum" : [ "EVERY_NIGHT", "FIRST_NIGHT", "LAST_NIGHT", "CHEAPEST_NIGHT", "DAYS_OF_WEEK" ]
          },
          "discountValue" : {
            "$ref" : "#/components/schemas/DiscountValue"
          },
          "monday" : {
            "type" : "boolean"
          },
          "tuesday" : {
            "type" : "boolean"
          },
          "wednesday" : {
            "type" : "boolean"
          },
          "thursday" : {
            "type" : "boolean"
          },
          "friday" : {
            "type" : "boolean"
          },
          "saturday" : {
            "type" : "boolean"
          },
          "sunday" : {
            "type" : "boolean"
          }
        },
        "description" : "The policy defining the discount applied by the promotion."
      },
      "DiscountValue" : {
        "type" : "object",
        "properties" : {
          "discountValueType" : {
            "type" : "string",
            "enum" : [ "AMOUNT", "PERCENT" ]
          },
          "value" : {
            "type" : "number"
          }
        }
      },
      "Promotion" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "string",
            "description" : "The unique identifier of the promotion.",
            "example" : "a1b2c3d4"
          },
          "name" : {
            "type" : "string",
            "description" : "The name of the promotion.",
            "example" : "Summer Special"
          },
          "description" : {
            "type" : "string",
            "description" : "A description of the promotion.",
            "example" : "20% off summer stays"
          },
          "promotionalCode" : {
            "type" : "string",
            "description" : "The promotional code guests enter to apply the promotion.",
            "example" : "SUMMER20"
          },
          "minimumNights" : {
            "type" : "integer",
            "description" : "The minimum number of nights required to qualify for the promotion.",
            "format" : "int32",
            "example" : 1
          },
          "maximumNights" : {
            "type" : "integer",
            "description" : "The maximum number of nights eligible for the promotion.",
            "format" : "int32",
            "example" : 1
          },
          "stayDatePolicy" : {
            "oneOf" : [ {
              "$ref" : "#/components/schemas/AllDatePolicy"
            }, {
              "$ref" : "#/components/schemas/DateRangeDatePolicy"
            }, {
              "$ref" : "#/components/schemas/DaysOfWeekDatePolicy"
            }, {
              "$ref" : "#/components/schemas/DaysOfWeekDateRangeDatePolicy"
            } ]
          },
          "bookingDatePolicy" : {
            "oneOf" : [ {
              "$ref" : "#/components/schemas/AllDatePolicy"
            }, {
              "$ref" : "#/components/schemas/DateRangeDatePolicy"
            }, {
              "$ref" : "#/components/schemas/DaysOfWeekDatePolicy"
            }, {
              "$ref" : "#/components/schemas/DaysOfWeekDateRangeDatePolicy"
            } ]
          },
          "roomTypePolicy" : {
            "oneOf" : [ {
              "$ref" : "#/components/schemas/RoomTypePolicy"
            }, {
              "$ref" : "#/components/schemas/AllRoomTypePolicy"
            }, {
              "$ref" : "#/components/schemas/SpecificRoomTypePolicy"
            } ]
          },
          "rateTypePolicy" : {
            "oneOf" : [ {
              "$ref" : "#/components/schemas/RateTypePolicy"
            }, {
              "$ref" : "#/components/schemas/AllRateTypePolicy"
            }, {
              "$ref" : "#/components/schemas/SpecificRateTypePolicy"
            } ]
          },
          "discountPolicy" : {
            "$ref" : "#/components/schemas/DiscountPolicy"
          },
          "targetChannel" : {
            "type" : "string",
            "description" : "The channel the promotion targets.",
            "example" : "Website"
          },
          "leadTimePolicy" : {
            "$ref" : "#/components/schemas/TimePolicy"
          },
          "inactive" : {
            "type" : "boolean",
            "description" : "Whether the promotion is inactive.",
            "example" : true
          },
          "createdAt" : {
            "type" : "string",
            "description" : "The timestamp when the promotion was created.",
            "format" : "date-time",
            "example" : "2026-06-01T15:00:00Z"
          },
          "updatedAt" : {
            "type" : "string",
            "description" : "The timestamp when the promotion was last updated.",
            "format" : "date-time",
            "example" : "2026-06-01T15:00:00Z"
          }
        },
        "description" : "A promotion defining discount rules, eligibility policies, and applicable date ranges."
      },
      "RateTypePolicy" : {
        "type" : "object",
        "properties" : {
          "type" : {
            "type" : "string"
          }
        },
        "description" : "The policy defining which rate types the promotion applies to.",
        "discriminator" : {
          "propertyName" : "type"
        }
      },
      "RoomTypePolicy" : {
        "type" : "object",
        "properties" : {
          "type" : {
            "type" : "string"
          }
        },
        "description" : "The policy defining which room types the promotion applies to.",
        "discriminator" : {
          "propertyName" : "type"
        }
      },
      "SpecificRateTypePolicy" : {
        "type" : "object",
        "allOf" : [ {
          "$ref" : "#/components/schemas/RateTypePolicy"
        }, {
          "type" : "object",
          "properties" : {
            "rateTypeIds" : {
              "type" : "array",
              "items" : {
                "type" : "string"
              }
            }
          }
        } ]
      },
      "SpecificRoomTypePolicy" : {
        "type" : "object",
        "allOf" : [ {
          "$ref" : "#/components/schemas/RoomTypePolicy"
        }, {
          "type" : "object",
          "properties" : {
            "roomTypeIds" : {
              "type" : "array",
              "items" : {
                "type" : "string"
              }
            }
          }
        } ]
      },
      "TimePolicy" : {
        "type" : "object",
        "properties" : {
          "operationType" : {
            "type" : "string",
            "enum" : [ "LESS_THAN", "LESS_THAN_OR_EQUAL_TO", "EQUAL_TO", "GREATER_THAN", "GREATER_THAN_OR_EQUAL_TO" ]
          },
          "timeUnitType" : {
            "type" : "string",
            "enum" : [ "DAY" ]
          },
          "timeUnitQuantity" : {
            "type" : "integer",
            "format" : "int32"
          }
        },
        "description" : "The policy defining the lead time required before the stay for the promotion."
      },
      "RoomTypeDailyInventory" : {
        "type" : "object",
        "properties" : {
          "roomTypeId" : {
            "type" : "string"
          },
          "date" : {
            "type" : "string",
            "format" : "date"
          },
          "totalRooms" : {
            "type" : "integer",
            "format" : "int32"
          },
          "roomsToSell" : {
            "type" : "integer",
            "format" : "int32"
          },
          "booked" : {
            "type" : "integer",
            "format" : "int32"
          },
          "blocked" : {
            "type" : "integer",
            "format" : "int32"
          }
        }
      },
      "Blackout" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "string",
            "description" : "The unique identifier of the blackout.",
            "example" : "a1b2c3d4"
          },
          "type" : {
            "type" : "string",
            "description" : "The type of the blackout.",
            "example" : "Maintenance"
          },
          "roomIdDatePairs" : {
            "type" : "array",
            "description" : "The list of room and date pairs covered by this blackout.",
            "items" : {
              "$ref" : "#/components/schemas/RoomIdDatePair"
            }
          },
          "notes" : {
            "type" : "string",
            "description" : "Free-form notes about the blackout.",
            "example" : "Annual deep cleaning"
          }
        },
        "description" : "A blackout that marks rooms as unavailable for specific dates."
      },
      "RoomIdDatePair" : {
        "type" : "object",
        "properties" : {
          "room_id" : {
            "type" : "string"
          },
          "date" : {
            "type" : "string",
            "format" : "date"
          }
        },
        "description" : "The list of room and date pairs covered by this blackout."
      },
      "AppliedPromotion" : {
        "type" : "object",
        "properties" : {
          "promotionId" : {
            "type" : "string"
          },
          "name" : {
            "type" : "string"
          },
          "description" : {
            "type" : "string"
          }
        },
        "description" : "The promotion applied to this rate type, if any."
      },
      "Availability" : {
        "type" : "object",
        "properties" : {
          "unit" : {
            "$ref" : "#/components/schemas/Unit"
          },
          "numberOfUnits" : {
            "type" : "integer",
            "description" : "The number of units of this type that are available.",
            "format" : "int32",
            "example" : 2
          },
          "rateTypeAvailabilities" : {
            "type" : "array",
            "description" : "The list of rate types available for this unit, with pricing details.",
            "items" : {
              "$ref" : "#/components/schemas/RateTypeAvailability"
            }
          }
        },
        "description" : "Availability for a single unit, including the number of available units and the rate types that can be booked."
      },
      "RateTypeAvailability" : {
        "type" : "object",
        "properties" : {
          "rateType" : {
            "$ref" : "#/components/schemas/RateType"
          },
          "booking" : {
            "$ref" : "#/components/schemas/Booking"
          },
          "rateTypeRestrictions" : {
            "type" : "array",
            "description" : "The list of restrictions that apply to this rate type.",
            "items" : {
              "$ref" : "#/components/schemas/RateTypeRestriction"
            }
          },
          "roomPricesPerDay" : {
            "type" : "array",
            "description" : "The room price for each day of the stay.",
            "items" : {
              "type" : "number",
              "description" : "The room price for each day of the stay."
            }
          },
          "averagePricePerDay" : {
            "type" : "number",
            "description" : "The average room price per day.",
            "example" : 199.0
          },
          "price" : {
            "type" : "number",
            "description" : "The total room price for the stay.",
            "example" : 199.0
          },
          "fees" : {
            "type" : "number",
            "description" : "The total fees for the stay.",
            "example" : 199.0
          },
          "taxes" : {
            "type" : "number",
            "description" : "The total taxes for the stay.",
            "example" : 199.0
          },
          "total" : {
            "type" : "number",
            "description" : "The grand total for the stay including price, fees, and taxes.",
            "example" : 199.0
          },
          "deposit" : {
            "type" : "number",
            "description" : "The deposit required for the booking.",
            "example" : 199.0
          },
          "appliedPromotion" : {
            "$ref" : "#/components/schemas/AppliedPromotion"
          },
          "subtotalBeforePromotion" : {
            "type" : "number",
            "description" : "The subtotal before any promotion was applied.",
            "example" : 199.0
          },
          "averagePricePerDayBeforePromotion" : {
            "type" : "number",
            "description" : "The average price per day before any promotion was applied.",
            "example" : 199.0
          }
        },
        "description" : "Availability and pricing details for a specific rate type, including restrictions, daily prices, totals, deposits, and any applied promotion."
      },
      "RateTypeRestriction" : {
        "type" : "object",
        "properties" : {
          "name" : {
            "type" : "string",
            "enum" : [ "NUMBER_OF_GUESTS", "NUMBER_OF_PETS", "PRICE_CONFIGURED", "MINIMUM_NIGHTS_ON_ARRIVAL", "MINIMUM_NIGHTS_THROUGH", "MAXIMUM_NIGHTS_ON_ARRIVAL", "MAXIMUM_NIGHTS_THROUGH", "CLOSED_ON_ARRIVAL", "CLOSED_ON_DEPARTURE", "STOP_SELL" ]
          },
          "value" : {
            "type" : "object"
          }
        },
        "description" : "The list of restrictions that apply to this rate type."
      },
      "Unit" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "string",
            "description" : "The unique identifier of the unit.",
            "example" : "a1b2c3d4"
          },
          "description" : {
            "type" : "string",
            "description" : "A detailed description of the unit.",
            "example" : "Spacious king room with ocean view"
          },
          "imageUrls" : {
            "type" : "array",
            "description" : "The list of image URLs for the unit.",
            "items" : {
              "type" : "string",
              "description" : "The list of image URLs for the unit."
            }
          },
          "altTexts" : {
            "type" : "array",
            "description" : "The list of alternative text descriptions corresponding to the images.",
            "items" : {
              "type" : "string",
              "description" : "The list of alternative text descriptions corresponding to the images."
            }
          },
          "name" : {
            "type" : "string",
            "description" : "The name of the unit.",
            "example" : "Deluxe King"
          },
          "shortName" : {
            "type" : "string",
            "description" : "The short name of the unit.",
            "example" : "DLXK"
          },
          "amenities" : {
            "type" : "array",
            "description" : "The list of amenities available in the unit.",
            "items" : {
              "type" : "string",
              "description" : "The list of amenities available in the unit."
            }
          },
          "numberOfBedrooms" : {
            "type" : "integer",
            "description" : "The number of bedrooms in the unit.",
            "format" : "int32",
            "example" : 2
          },
          "numberOfFullBaths" : {
            "type" : "integer",
            "description" : "The number of full bathrooms in the unit.",
            "format" : "int32",
            "example" : 2
          },
          "numberOfHalfBaths" : {
            "type" : "integer",
            "description" : "The number of half bathrooms in the unit.",
            "format" : "int32",
            "example" : 2
          },
          "adaCompliant" : {
            "type" : "boolean",
            "description" : "Whether the unit is compliant with ADA accessibility requirements.",
            "example" : true
          }
        },
        "description" : "A bookable unit such as a room or accommodation, including its descriptive details, imagery, amenities, and bedroom/bathroom configuration."
      }
    },
    "securitySchemes" : {
      "oauth2" : {
        "type" : "oauth2",
        "description" : "Auth0 OAuth 2.0 authorization code flow. Authorize a user, then exchange the code for an access token scoped to the hotel(s) you integrate with.",
        "flows" : {
          "authorizationCode" : {
            "authorizationUrl" : "https://auth.thinkreservations.com/authorize",
            "tokenUrl" : "https://auth.thinkreservations.com/oauth/token",
            "scopes" : {
              "read:rate" : "Read rate types and daily rate configurations",
              "write:rate" : "Update daily rate configurations",
              "read:availability" : "Read availability and inventory",
              "read:reservation" : "Read reservations",
              "write:reservation" : "Create reservations",
              "read:customer" : "Include guest contact details on reservations",
              "read:room" : "Read rooms and room types",
              "read:hotel" : "Read hotel details"
            },
            "x-usePkce" : "no"
          }
        }
      },
      "apiKey" : {
        "type" : "http",
        "description" : "Restricted API key (rk_live_… / rk_test_…) presented as a bearer token in the Authorization header. Each request is scoped to the hotel in the path.",
        "scheme" : "bearer"
      }
    }
  }
}