{
  "openapi": "3.0.1",
  "info": {
    "title": "Historical Reservations API",
    "description": "Retrieve a property's historical reservation details for use in a revenue management system. Select room reservations by check-in date and optionally by status. Responses include stay dates, available occupancy, and guest and property price perspectives. Access requires a connection authorised to read the property's reservation history.",
    "version": "1.0.0",
    "contact": {
      "name": "Connectivity Team",
      "url": "https://connect.booking.com",
      "email": "connectivity@booking.com"
    },
    "license": {
      "name": "Copyright Booking.com. All rights reserved.",
      "url": "https://www.booking.com"
    }
  },
  "externalDocs": {
    "description": "Historical Reservations API guide",
    "url": "https://developers.booking.com/connectivity/docs/historical-reservations-api/overview"
  },
  "servers": [
    {
      "url": "https://supply-xml.booking.com",
      "description": "Intended production API gateway; confirm availability and access before use"
    }
  ],
  "security": [
    {
      "BearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Historical reservations",
      "description": "Retrieve historical reservation data for an authorized property."
    },
    {
      "name": "About Try it",
      "description": "Use **Try it** to retrieve historical reservations with this read-only endpoint:\n\n```http\nGET /revenue-management-api/properties/{property_id}/historical-reservations\n```\n\n## Environment\n\n- **Mock (schema only)** returns schema-driven mock responses or predefined examples. Use it to inspect the response format; it does not verify live authentication, property access, or reservation data.\n- **Intended production API gateway** sends a request to the live API. Confirm availability and arrange access with Connectivity Support first. Use an authorized test property and a valid Connectivity access token. Live requests are subject to the [request quota](/connectivity/docs/historical-reservations-api/overview#rate-limit).\n\n## Request\n\n1. Open **Try it** for the GET operation and select the environment.\n2. For a live request, configure `Authorization: Bearer {access_token}`. Send `Accept: application/json` and `Accept-Version: 1.0`.\n3. Fill in the following parameters:\n\n| Parameter | Location | Required | Value |\n| --- | --- | --- | --- |\n| `property_id` | Path | Yes | The ID of the test property your account is authorized to access for reservation history. |\n| `check_in_start` | Query | Yes | Inclusive check-in lower bound, as a date in `YYYY-MM-DD` format. |\n| `check_in_end` | Query | Yes | Inclusive check-in upper bound, as a date in `YYYY-MM-DD` format. |\n| `status` | Query | No | `OK`, `CANCELLED`, or `NO_SHOW`. Omit to include all supported statuses. In Try it, add each status as a separate item, for example `OK` and `NO_SHOW`. |\n| `Accept-Version` | Header | No | API version. Send `1.0`. The default when omitted is also `1.0`. |\n\nBoth bounds are required and have no defaults. Use date-only values without a time or timezone suffix. The inclusive range must satisfy `today (UTC) minus 24 calendar months <= check_in_start <= check_in_end <= today (UTC)`. Equal bounds select a single check-in day; today is allowed. See the [check-in-date eligibility limits](/connectivity/docs/historical-reservations-api/overview#choose-the-check-in-date-interval). These dates select room check-ins; reservation creation and check-out dates do not restrict the range. The response `created_at` field remains the creation timestamp.\n\nThe request has no body. Check the selected environment and parameter values, then click **Send**.\n\n## Response\n\nInspect the HTTP status and JSON response. A successful `200` response contains `data.property_id` and `data.property_reservations`. An empty reservation array is valid. Mock responses do not establish that the live request succeeds or that matching reservations exist.\n\nIf a live request for a period fails or times out while retrieving reservations, try again with a smaller check-in-date interval. For consecutive intervals, start the next interval on the calendar day after the previous end so check-in days do not overlap. Keep all matching room reservations.\n\nFor a live error, use the endpoint's documented response and the [troubleshooting guidance](/connectivity/docs/historical-reservations-api/overview#troubleshooting). Retain the request identifier when present for Connectivity Support. Do not include your access token or client secret.\n"
    }
  ],
  "x-tagGroups": [
    {
      "name": "API Endpoints",
      "tags": [
        "Historical reservations"
      ]
    },
    {
      "name": "Documentation",
      "tags": [
        "About Try it"
      ]
    }
  ],
  "paths": {
    "/revenue-management-api/properties/{property_id}/historical-reservations": {
      "get": {
        "tags": [
          "Historical reservations"
        ],
        "summary": "Retrieve historical reservations",
        "description": "Retrieve eligible room reservations whose check-in dates fall within the inclusive requested range, grouped by property reservation. Both check_in_start and check_in_end are required in YYYY-MM-DD format, without a time or timezone suffix. The bounds must satisfy today (UTC) minus 24 calendar months <= check_in_start <= check_in_end <= today (UTC). Equal bounds select a single check-in day; today is allowed. Reservation creation and check-out dates do not restrict this range. A reservation created before the requested period can be returned when its check-in date is in range. The response created_at field remains the reservation creation timestamp. The endpoint returns confirmed, cancelled, and no-show reservations and supports an optional room status filter. It does not expose pagination or a continuation token. If a request fails or times out, try smaller check-in-date intervals. For consecutive intervals, start the next interval on the calendar day after the previous end to avoid overlapping check-in days. Optional response fields are omitted when their values were not recorded or are unavailable for this response.",
        "operationId": "getHistoricalReservations",
        "parameters": [
          {
            "name": "property_id",
            "in": "path",
            "required": true,
            "description": "Booking.com property ID for a property your connection is authorized to access for reservation history.",
            "schema": {
              "type": "integer",
              "format": "int32",
              "minimum": 1,
              "maximum": 2147483647
            },
            "examples": {
              "property": {
                "summary": "Example property ID",
                "value": 1234567
              }
            }
          },
          {
            "name": "check_in_start",
            "in": "query",
            "required": true,
            "description": "Inclusive check-in lower bound in YYYY-MM-DD format, without a time or timezone suffix. Must be on or after today (UTC) minus 24 calendar months and no later than check_in_end. Both bounds are required and have no defaults. Calendar subtraction adjusts a leap day to the final valid day of February. Choose dates within the current eligibility window; fixed examples eventually expire.",
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            },
            "examples": {
              "start": {
                "summary": "Start of the example check-in range",
                "value": "2026-02-01"
              }
            }
          },
          {
            "name": "check_in_end",
            "in": "query",
            "required": true,
            "description": "Inclusive check-in upper bound in YYYY-MM-DD format, without a time or timezone suffix. Must be on or after check_in_start and no later than today (UTC). Today is allowed. Equal bounds select a single check-in day.",
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            },
            "examples": {
              "end": {
                "summary": "End of the example check-in range",
                "value": "2026-02-28"
              }
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": true,
            "description": "Room reservation statuses to include. Omit this parameter to include all supported statuses. An empty `status` value returns HTTP `400`. Repeat the query parameter to select multiple values. For example, an HTTP request can use `status=OK&status=NO_SHOW`. In Try it, enter individual status values as separate items. Only matching rooms remain in each property reservation; property reservations without matching rooms are omitted.",
            "schema": {
              "type": "array",
              "uniqueItems": true,
              "items": {
                "$ref": "#/components/schemas/ReservationStatus"
              }
            },
            "examples": {
              "confirmed": {
                "summary": "Confirmed reservations",
                "value": [
                  "OK"
                ]
              },
              "confirmedAndNoShow": {
                "summary": "Confirmed and no-show reservations",
                "value": [
                  "OK",
                  "NO_SHOW"
                ]
              }
            }
          },
          {
            "name": "Accept-Version",
            "in": "header",
            "required": false,
            "description": "API version. Send `1.0`. This is also the default when the header is omitted.",
            "schema": {
              "type": "string",
              "enum": [
                "1.0"
              ],
              "default": "1.0"
            },
            "examples": {
              "version": {
                "summary": "API version",
                "value": "1.0"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Historical reservations matching the request. The response has no pagination parameters or continuation token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HistoricalReservationsResponse"
                },
                "examples": {
                  "confirmedAndCancelled": {
                    "summary": "Confirmed and cancelled reservations",
                    "value": {
                      "data": {
                        "property_id": 1234567,
                        "currency": "EUR",
                        "property_reservations": [
                          {
                            "property_reservation_id": "9876543210",
                            "room_reservations": [
                              {
                                "room_id": "123456701",
                                "created_at": "2026-01-15T10:00:00Z",
                                "checkin": "2026-02-01",
                                "checkout": "2026-02-03",
                                "status": "OK",
                                "occupancy": {
                                  "adults": 2,
                                  "children": 0
                                },
                                "guest": {
                                  "total_price": "123.45",
                                  "price_components": [
                                    {
                                      "description": "room price",
                                      "type": "BASE_PRICE",
                                      "price": "123.45",
                                      "included": true
                                    },
                                    {
                                      "description": "city tax",
                                      "type": "TAX",
                                      "price": "10.00",
                                      "included": false
                                    }
                                  ]
                                },
                                "hotel": {
                                  "total_price": "100.00",
                                  "price_components": [
                                    {
                                      "description": "room price",
                                      "type": "BASE_PRICE",
                                      "price": "100.00",
                                      "included": true
                                    },
                                    {
                                      "description": "service fee",
                                      "type": "FEE",
                                      "price": "5.00",
                                      "included": false
                                    }
                                  ]
                                }
                              }
                            ]
                          },
                          {
                            "property_reservation_id": "9876543211",
                            "room_reservations": [
                              {
                                "room_id": "123456702",
                                "created_at": "2026-01-16T10:00:00Z",
                                "cancelled_at": "2026-01-17T11:00:00Z",
                                "checkin": "2026-02-04",
                                "checkout": "2026-02-05",
                                "status": "CANCELLED",
                                "hotel": {
                                  "total_price": "80.00",
                                  "price_components": []
                                }
                              }
                            ]
                          }
                        ]
                      },
                      "meta": {
                        "ruid": "synthetic-request-id"
                      }
                    },
                    "description": "Synthetic data showing both price perspectives, an explicit zero child count, and a cancelled reservation without optional guest or occupancy data."
                  },
                  "noShows": {
                    "summary": "No-show reservation with partial occupancy",
                    "value": {
                      "data": {
                        "property_id": 1234567,
                        "currency": "EUR",
                        "property_reservations": [
                          {
                            "property_reservation_id": "9876543212",
                            "room_reservations": [
                              {
                                "room_id": "123456701",
                                "created_at": "2026-01-15T12:00:00Z",
                                "checkin": "2026-02-03",
                                "checkout": "2026-02-05",
                                "status": "NO_SHOW",
                                "occupancy": {
                                  "adults": 1
                                },
                                "hotel": {
                                  "total_price": "100.00",
                                  "price_components": []
                                }
                              }
                            ]
                          }
                        ]
                      },
                      "meta": {
                        "ruid": "synthetic-request-id"
                      }
                    },
                    "description": "Synthetic data for status=NO_SHOW. The omitted children count is unknown; it does not mean zero."
                  },
                  "noMatches": {
                    "summary": "No matching reservations",
                    "value": {
                      "data": {
                        "property_id": 1234567,
                        "property_reservations": []
                      },
                      "meta": {
                        "ruid": "synthetic-request-id"
                      }
                    },
                    "description": "Synthetic data for a request with no reservations matching the check-in range and status filter. This example omits the optional currency field because it contains no monetary amounts."
                  }
                }
              }
            }
          },
          "400": {
            "description": "A required parameter is missing or invalid, including an invalid property ID, check-in date, range, or status. Missing bounds, timestamps, timezone suffixes, malformed dates, reversed bounds, starts before today (UTC) minus 24 calendar months, and future check-ins return HTTP 400. The legacy created_at_start and created_at_end parameters do not satisfy the required check-in bounds.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServiceErrorResponse"
                },
                "examples": {
                  "invalidRequest": {
                    "summary": "Request parameters are missing or invalid",
                    "value": {
                      "errors": [
                        {
                          "code": "INVALID_REQUEST_PARAMETERS",
                          "message": "Request parameters are missing or invalid"
                        }
                      ],
                      "meta": {
                        "ruid": "synthetic-request-id"
                      }
                    }
                  },
                  "futureCheckIn": {
                    "summary": "An ordered check-in range ends after today (UTC)",
                    "value": {
                      "errors": [
                        {
                          "code": "INVALID_REQUEST_PARAMETERS",
                          "message": "Check-in dates must not be in the future (UTC)"
                        }
                      ],
                      "meta": {
                        "ruid": "synthetic-request-id"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Authentication is missing, invalid, or expired. Obtain a valid Connectivity token and send it in the Authorization header. Gateway authentication error codes and messages can differ from the service example.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServiceErrorResponse"
                },
                "examples": {
                  "serviceAuthenticationRequired": {
                    "summary": "Authentication required",
                    "value": {
                      "errors": [
                        {
                          "code": "UNAUTHORIZED",
                          "message": "Authentication is required"
                        }
                      ],
                      "meta": {
                        "ruid": "synthetic-request-id"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Access to the requested property is not permitted. Check that your connection includes permission to read reservation history.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServiceErrorResponse"
                },
                "examples": {
                  "propertyAccessDenied": {
                    "summary": "Access to this property is not permitted",
                    "value": {
                      "errors": [
                        {
                          "code": "FORBIDDEN",
                          "message": "Access to this property is not permitted"
                        }
                      ],
                      "meta": {
                        "ruid": "synthetic-request-id"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "The API gateway rejected the request because a rate limit was exceeded. The production quota is 250 requests per provider and property in a rolling one-day window. Wait before retrying and reduce the request frequency. The daily quota returns a `fault` object; the general Connectivity throttle returns an `errors` array with `meta` and may also include `warnings` and error `details`. A request identifier and Retry-After header are not guaranteed.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/GatewayFaultResponse"
                    },
                    {
                      "$ref": "#/components/schemas/GatewayErrorResponse"
                    }
                  ]
                },
                "examples": {
                  "dailyQuotaExceeded": {
                    "summary": "HTTP 429 — rolling-day quota exceeded",
                    "description": "HTTP 429 with Content-Type: application/json. This gateway fault has no service errors array. Provider and property identifiers below are synthetic; the diagnostic message can vary.",
                    "value": {
                      "fault": {
                        "faultstring": "Rate limit quota violation. Quota limit exceeded. Identifier : 1234-1234567",
                        "detail": {
                          "errorcode": "policies.ratelimit.QuotaViolation"
                        }
                      }
                    }
                  },
                  "connectivityThrottleExceeded": {
                    "summary": "HTTP 429 — Connectivity throttle exceeded",
                    "description": "HTTP 429 with Content-Type: application/json. The shared gateway throttle uses the errors envelope and adds warnings and details. The request identifier is synthetic.",
                    "value": {
                      "meta": {
                        "ruid": "synthetic-request-id"
                      },
                      "warnings": [],
                      "errors": [
                        {
                          "message": "Too Many Requests. Try again soon.",
                          "code": "TOO_MANY_REQUESTS",
                          "details": null
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred while processing the request. Retain the request identifier when contacting support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServiceErrorResponse"
                },
                "examples": {
                  "unexpectedError": {
                    "summary": "An unexpected error occurred",
                    "value": {
                      "errors": [
                        {
                          "code": "INTERNAL_SERVER_ERROR",
                          "message": "An unexpected error occurred"
                        }
                      ],
                      "meta": {
                        "ruid": "synthetic-request-id"
                      }
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "Authorization or historical reservation data is temporarily unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServiceErrorResponse"
                },
                "examples": {
                  "authorizationUnavailable": {
                    "summary": "HTTP 502 — Authorization service is temporarily unavailable",
                    "value": {
                      "errors": [
                        {
                          "code": "AUTHORIZATION_SERVICE_ERROR",
                          "message": "Authorization service is temporarily unavailable"
                        }
                      ],
                      "meta": {
                        "ruid": "synthetic-request-id"
                      }
                    },
                    "description": "HTTP 502 with Content-Type: application/json. The service errors array identifies the failed dependency; meta.ruid is a synthetic request identifier."
                  },
                  "reservationsUnavailable": {
                    "summary": "HTTP 502 — Historical reservations are temporarily unavailable",
                    "value": {
                      "errors": [
                        {
                          "code": "UPSTREAM_SERVICE_ERROR",
                          "message": "Historical reservations are temporarily unavailable"
                        }
                      ],
                      "meta": {
                        "ruid": "synthetic-request-id"
                      }
                    },
                    "description": "HTTP 502 with Content-Type: application/json. The service errors array identifies the failed dependency; meta.ruid is a synthetic request identifier."
                  }
                }
              }
            }
          },
          "503": {
            "description": "The gateway or an upstream service is temporarily unavailable. JSON may use a gateway fault object or the shared errors envelope. Plain-text infrastructure errors are also possible. Check Content-Type before parsing, retry with backoff, and retain any request identifier provided.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/GatewayFaultResponse"
                    },
                    {
                      "$ref": "#/components/schemas/GatewayErrorResponse"
                    }
                  ]
                },
                "examples": {
                  "gatewayUnavailable": {
                    "summary": "HTTP 503 — gateway target unavailable",
                    "description": "HTTP 503 with Content-Type: application/json. Representative native gateway fault when the target cannot be reached. Other gateway failures may use different codes or the errors envelope.",
                    "value": {
                      "fault": {
                        "faultstring": "The Service is temporarily unavailable",
                        "detail": {
                          "errorcode": "messaging.adaptors.http.flow.ServiceUnavailable"
                        }
                      }
                    }
                  }
                }
              },
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayTextErrorResponse"
                },
                "examples": {
                  "upstreamUnavailable": {
                    "summary": "HTTP 503 — no healthy upstream",
                    "description": "HTTP 503 with Content-Type: text/plain. Representative infrastructure diagnostic; the exact message depends on the failing hop.",
                    "value": "no healthy upstream"
                  }
                }
              }
            }
          },
          "504": {
            "description": "The gateway or an upstream service did not respond within its timeout. The body can be plain text or a gateway JSON fault; check Content-Type before parsing. Try a smaller check-in-date interval and avoid repeatedly retrying the full range. No fixed interval guarantees completion.",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayTextErrorResponse"
                },
                "examples": {
                  "upstreamTimeout": {
                    "summary": "HTTP 504 — upstream request timeout",
                    "description": "HTTP 504 with Content-Type: text/plain. Representative timeout diagnostic. There is no errors array or guaranteed meta.ruid.",
                    "value": "upstream request timeout"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayFaultResponse"
                },
                "examples": {
                  "gatewayTimeout": {
                    "summary": "HTTP 504 — gateway timeout fault",
                    "description": "HTTP 504 with Content-Type: application/json. Representative native gateway timeout fault; the message and code depend on the failing hop.",
                    "value": {
                      "fault": {
                        "faultstring": "Gateway Timeout",
                        "detail": {
                          "errorcode": "messaging.adaptors.http.flow.GatewayTimeout"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Fallback for HTTP statuses not listed above. Inspect the actual HTTP status and Content-Type. Gateway JSON fields and plain-text diagnostics vary; retain any request identifier supplied. The examples illustrate formats rather than an exhaustive set of gateway errors.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayFallbackResponse"
                },
                "examples": {
                  "gatewayError": {
                    "summary": "Illustrative JSON fallback format",
                    "description": "Content-Type: application/json. Use the actual unlisted HTTP status returned by the gateway. Placeholder values illustrate one possible fault envelope; they are not literal gateway messages or codes.",
                    "value": {
                      "fault": {
                        "faultstring": "<gateway diagnostic>",
                        "detail": {
                          "errorcode": "<gateway fault code>"
                        }
                      }
                    }
                  }
                }
              },
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayTextErrorResponse"
                },
                "examples": {
                  "gatewayError": {
                    "summary": "Illustrative plain-text fallback",
                    "description": "Content-Type: text/plain. Use the actual unlisted HTTP status returned by the gateway. This generic message is illustrative; exact text is not part of the contract.",
                    "value": "Gateway error"
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "HistoricalReservationsResponse": {
        "type": "object",
        "description": "Historical reservations and metadata for this request.",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/HistoricalReservationsData"
          },
          "meta": {
            "$ref": "#/components/schemas/RequestMetadata"
          }
        },
        "required": [
          "data",
          "meta"
        ]
      },
      "HistoricalReservationsData": {
        "type": "object",
        "description": "Reservation data for the requested property. Optional values are omitted when unavailable, rather than returned as null.",
        "properties": {
          "property_id": {
            "type": "integer",
            "format": "int32",
            "minimum": 1,
            "maximum": 2147483647,
            "description": "The Booking.com property ID requested in the path."
          },
          "currency": {
            "type": "string",
            "description": "Currency code for the monetary amounts, for example EUR. Omitted when unavailable; do not infer a currency when this field is absent."
          },
          "property_reservations": {
            "type": "array",
            "description": "Property reservations with matching room reservations. Empty when no eligible room reservations match the check-in range and status filter.",
            "items": {
              "$ref": "#/components/schemas/PropertyReservation"
            }
          }
        },
        "required": [
          "property_id",
          "property_reservations"
        ]
      },
      "PropertyReservation": {
        "type": "object",
        "description": "A property reservation grouping one or more matching room reservations.",
        "properties": {
          "property_reservation_id": {
            "type": "string",
            "description": "Booking.com property reservation identifier.",
            "minLength": 1
          },
          "room_reservations": {
            "type": "array",
            "description": "Matching room reservations. Rooms outside the check-in range or excluded by the status filter are omitted; the entire property reservation is omitted if no rooms match.",
            "items": {
              "$ref": "#/components/schemas/RoomReservation"
            },
            "minItems": 1
          }
        },
        "required": [
          "property_reservation_id",
          "room_reservations"
        ]
      },
      "RoomReservation": {
        "type": "object",
        "description": "Reservation details for a room selected by its check-in date. The created_at field retains the reservation creation timestamp and does not determine selection.",
        "properties": {
          "room_id": {
            "type": "string",
            "description": "Booking.com room product identifier. This identifies the booked room type; it is not a unique room-reservation identifier.",
            "minLength": 1
          },
          "created_at": {
            "type": "string",
            "description": "Reservation creation timestamp in UTC.",
            "format": "date-time"
          },
          "cancelled_at": {
            "type": "string",
            "description": "Cancellation timestamp in UTC when available. Omitted when unavailable.",
            "format": "date-time"
          },
          "checkin": {
            "type": "string",
            "description": "Check-in date as an ISO 8601 calendar date (YYYY-MM-DD).",
            "format": "date"
          },
          "checkout": {
            "type": "string",
            "description": "Check-out date as an ISO 8601 calendar date (YYYY-MM-DD).",
            "format": "date"
          },
          "status": {
            "$ref": "#/components/schemas/ReservationStatus"
          },
          "occupancy": {
            "description": "Guest counts when available. Omitted when unavailable. An absent count does not mean zero.",
            "allOf": [
              {
                "$ref": "#/components/schemas/Occupancy"
              }
            ]
          },
          "guest": {
            "description": "Guest price perspective. total_price is the reservation total value; included indicates whether a component is included in that total. This object and its price components are omitted for net-rate reservations.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ReservationPrice"
              }
            ]
          },
          "hotel": {
            "description": "Property price perspective. total_price is the total net room price; included indicates whether a component is included in the room rate. This required object can differ from the guest price perspective.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ReservationPrice"
              }
            ]
          }
        },
        "required": [
          "room_id",
          "created_at",
          "checkin",
          "checkout",
          "status",
          "hotel"
        ]
      },
      "ReservationStatus": {
        "type": "string",
        "description": "Room reservation status: OK for confirmed reservations, CANCELLED for cancellations, and NO_SHOW for no-shows.",
        "enum": [
          "OK",
          "CANCELLED",
          "NO_SHOW"
        ]
      },
      "Occupancy": {
        "type": "object",
        "description": "Known guest counts. Each count is independently optional and is omitted when unknown.",
        "properties": {
          "adults": {
            "type": "integer",
            "format": "int32",
            "minimum": 0,
            "description": "Number of adults, when known."
          },
          "children": {
            "type": "integer",
            "format": "int32",
            "minimum": 0,
            "description": "Number of children, when known. An explicit zero means no children."
          }
        }
      },
      "ReservationPrice": {
        "type": "object",
        "description": "Monetary values for one price perspective, as major-unit decimal strings in `data.currency`.\n\nConnectivity applies these fractional-digit limits:\n- 0 for AFA, BIF, BYR, CLP, COP, DJF, ECS, GNF, HUF, IDR, ISK, JPY, KMF, KRW, LAK, MGA, MZM, PYG, RWF, TJR, TMM, TWD, UGX, VND, VUV, XAF, XOF and XPF.\n- 3 for BHD, IQD, JOD, KWD, LYD, OMR and TND.\n- 2 for all other currency codes.\n\nThese limits include historical currency codes and can differ from ISO currency fraction digits.\n\nAmounts with more fractional digits than the currency limit are rounded to the nearest value at that limit. Exact halfway amounts are rounded to the value whose last retained digit is even (HALF_EVEN). Shorter scales are preserved without zero-padding.\n\nValues use plain decimal notation without exponents or locale separators. Preserve the returned decimal value.\n\nUse the supplied total instead of reconstructing it by summing components. Totals and components are rounded independently. Components have inclusion flags, and some component categories are omitted.",
        "properties": {
          "total_price": {
            "type": "string",
            "description": "Total amount for this perspective, as a major-unit decimal string in data.currency. When an amount has more fractional digits than the currency limit, the amount is rounded to drop the excess digits using the currency limits and HALF_EVEN rule described in ReservationPrice; shorter scales are preserved. For example, EUR 2.665 becomes \"2.66\", EUR 2.675 becomes \"2.68\", and EUR 12.3 stays \"12.3\". The supplied total is authoritative and need not equal the sum of returned components. See guest and hotel for the meaning of each total.",
            "minLength": 1
          },
          "price_components": {
            "type": "array",
            "description": "Available price components. The array can be empty.",
            "items": {
              "$ref": "#/components/schemas/PriceComponent"
            }
          }
        },
        "required": [
          "total_price",
          "price_components"
        ]
      },
      "PriceComponent": {
        "type": "object",
        "description": "One base-price, fee, or tax component.",
        "properties": {
          "description": {
            "type": "string",
            "description": "Human-readable component description.",
            "minLength": 1
          },
          "type": {
            "type": "string",
            "description": "Component category: `BASE_PRICE` is the base room price. `FEE` is an additional fee. `TAX` is a tax amount.",
            "enum": [
              "FEE",
              "BASE_PRICE",
              "TAX"
            ]
          },
          "price": {
            "type": "string",
            "description": "Component amount as a major-unit decimal string in data.currency, rounded only when it exceeds the currency limit. Uses the currency limits and HALF_EVEN rule described in ReservationPrice; shorter scales are preserved without zero-padding. For example, JPY 1526.99 becomes \"1527\", IDR -12.9 becomes \"-13\", and BHD 1.2345 becomes \"1.234\".",
            "minLength": 1
          },
          "included": {
            "type": "boolean",
            "description": "Inclusion indicator for this price perspective. See `guest` and `hotel` for its meaning."
          }
        },
        "required": [
          "description",
          "type",
          "price",
          "included"
        ]
      },
      "RequestMetadata": {
        "type": "object",
        "description": "Metadata for support and request tracing.",
        "properties": {
          "ruid": {
            "type": "string",
            "description": "Request unique identifier. Include it when contacting Connectivity support."
          }
        },
        "required": [
          "ruid"
        ]
      },
      "ServiceErrorResponse": {
        "type": "object",
        "description": "An error returned while processing the historical reservations request.",
        "properties": {
          "errors": {
            "type": "array",
            "description": "One or more errors.",
            "items": {
              "$ref": "#/components/schemas/ApiError"
            },
            "minItems": 1
          },
          "meta": {
            "$ref": "#/components/schemas/RequestMetadata"
          }
        },
        "required": [
          "errors",
          "meta"
        ]
      },
      "ApiError": {
        "type": "object",
        "description": "Details of an error.",
        "properties": {
          "code": {
            "type": "string",
            "description": "Machine-readable error code."
          },
          "message": {
            "type": "string",
            "description": "Human-readable error description."
          }
        },
        "required": [
          "code",
          "message"
        ]
      },
      "GatewayFaultResponse": {
        "type": "object",
        "description": "A gateway fault, distinct from the service errors array. Read the HTTP status separately. A request identifier may be absent.",
        "properties": {
          "fault": {
            "type": "object",
            "properties": {
              "faultstring": {
                "type": "string",
                "description": "Diagnostic message. Its text can vary; do not parse it as a stable identifier."
              },
              "detail": {
                "type": "object",
                "properties": {
                  "errorcode": {
                    "type": "string",
                    "description": "Gateway fault code."
                  }
                },
                "required": [
                  "errorcode"
                ]
              }
            },
            "required": [
              "faultstring",
              "detail"
            ]
          },
          "meta": {
            "$ref": "#/components/schemas/RequestMetadata"
          }
        },
        "required": [
          "fault"
        ]
      },
      "GatewayTextErrorResponse": {
        "type": "string",
        "description": "Plain-text gateway or upstream diagnostic. There is no JSON envelope or guaranteed request identifier. Use the HTTP status and Content-Type to handle the response; do not depend on exact message text."
      },
      "GatewayFallbackResponse": {
        "type": "object",
        "description": "An otherwise undocumented gateway JSON response. Fields depend on the failure; no particular envelope or error code is guaranteed.",
        "additionalProperties": true
      },
      "GatewayErrorResponse": {
        "type": "object",
        "description": "The shared Connectivity gateway error envelope. Unlike native gateway faults, it includes an errors array and request metadata. Warnings and nullable error details may also be present.",
        "properties": {
          "meta": {
            "$ref": "#/components/schemas/RequestMetadata"
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "Additional gateway warnings; empty for the throttle example."
          },
          "errors": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "string",
                  "description": "Gateway error code; may be empty when the failing policy does not provide one."
                },
                "message": {
                  "type": "string",
                  "description": "Gateway diagnostic; may be empty when the failing policy does not provide one."
                },
                "details": {
                  "type": "object",
                  "nullable": true,
                  "additionalProperties": true,
                  "description": "Additional error details, or null."
                }
              },
              "required": [
                "code",
                "message"
              ]
            }
          }
        },
        "required": [
          "errors",
          "meta"
        ]
      }
    },
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Use a Connectivity API token obtained through token-based authentication. Send `Authorization: Bearer {token}`. Your connection must be authorized to read reservation history for the requested property."
      }
    }
  }
}