{"openapi":"3.1.0","info":{"title":"EffectiveTours Hotel Management API","description":"Comprehensive hotel management system with multi-tenant support, booking channel integrations, and dynamic pricing.\n\n## How to Find Your API Key\n\nTo obtain your API key, log in to EffectiveTours using your company administrator account. Once logged in, click on your company name in the top-right menu to open the dropdown menu. Select \"Company Settings - Company Profile\" from the dropdown.\n\nIn the company settings page, navigate to the \"API Access\" tab. You'll find your API key in the \"API Key\" field. If the field is empty, click the blue button next to it to generate a new key.","version":"0.1.0"},"paths":{"/auth/me":{"get":{"tags":["auth","auth"],"summary":"Get Current Company Info","description":"Get information about the currently authenticated company.\n\nVerify your API authentication and retrieve detailed information about your company,\nincluding business model, company type, and account details.\n\n**Authentication:**\n- Requires valid Bearer token in Authorization header\n- Token must correspond to an active company account\n\n**Response Includes:**\n- Company identification (ID, name)\n- Company type (direct operator vs distributor)\n- Business model configuration\n- Account status and settings\n- Contact and administrative information\n\n**Use Cases:**\n- **Token Validation**: Verify your API key is valid and active\n- **Company Details**: Get current company information for display\n- **Business Logic**: Determine company type for feature access\n- **Account Management**: Retrieve company settings and configuration\n\n**Business Models:**\n- **Direct Operations**: Companies that own and operate hotels directly\n- **Distributor**: Companies that distribute rooms from other hotel operators\n\n**Security:**\n- Only returns information about the authenticated company\n- No access to other companies' data\n- Full audit logging of authentication requests\n\n**Error Responses:**\n- `401`: Invalid or missing authentication token\n- `403`: Token valid but company account is inactive","operationId":"me_auth_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/hotels/":{"get":{"tags":["hotels","hotels"],"summary":"List All Hotels","description":"Get all hotels owned by your company.\n\nRetrieve a comprehensive list of all active hotels belonging to your company,\nincluding geographical information, booking channel connections, and detailed\nproperty information.\n\n**Features:**\n- **Multi-tenant security**: Only returns hotels owned by your company\n- **Rich data**: Includes geographical location with localized names\n- **Channel integrations**: Shows active booking platform connections\n- **Performance optimized**: Uses efficient database queries with eager loading\n\n**Data Included:**\n- Basic hotel information (name, category, address, rate type)\n- Company ownership details\n- Geographical location (country, city) with localized names\n- Active booking channel connections (Agoda, Booking.com, etc.)\n- Channel-specific configurations and settings\n\n**Filtering Applied:**\n- Only active hotels (`is_active = true`)\n- Excludes soft-deleted hotels\n- Only hotels belonging to authenticated company\n- Only active booking channel connections\n\n**Business Models Supported:**\n- **Direct Operations**: Hotels owned and operated directly\n- **Distributor Model**: Hotels managed through distribution agreements","operationId":"get_hotels_hotels__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/HotelResponse"},"type":"array","title":"Response Get Hotels Hotels  Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/hotels/{id}":{"get":{"tags":["hotels","hotels"],"summary":"Get Specific Hotel","description":"Retrieve detailed information for a specific hotel.\n\nGet complete details for a single hotel including all related information\nsuch as geographical location, booking channel integrations, and property details.\n\n**Path Parameters:**\n- **id**: The unique identifier of the hotel\n\n**Response Includes:**\n- Complete hotel information (name, category, address, rate type)\n- Company ownership details\n- Geographical location with localized country and city names\n- Active booking channel connections and configurations\n- Channel-specific settings and integration details\n\n**Access Control:**\n- Only accessible for hotels belonging to your company\n- Automatic filtering of inactive and deleted hotels\n- Multi-tenant security ensures data isolation\n\n**Business Models:**\n- **Direct Operations**: Full hotel details with ownership information\n- **Distributor Model**: Hotel details with distribution agreement info\n\n**Error Responses:**\n- `404`: Hotel not found or not accessible by your company\n- `410`: The hotel belongs to your company but has been permanently removed; any other company, or an unknown id, still gets `404`","operationId":"get_hotel_hotels__id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","title":"Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HotelResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/hotels/{id}/rates":{"get":{"tags":["hotels","hotels","rates"],"summary":"Get Hotel Rate Types","description":"Get all rate types and pricing categories for a hotel.\n\nRetrieve comprehensive information about all available rate types for the specified hotel,\nincluding occupancy configurations and booking channel rate plan connections.\n\n**Path Parameters:**\n- **id**: The unique identifier of the hotel\n\n**Rate Type Information:**\n- Rate names and descriptions\n- Supported occupancy types (single, double, triple, apartment)\n- Food service inclusions (room only, breakfast, half board, full board)\n- Booking channel rate plan mappings\n- Active rates only (inactive rates are filtered out)\n\n**Channel Integrations:**\n- Rate plan IDs for each booking platform\n- Platform-specific configurations\n- Multiple rate plans per channel support\n- Channel-specific markup and pricing rules\n\n**Access Control:**\n- Hotel must belong to your company\n- Only active rate types are returned\n- Multi-tenant data scoping applied\n\n**Error Responses:**\n- `404`: Hotel not found or not accessible by your company\n- `410`: The hotel belongs to your company but has been permanently removed; any other company, or an unknown id, still gets `404`","operationId":"get_hotel_rates_hotels__id__rates_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","title":"Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RateResponse"},"title":"Response Get Hotel Rates Hotels  Id  Rates Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/hotels/{id}/rooms":{"get":{"tags":["hotels","hotels","rooms"],"summary":"Get Hotel Rooms","description":"Get all rooms and inventory for a specific hotel.\n\nRetrieve information about all physical and virtual rooms within the hotel,\nincluding occupancy configurations and associated rate types.\n\n**Path Parameters:**\n- **id**: The unique identifier of the hotel\n\n**Room Information:**\n- Room numbers and identifiers\n- Room types and categories\n- Occupancy configurations (single, double, triple, apartment support)\n- Physical vs virtual room designations\n- Room characteristics and amenities\n\n**Rate Type Associations:**\n- Available rate types for each room\n- Many-to-many relationships between rooms and rates\n- Rate-specific occupancy support per room\n\n**Room Types Included:**\n- **Physical rooms**: Actual hotel rooms with specific numbers/identifiers\n- **Virtual rooms**: Inventory management units for booking systems\n- **All occupancy types**: Single, double, triple, apartment configurations\n- **Active rooms only**: Inactive and deleted rooms are filtered out\n\n**Distributor Hotels:**\n- For distributor hotels, rooms are automatically resolved from the\n  parent hotel to ensure consistency with reservation endpoints\n- Room IDs returned here can be used directly with POST /hotels/{id}/reservations\n\n**Access Control:**\n- Hotel must belong to your company\n- Only active rooms are returned\n- Multi-tenant data scoping ensures security\n\n**Error Responses:**\n- `404`: Hotel not found or not accessible by your company\n- `410`: The hotel belongs to your company but has been permanently removed; any other company, or an unknown id, still gets `404`","operationId":"get_hotel_rooms_hotels__id__rooms_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","title":"Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RoomResponse"},"title":"Response Get Hotel Rooms Hotels  Id  Rooms Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/hotels/{id}/rates/{rate_id}/prices":{"get":{"tags":["hotels","hotels","rates","pricing"],"summary":"Get Daily Pricing","description":"Get daily pricing for a specific hotel rate type.\n\nRetrieve comprehensive daily pricing information with business model-aware calculations.\nPricing adapts automatically based on your company type and business model.\n\n**Path Parameters:**\n- **id**: The unique identifier of the hotel\n- **rate_id**: The unique identifier of the rate type\n\n**Business Model Logic:**\n- **Distributor Companies**: Base prices shown as sell prices, no buy prices\n- **Direct Operations**: Buy prices (your cost) and sell prices (with markup)\n- **Dynamic Markup**: Automatic markup application based on configurations\n\n**Pricing Structure:**\n- **Buy Prices**: Your cost prices (null for distributors)\n- **Sell Prices**: Customer-facing prices (base for distributors, marked up for direct)\n- **Occupancy Types**: Single, double, triple, apartment pricing\n- **Date Range**: Current and future prices only\n\n**Response Data:**\n- Daily price entries with specific dates\n- Occupancy-specific pricing (sgl, dbl, tpl, full)\n- Buy and sell prices per occupancy type\n- Only supported occupancy types (unsupported return null)\n\n**Validation:**\n- Hotel ownership verification\n- Rate type belongs to specified hotel\n- Proper business model calculations applied\n\n**Example Response:**\n```json\n[\n  {\n    \"date\": \"2024-01-15\",\n    \"sgl_buy\": null,\n    \"sgl_sell\": \"100.00\",\n    \"dbl_buy\": \"80.00\",\n    \"dbl_sell\": \"120.00\",\n    \"tpl_buy\": null,\n    \"tpl_sell\": null,\n    \"full_buy\": \"150.00\",\n    \"full_sell\": \"200.00\"\n  }\n]\n```\n\n**Error Responses:**\n- `404`: Hotel or rate type not found or not accessible\n- `410`: The hotel belongs to your company but has been permanently removed; any other company, or an unknown id, still gets `404`","operationId":"get_hotel_rate_prices_hotels__id__rates__rate_id__prices_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","title":"Id"}},{"name":"rate_id","in":"path","required":true,"schema":{"type":"integer","title":"Rate Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DayPriceResponse"},"title":"Response Get Hotel Rate Prices Hotels  Id  Rates  Rate Id  Prices Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["hotels","hotels","rates","pricing"],"summary":"Update Daily Pricing","description":"Update daily pricing for a hotel rate type (distributors only).\n\nSubmit daily price updates for a specific rate type. Only distributor companies\ncan update pricing through this endpoint.\n\n**Path Parameters:**\n- **id**: The unique identifier of the hotel\n- **rate_id**: The unique identifier of the rate type\n\n**Authorization:**\n- **Distributor companies only**: Direct operation companies cannot update prices\n- Hotel and rate must be accessible by your company\n\n**Request Body:**\n- Array of daily price updates\n- Each entry specifies date and occupancy-specific prices\n- Prices for unsupported occupancy types are automatically filtered\n\n**Pricing Rules:**\n- Only supported occupancy types are accepted\n- Unsupported occupancy prices are automatically set to null\n- Rate type configuration determines which occupancies are valid\n\n**Validation Process:**\n- Verifies distributor authorization\n- Validates hotel and rate accessibility\n- Filters prices by rate type occupancy support\n- Updates or creates price records as needed\n\n**Example Request:**\n```json\n[\n  {\n    \"date\": \"2024-01-15\",\n    \"sgl\": \"100.00\",\n    \"dbl\": \"120.00\",\n    \"tpl\": null,\n    \"full\": \"200.00\"\n  }\n]\n```\n\n**Response:**\n- Returns updated pricing with same format as GET endpoint\n- Includes business logic calculations\n- Shows only supported occupancy types\n\n**Error Responses:**\n- `403`: Company is not authorized (not a distributor)\n- `404`: Hotel or rate type not found or not accessible\n- `410`: The hotel belongs to your company but has been permanently removed; any other company, or an unknown id, still gets `404`\n\n**Note:** Price updates are immediately saved and cannot be undone through the API.","operationId":"update_hotel_rate_prices_hotels__id__rates__rate_id__prices_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","title":"Id"}},{"name":"rate_id","in":"path","required":true,"schema":{"type":"integer","title":"Rate Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DayPriceRequest"},"title":"Prices"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DayPriceResponse"},"title":"Response Update Hotel Rate Prices Hotels  Id  Rates  Rate Id  Prices Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/hotels/{hotel_id}/ota-update":{"post":{"tags":["hotels","hotels","availability"],"summary":"Trigger OTA Availability Update","description":"Manually trigger OTA availability updates for a hotel.\n\nAllows hotel distributors and hoteliers to manually trigger availability updates\nfor booking channel platforms. et-new calls the ET website's update-ota endpoint\n(`safe_call_update_availability`), which only ENQUEUES per-channel jobs on the ET\nDjango side; whether any given OTA channel (Agoda/Booking/Expedia/Airbnb) accepts\nthe push is decided later, asynchronously, and is not known at response time. The\nendpoint also publishes an AVAILABILITY_UPDATE event; that event alone does not\nupdate any channel either.\n\n**Path Parameters:**\n- **hotel_id**: The unique identifier of the hotel\n\n**Request Body:**\n- **start_date**: Starting date for availability update (required, must be today or future)\n- **end_date**: Ending date for availability update (optional, must be after start_date)\n- **channel_id**: Specific booking channel to update (optional, updates all if not specified)\n\n**Authorization:**\n- **Distributor/Hotelier companies only**: Only companies with distributor or hotelier type can trigger updates\n- **Hotel access required**: Company must own the hotel OR have read-book or full access permissions\n\n**Validation Rules:**\n- start_date must be today or in the future\n- end_date must be after start_date when provided\n- channel_id must be a valid ChannelCode enum value (agoda, booking, expedia, airbnb)\n- Company must have distributor or hotelier type\n- Company must have appropriate access to the hotel\n\n**Event Publishing:**\n- Publishes AVAILABILITY_UPDATE event with hotel, date range, and channel information\n- Event includes trace ID for observability and debugging\n- Publishing failures are logged but don't fail the request\n- The channel push requires ET_WEBSITE_BASE_URL; when it is unset the push is skipped and\n  logged as an error, while `success` in the response is still `true`\n\n**Response:**\n- `success` is always `true` on a well-formed request (kept for backward compatibility)\n- `ota_push` carries what actually happened calling ET Django: `sent` (bool), `status`\n  (ET Django's own `\"success\"`/`\"ERROR\"`, when sent), `message` (ET Django's message,\n  e.g. \"house not found\" / \"no active channels\", when provided), `reason` (why nothing\n  was sent: `not_configured` / `http_error` / `timeout` / `invalid_response`), and a\n  `note` that per-channel OTA delivery results are not available in this response\n- Example: `{\"success\": true, \"ota_push\": {\"sent\": true, \"status\": \"ERROR\",\n  \"message\": \"no active channels\", \"reason\": null, \"note\": \"...\"}}`\n\n**Error Responses:**\n- `403`: Company type not authorized (not distributor/hotelier) or no hotel access\n- `404`: Hotel not found or not accessible\n- `410`: The hotel belongs to your company but has been permanently removed; any other company, or an unknown id, still gets `404`\n- `422`: Validation errors (invalid dates, channel codes)\n\n**Usage Examples:**\n```json\n// Update all channels for date range\n{\n  \"start_date\": \"2024-01-15\",\n  \"end_date\": \"2024-01-30\"\n}\n\n// Update specific channel for single date\n{\n  \"start_date\": \"2024-01-15\",\n  \"channel_id\": \"booking\"\n}\n\n// Update all channels for single date\n{\n  \"start_date\": \"2024-01-15\"\n}\n```\n\n**Business Logic:**\n- Only distributor and hotelier company types can trigger OTA updates\n- Hotel ownership provides automatic access\n- READ_BOOK and FULL_ACCESS permissions allow OTA updates\n- READ_ONLY permissions are insufficient for OTA updates\n- Events are published with company and hotel context for downstream processing","operationId":"launch_ota_update_hotels__hotel_id__ota_update_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"hotel_id","in":"path","required":true,"schema":{"type":"integer","title":"Hotel Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OTAUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OTAUpdateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/hotels/{hotel_id}/reservations":{"get":{"tags":["reservations","reservations"],"summary":"Get Hotel Reservations","description":"Retrieve all reservations for a specific hotel.\n\nGet a list of reservations for the specified hotel. You can optionally filter\nreservations by date range and choose between basic or detailed response format.\n\n**Query Parameters:**\n- **full**: Set to `true` for detailed reservation information (guest details subject to visibility rules)\n- **start**: Filter reservations starting from this date (YYYY-MM-DD format)\n- **end**: Filter reservations ending up to this date (YYYY-MM-DD format)\n\n**Response Format:**\n- When `full=false` (default): Returns basic reservation information (carries no guest data)\n- When `full=true`: Returns detailed reservation information (guest details subject to visibility rules)\n\n**Guest data visibility:**\n- Hotel owner: full guest data on every reservation.\n- Every non-owner company (agent / distributor), whatever its access level, FA included:\n  guest data only on reservations it authored itself; on all others `first_name`, `last_name`, `client` answer `null` and `comment` answers `\"\"`; dates, room, rate, status, head count and price stay.\n- When `full=false` (default), the basic list carries no guest data for any caller.\n\n**Access Control:**\n- Only returns reservations for hotels belonging to your company\n- Supports both direct hotel ownership and distributor access","operationId":"get_reservations_hotels__hotel_id__reservations_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"hotel_id","in":"path","required":true,"schema":{"type":"integer","title":"Hotel Id"}},{"name":"full","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Full"}},{"name":"start","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Start"}},{"name":"end","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"End"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/ReservationResponse"},{"$ref":"#/components/schemas/ReservationBaseResponse"}]},"title":"Response Get Reservations Hotels  Hotel Id  Reservations Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["reservations","reservations"],"summary":"Create New Reservation","description":"Create a new reservation for a hotel.\n\nSubmit a new reservation request with guest details, room preferences, and booking dates.\nThe system will validate availability and create the reservation if all checks pass.\n\n**Authentication:**\n- A company API key (scoped to that company), or\n- The platform/service token together with an explicit `company_id` query\n  parameter (acts on that company's behalf — one credential for many\n  companies).\n\n**Booking target (one of):**\n- `room_id` — book a specific physical room (wins when supplied).\n- `rate_id` (room type) — omit `room_id` and the server auto-assigns an\n  available physical room of that type for the dates.\n\n**Authorship:**\n- The reservation records the calling company as its author — with the\n  platform token, the `company_id` it acts for. Only the author may cancel it.\n\n**Idempotency:**\n- When a non-empty `reference` is supplied and a live reservation already\n  exists for that `(company, reference)`, the existing reservation is\n  returned with status `200` instead of creating a duplicate. A replay never\n  double-books. Another company's reservation with the same reference is\n  never returned — the create proceeds as if it did not exist. The hotel\n  owner also replays onto a reservation that carries no author (created\n  before authorship was recorded).\n\n**Validation Process:**\n- Hotel ownership verification\n- Room availability check for requested dates\n- Rate validation (if rate_id provided)\n- Guest information validation\n- Accommodation type compatibility with room\n\n**Error Responses:**\n- `400`: Room not available for requested dates\n- `403`: Access denied to hotel\n- `404`: Hotel not found\n- `410`: The hotel belongs to your company but has been permanently removed; any other company, or an unknown id, still gets `404`\n- `409`: No room of the requested type is available for the dates\n- `422`: Validation errors (invalid room, rate, or guest data)","operationId":"create_reservation_hotels__hotel_id__reservations_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"hotel_id","in":"path","required":true,"schema":{"type":"integer","title":"Hotel Id"}},{"name":"company_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Target company id. Required only when authenticating with the platform/service token; ignored for per-company API keys.","title":"Company Id"},"description":"Target company id. Required only when authenticating with the platform/service token; ignored for per-company API keys."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReservationCreateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReservationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["reservations","reservations"],"summary":"Cancel Reservations By Reference","description":"Cancel the whole booking set for a correlation id (`reference`).\n\nLets a caller cancel by the `reference` it stamped at create time instead of\npersisting ET's numeric reservation id. Every live reservation the calling\ncompany created carrying the reference (and its direct children) is\nsoft-deleted; another company's reservations with the same reference are\nleft alone. The hotel owner may also cancel reservations that carry no\nauthor (created before authorship was recorded).\n\n**Authentication:** same as create — a company API key, or the platform token\nplus an explicit `company_id`.\n\n**Idempotency:** a repeat cancel after everything is already cancelled is a\nsuccess no-op (`200`). A change signal is emitted only for reservations this\ncall actually cancels.\n\n**Response:** `{\"status\": \"OK\", \"cancelled\": <count>}`.\n\n**Error Responses:**\n- `403`: Access denied to hotel\n- `404`: Hotel not found, or this company never had a reservation with that\n  reference — another company's reservation answers the same `404`\n- `410`: The hotel belongs to your company but has been permanently removed; any other company, or an unknown id, still gets `404`\n- `500`: Unexpected error during cancellation","operationId":"cancel_reservations_by_reference_hotels__hotel_id__reservations_delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"hotel_id","in":"path","required":true,"schema":{"type":"integer","title":"Hotel Id"}},{"name":"reference","in":"query","required":true,"schema":{"type":"string","minLength":1,"description":"Correlation id (reference_code) of the booking set to cancel","title":"Reference"},"description":"Correlation id (reference_code) of the booking set to cancel"},{"name":"company_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Target company id. Required only when authenticating with the platform/service token; ignored for per-company API keys.","title":"Company Id"},"description":"Target company id. Required only when authenticating with the platform/service token; ignored for per-company API keys."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/hotels/{hotel_id}/reservations/{id}":{"get":{"tags":["reservations","reservations"],"summary":"Get Specific Reservation","description":"Retrieve detailed information for a specific reservation.\n\nGet details for a single reservation including room details, dates, booking\nstatus, and guest information (where visible).\n\n**Path Parameters:**\n- **hotel_id**: The unique identifier of the hotel\n- **id**: The unique identifier of the reservation\n\n**Response Includes:**\n- Reservation details\n- Guest information (name, email, phone, where visible)\n- Room and accommodation details\n- Check-in/check-out dates\n- Booking status and reference code\n\n**Guest data visibility:**\n- Hotel owner: full guest data on every reservation.\n- Every non-owner company (agent / distributor), whatever its access level, FA included:\n  guest data only on reservations it authored itself; on all others `first_name`, `last_name`, `client` answer `null` and `comment` answers `\"\"`; dates, room, rate, status, head count and price stay.\n\n**Access Control:**\n- Only accessible for reservations in hotels belonging to your company\n- Returns 404 if reservation or hotel not found or not accessible","operationId":"get_reservation_hotels__hotel_id__reservations__id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"hotel_id","in":"path","required":true,"schema":{"type":"integer","title":"Hotel Id"}},{"name":"id","in":"path","required":true,"schema":{"type":"integer","title":"Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReservationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/hotels/{hotel_id}/reservations/{reservation_id}":{"patch":{"tags":["reservations","reservations"],"summary":"Update Existing Reservation","description":"Update an existing hotel reservation.\n\nModify reservation details such as dates, room assignment, guest information,\nor booking status. Only provided fields will be updated.\n\n**Path Parameters:**\n- **hotel_id**: The unique identifier of the hotel\n- **reservation_id**: The unique identifier of the reservation to update\n\n**Updatable Fields:**\n- Guest information (first_name, last_name, email, phone)\n- Room assignment (room_id)\n- Dates (checkin, checkout)\n- Guest count (adults, children)\n- Accommodation type\n- Rate type (rate_id)\n- Booking reference\n- Comments\n- Acceptance status\n\n**Validation Process:**\n- Verifies reservation belongs to specified hotel\n- Checks room availability for new dates (excluding current reservation)\n- Validates new room/rate compatibility if changed\n- Ensures accommodation type matches room capabilities\n\n**Partial Updates:**\n- Send only the fields you want to update\n- Existing values are preserved for omitted fields\n- The `id` field in the payload must match the reservation_id in the URL\n\n**Access Control:**\n- Only the company that owns the reservation's room (the hotel owner) may\n  update it — not the company that booked it, and not an agent with access\n  to the hotel. For any other company the reservation answers `404`, as if\n  it did not exist.\n- A room owner whose company type is AGENT also needs FULL access to the\n  hotel, otherwise `403`.\n\n**Error Responses:**\n- `400`: Invalid data or room unavailable for new dates\n- `403`: Access denied to hotel\n- `404`: Hotel or reservation not found\n- `410`: The hotel belongs to your company but has been permanently removed; any other company, or an unknown id, still gets `404`\n- `422`: Validation errors for updated fields","operationId":"update_reservation_hotels__hotel_id__reservations__reservation_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"hotel_id","in":"path","required":true,"schema":{"type":"integer","title":"Hotel Id"}},{"name":"reservation_id","in":"path","required":true,"schema":{"type":"integer","title":"Reservation Id"}},{"name":"company_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Target company id. Required only when authenticating with the platform/service token; ignored for per-company API keys.","title":"Company Id"},"description":"Target company id. Required only when authenticating with the platform/service token; ignored for per-company API keys."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReservationUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReservationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["reservations","reservations"],"summary":"Delete Reservation","description":"Delete a hotel reservation by its numeric id.\n\nPermanently remove a reservation from the system. This performs a soft delete\nby marking the reservation as deleted rather than physically removing it.\n\nTo cancel a whole booking set by its correlation id instead of the numeric\nid, use `DELETE /hotels/{hotel_id}/reservations?reference=<ref>`.\n\n**Path Parameters:**\n- **hotel_id**: The unique identifier of the hotel\n- **reservation_id**: The unique identifier of the reservation to delete\n\n**Idempotency:**\n- Cancelling an already-cancelled reservation is a success no-op (`200`),\n  not an error — so a retry is always safe. No event is re-emitted when\n  nothing changed.\n\n**Deletion Process:**\n- Marks the reservation as deleted (soft delete)\n- Includes any direct child reservations in the deletion\n- Preserves data for audit and reporting purposes\n\n**Access Control:**\n- Only the company that created the reservation may delete it; the hotel\n  owner may also delete reservations that carry no author (created before\n  authorship was recorded). Another company's reservation answers `404`,\n  as if it did not exist.\n\n**Response:**\n- Returns `{\"status\": \"OK\"}` on successful (or idempotent) deletion\n\n**Error Responses:**\n- `403`: Access denied to hotel\n- `404`: Hotel or reservation not found (never existed)\n- `410`: The hotel belongs to your company but has been permanently removed; any other company, or an unknown id, still gets `404`\n- `500`: Unexpected error during deletion process","operationId":"delete_reservation_hotels__hotel_id__reservations__reservation_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"hotel_id","in":"path","required":true,"schema":{"type":"integer","title":"Hotel Id"}},{"name":"reservation_id","in":"path","required":true,"schema":{"type":"integer","title":"Reservation Id"}},{"name":"company_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Target company id. Required only when authenticating with the platform/service token; ignored for per-company API keys.","title":"Company Id"},"description":"Target company id. Required only when authenticating with the platform/service token; ignored for per-company API keys."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/hotels/{hotel_id}/bookings/cancelled":{"get":{"tags":["reservations","reservations"],"summary":"Get Cancelled Bookings","description":"Retrieve all cancelled bookings for a specific hotel.\n\nGet a list of cancelled bookings from booking channels (Agoda, Booking.com, Expedia, etc.)\nfor the specified hotel. You can optionally filter bookings by date range.\n\n**Query Parameters:**\n- **start**: Start date filter in YYYY-MM-DD format\n- **end**: End date filter in YYYY-MM-DD format\n\n**Date Filtering Logic:**\n- When both start and end are provided: Returns bookings where `checkin < end AND checkout > start`\n- When only start is provided: Returns bookings where `checkout > start`\n- When only end is provided: Returns bookings where `checkin < end`\n- When no dates are provided: Returns bookings where `checkout >= today`\n\n**Date Range Validation:**\n- Start date must be before or equal to end date if both are provided\n- Dates must be in YYYY-MM-DD format\n\n**Cancelled Status Filter:**\n- Only returns bookings with status: \"CancelBooking\", \"cancelled\", or \"Cancel\"\n\n**Access Control:**\n- Only returns cancelled bookings for hotels belonging to your company\n- Supports both direct hotel ownership and distributor access\n\n**Response Includes:**\n- Channel information (name, ID, rate plan)\n- Room type details\n- Check-in and check-out dates\n- Guest information (name, contact details, where visible)\n- Pricing information (total, tax, fees, commission)\n- Booking metadata (booking date, extra info)\n\n**Guest data visibility:**\n- Hotel owner: full guest data.\n- Every non-owner company (agent / distributor), whatever its access level, FA included:\n  every `guest` field is empty (channel bookings have no author on this API).","operationId":"get_cancelled_bookings_hotels__hotel_id__bookings_cancelled_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"hotel_id","in":"path","required":true,"schema":{"type":"integer","title":"Hotel Id"}},{"name":"start","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Start"}},{"name":"end","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"End"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelledBookingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/health":{"get":{"tags":["core"],"summary":"Health","description":"Perform basic application health check.\n\nReturns application status information for monitoring and load balancer health checks.\nThis endpoint verifies that the application is running and responsive but does not\nperform deep health checks like database connectivity.\n\nReturns:\n    dict: Health status information containing:\n        - status: Application status (\"ok\" indicates healthy)\n\nExample:\n    ```python\n    {\n        \"status\": \"ok\"\n    }\n    ```\n\nNote:\n    For comprehensive health checks including database connectivity,\n    consider implementing additional endpoints that verify external dependencies.","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"CancelledBookingItem":{"properties":{"channel":{"type":"string","title":"Channel","description":"Booking channel name"},"channel_id":{"type":"string","title":"Channel Id","description":"Channel booking identifier"},"rate_plan_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rate Plan Id","description":"Rate plan identifier"},"room_type":{"type":"string","title":"Room Type","description":"Room type name"},"checkin":{"type":"string","format":"date","title":"Checkin","description":"Check-in date"},"checkout":{"type":"string","format":"date","title":"Checkout","description":"Check-out date"},"room_count":{"type":"integer","title":"Room Count","description":"Number of rooms booked","default":1},"adults":{"type":"integer","title":"Adults","description":"Number of adults","default":1},"children":{"type":"integer","title":"Children","description":"Number of children","default":0},"currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency","description":"Booking currency"},"tax":{"type":"string","title":"Tax","description":"Tax amount","default":0},"fees":{"type":"string","title":"Fees","description":"Fees amount","default":0},"price":{"type":"string","title":"Price","description":"Total booking price"},"commission":{"type":"string","title":"Commission","description":"Commission amount","default":0},"guest":{"$ref":"#/components/schemas/GuestInfo","description":"Guest information"},"booking_date":{"type":"string","format":"date-time","title":"Booking Date","description":"Date when booking was made"},"room_extra_info":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Room Extra Info","description":"Additional room information"}},"type":"object","required":["channel","channel_id","room_type","checkin","checkout","price","guest","booking_date"],"title":"CancelledBookingItem","description":"Schema for individual cancelled booking item."},"CancelledBookingResponse":{"properties":{"bookings":{"items":{"$ref":"#/components/schemas/CancelledBookingItem"},"type":"array","title":"Bookings","description":"List of cancelled bookings"}},"type":"object","required":["bookings"],"title":"CancelledBookingResponse","description":"Schema for cancelled bookings API response."},"ChannelCode":{"type":"string","enum":["agoda","booking","expedia","airbnb"],"title":"ChannelCode","description":"Enumeration of booking channel codes."},"ChannelHotel":{"properties":{"agoda_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agoda Id"},"agoda_markup":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agoda Markup"},"agoda_zone_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Agoda Zone Id"},"agoda_interest":{"type":"integer","title":"Agoda Interest","default":0},"agoda_decrease":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agoda Decrease"},"booking_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Booking Id"},"booking_markup":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Booking Markup"},"booking_zone_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Booking Zone Id"},"booking_interest":{"type":"integer","title":"Booking Interest","default":0},"booking_decrease":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Booking Decrease"},"expedia_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expedia Id"},"expedia_markup":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expedia Markup"},"expedia_decrease":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expedia Decrease"},"airbnb_markup":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Airbnb Markup"},"airbnb_interest":{"type":"integer","title":"Airbnb Interest","default":0},"airbnb_decrease":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Airbnb Decrease"}},"type":"object","title":"ChannelHotel","description":"Database model for booking channel integration settings.\n\nStores configuration and connection information for major booking platforms\nincluding Agoda, Booking.com, Expedia, and Airbnb. Each hotel can have\nchannel-specific settings for pricing, markup, and zone management.\n\nForeign Key Relationships:\n    - house_id: References houses_house.id (one-to-one relationship with Hotel)\n\nChannel Configuration:\n    Each booking channel (Agoda, Booking.com, Expedia, Airbnb) has:\n    - Activation flag (is_<channel>): Whether the channel is enabled\n    - Channel ID (<channel>_id): Platform-specific hotel identifier\n    - Markup settings (<channel>_markup): Pricing markup configuration\n    - Zone ID (<channel>_zone_id): Platform zone classification (where applicable)\n    - Interest rate (<channel>_interest): Commission or interest percentage\n    - Decrease amount (<channel>_decrease): Price reduction settings\n\nAttributes:\n    id: Primary key identifier for the channel settings record.\n    house_id: Foreign key linking to the associated hotel.\n    is_active: Whether channel settings are currently active.\n\n    Agoda Channel Settings:\n        is_agoda: Activation flag for Agoda integration.\n        agoda_id: Agoda platform hotel identifier.\n        agoda_markup: Markup configuration for Agoda pricing.\n        agoda_zone_id: Agoda zone classification ID.\n        agoda_interest: Interest rate percentage for Agoda.\n        agoda_decrease: Price decrease amount for Agoda.\n\n    Booking.com Channel Settings:\n        is_booking: Activation flag for Booking.com integration.\n        booking_id: Booking.com platform hotel identifier.\n        booking_markup: Markup configuration for Booking.com pricing.\n        booking_zone_id: Booking.com zone classification ID.\n        booking_interest: Interest rate percentage for Booking.com.\n        booking_decrease: Price decrease amount for Booking.com.\n\n    Expedia Channel Settings:\n        is_expedia: Activation flag for Expedia integration.\n        expedia_id: Expedia platform hotel identifier.\n        expedia_markup: Markup configuration for Expedia pricing.\n        expedia_decrease: Price decrease amount for Expedia.\n\n    Airbnb Channel Settings:\n        is_airbnb: Activation flag for Airbnb integration.\n        airbnb_markup: Markup configuration for Airbnb pricing.\n        airbnb_interest: Interest rate percentage for Airbnb.\n        airbnb_decrease: Price decrease amount for Airbnb."},"ChannelRate":{"properties":{"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"name":{"type":"string","title":"Name"},"food":{"type":"string","title":"Food","default":"RO"},"room_count":{"type":"integer","title":"Room Count","default":0},"is_agoda":{"type":"boolean","title":"Is Agoda","default":false},"agoda_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Agoda Id"},"occupancy":{"type":"integer","title":"Occupancy","default":0},"rate_plan_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rate Plan Id"},"is_booking":{"type":"boolean","title":"Is Booking","default":false},"booking_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Booking Id"},"booking_rate":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Booking Rate"},"is_expedia":{"type":"boolean","title":"Is Expedia","default":false},"expedia_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expedia Id"},"expedia_rate":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expedia Rate"},"is_active":{"type":"boolean","title":"Is Active","default":true},"room_type_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Room Type Id"}},"type":"object","required":["name"],"title":"ChannelRate","description":"Database model for booking channel rate and room type integration settings.\n\nStores configuration for room types and rate plans across different booking channels.\nThis model connects hotel room types with their corresponding identifiers and settings\non various booking platforms (Agoda, Booking.com, Expedia).\n\nForeign Key Relationships:\n    - room_type_id: References houses_roomtype.id (many-to-one relationship with Rate)\n\nRelationships:\n    - room_type: Many-to-one relationship with Rate (room type) object\n\nChannel Configuration:\n    Each booking channel has specific fields for rate management:\n    - Activation flag (is_<channel>): Whether the channel is enabled for this rate\n    - Channel ID (<channel>_id): Platform-specific rate identifier\n    - Rate plan settings: Platform-specific rate plan configurations\n    - Occupancy settings: Guest capacity information\n\nAttributes:\n    id: Primary key identifier for the channel rate record.\n    name: Rate name or description.\n    food: Food service type (default: \"RO\" - Room Only).\n    room_count: Number of rooms available for this rate.\n    occupancy: Maximum occupancy for this rate type.\n    is_active: Whether this rate configuration is currently active.\n    room_type_id: Foreign key linking to the associated room type.\n    room_type: The room type this rate configuration belongs to.\n\n    Agoda Channel Settings:\n        is_agoda: Activation flag for Agoda rate integration.\n        agoda_id: Agoda platform rate identifier.\n        rate_plan_id: Agoda rate plan identifier.\n\n    Booking.com Channel Settings:\n        is_booking: Activation flag for Booking.com rate integration.\n        booking_id: Booking.com platform rate identifier.\n        booking_rate: Booking.com rate plan identifier.\n\n    Expedia Channel Settings:\n        is_expedia: Activation flag for Expedia rate integration.\n        expedia_id: Expedia platform rate identifier.\n        expedia_rate: Expedia rate plan identifier."},"ChannelResponse":{"properties":{"id":{"type":"integer","title":"Id","description":"Channel booking ID"},"name":{"type":"string","title":"Name","description":"Display name of the booking channel"},"rate_plan_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rate Plan Id","description":"Rate plan identifier from the channel"},"payment_preferences":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Payment Preferences","description":"Payment collection preferences for the channel"}},"type":"object","required":["id","name"],"title":"ChannelResponse","description":"Schema for representing a booking channel in API responses."},"CityName":{"properties":{"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"city_id":{"type":"integer","title":"City Id"},"name":{"type":"string","title":"Name"},"language_id":{"type":"integer","title":"Language Id"}},"type":"object","required":["city_id","name","language_id"],"title":"CityName","description":"Database model for city names with language support.\n\nStores city names in multiple languages, linked to cities via foreign key.\nEach city can have multiple names for different languages.\n\nForeign Key Relationships:\n    - city_id: References geo_city.id (many-to-one relationship)\n\nAttributes:\n    id: Primary key for the city name record.\n    city_id: Foreign key linking to the parent city.\n    name: The city name in a specific language.\n    language_id: Foreign key reference to the language identifier.\n    city: SQLModel relationship to the parent City object."},"CityResponse":{"properties":{"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"country":{"anyOf":[{"$ref":"#/components/schemas/CountryResponse"},{"type":"null"}]},"name":{"type":"string","title":"Name","description":"Get the localized city name.\n\nReturns the first name from the filtered names list (based on language_id).\nSince names are pre-filtered by language in the database query, this provides\ndirect access to the appropriate localized name.\n\nReturns:\n    str: Localized city name or empty string if no names available.","readOnly":true}},"type":"object","required":["name"],"title":"CityResponse","description":"Response model for city information in API responses.\n\nProvides city data with localized name access and country relationship.\nThe names list is excluded from API responses to simplify client consumption.\n\nAttributes:\n    id: City identifier.\n    country: Associated country information with localized name.\n    names: List of city names in different languages (excluded from response).\n    name: Computed field providing localized city name for the configured language."},"ClientResponse":{"properties":{"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"name":{"type":"string","title":"Name","default":"","nullable":false},"first_name":{"type":"string","title":"First Name","default":"","nullable":false},"last_name":{"type":"string","title":"Last Name","default":"","nullable":false},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email","default":"","nullable":false},"phone":{"type":"string","title":"Phone","default":"","nullable":false}},"type":"object","title":"ClientResponse","description":"Schema for representing a client in API responses."},"Company":{"properties":{"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"name":{"type":"string","title":"Name"},"company_type":{"type":"string","title":"Company Type"},"api_key":{"type":"string","title":"Api Key"},"slug":{"type":"string","title":"Slug"},"email":{"type":"string","title":"Email"},"business_type":{"type":"string","title":"Business Type"},"timezone":{"type":"string","title":"Timezone"},"tariff_plan":{"type":"string","title":"Tariff Plan"},"is_active":{"type":"boolean","title":"Is Active","default":true},"is_deleted":{"type":"boolean","title":"Is Deleted","default":false},"address":{"type":"string","title":"Address","default":""},"phone":{"type":"string","title":"Phone","default":""},"smtp_type":{"type":"string","title":"Smtp Type","default":"GMAIL"},"smtp_tls":{"type":"boolean","title":"Smtp Tls","default":true},"imap_ssl":{"type":"boolean","title":"Imap Ssl","default":true},"sns_topic":{"type":"string","title":"Sns Topic","default":""},"color_accepted":{"type":"integer","title":"Color Accepted","default":0},"color_agoda":{"type":"integer","title":"Color Agoda","default":0},"color_booking":{"type":"integer","title":"Color Booking","default":0},"color_hold":{"type":"integer","title":"Color Hold","default":0},"color_expedia":{"type":"integer","title":"Color Expedia","default":0},"api_original_photos":{"type":"boolean","title":"Api Original Photos","default":false},"prepayment_taxi":{"type":"integer","title":"Prepayment Taxi","default":0},"is_use_pms":{"type":"boolean","title":"Is Use Pms","default":false},"bill_payment":{"type":"string","title":"Bill Payment","default":""},"is_blocked":{"type":"boolean","title":"Is Blocked","default":false},"is_trial_used":{"type":"boolean","title":"Is Trial Used","default":false},"is_moto":{"type":"boolean","title":"Is Moto","default":false},"card_processing":{"type":"string","title":"Card Processing","default":""},"sbp_account_id":{"type":"string","title":"Sbp Account Id","default":""},"sbp_legal_id":{"type":"string","title":"Sbp Legal Id","default":""},"sbp_mcc_id":{"type":"integer","title":"Sbp Mcc Id","default":0},"is_wise":{"type":"boolean","title":"Is Wise","default":false},"email_reminders":{"type":"string","title":"Email Reminders","default":""},"currency_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Currency Id"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["name","company_type","api_key","slug","email","business_type","timezone","tariff_plan"],"title":"Company","description":"Company database model with authentication and business information.\n\nRepresents companies in the hotel management system with authentication\ncapabilities using API keys. Companies can be distributors, agents, or\ndirect operators with different access levels and business models.\n\nAuthentication:\n    Companies authenticate using API keys to access hotel management endpoints.\n    API keys are indexed for fast authentication lookups.\n\nBusiness Types:\n    - DISTRIBUTOR: Companies that distribute hotel inventory\n    - HOTELIER: Companies that operate hotels directly\n    - AGENT: Companies that act as booking agents\n    - DIRECT: Companies with direct booking operations\n\nAttributes:\n    id: Primary key identifier for the company.\n    name: Company name.\n    company_type: Type/category of the company for business logic.\n    api_key: API key for authentication (indexed for fast lookups).\n    slug: URL-friendly company identifier.\n    email: Company contact email address.\n    business_type: Detailed business type classification.\n    timezone: Company's operational timezone.\n    tariff_plan: Pricing plan for the company.\n    is_active: Whether the company account is active.\n    is_deleted: Soft delete flag for the company."},"CompanyResponse":{"properties":{"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"name":{"type":"string","title":"Name"},"company_type":{"type":"string","title":"Company Type"}},"type":"object","required":["name","company_type"],"title":"CompanyResponse","description":"Response model for company information in hotel responses.\n\nSimplified company information used within hotel response objects\nto avoid circular imports and provide only necessary company data.\n\nAttributes:\n    id: Company identifier.\n    name: Company name.\n    company_type: Type or category of the company."},"CountryName":{"properties":{"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"country_id":{"type":"integer","title":"Country Id"},"name":{"type":"string","title":"Name"},"language_id":{"type":"integer","title":"Language Id"}},"type":"object","required":["country_id","name","language_id"],"title":"CountryName","description":"Database model for country names with language support.\n\nStores country names in multiple languages, linked to countries via foreign key.\nEach country can have multiple names for different languages.\n\nForeign Key Relationships:\n    - country_id: References geo_country.id (many-to-one relationship)\n\nAttributes:\n    id: Primary key for the country name record.\n    country_id: Foreign key linking to the parent country.\n    name: The country name in a specific language.\n    language_id: Foreign key reference to the language identifier.\n    country: SQLModel relationship to the parent Country object."},"CountryResponse":{"properties":{"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"code":{"type":"string","title":"Code","nullable":false},"name":{"type":"string","title":"Name","description":"Get the localized country name.\n\nReturns the first name from the filtered names list (based on language_id).\nSince names are pre-filtered by language in the database query, this provides\ndirect access to the appropriate localized name.\n\nReturns:\n    str: Localized country name or empty string if no names available.","readOnly":true}},"type":"object","required":["code","name"],"title":"CountryResponse","description":"Response model for country information in API responses.\n\nProvides country data with localized name access through computed fields.\nThe names list is excluded from API responses to simplify client consumption.\n\nAttributes:\n    id: Country identifier.\n    code: Country code (e.g., ISO country codes).\n    names: List of country names in different languages (excluded from response).\n    name: Computed field providing localized country name for the configured language."},"DayPriceRequest":{"properties":{"date":{"type":"string","format":"date","title":"Date","nullable":false},"sgl":{"anyOf":[{"type":"number","minimum":0.0},{"type":"string"},{"type":"null"}],"title":"Sgl"},"dbl":{"anyOf":[{"type":"number","minimum":0.0},{"type":"string"},{"type":"null"}],"title":"Dbl"},"tpl":{"anyOf":[{"type":"number","minimum":0.0},{"type":"string"},{"type":"null"}],"title":"Tpl"},"full":{"anyOf":[{"type":"number","minimum":0.0},{"type":"string"},{"type":"null"}],"title":"Full"}},"type":"object","required":["date"],"title":"DayPriceRequest"},"DayPriceResponse":{"properties":{"date":{"type":"string","format":"date","title":"Date","nullable":false},"sgl_buy":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sgl Buy","readOnly":true},"sgl_sell":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sgl Sell","readOnly":true},"dbl_buy":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dbl Buy","readOnly":true},"dbl_sell":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dbl Sell","readOnly":true},"tpl_buy":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tpl Buy","readOnly":true},"tpl_sell":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tpl Sell","readOnly":true},"full_buy":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Full Buy","readOnly":true},"full_sell":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Full Sell","readOnly":true}},"type":"object","required":["date","sgl_buy","sgl_sell","dbl_buy","dbl_sell","tpl_buy","tpl_sell","full_buy","full_sell"],"title":"DayPriceResponse","description":"Response model for daily pricing with company-aware business logic.\n\nProvides comprehensive daily pricing information that adapts to different business models\n(distributor vs direct operation) and applies dynamic markup calculations. This model\nencapsulates complex pricing logic while presenting clean, computed price fields.\n\nBusiness Model Support:\n    - Direct Operations: Shows buy prices (cost) and sell prices (with markup applied)\n    - Distributor Operations: Shows only sell prices (base prices without markup)\n    - Occupancy-Based Pricing: Different prices for single, double, triple, and apartment occupancy\n    - Dynamic Markup: Contextual markup application based on rate type and company configuration\n\nPricing Architecture:\n    - Base Values: Raw price data from DayPrice model (excluded from API response)\n    - Buy Prices: Cost prices for direct operation companies (null for distributors)\n    - Sell Prices: Final prices for customer-facing display (includes markup for direct operations)\n    - Occupancy Support: Prices only shown for supported occupancy types per room type\n\nContext Injection:\n    The model requires company context and markup information to be injected through\n    the factory method. This enables business logic processing while maintaining\n    clean separation between data models and business rules.\n\nComputed Price Fields:\n    Each occupancy type has both buy and sell computed properties:\n    - sgl_buy/sgl_sell: Single occupancy pricing\n    - dbl_buy/dbl_sell: Double occupancy pricing\n    - tpl_buy/tpl_sell: Triple occupancy pricing\n    - full_buy/full_sell: Apartment/full accommodation pricing\n\nPrice Calculation Logic:\n    1. Check if occupancy type is supported by room type\n    2. For distributors: Return base price as sell price, null for buy price\n    3. For direct operations: Return base price as buy, calculated markup as sell\n    4. Return null for unsupported occupancy types\n\nAttributes:\n    day: The specific date for pricing.\n    sgl_value: Base single occupancy price (excluded from response).\n    dbl_value: Base double occupancy price (excluded from response).\n    tpl_value: Base triple occupancy price (excluded from response).\n    apartment_value: Base apartment price (excluded from response).\n    room_type: Associated rate type for occupancy support validation (excluded from response).\n    company: Company context for business logic (excluded from response).\n    markup: Markup configuration for price calculations (excluded from response).\n    rate_type: Rate type for markup application (excluded from response).\n\n    Computed Properties (API Response):\n    - sgl_buy, sgl_sell: Single occupancy buy/sell prices\n    - dbl_buy, dbl_sell: Double occupancy buy/sell prices\n    - tpl_buy, tpl_sell: Triple occupancy buy/sell prices\n    - full_buy, full_sell: Apartment buy/sell prices"},"GuestInfo":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","description":"Guest first name"},"surname":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Surname","description":"Guest surname"},"nationality":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nationality","description":"Guest nationality"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email","description":"Guest email address"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country","description":"Guest country"},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City","description":"Guest city"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address","description":"Guest address"},"post_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Post Code","description":"Guest postal code"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone","description":"Guest phone number"},"comments":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Comments","description":"Guest comments"}},"type":"object","title":"GuestInfo","description":"Schema for guest information in cancelled bookings."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HotelResponse":{"properties":{"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"name":{"type":"string","title":"Name","nullable":false},"category":{"type":"string","title":"Category","nullable":false},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"rate_type":{"type":"string","title":"Rate Type","nullable":false},"company":{"anyOf":[{"$ref":"#/components/schemas/CompanyResponse"},{"type":"null"}]},"city":{"anyOf":[{"$ref":"#/components/schemas/CityResponse"},{"type":"null"}]},"connections":{"additionalProperties":true,"type":"object","title":"Connections","description":"Get organized booking channel connection information.\n\nProcesses the raw channel_hotel data to provide a clean, organized\nstructure of active booking channel configurations. Only includes\nchannels that are marked as active (is_<channel> = True).\n\nChannel Processing:\n    - Checks activation flags for each supported channel\n    - Maps raw database fields to clean response structures\n    - Applies appropriate aliases for consistent API naming\n    - Excludes inactive channels from the response\n\nSupported Channels:\n    - agoda: Agoda.com integration settings\n    - booking: Booking.com integration settings\n    - expedia: Expedia.com integration settings\n    - airbnb: Airbnb integration settings\n\nReturns:\n    dict[str, dict[str, Any]]: Dictionary with channel names as keys\n    and their respective configuration settings as values. Empty dict\n    if no channel_hotel data or no active channels.\n\nExample:\n    {\n        \"agoda\": {\n            \"id\": \"agoda_123\",\n            \"markup\": \"percentage\",\n            \"zone_id\": 1001,\n            \"interest\": 5,\n            \"decrease\": \"10.50\"\n        },\n        \"booking\": {\n            \"id\": \"booking_456\",\n            \"markup\": \"fixed\",\n            \"zone_id\": 2001,\n            \"interest\": 3,\n            \"decrease\": \"15.00\"\n        }\n    }","readOnly":true}},"type":"object","required":["name","category","rate_type","connections"],"title":"HotelResponse","description":"Response model for hotel data in API responses.\n\nProvides comprehensive hotel information including company ownership,\ngeographical location with localized names, and booking channel integrations.\n\nFeatures:\n    - Complete hotel details (name, category, address, rate type)\n    - Company information through CompanyResponse relationship\n    - City and country data with localized names via computed fields\n    - Booking channel connections via computed 'connections' field\n    - Automatic filtering of active booking channels only\n\nAttributes:\n    id: Hotel identifier.\n    name: Hotel name.\n    category: Hotel category or star rating.\n    address: Hotel physical address.\n    rate_type: Rate or pricing model type.\n    company: Company ownership information.\n    city: City location with country relationship and localized names.\n    channel_hotel: Raw channel data (excluded from API response).\n    connections: Computed field with organized booking channel settings."},"OTAPushResult":{"properties":{"sent":{"type":"boolean","title":"Sent","description":"Whether the request reached ET Django and got a parseable response"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status","description":"ET Django's own status for the request ('success' or 'ERROR'), when sent"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message","description":"ET Django's message (e.g. reason for an ERROR status), when provided"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason","description":"Why the request was not sent, when sent is false: 'not_configured' (ET_WEBSITE_BASE_URL unset), 'http_error', 'timeout', or 'invalid_response'"},"note":{"type":"string","title":"Note","description":"Always-present caveat: this does not mean any OTA channel was updated","default":"OTA channels are updated asynchronously; per-channel results are not available in this response"}},"type":"object","required":["sent"],"title":"OTAPushResult","description":"What actually happened when et-new forwarded the update to ET Django.\n\nET Django only enqueues per-channel jobs (RQ) for OTA delivery; whether any given\nchannel (Agoda/Booking/Expedia/Airbnb) accepted the push is NOT known at response\ntime. This reports only the outcome of the et-new -> ET Django call itself."},"OTAUpdateRequest":{"properties":{"start_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Start Date","description":"Start date for availability update (defaults to today if not provided)"},"end_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"End Date","description":"End date for availability update (optional, must be after start_date)"},"channel_id":{"anyOf":[{"$ref":"#/components/schemas/ChannelCode"},{"type":"null"}],"description":"Specific booking channel to update (optional, updates all if not specified)"}},"type":"object","title":"OTAUpdateRequest","description":"Request schema for triggering OTA availability updates.\n\nThis schema defines the payload structure for manual OTA update triggers,\nallowing hotel distributors and hoteliers to synchronize availability data\nwith booking channel platforms.\n\nFeatures:\n- Date range validation ensuring start_date is today or future\n- Optional end_date with validation that it's after start_date\n- Optional channel filtering using ChannelCode enum\n- Automatic validation using Pydantic field validators\n\nBusiness Logic:\n- start_date must be >= today to prevent historical updates\n- end_date is optional; when provided, must be after start_date\n- channel_id filters updates to specific booking platforms\n- No channel_id means update all configured channels\n\nAttributes:\n    start_date: Beginning date for availability update (required)\n    end_date: Ending date for availability update (optional)\n    channel_id: Specific booking channel to update (optional)"},"OTAUpdateResponse":{"properties":{"success":{"type":"boolean","title":"Success","default":true},"ota_push":{"$ref":"#/components/schemas/OTAPushResult"}},"type":"object","required":["ota_push"],"title":"OTAUpdateResponse","description":"Response schema for POST /{hotel_id}/ota-update.\n\n``success`` stays ``true`` on any well-formed request for backward compatibility\nwith existing clients; ``ota_push`` carries the real outcome of the call to ET\nDjango's update-ota endpoint."},"Rate":{"properties":{"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"code":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Code"},"name":{"type":"string","title":"Name"},"food":{"type":"string","title":"Food","default":"RO"},"sgl":{"type":"boolean","title":"Sgl","default":false},"dbl":{"type":"boolean","title":"Dbl","default":false},"tpl":{"type":"boolean","title":"Tpl","default":false},"child":{"type":"boolean","title":"Child","default":false},"apartment":{"type":"boolean","title":"Apartment","default":false},"full_max_guests":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Full Max Guests"},"whole_house":{"type":"boolean","title":"Whole House","default":false},"is_active":{"type":"boolean","title":"Is Active","default":true},"is_deleted":{"type":"boolean","title":"Is Deleted","default":false},"show_on_minisite":{"type":"boolean","title":"Show On Minisite","default":false},"min_stay":{"type":"integer","title":"Min Stay","default":1},"critical_stay":{"type":"integer","title":"Critical Stay","default":1},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"house_id":{"type":"integer","title":"House Id"}},"type":"object","required":["name","house_id"],"title":"Rate","description":"Database model for hotel room types and rate categories.\n\nRepresents different rate types and pricing categories available in hotels.\nRate types define pricing structures and service levels that can be applied\nto multiple physical rooms through many-to-many relationships. Each rate can\nhave multiple channel configurations for different booking platforms.\n\nForeign Key Relationships:\n    - house_id: References houses_house.id (many-to-one relationship with Hotel)\n\nRelationships:\n    - house: Many-to-one relationship with Hotel object\n    - channel_rates: One-to-many relationship with ChannelRate objects, filtered by active status\n                    and loaded eagerly using joined loading for optimal performance\n    - rooms: Many-to-many relationship with Room objects through RoomRatePivot,\n            filtered by active rooms and loaded eagerly using joined loading\n\nRate Configuration:\n    The model supports various rate types and occupancy configurations:\n    - Single occupancy (sgl): Rates for single occupancy bookings\n    - Double occupancy (dbl): Rates for double occupancy bookings\n    - Triple occupancy (tpl): Rates for triple occupancy bookings\n    - Apartment style (apartment): Rates for apartment-style accommodations\n    - Food service integration: Different meal plans and service levels\n\nFlexible Rate Assignment:\n    Through the many-to-many relationship with rooms, rates enable:\n    - Multiple pricing tiers for the same physical room\n    - Seasonal rate variations across room inventory\n    - Service level differentiation (room only, breakfast, half-board, etc.)\n    - Promotional and special offer rates\n\nAttributes:\n    id: Primary key identifier for the rate type.\n    code: Rate type code for internal classification and ordering.\n    name: Rate type name or description.\n    food: Food service type included (default: \"RO\" - Room Only).\n    sgl: Whether this rate supports single occupancy.\n    dbl: Whether this rate supports double occupancy.\n    tpl: Whether this rate supports triple occupancy.\n    apartment: Whether this is an apartment-style accommodation rate.\n    is_active: Whether this rate type is currently active.\n    is_deleted: Soft delete flag for the rate type.\n    house_id: Foreign key linking to the parent hotel.\n    house: The hotel this rate type belongs to.\n    channel_rates: List of active channel rate configurations for this rate type.\n                  Uses joined loading and filtered by is_active=True for performance.\n    rooms: List of physical rooms associated with this rate type through pivot table.\n           Uses joined loading for optimal performance."},"RateBaseResponse":{"properties":{"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"name":{"type":"string","title":"Name","nullable":false},"food":{"type":"string","title":"Food","default":"RO"}},"type":"object","required":["name"],"title":"RateBaseResponse","description":"Base response model for rate type information.\n\nProvides essential rate type data that can be used in different contexts\nwithout the complexity of channel connections or occupancy configurations.\nThis base model is useful for embedded rate information within room responses\nor simplified rate listings.\n\nAttributes:\n    id: Rate type identifier.\n    name: Rate type name or description.\n    food: Food service type included (e.g., \"RO\" for Room Only, \"BB\" for Bed & Breakfast)."},"RateResponse":{"properties":{"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"name":{"type":"string","title":"Name","nullable":false},"food":{"type":"string","title":"Food","default":"RO"},"sgl":{"type":"boolean","title":"Sgl","default":false},"dbl":{"type":"boolean","title":"Dbl","default":false},"tpl":{"type":"boolean","title":"Tpl","default":false},"full":{"type":"boolean","title":"Full","default":false},"connections":{"additionalProperties":{"items":{"additionalProperties":true,"type":"object"},"type":"array"},"type":"object","title":"Connections","description":"Get organized booking channel rate information.\n\nProcesses the raw channel_rates data to provide clean, organized\nrate plan information grouped by booking platform. Only includes\nrates that are active and have valid channel-specific identifiers.\n\nChannel Processing Logic:\n    - Agoda: Requires is_agoda=True, valid agoda_id, and rate_plan_id\n    - Booking.com: Requires is_booking=True, valid booking_id, and booking_rate\n    - Expedia: Requires is_expedia=True, valid expedia_id, and expedia_rate\n    - Each platform can have multiple rate plans for the same room type\n\nRate Plan Grouping:\n    Each booking channel can have multiple rate configurations,\n    allowing for different occupancy levels, seasonal rates, or\n    package deals within the same room type.\n\nReturns:\n    dict[str, list[dict[str, Any]]]: Dictionary with channel names as keys\n    and lists of rate configurations as values. Each rate configuration\n    includes platform-specific identifiers and settings.\n\nExample:\n    {\n        \"agoda\": [\n            {\n                \"rate_id\": 123,\n                \"rate_plan_id\": 456,\n                \"occupancy\": 2\n            },\n            {\n                \"rate_id\": 124,\n                \"rate_plan_id\": 457,\n                \"occupancy\": 3\n            }\n        ],\n        \"booking\": [\n            {\n                \"rate_id\": 789,\n                \"rate_plan_id\": 101,\n                \"occupancy\": 2\n            }\n        ]\n    }","readOnly":true}},"type":"object","required":["name","connections"],"title":"RateResponse","description":"Response model for hotel room type and rate information.\n\nProvides comprehensive room type information including occupancy configurations\nand booking channel rate integrations. The response includes computed channel\nconnections that organize rate plans by booking platform.\n\nFeatures:\n    - Complete room type details (name, food service, occupancy types)\n    - Occupancy configuration flags (single, double, triple, apartment)\n    - Booking channel rate connections via computed 'connections' field\n    - Automatic filtering of active channel rates only\n    - Organized rate plans grouped by booking platform\n\nAttributes:\n    id: Room type identifier.\n    name: Room type name or description.\n    food: Food service type included (e.g., \"RO\" for Room Only).\n    sgl: Whether this rate supports single occupancy.\n    dbl: Whether this rate supports double occupancy.\n    tpl: Whether this rate supports triple occupancy.\n    apartment: Whether this is apartment-style accommodation (aliased as 'full' in response).\n    channel_rates: Raw channel rate data (excluded from API response).\n    connections: Computed field with organized booking channel rate information."},"ReservationBaseResponse":{"properties":{"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"checkin":{"type":"string","format":"date","title":"Checkin","nullable":false},"checkout":{"type":"string","format":"date","title":"Checkout","nullable":false},"is_accepted":{"type":"boolean","title":"Is Accepted","default":false},"adults":{"type":"integer","title":"Adults","default":1,"nullable":false},"children":{"type":"integer","title":"Children","default":0,"nullable":false},"is_fake":{"type":"boolean","title":"Is Fake","default":false},"room":{"anyOf":[{"$ref":"#/components/schemas/RoomBaseResponse"},{"type":"null"}]},"rate":{"anyOf":[{"$ref":"#/components/schemas/RateBaseResponse"},{"type":"null"}]},"channel":{"anyOf":[{"$ref":"#/components/schemas/ChannelResponse"},{"type":"null"}],"description":"Booking channel information if available"}},"type":"object","required":["checkin","checkout"],"title":"ReservationBaseResponse","description":"Base schema for a reservation response, containing essential details."},"ReservationCreateRequest":{"properties":{"room_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Room Id","nullable":true},"rate_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rate Id","nullable":true},"accommodation":{"type":"string","title":"Accommodation","nullable":false},"checkin":{"type":"string","format":"date","title":"Checkin","nullable":false},"checkout":{"type":"string","format":"date","title":"Checkout","nullable":false},"adults":{"type":"integer","title":"Adults","default":1,"nullable":false},"children":{"type":"integer","title":"Children","default":0,"nullable":false},"is_accepted":{"type":"boolean","title":"Is Accepted","default":false,"nullable":false},"reference":{"type":"string","title":"Reference","default":"","nullable":false},"first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Name","nullable":true},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Name","nullable":true},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email","nullable":true},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone","nullable":true},"comment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Comment","nullable":true},"price":{"anyOf":[{"type":"number","minimum":0.0},{"type":"string"},{"type":"null"}],"title":"Price"},"revenue":{"anyOf":[{"type":"number"},{"type":"string"},{"type":"null"}],"title":"Revenue"}},"type":"object","required":["accommodation","checkin","checkout"],"title":"ReservationCreateRequest","description":"Schema for creating a new reservation.\n\nA caller may book in one of two spaces:\n\n- **Physical-room space**: supply ``room_id`` (wins when present).\n- **Room-type space**: omit ``room_id`` and supply ``rate_id`` (the\n  room type); the server auto-assigns an available physical room for the\n  dates. See CR 2026-07-10-etnew-public-reservation-write-contract (item 2)."},"ReservationResponse":{"properties":{"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"checkin":{"type":"string","format":"date","title":"Checkin","nullable":false},"checkout":{"type":"string","format":"date","title":"Checkout","nullable":false},"is_accepted":{"type":"boolean","title":"Is Accepted","default":false},"adults":{"type":"integer","title":"Adults","default":1,"nullable":false},"children":{"type":"integer","title":"Children","default":0,"nullable":false},"is_fake":{"type":"boolean","title":"Is Fake","default":false},"room":{"anyOf":[{"$ref":"#/components/schemas/RoomBaseResponse"},{"type":"null"}]},"rate":{"anyOf":[{"$ref":"#/components/schemas/RateBaseResponse"},{"type":"null"}]},"channel":{"anyOf":[{"$ref":"#/components/schemas/ChannelResponse"},{"type":"null"}],"description":"Booking channel information if available"},"first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Name","nullable":true},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Name","nullable":true},"price":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Price","nullable":true},"revenue":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Revenue","nullable":true},"comment":{"type":"string","title":"Comment","default":"","nullable":false},"reference_code":{"type":"string","title":"Reference Code","default":"","nullable":false},"client":{"anyOf":[{"$ref":"#/components/schemas/ClientResponse"},{"type":"null"}]}},"type":"object","required":["checkin","checkout","first_name","last_name","price","revenue"],"title":"ReservationResponse","description":"Detailed schema for a reservation response, including guest and pricing info."},"ReservationUpdateRequest":{"properties":{"id":{"type":"integer","title":"Id","nullable":false},"room_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Room Id","nullable":true},"rate_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rate Id","nullable":true},"accommodation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accommodation","nullable":true},"checkin":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Checkin","nullable":true},"checkout":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Checkout","nullable":true},"adults":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Adults","nullable":true},"children":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Children","nullable":true},"is_accepted":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Accepted","nullable":true},"reference":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reference","nullable":true},"first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Name","nullable":true},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Name","nullable":true},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email","nullable":true},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone","nullable":true},"comment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Comment","nullable":true},"price":{"anyOf":[{"type":"number","minimum":0.0},{"type":"string"},{"type":"null"}],"title":"Price"},"revenue":{"anyOf":[{"type":"number"},{"type":"string"},{"type":"null"}],"title":"Revenue"}},"type":"object","required":["id"],"title":"ReservationUpdateRequest","description":"Schema for updating an existing reservation."},"RoomBaseResponse":{"properties":{"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"name":{"type":"string","title":"Name","nullable":false},"sgl":{"type":"boolean","title":"Sgl","default":false},"dbl":{"type":"boolean","title":"Dbl","default":false},"tpl":{"type":"boolean","title":"Tpl","default":false},"apartment":{"type":"boolean","title":"Apartment","default":false},"is_virtual":{"type":"boolean","title":"Is Virtual","default":false}},"type":"object","required":["name"],"title":"RoomBaseResponse","description":"Response model for hotel room information."},"RoomResponse":{"properties":{"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"name":{"type":"string","title":"Name","nullable":false},"sgl":{"type":"boolean","title":"Sgl","default":false},"dbl":{"type":"boolean","title":"Dbl","default":false},"tpl":{"type":"boolean","title":"Tpl","default":false},"apartment":{"type":"boolean","title":"Apartment","default":false},"is_virtual":{"type":"boolean","title":"Is Virtual","default":false},"rates":{"items":{"$ref":"#/components/schemas/RateBaseResponse"},"type":"array","title":"Rates"}},"type":"object","required":["name"],"title":"RoomResponse","description":"Response model for hotel room information with associated rate types.\n\nProvides comprehensive room information including room characteristics,\noccupancy configurations, and associated rate types. This model represents\nphysical or virtual rooms within a hotel inventory system.\n\nFeatures:\n    - Complete room details (name, occupancy types, virtual status)\n    - Occupancy configuration flags for different guest arrangements\n    - Associated rate types through embedded RateBaseResponse objects\n    - Support for both physical and virtual inventory management\n\nRoom Types:\n    - Physical Rooms: Actual hotel rooms with specific locations/numbers\n    - Virtual Rooms: Logical inventory categories for flexible booking management\n\nOccupancy Support:\n    The model indicates which guest arrangements are supported:\n    - Single (sgl): Room suitable for one guest\n    - Double (dbl): Room suitable for two guests/couple\n    - Triple (tpl): Room can accommodate three guests\n    - Apartment (apartment): Full apartment with separate living areas\n\nAttributes:\n    id: Room identifier.\n    name: Room name or identifier (e.g., \"101\", \"Presidential Suite\", \"Standard Virtual\").\n    sgl: Whether this room supports single occupancy.\n    dbl: Whether this room supports double occupancy.\n    tpl: Whether this room supports triple occupancy.\n    apartment: Whether this is apartment-style accommodation.\n    is_virtual: Whether this is a virtual room for inventory management purposes.\n    rates: List of rate types associated with this room through many-to-many relationship.\n           Each rate provides basic information (id, name, food service type).\n\nUsage Context:\n    This model is typically used for:\n    - Room inventory listings\n    - Availability displays showing room-rate combinations\n    - Booking interfaces where guests select specific rooms\n    - Hotel management systems for room configuration"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer"}}},"servers":[{"url":"/v1"}]}